0012 — The Smith review runs itself every morning, and a merge refuses under a person
- Status: Proposed (flips to Accepted with the first morning that records a checkpoint) ⚠️ PARTIALLY SUPERSEDED 2026-09-12 by ADR-0025: the Can count Rung 5 clause below —
shippedderived only from a merged PR AND aprod_evidencepermalink, a merged-but-untested fix not counting — is retired AS A GATE. The bar is now a PR that addresses the point plus the sub-agent's own completion naming that PR; prod evidence survives as the stronger grade a sub-agent is encouraged to reach, and as the record of why the distinction was drawn. Everything else here stands, includingmerge_guard, which is a restart interlock and not an approval gate. (Appended toStatuson purpose: this adds NO line, so every line-number citation into this file stays true.) - Date: 2026-09-07
- Deciders: Gera, in the 2026-09-07 review read-back — "it should run daily
in the morning queue, and also drive itself to merge" — and the session that
built it (agent-smith PR
smith/daily-self-review). Written at decision time because ADR-0004 says a decision that changes how systems relate is not done until it is; this one changes how the review relates to the morning queue, to the worker, and to every other conversation Smith is having.
What changes
Until today the smith-review skill — the day's pass over everything Smith
said and did, ending in fixes — ran only when a human typed /smith-review.
Its own preamble calls it "the inventory that a future autonomous self-repair
engine will run." Three things become true at once:
- The review is a scheduled pipeline.
MorningQueueWorkflow's last step,smith-review, runsagent_smith.self_review run, which reads the checkpoint store for the window (since the last checkpoint; a day if there is none), refuses to run twice in a day, posts the brief as a#agent-smiththread and starts a durableSmithTaskWorkflowcarrying it. The brain runs the skill inside that container, onMODEL_HIGH, and closes it withsmith-task verdict— Rung 6's receipt, not a merge. - The review may merge its own PRs. That is the instruction. Rung 0 (never under an agent still pushing) and Rungs 1–6 (merged-verified, deployed, tooling re-run, live test, proved in prod in the channel, checkpoint) still bind; what is gone is the human deciding the moment.
- A merge that would restart the worker refuses while a person is mid-turn
with Smith. New:
live_runs(everyclaude -pturn registers itself by pid while it runs) andmerge_guard(refuses a merge into a restart repo while a human-facing turn is live). It is consulted at BOTH merge sites — the brain's owngh pr mergethrough the command-gate hook, and the human-✅ approval path'smerge_pr_activity— and it fails CLOSED when it cannot see the registry.
Why a task container and not a turn, and why not a new scheduler
A brain turn has a two-hour wall and no memory of why it started once it ends.
The review opens PRs, waits on CI, merges, restarts the very worker it runs
on, and must then come back and prove each fix in prod. SmithTaskWorkflow is
the structure agent-smith already has for "a task that outlives a turn": it
restates goal and acceptance on every wake, re-wakes the brain when the
thread's PR evidence changes phase, and closes DONE only on a receipt. Its
workflow id is derived from the goal, and the goal names the date — so a
second dispatch the same morning collides into "already driving" instead of a
second review. No scheduler was invented: the step is a NightJobSpec run
through the same run_night_job_activity every nightly job uses.
How it relates to the ladder
- ADR-0002 — agent↔agent is SendMessage, tmux is hosting. Nothing here
attaches to a pane. The container wakes turns through
dispatcher.dispatch, the door a Slack message takes; fixes fan out as the brain's own subagents. - ADR-0003 — rungs integrate by signals, never calls. The queue does not await the review; it dispatches and reads back nothing. What the review produces are files other rungs read: the dispatch log (this system's ignition), the checkpoint store's mtime (its end), and the tracker's JSON block on docs.propflowai.co (its answer). The merge guard is likewise a file read — a marker per running turn — not a call into the worker.
- ADR-0009 — a signal must fail when the system fails. The dispatch-log pattern is written ONLY on a real dispatch (a skip or a failed launch writes a different word); the checkpoint mtime moves ONLY when Rung 6 records. A green pair means "the queue started a review and a review reached its end", and nothing more — the N/M on the page is the verdict.
- ADR-0010 — a finished session leaves by its own exit. The live-run
marker is removed in the runner's
finally, and a marker whose pid is gone is stale, reported, and never counted: the guard never becomes a reason to kill anything, and a dead worker cannot pin every merge shut.
What the guard means for the graceful drain (agent-smith #422)
#422 (merged 2026-09-07) makes the worker drain in-flight activities on
SIGTERM instead of killing them — deploys relaunch within ~4s of a merge via
SIGTERM+wait, not kickstart -k. That makes a restart survivable; this makes the review not the thing
that asked for one while a person is waiting. They are two lines, not one:
the drain protects a turn from a restart that happens; the guard stops a
Smith-initiated merge from scheduling that restart under a person in the
first place. Gera's phrasing — "the drain makes it safe, not polite" — is
the reason both exist.
What the first morning can and cannot do
- Can: dispatch, run the sweep and triage, write rows, open PRs, merge its own green PRs when no person is mid-turn, record the checkpoint, refresh the tracker, post N/M. Every one of these is a tool the brain already has.
- Can count Rung 5: propflow-docs #47 (
p6-merged-is-not-shipped) is live, sobin/refresh-trackerderivesshippedonly from a merged PR AND aprod_evidencepermalink — the permalink the brief tells the brain to post in the thread and put on the row. A merged-but-untested fix rendersmerged · untestedand does not count. A fix the brain cannot trigger on demand is carried UNVERIFIED rather than closed. - Cannot see: a human joining the review's OWN thread. The guard excludes the asking turn by workflow id, and a human message coalesced into a running turn keeps that turn's machine sender. It never hides a stranger's turn; it can fail to notice a colleague in this one. Named here rather than papered.
Consequences
The catalog gains smith-daily-review, proposed, with the two signals
above; it flips to active after the first morning whose thread carries a
checkpoint. The review's #agent-smith receipt becomes a daily thread, and
the phase doc's hero number is expected to go DOWN on mornings the sweep
finds more than it fixes — which the skill's §0 says is the count getting
more honest, not the work regressing.