From 9852b061a561f0e475dc2aba0c0cffdf49cf070b Mon Sep 17 00:00:00 2001 From: Noah Gift Date: Thu, 15 Oct 2026 12:56:10 +0200 Subject: [PATCH] fix(rex): S-4 cap in decide() records its reason (FALSIFY-RXG-008) decide() capped a devbox or unnamed-primary lane above tripwire at Tripwire without adding a reason when the report alone was below tripwire, so the Decision said Tripwire while its reasons explained shadow. The S-4 branch now pushes one "S-4:" reason unless capped() already did. RXG-008 asserts exactly one S-4 reason for vote and tie-breaker lanes on a shadow report and on a full one. It goes red with the fix reverted. Follow-up to the C314 refusal on #5393. Co-Authored-By: Claude Opus 5.5 --- crates/aprender-review-experiment/src/ladder.rs | 6 ++++++ crates/aprender-review-experiment/src/ladder_tests.rs | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/crates/aprender-review-experiment/src/ladder.rs b/crates/aprender-review-experiment/src/ladder.rs index cdf644e4a0..c8f0cffdc9 100644 --- a/crates/aprender-review-experiment/src/ladder.rs +++ b/crates/aprender-review-experiment/src/ladder.rs @@ -282,6 +282,12 @@ pub fn decide(report_json: &str, prereg_sha: &str, current: Mode) -> Decision { Err(d) => (d, false), }; if devbox && current > Mode::Tripwire { + if !d.reasons.iter().any(|r| r.starts_with("S-4:")) { + d.reasons.push(format!( + "S-4: {current:?} lane on a devbox or unnamed primary cell is capped at Tripwire at once; the report alone gives {:?} (R-9)", + d.mode + )); + } d.mode = Mode::Tripwire; return d; } diff --git a/crates/aprender-review-experiment/src/ladder_tests.rs b/crates/aprender-review-experiment/src/ladder_tests.rs index 22fed4c0d7..13935419ec 100644 --- a/crates/aprender-review-experiment/src/ladder_tests.rs +++ b/crates/aprender-review-experiment/src/ladder_tests.rs @@ -330,6 +330,17 @@ fn falsify_rxg_008_never_skips_a_rung_and_demotes_one() { decide(&devbox_h4_fail.to_string(), PREREG, Mode::Shadow).mode, Mode::Shadow ); + // ...and a devbox vote lane whose report alone is shadow is still capped + // at tripwire, with S-4 named as the reason exactly once + for current in [Mode::Vote, Mode::TieBreaker] { + let d = decide(&devbox_h4_fail.to_string(), PREREG, current); + assert_eq!(d.mode, Mode::Tripwire, "{:?}", d.reasons); + let s4 = d.reasons.iter().filter(|r| r.starts_with("S-4:")).count(); + assert_eq!(s4, 1, "{:?}", d.reasons); + } + let d = decide(&devbox, PREREG, Mode::Vote); + let s4 = d.reasons.iter().filter(|r| r.starts_with("S-4:")).count(); + assert_eq!(s4, 1, "{:?}", d.reasons); // a tripwire-only report demotes a vote lane one rung, not two let h4_only = drop_h(drop_h(full(), "H5"), "H7").to_string(); assert_eq!(decide(&h4_only, PREREG, Mode::Vote).mode, Mode::TieBreaker);