fix(cb-r9ac): the unchanged-work guard measures a start against the queue the pass found - #472
Conversation
…ueue the pass found The start path recorded a role's fingerprint after `facts.take` removed the handed bead, so the record already lacked it. A pass that merged and closed exactly that bead left the live queue equal to the record, `unchanged` held the next start, and the only bugfixer in atlantis-hud sat idle for twenty minutes while three candidates waited. The fingerprint is now taken before the hand-off: a pass that closes its bead reads as changed and starts again on the next candidate; one that gives it back untouched reads as unchanged and is held, which is what the guard is for. Covered by a start_due test that hands one of two beads, ends the pass, and asks the guard both ways. Also rewrites the one `grep -q` pipeline in tests/worktree-safety.sh that scripts/pipefail-pipelines refuses, so `bash tests/gate` is green again. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKiLr59caM9f6DxkrsDYR8
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
The change alters load-bearing fleet-supervision timing logic whose correctness depends on subtle within-tick ordering, warranting a final human check.
Review effort: Balanced
Findings: None
What changed in this PR
This PR fixes a timing bug in the fleet view's start_due (fleet-view/src/main.rs), where the "unchanged-work" guard's fingerprint was recorded after facts.take had already removed the just-handed bead from the queue. As a result, a pass that closed exactly its one handed bead left the live queue equal to the recorded fingerprint, so the guard misread it as "nothing changed" and held the next start — in atlantis-hud the only bugfixer sat idle for 20+ minutes with three candidates queued. The fingerprint is now captured before the hand-off, so a pass that closes its bead reads as changed (starts again) while a pass that returns its bead untouched reads as unchanged (correctly held).
Changes:
- Capture the start fingerprint (
found) beforefacts.takeinstart_due, and use it inledger.note_started. - Add explanatory doc comments in
triggers.rs::unchangedandmain.rsdescribing the "queue as found" semantics. - Add a regression test (
a_pass_that_took_its_bead_off_the_queue_is_not_held_as_unchanged) covering both the closed-bead and returned-bead cases. - Rewrite the
grep -qpipeline intests/worktree-safety.shthatscripts/pipefail-pipelinesrefuses, keeping the local gate green.
| File | Description |
|---|---|
fleet-view/src/main.rs |
Records the start fingerprint before facts.take; adds a regression test for the closed vs. returned-bead cases. |
fleet-view/src/triggers.rs |
Adds a doc comment clarifying the guard measures against the queue the pass found. |
tests/worktree-safety.sh |
Replaces the pipefail-unsafe grep -q pipeline with an equivalent bash glob check on the porcelain output. |
I verified the fix: found is computed before facts.take(id) and passed to note_started; the new test genuinely fails before the fix (the recorded fingerprint would drop the handed bead) and passes after. The worktree-safety.sh rewrite preserves the original end-of-line anchoring semantics (the appended echo restores a trailing newline stripped by command substitution, and the quoted "worktree $tree" is matched literally). Helper functions and public symbols used by the test all exist and match.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Summary
start_duerecorded a role's fingerprint afterfacts.takehad removed the handed bead, so a pass that did exactly its one bead left the live queue equal to the record and the unchanged-work guard held the next start. In atlantis-hud the only bugfixer sat idle 20+ minutes with three candidates queued.start_duetest: one producer, two beads, one handed; after the pass ends, the guard does not hold with the bead gone and does hold with the queue as found.grep -qpipeline intests/worktree-safety.sh(from fix(cb-7suc): the worktree pruner removes finished trees in a repo with submodules or squash merges #471) thatscripts/pipefail-pipelinesrefuses, so the local gate is green again. CI does not run that check, which is why fix(cb-7suc): the worktree pruner removes finished trees in a repo with submodules or squash merges #471 passed.Test plan
cargo test --locked --bin cerebro-tui a_pass_that_took_its_bead_off_the_queuefails before the fix, passes afterbash tests/gategreen🤖 Generated with Claude Code
https://claude.ai/code/session_01GKiLr59caM9f6DxkrsDYR8