Skip to content

bc-dgx7.44: B7e-signoff — End a delivered run — the pull request - #694

Open
mordam wants to merge 24 commits into
mainfrom
worktree-b7e-signoff-dgx744
Open

bc-dgx7.44: B7e-signoff — End a delivered run — the pull request#694
mordam wants to merge 24 commits into
mainfrom
worktree-b7e-signoff-dgx744

Conversation

@mordam

@mordam mordam commented Aug 24, 2026

Copy link
Copy Markdown
Owner

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, and runSteps, a tiny sequencer
that 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#debrief into it).

Two things it fixes structurally rather than by telling the next session to be careful:

  1. bin/deliver.js decides the pull request's head from the branch checked out where
    it 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-signoff resolves the bead's own live
    worktree itself first (its branch is worktree-<slug>-<tag>, where <tag> is the
    bead id with its workspace prefix and punctuation stripped — the same rule
    lib/notinmain.js's tagOf/ownsBranch already use), and hands deliver.js
    --dir <that worktree> explicitly. Zero live worktrees claiming that tag, or more
    than one, is a refusal naming the pattern it looked for — deliver.js's own refusal
    never gets a chance to fire, because it is never reached with the wrong directory.
  2. beadcause-memory debrief "…" and a hand-typed rename have both, at different
    times, 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 shell
    before the command ever runs (bc-ibt8g.1's own stored debrief still carries
    (eval):1: no such file or directory from exactly this). --summary/--debrief/
    --tests/--risk/--left all take a file path (or - for stdin) here — never
    inline text — so nothing this reads is ever re-parsed by a shell.

What I chose against: shelling out to ~/.claude/rename-session.sh in "set" mode
directly with a hand-built name, the way every prior session did — instead this reads
the session's current name (--show) and only ever prepends QUEUED- to it
(lib/signoff.js#queuedTitle), which is what fixes the other historical bug (five
sessions 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 --marker to
REVIEWED whenever the delivery ended in a question card rather than a merge (auto-merge
off, --review, an in-app edit) — deliver.js's own header is explicit that nothing
after 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 using
lib/retitle.js's in-process retitle() — that function needs a session object
resolved from liveSessions(cfg), and finding "which live session is me" needs a
process-tree walk rename-session.sh already does correctly in bash; I judged
duplicating 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-signoff is deliberately not on DEFAULT_TOOL_LIST — it delivers, comments and
renames, which is write-shaped exactly like b7e-apply/b7e-gate, and dispatch (the
one 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`
test/signoff.mjs   +627 −0
bin/b7e-signoff    +304 −0
lib/signoff.js     +197 −0
README.md          +81 −0
lib/toolbelt.js    +8 −0
package-lock.json  +1 −0
package.json       +1 −0

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

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>
@mordam

mordam commented Aug 24, 2026

Copy link
Copy Markdown
Owner Author

A beadcause worker opened this and does not merge its own work. It is on the merge queue as bc-m6l22.

@mordam

mordam commented Aug 24, 2026

Copy link
Copy Markdown
Owner Author

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.

@NeanderthalMan

Copy link
Copy Markdown
Contributor

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:
#	README.md
#	lib/tooldecl.js
…dgx744

# Conflicts:
#	README.md
#	lib/tooldecl.js
@NeanderthalMan

Copy link
Copy Markdown
Contributor

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.

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.

2 participants