Running approved plans under the conductor
tools/conductor/ runs approved plans to a merged main with nobody at the keyboard. It works in up
to two worktree lanes, and each plan gets separate headless claude -p sessions: its implementer
runs, then a review that also closes the plan, then a fast-forward of main and removal of the lane
(ADR-0205).
It never pushes. Anything it cannot decide — a human phase, a red gate, a review still failing
after two fix rounds, a spend cap — parks the plan and moves on to the next one.
node tools/conductor/conductor.mjs check # local.json, the CLI version, the queuenode tools/conductor/conductor.mjs run # both lanes, until the queue is merged or parkednode tools/conductor/conductor.mjs status # what each lane is doing, and every parkBefore the first run:
- Spend caps. Write
tools/conductor/local.jsonwith your per-step caps. It is gitignored, and the conductor refuses to start without it. - The main checkout. Keep it clean while a run is live: a fast-forward refuses a dirty one.
What changes for a plan it runs:
- The approval is the go. The plan’s
Status: approvedis the only approval it needs. - The review is a separate process. A fresh session, handed the plan and the lane and nothing an implementer wrote, performs the close review.
- The review is committed. It lands in the plan’s
## Close reviewsection.
Every other seam stays exactly as the skills describe it.
Watch it from the terminal that started it. run prints one line per milestone as it happens: a
step starting and ending with its duration, spend and turn count, each commit that lands in the
worktree, each phase whose log row flips to done, each test and gate command with its counts and lock
wait, the 5-hour and 7-day usage readings, and every command a permission rule denied. The same lines
go to tools/conductor/state/live.log, under one header per run, for a run you did not watch.
Next morning, read tools/conductor/digest.md. It is the current state in two sections and
nothing else
(ADR-0214).
Needs you comes first and is the whole worklist: each park with its age, the worktree it holds —
or the branch resume reopens it from, when you have already removed that worktree — the usage
reading its session ended on and its resume command; each lane stopped at the worktree cap; each lane
still on disk after a merge; and every merge’s still-open findings with their file:line. A park the
repository itself shows as finished closes that section under Already settled, clear the record,
counted apart from the live ones, so a plan you closed by hand is never repeated at you as work.
Now follows: per lane, the plan, the step and how long it has been in it, and what it has spent.
A first section that says it found nothing means nothing is waiting on you.
What last night produced is one command away: node tools/conductor/conductor.mjs digest --history writes digest-history.md beside it, newest run first, each run with its own closed
plans, its failures and its Totals — the usage windows at run start and run end, and gate minutes
split into the full workspace suite and everything else, with the count of suite runs skipped because
the conductor had already seen that exact tree pass
(ADR-0207).
Nothing writes that file until you ask for it, and a closed plan’s own committed ## Close review
carries its review either way.
The operator guide — every command, what to do about each kind of park, and how to verify a new CLI
version — is tools/conductor/README.md. Its tests need no network
and spend nothing:
node --test "tools/conductor/test/*.test.mjs"Built from f4f807a at version 0.178.0. This site tracks main and is not versioned per release.