Operating

The planning loop

Five steps from a rough note to filed, dispatchable work — and not one of them is reported. Every step is derived from an event or from the board, so a plan has no field it could lie in.

in-flux

Sourced from the fleet's own component document for planning-loop. Called in-flux rather than stable because it has accumulated seven decision records; because its own doctrine file states a count that disk has already outgrown; and because the hooks that derive its first two steps ship in a separately versioned package that nothing in the repository can grade.

This is the process a human and the planning agent run together, and the vocabulary the rest of the fleet uses to talk about work. Stop it and every agent keeps executing whatever is already filed, then runs dry — nothing else in the organization turns an intention into a board issue.

What the five steps mean is on How work flows. This page is about the one structural property that makes them trustworthy.

No step is reported. Every step is derived

1 BRIEF · 2 LOOP ⟳  ‖  3 FILE · 4 DISPATCHED · 5 DONE
                      ↑ planning ends, execution begins
#StepDerived from
1BRIEFa brief event, with its timestamp, on the plan's registry entry
2LOOPat least one recorded planning-agent turn on that entry
3FILEan issue reference on that entry
4DISPATCHEDat least one referenced issue still open
5DONEevery referenced issue closed

That is why a plan cannot lie about where it is: there is no field to lie in. Steps 3 through 5 are read off the board on every render. Steps 1 and 2 come from events a hook writes as they happen, not from a summary written afterwards.

step < 3 is the whole definition of planning. The command center's planning and execution sections partition on that single number, which means the boundary between "still thinking" and "being built" is one comparison rather than a judgement anyone makes.

Step zero asks three ordered questions, and the order is load-bearing

Before step 1 there is a step zero: mode, then portfolio, then subprocess. The order matters because each answer narrows the next. Mode decides which section of a catalogue exists at all; portfolio decides which catalogue.

The three modes are exactly three, and they are literals rather than descriptions:

ModeWhat it means
dispatch-monitoragents execute, and the planning agent stays on it until the chain completes
dispatch-no-monitoragents execute, and the planning agent's involvement ends at dispatch — the normal case
interactivethe human and the planning agent work it in session, with the human in it

🔴 interactive is the whole name. Not needs-human, not blocked, not manual, and above all it is not a synonym for blocked. It is a mode: work that is running, with a person in it. Work that genuinely cannot run unattended is filed as interactive; it is never filed as unattended work that then reports itself stuck.

That distinction sounds pedantic and is not. The moment "interactive" and "blocked" become the same word, a queue of work that is running fine with a human in it becomes indistinguishable from a queue of work that is stopped, and no dashboard can tell the two apart afterwards.

Two things end the loop, and both are read rather than remembered

Every turn in step 2 ends by asking the human a question whose last two options are, in that order, research more and file it, move to step 3. The loop ends when one of exactly two things happens:

  1. The human clicks the second option.
  2. The human types the sentence that means the same thing.

An approving remark is neither. Enthusiasm about the artifact is neither.

The click is the interesting half, because it is nearly invisible. A click comes back as a tool result, not as a message — so a per-turn injector that reads what the human said structurally cannot see it. A separate hook reads the tool response's answers field, and only that field, which is the difference between a mechanism that observes the exit and one that infers it from tone.

And neither exit advances the step. Filing does. The click ends a conversation; a step changes when an issue exists.

Filing is one command, and its shape is a real decision

Filing chains or waves the work, and the difference is not cosmetic — a plan designed as parallel groups and filed as a chain has exactly one dispatchable issue. The mechanics, the refusal rule and the case that produced it are on The board.

The loop ends at dispatch

Steps 1 and 2 of the next plan run concurrently with the execution of the last one. The scheduler, the reaper and the announcer carry the tail; the planner does not.

Watching an agent work is indistinguishable from not trusting it. If the only reason to stay is to see whether the run succeeds, the run already announces that on the issue, and staying buys nothing but a serialized planner.

🔴 The step-4 mode is not the planning mode, and the two words collide. The planning mode is the step zero question above and decides which subprocesses exist. The step-4 mode is what the board shows for work already dispatched. They are different vocabularies that happen to share three of their words, and the mapping between them is one table in doctrine rather than an inference anyone makes at the keyboard.

Where this loop is currently weakest

  • A doctrine file states a subprocess count that disk has outgrown. It heads its own table with a count; a directory walk returns one more than that. The same section already carries a note saying the count had drifted once before and instructing the reader to re-derive rather than edit the cell — and it drifted again anyway. A number in prose is a claim about the filesystem, and nothing was re-checking it.
  • Nothing binds the two doctrine files to each other. One is the full loop; the other is the compacted version the executing agents read, and by design the same path resolves to a different file depending on the agent's class. A rule changed in one is not checked against the other. A contradiction between them is invisible to continuous integration and surfaces as an agent doing the planner's job, or the reverse.
  • The loop's own machinery is not gradable from the repository that documents it. Everything that derives steps 1 and 2 lives in a separate, version-gated package, so the repository's assertion checker can bind the doctrine and never the mechanism. One script reads the real population across boxes, and it is run by hand.

Publishing that third one matters more than it looks: a process whose enforcement lives in a different release train from its documentation will drift, and the drift will be invisible from either side.

Take it further

Harness

2 · Find the planning state your system is guessing at

Reads your planning artifacts and issue tracker, and reports which status you can DERIVE and which you are trusting a human to have updated. Reads only; writes nothing.

On this page