Repository navigation
fix(vibe): acknowledge and watch mid-run scope changes - #347
Merged
Merged
Conversation
- Record mid-run scope changes on the board with the writer's head - Writers read board.mjs pending and ack each change by id - Flag UNACKED-SCOPE and SCOPE-NOT-STARTED; the watcher wakes on them - Preamble: no sleep polls; read pending before commits and checks - Ship vibe 1.0.83 (1.0.82 is the open one-hook-per-event branch) Testing: node --test board and snapshot suites, vibe pytest, ruff Risks: deliver --kind scope refuses a writer row with no --worktree
- Name the incident by date in board and snapshot scripts and tests - Use a plain git identity in the board test fixture Testing: node --test generic and board suites Risks: None identified
#345 took 1.0.83 on main. Retire its 1.0.83 version pin and pin this release at 1.0.84.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
Ships vibe 1.0.83. A Claude writer that is in the middle of one long turn now cannot silently miss a mid-run answer or scope change. The orchestrator records each change on the fleet board, the writer acknowledges it by id, and the watcher wakes the orchestrator when an acknowledgement is late or the writer's worktree has not moved.
Version: 1.0.82 is taken by the open
fix/vibe-one-hook-per-eventbranch, so this takes 1.0.83. Whichever merges second rebases. The one expected conflict istest_vibe_1081_lessons_contract.py, where both branches drop the 1.0.81 version pin.The incident (ISS-13096, 2026-10-26)
What the transcripts show:
fix-13096, an iTerm2 pane teammate, at 14:49Z with an ad hoc brief. It did not use the fleet worker preamble, so the brief had no "end the turn while long commands run" line and no ack ids.sleep 240/280/500poll loops on background runs.board.mjs deliverorquestionfor this writer, so nothing on the board could flag it. The operator found the problem at 16:52Z by asking for status.SendMessage's tool text says messages "drain at the receiver's next tool round". This incident shows a pane teammate drains them only when its turn ends, which matches what the fleet skill already said.
Changes
fleet-orchestrator/scripts/board.mjswriter --worktree <path>.deliver --kind scope --text <change>(or--reference) refuses a recipient with no worktree and records that worktree's HEAD.ack <writer> --id <id>now acknowledges a scope change as well as an answer, andanswered --textstores the answer.pending <writer>lists unacknowledged scope changes and answers and exits 1 while any remain: this is the writer's inbox, read by pull, so it works whatever the mailbox does.statusaddsUNACKED-SCOPE(told 15 minutes ago, no ack) andSCOPE-NOT-STARTED(30 minutes after it was told, the worktree is still clean at the recorded HEAD).watch-linesprints those and the late-question flags without minutes.board.mdlists the open scope changes.codex-fleet-monitor/scripts/snapshot.shwatch-linesoutput to the snapshot when the work dir has aboard.json, so the armed watcher wakes once when a flag appears and again when it clears. Before this,QUESTION-UNANSWEREDandUNACKEDfor Claude writers showed only when the orchestrator ranboard.mjs statusitself.references/templates.md)sleeppoll; run the command in the background and end the turn. Before each commit and each verification phase, runboard.mjs pending <you>, apply and ack each item, and name what was applied in the next status. This replaces "Check the worker inbox between steps", which named no action: a Claude agent has no inbox to check.SKILL.mddeliver --kind scope, then the message, thentold; add--worktreeto writer rows. OnUNACKED-SCOPEorSCOPE-NOT-STARTED, interrupt at once or TaskStop and relaunch with the change in the prompt, because a resend never reaches a writer mid-turn.judgment.mdcodex-fleet-monitor/SKILL.mdboard ...lines.To keep instruction length flat, the fleet skill drops three lines other places already state: the transient-recovery line (the monitor's table covers
recovery), the "run every lane" line (the preamble, the resume prompt andpr-facts.mjscover it), and the "writers message each other" line (the preamble covers it). The plugin's instruction text is 2 words shorter than 1.0.81 (instruction-words.mjs --base origin/main --changelog CHANGELOG.md --version 1.0.83).Other places checked
writer-state.mjs's serial queue and a resume per request, so they always land on a turn boundary. Not the same gap.fleet.sh session steer, which adds to the active turn. Not the same gap.judgment.mdis the same gap; fixed above.Prevention
Commands run
The suites ran on the second laptop at the final head, because the first laptop was at load 118 on 10 cores. A local run there timed out the zsh snapshot tests at 50 seconds each.
node --testover everyplugins/**/*.test.mjs, as CI runs it: 791 of 791 passed. An earlier run caughtgeneric.test.mjsrejecting a ticket id and an email address in the new board code and tests; they are now named by date and use a plain git identity.uv run pytest plugins/: 2,493 passed, 3 skipped. Locally,plugins/code/tools/python/test_install_script.pyfails 7 of 9 on main as well as on this branch; on the second laptop it passes.uv run ruff check .: clean.uv run pyright: 0 errors, 0 warnings.node plugins/vibe/skills/fleet-orchestrator/scripts/instruction-words.mjs --base origin/main --changelog CHANGELOG.md --version 1.0.83:added 404 removed 406 net -2, exit 0.Test changes
test_vibe_1074_lessons_contract.pypinned "Check the worker inbox between steps". That line is replaced on purpose (it named no action), so the pin now checks forboard.mjs <orchDir> pending <you>.test_vibe_1081_lessons_contract.pyloses its 1.0.81 version pin; the newtest_vibe_1083_scope_change_ack_contract.pypins 1.0.83 and the new wiring.