Skip to content

fix: route second-mate wakes by new status span - #5867

Closed
kunchenguid wants to merge 11 commits into
mainfrom
fm/fm-signal-span-scope-r1
Closed

kunchenguid wants to merge 11 commits into
mainfrom
fm/fm-signal-span-scope-r1

Conversation

@kunchenguid

Copy link
Copy Markdown
Owner

Intent

Fix the supervision wake scope so a second mate's routine status updates are no longer pinned to main by an unrelated open decision in the same status file.

Evidence from the main home since the attended supervision host landed (PR #5748): of about 60 actionable wakes the host handled 1; 58 were pass-through "attended main-only" (41 mini-default.status, 13 fmdev-f1.status signals), errors=0. Cause: .pi/extensions/lib/fm-branch-dispatch.ts scopeForUnreadWake treats a signal row as decision-owned when hasOpenNeedsDecision over the WHOLE status file is true. For a crewmate one status file is one task, so that is sound; for a second mate the status file is a shared channel carrying many independently keyed decisions, so any one parked captain hold (for example deferred holds) pins every later routine update from that mate to main. The same rule applies on Pi.

Approved design: judge the NEW span of each signal row, not the whole file. Send the wake to main when any new line in the span (a) is a decision (needs-decision or captain-held) or resolves one, or (b) carries the same key as a still-open decision in that file. A key-less new line falls back to its verb: a decision or blocked goes to main, otherwise routine. A wake whose span mixes routine and decision lines goes wholly to main (no row splitting). All-routine spans go to the branch. Keep single-task crewmate status files behaving as today unless the same new-span rule is strictly equivalent for them. Add behavioral tests including a second-mate file with an unrelated open hold plus a routine merged line (branch-eligible), a mixed span (main), a same-key update (main), and a key-less blocked line (main).

Also noted, lower priority: the first attended drain after the switch replayed old branch outcomes as new (already-merged PRs reported open); check whether that one-time backlog needs a cutover guard.

Ship through no-mistakes; the captain merges.

i want to wait for that fix, then live validate the second mate path as well. is that doable?

Context: that means holding the /quiet PR #5779 until this fix lands, and live-validating this fix on the second-mate path before it is called done: a lab primary with the attended supervision host on and a real seeded local second mate under it (lab homes, never live homes). The second mate carries an unrelated open captain hold and then reports routine outcomes (the branch should take them), a mixed batch, a same-key update, and a new decision (main should get them), with the host log lines and main pane evidence shown per scenario. Run it on Claude, and on Pi if the fix touches the Pi branch path.

What Changed

  • Classify second-mate signal wakes using newly presented status lines, so unrelated open holds no longer pin routine updates to main; decision-related and mixed spans remain main-owned.
  • Keep second-mate retirement main-only and clarify branch handling of signal and stale wakes.
  • Add regression coverage for span routing, unchanged crewmate behavior, and retirement safeguards.

Risk Assessment

⚠️ Medium: The change spans both supervision hosts and relies on status-cursor and cache semantics, making routing behavior nontrivial to verify from source alone.

Testing

Targeted branch tests passed, and the real dispatch CLI produced the expected routing verdicts recorded in the evidence transcript. Teardown and second-mate safety scripts timed out. The Claude lab primary could not start because the required private tmux socket path exceeded the Unix socket length limit under this worktree; consequently neither the Claude host nor Pi primary was validated with a seeded live second mate.

  • Live validation: ⚠️ inconclusive - 3 of 5 scenarios driven live against the product
Scenario Result Live Evidence
A second mate reports a routine merged outcome despite an unrelated open hold, and dispatch offers its signal to the branch ✅ pass live Second-mate dispatch CLI verdicts: unrelated-hold-routine eligible=1
A second mate reports mixed, timestamped same-key, new-decision, or key-less blocked updates, and dispatch keeps each signal on main ✅ pass live Second-mate dispatch CLI verdicts: each case eligible=0
A routine note merely mentions an open key in prose, and a stale wake has no new lines; dispatch offers both to the branch ✅ pass live Second-mate dispatch CLI verdicts: prose-key-routine and stale wake eligible=1
An attended Claude lab primary handles a seeded second mate’s routine outcome in the branch and presents decision outcomes on main, with host-log and pane evidence ⏸️ untested no The required TMUX_TMPDIR beneath this worktree made tmux’s Unix socket path too long. Provide authority for a short disposable lab path outside the worktree and rerun with a real seeded second mate.
A Pi lab primary routes a seeded second mate’s signal spans and preserves the same-key decision guard ⏸️ untested no The same required private-tmux lab layout exceeds the Unix socket path limit here. Provide authority for a short disposable lab path outside the worktree and rerun the Pi primary.
Evidence: Second-mate dispatch CLI verdicts

Source: Second-mate dispatch CLI verdicts

unrelated-hold-routine: eligible=1 status=safe rows=1 tasks=mate 
mixed: eligible=0 status=unsafe rows= tasks= 
timestamped-same-key: eligible=0 status=unsafe rows= tasks= 
new-decision: eligible=0 status=unsafe rows= tasks= 
keyless-blocked: eligible=0 status=unsafe rows= tasks= 
prose-key-routine: eligible=1 status=safe rows=1 tasks=mate 
Second-mate stale wake without new status lines: eligible=1 status=safe rows=1 tasks=mate 
- Outcome: ⚠️ 1 warning across 1 run (11m47s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - medium risk

✅ No issues found.

⚠️ **Test** - 1 warning
  • ⚠️ live validation verdict: inconclusive (3 of 5 scenarios were driven live against the product); untested: An attended Claude lab primary handles a seeded second mate’s routine outcome in the branch and presents decision outcomes on main, with host-log and pane evidence, A Pi lab primary routes a seeded second mate’s signal spans and preserves the same-key decision guard
  • Live validation: ⚠️ inconclusive - 3 of 5 scenarios driven live against the product
Scenario Result Live Evidence
A second mate reports a routine merged outcome despite an unrelated open hold, and dispatch offers its signal to the branch ✅ pass live Second-mate dispatch CLI verdicts: unrelated-hold-routine eligible=1
A second mate reports mixed, timestamped same-key, new-decision, or key-less blocked updates, and dispatch keeps each signal on main ✅ pass live Second-mate dispatch CLI verdicts: each case eligible=0
A routine note merely mentions an open key in prose, and a stale wake has no new lines; dispatch offers both to the branch ✅ pass live Second-mate dispatch CLI verdicts: prose-key-routine and stale wake eligible=1
An attended Claude lab primary handles a seeded second mate’s routine outcome in the branch and presents decision outcomes on main, with host-log and pane evidence ⏸️ untested no The required TMUX_TMPDIR beneath this worktree made tmux’s Unix socket path too long. Provide authority for a short disposable lab path outside the worktree and rerun with a real seeded second mate.
A Pi lab primary routes a seeded second mate’s signal spans and preserves the same-key decision guard ⏸️ untested no The same required private-tmux lab layout exceeds the Unix socket path limit here. Provide authority for a short disposable lab path outside the worktree and rerun the Pi primary.
  • bash tests/fm-pi-branch-extension.test.sh — passed
  • bash tests/fm-branch-supervision.test.sh — passed
  • bash tests/fm-teardown.test.sh and bash tests/fm-secondmate-safety.test.sh — timed out
  • Drove node bin/fm-branch-dispatch.mjs offer against an isolated lab home for routine, mixed, timestamped same-key, new-decision, key-less blocked, prose-key, and stale wakes
  • Attempted to launch a Claude primary on the lab-private tmux socket
⏭️ **Document** - skipped

Step was skipped.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@kunchenguid

Copy link
Copy Markdown
Owner Author

Superseded by #5879, which re-landed this new-span wake-scope fix from a clean branch and has now merged. Closing this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant