fix(tests): gate _FakeLoop fakes that carry probe monitor state - #8301
fix(tests): gate _FakeLoop fakes that carry probe monitor state#8301dwu96 wants to merge 1 commit into
Conversation
Main breakage: the five terminal-subject tests #8201 added fail on every branch. #8201 branched before #5184 landed is_structured_monitor_loop (monitor set + gate falsy = structured controller record), and merged at 20:08Z with green-but-stale CI, so the semantic conflict was never run. Its _FakeLoop fixtures carry probe 'monitor' state but never set 'gate', a shape production never stores: the probe only runs on gated prompt loops, so a real loop with monitor.terminal_pending always has gate=True. The un-gated fakes misroute monitor_update into the structured branch, which rejects legacy fields ('monitor_update cannot apply legacy fields to a structured monitor'). Give _FakeLoop the production invariant: gate is True exactly when the fake carries monitor state. Test-only change; all 50 tests in the file pass, previously 45 passed + 5 failed.
|
Independent verification, for merge confidence on this main-red:
|
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
Opus 4.8 Review — ✅ no blocking findingsReviewed Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
Design Review (Fable 5) — ✅ PASSDesign-level review of All claims verified: Design-Verdict: PASS Root-cause test-only fix at the right layer: the fixture now encodes the production invariant once, instead of patching five call sites. [DESIGN-REVIEWED] f4ec9d7 |
|
Hi @dwu96 — thanks for picking this up! Heads-up that main moved again and this PR is now showing CONFLICTING, which also means its own CI can't dispatch. This fix is currently the unblocker for the No rush at all, but whenever you get a chance, a rebase onto current main would unblock the queue. Happy to help verify on our side once it's re-pushed. 🙏 |
|
Closing as superseded: #8317 (merged 2026-09-03T23:46Z) fixes the same main breakage with the same shape — gating the The diagnosis this PR carried (the #8201/#5184 green-but-stale-CI merge race, the production invariant that probe state only exists on gated loops, and the independent macOS repro by @jeeshofone in the thread) matches what #8317 shipped, so nothing here is lost by closing. Thanks @bolichen97 for the fast fix. |
Symptom (main breakage — blocks every open PR's backend shards)
The five terminal-subject tests #8201 added in
test/test_autonudge_stop_auth.pyfail on current main (b2320e02c) and on every branch cut from it, withmonitor_update cannot apply legacy fields to a structured monitor(or0 == 1update-call counts). First seen asBackend Tests (Windows) (1)red on PR #8291; reproduced locally on a pristineorigin/mainworktree on Linux — it is platform-independent main breakage, not a shard flake.Root cause: a merge race, not a bad fix
is_structured_monitor_loop: a loop withmonitorset andgatefalsy is read as a structured controller record, and_monitor_updateroutes it to_structured_monitor_update, which rejects legacy fields (message,max_cycles,active).git merge-base --is-ancestorconfirms feat: expose session monitors to agents #5184 is not in fix(autonudge): treat a merged subject as terminal when a paused loop's cap is raised #8201's branch) and merged at 20:08Z with green-but-stale CI, so the semantic conflict never ran._FakeLoopfixtures carry probemonitorstate but never setgate— a shape production never stores: the observation probe only runs on gated prompt loops (autonudge.py:2916), so any real loop withmonitor.terminal_pendinghasgate=True. The un-gated fakes misroute into the structured branch and the legacy patch is refused.Fix (test-only, one invariant)
_FakeLoopnow setsgate = monitor is not None, mirroring the production invariant, with a comment explaining why. Nosrc/change; #8201's production behaviour is correct once the fixture has the shape real loops have.Verification
origin/main(b2320e02c) locally, identical to CI.test/test_autonudge_stop_auth.pypasses 50/50 (was 45 passed + 5 failed)._FakeLoopis module-local (no cross-file imports); black (26.3.1) + flake8 clean.Pattern harvest
Rule candidate: a test fake that carries a state field must also carry every invariant production couples to that field (here: probe
monitorstate exists only ongate=Trueloops) — otherwise a later dispatcher keyed on the coupled field silently reroutes the fake down a branch production never takes. Knowingly out-of-scope sibling: the general "PR merged with green-but-stale CI across a semantic conflict" class (merge-queue/re-run-on-merge policy) is a process question, not fixable in this test file.