Plan dispatch, drawn
One feature plan, from draft to merge. Version 1.10, 13 September 2026.
This is the picture behind Merge is ignition. It traces a single feature through the whole path: I write a plan file, a human merge arms it, a watcher spawns one orchestrator per plan, and the work comes back as a pull request a human merges again.
One thing happens earlier than any of that. The planning session routes the architecture, security and privacy questions to a person before there is a plan to review at all. Answering those inside a plan review is too late — by then the shape is already argued for, and the reviewer is correcting a direction rather than choosing one.
There are two versions of the picture below, and they answer different questions. The short one asks who acts at each step — a model, a piece of code, or a person. The full one asks what is actually built. Each carries its own legend, and it is worth not reading one through the other's colours.
The short version
Eight steps, no lanes. What it is for is the rhythm: agent, agent, person, code, code, agent, agent, person. Two of the eight gates need a human and nothing routes around them, which is the only claim in this whole system I would defend without qualification.
The full picture
Here the colours mean something else. Green is built and running. Blue is specified and not built. That distinction is the honest part of the diagram, and keeping it honest turns out to be the hard part — see below.
What the gate actually checks
A merged plan is necessary and not sufficient. Three things have to be true of the tree that was actually merged:
- a reviewer approved that tree — resolved from the merge commit, not from the branch tip, which keeps moving after a merge and would make every check disagree with itself;
- no question the review raised is still unanswered;
- the plan's declared effect on the spec is covered by the files it claimed.
All three are checked at once and reported in one message. A failure that could not be determined is never rendered as a refusal — "I could not tell" and "no" are different answers, and a system that collapses them gets trusted while blind.
What happens when a run fails
A failed run used to be a log I had to go find. Now a separate component composes a brief from it — the plan, the reason, the log — and pages me with a handle that opens straight into that context.
It decides nothing and it acts on nothing, and that constraint is the whole design. The moment a failure handler is allowed to retry, the system acquires a way to make progress that no human authorised. It is permitted to summarise and to interrupt me. That is all.
Why the tests come from someone who never saw the code
The right-hand lane is the part I have specified and not built. The tests are written by two other vendors' models, from a generated contract — an interface description, event names, config keys — and never from the source.
A tester who reads the implementation writes tests shaped like the implementation, and they pass for the wrong reason. So the bundle those models receive is an allowlist of generated artifacts rather than the repository with things removed. Filtering means deciding what to strip and being wrong once. Generating means nothing is present unless code put it there.
Two vendors on one bundle, because where they disagree, the specification was ambiguous.
The diagram lies unless something makes it stop
Version 1.5 of this picture said "nothing here is built yet" for four days after the left lane shipped. It described a model of the system that had been true and had quietly stopped being true, which is the failure mode of every architecture diagram I have ever worked near.
Two of its labels had never been true at all. One box named the model that runs the implementation lane, and named the wrong one — the default had been something cheaper since the file was written. Another named two vendors for the test lanes that had been replaced months earlier, after one of them stopped serving individual accounts.
The fix is not discipline. It is that the picture is generated from a script and checked by a layout linter, and that one day it will take its colours from what the machinery actually logged rather than from a constant somebody has to remember to change. A diagram that can re-colour itself would have corrected the box I got wrong, on the day it changed, without me.
That last part is still a sentence about the future, and the bill came due. This page sat at version 1.7 while the diagram in the repository moved to 1.10 — three versions, a new failure-handling component, a legend I had added for who acts at each step, and a runner default that had changed again. The prose described a picture nobody was looking at any more.
Which is the same failure as before, one level up. Generating the diagram fixed the diagram. It did nothing for the essay wrapped around it, because that is still a file I edit by hand when I remember to. The honest version of this paragraph is that I have automated the part I already knew how to check.
What it costs to run all this: Lab token usage, 2026.