bc-dgx7.44: B7e-signoff — End a delivered run — the pull request - #694
bc-dgx7.44: B7e-signoff — End a delivered run — the pull request#694mordam wants to merge 24 commits into
Conversation
Sequences the four steps every worker brief ends with — deliver, debrief, rename, marker — through lib/signoff.js#runSteps, which stops without touching the steps after the one that throws. - lib/signoff.js: chooseWorktree (resolves a bead's own live worktree by branch tag, reusing lib/notinmain.js's tagOf/ownsBranch, before deliver.js is ever reached — so its 'refusing to open a PR from main into main' never fires), queuedTitle/fallbackTitle, markerLine, parseDeliverOutcome, ownedMarkerFor (forces the marker to REVIEWED over a question-card ending), runSteps. - bin/b7e-signoff: the CLI. --summary/--debrief/--tests/--risk/--left each take a file path or '-' for stdin, never inline text, so nothing this reads is ever re-parsed by a shell. - package.json / package-lock.json: bin registration. - lib/toolbelt.js: comment explaining it is deliberately NOT on DEFAULT_TOOL_LIST (write-shaped, b7e-apply precedent) — nothing added to lib/grants.js. - README.md: new section after b7e-known. - test/signoff.mjs: pure-function tests, a runSteps sequencing test, and five CLI-level scenarios against a fabricated repo (real bare origin, real 'git worktree add' under .claude/worktrees/) and tracker (fake bd/gh on PATH) — happy path, no-worktree refusal, mid-sequence rename failure, a --review question-card ending, and --dry. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
A beadcause worker opened this and does not merge its own work. It is on the merge queue as bc-m6l22. |
|
The beadcause merge queue tried to merge this and could not: it has been tried 3 times and stopped at the same place each time. 1 check failing (test). A merge queue will not merge over a check the branch broke — if it is a flake, that is your call. Tried 3 times — that was the last. It is Adam's call now — see bc-m6l22. |
…dgx744 # Conflicts: # README.md # lib/toolbelt.js
…dgx744 # Conflicts: # README.md # lib/toolbelt.js
…dgx744 # Conflicts: # lib/toolbelt.js
…dgx744 # Conflicts: # README.md # lib/toolbelt.js
…dgx744 # Conflicts: # lib/toolbelt.js
|
beadcause-resolver: stood down — the worktree for worktree-b7e-signoff-dgx744 is locked by another live resolver (pid 37220, still running per ps), reason "resolver pid 37220 #694". Left the tree and the branch untouched; the branch still conflicts with main. |
…dgx744 # Conflicts: # README.md # lib/toolbelt.js
…dgx744 # Conflicts: # lib/toolbelt.js # package-lock.json # package.json
…dgx744 # Conflicts: # lib/toolbelt.js
…dgx744 # Conflicts: # lib/toolbelt.js
…dgx744 # Conflicts: # lib/toolbelt.js
…dgx744 # Conflicts: # README.md
…dgx744 # Conflicts: # README.md
…dgx744 # Conflicts: # lib/toolbelt.js
…dgx744 # Conflicts: # README.md
…dgx744 # Conflicts: # README.md # lib/tooldecl.js
…dgx744 # Conflicts: # README.md
…dgx744 # Conflicts: # README.md # lib/tooldecl.js
|
beadcause-resolver: stood down at step 2 — worktree-b7e-signoff-dgx744 is locked by another live resolver, reason "resolver pid 65543 #694" (pid 65543 is a running claude, started 14:00:21 ADT today). Did not touch the tree, did not unlock, branch left as it is. |
…dgx744 # Conflicts: # lib/tooldecl.js
Sequences the four steps every worker brief in this repo already ends a delivered run
with — deliver the branch, leave a debrief, rename the session, print the closing
marker — behind one command instead of five hand-typed invocations. A session audit
(bc-1kwl.32) found the same four steps done by hand at the end of five sessions
(bc-1kwl.32, bc-ibt8g.1, bc-xl7n.120, bc-xl7n.118, bc-36xx.27), no two the same way, and
filed this bead as "the command that would have replaced it".
New:
lib/signoff.js(the sequencing —chooseWorktree,queuedTitle/fallbackTitle,markerLine,parseDeliverOutcome,ownedMarkerFor, andrunSteps, a tiny sequencerthat stops without touching later steps the moment one throws) and
bin/b7e-signoff(the CLI that wires real subprocesses —
node bin/deliver.js,~/.claude/rename-session.sh— and the real
lib/memory.js#debriefinto it).Two things it fixes structurally rather than by telling the next session to be careful:
bin/deliver.jsdecides the pull request's head from the branch checked out whereit runs, so delivering from the main checkout dies with "refusing to open a PR from
main into main" even when the actual work is finished one worktree over — hit by
three of the five sessions in the audit.
b7e-signoffresolves the bead's own liveworktree itself first (its branch is
worktree-<slug>-<tag>, where<tag>is thebead id with its workspace prefix and punctuation stripped — the same rule
lib/notinmain.js'stagOf/ownsBranchalready use), and handsdeliver.js--dir <that worktree>explicitly. Zero live worktrees claiming that tag, or morethan one, is a refusal naming the pattern it looked for —
deliver.js's own refusalnever gets a chance to fire, because it is never reached with the wrong directory.
beadcause-memory debrief "…"and a hand-typed rename have both, at differenttimes, taken prose as a literal argv token inside a Bash tool call's double-quoted
command string — and a backtick or
$(...)in that prose is resolved by the shellbefore the command ever runs (bc-ibt8g.1's own stored debrief still carries
(eval):1: no such file or directoryfrom exactly this).--summary/--debrief/--tests/--risk/--leftall take a file path (or-for stdin) here — neverinline text — so nothing this reads is ever re-parsed by a shell.
What I chose against: shelling out to
~/.claude/rename-session.shin "set" modedirectly with a hand-built name, the way every prior session did — instead this reads
the session's current name (
--show) and only ever prependsQUEUED-to it(
lib/signoff.js#queuedTitle), which is what fixes the other historical bug (fivesessions each hand-truncated the new name to a different length, twice cutting it
mid-word). With no current name to read at all it falls back to the bead's own title in
full, never hand-shortened. I also chose to have this command override
--markertoREVIEWEDwhenever the delivery ended in a question card rather than a merge (auto-mergeoff,
--review, an in-app edit) —deliver.js's own header is explicit that nothingafter a merge can be owed by work that has not merged, and I'd rather this enforce that
than trust every future caller to remember it.
What I'm not fully sure of: the rename step shells out to
~/.claude/rename-session.sh(overridable with
--rename-script, which is how the suite tests it) rather than usinglib/retitle.js's in-processretitle()— that function needs asessionobjectresolved from
liveSessions(cfg), and finding "which live session is me" needs aprocess-tree walk
rename-session.shalready does correctly in bash; I judgedduplicating that in JS wasn't worth it for this bead, but it does mean this command's
own rename step depends on a script outside the repo rather than on code this repo
tests directly (test/signoff.mjs proves the logic — queuedTitle/fallbackTitle — but
the real script's own process-tree walk is untested by this repo, same as it always
was).
b7e-signoffis deliberately not onDEFAULT_TOOL_LIST— it delivers, comments andrenames, which is write-shaped exactly like
b7e-apply/b7e-gate, anddispatch(theone agent that list governs) never delivers anything.
Tests: node test/signoff.mjs — 19/19 passing; node bin/b7e-gate — full suite 423/423 green in 8m47s (run b7e-signoff-dgx744-20260824T133420326Z-5v09)
Files changed — 7 files · +1219 −0 · against `main`
Opened by a beadcause worker session on bc-dgx7.44 — b7e-signoff — End a delivered run — the pull request, the debrief and the rename, in one call. It merges itself once the checks report; merging is what closes the bead. If this is still open, something stopped that, and the reason is on bc-dgx7.44 and in Adam's inbox.
bead: bc-dgx7.44