skip to content

When a run stops

The closed sets an operator meets when a run stops or asks a question: outcomes, dispositions, ledger statuses, prompt kinds, run states and exit codes.

The handover vocabulary

Handover vocabulary — 7 sets exported from src/engine/reference_vocabulary.rs

Stage outcomes

6 values from src/domain/mod.rs

How one stage of the pipeline ended. Mechanical stages (the gate, a merge) and agent stages share this set, so a card reads the same whichever ran it. The pattern language has a second, unrelated `Outcome` — what a matched rule does next — which is vocabulary for writing a pattern rather than for reading a stopped run, and is not this set.

value as the code writes it what it means
ok ok The stage finished cleanly: the agent completed its work, or the gate passed. The run carries on to the next stage.
amber amber Healthy, but not finished. It is reserved for goal verification, and no current build path emits it, so a stage you are looking at will not be carrying it.
failed failed The gate came back red, or the agent reported that it could not do the work. The pattern's recovery ladder takes it from here — a retry, a fix, a replan — and the run stops only once that ladder is spent.
errored errored The agent stopped without doing any work at all, most often because a headless harness was not authenticated. Nothing was attempted, so check the harness can run and start the run again.
oversized oversized The agent ran out of room or time before it could finish. The unit is too big for one agent: split it into smaller ones and resume.
note note Nothing failed. The stage recorded something worth reading — a plan amended, a review that applied its own improvements — and the run went on.

Run dispositions

4 values from src/engine/pattern_language.rs

The declared terminal verdict of a pattern run — what a `terminate` step or a rule outcome says the run's ending was. It is not a forced halt: a halt carries a reason instead and is a separate ending. A nested pattern threads its disposition up to the pattern that invoked it, where it is a signal the parent branches on, so a disposition you see in a journal is not always the end of the whole run.

value as the code writes it what it means
success success The pattern run declared itself finished: the work it was given is done. For a nested run this is the verdict its parent branches on, not necessarily the end of everything.
failure failure The pattern run declared a failed ending, and nothing further in it will run. The stop message beside it says what failed.
resumable_stop resumable-stop The pattern run ended unfinished but sound — a declared partial stop such as a cycle ceiling, not a failure. Whether there is more to do, and whether re-running picks it up, is what the stop message tells you.
empty_campaign empty-campaign There was nothing to build: the planner produced no work and none happened. A first-class ending rather than a failure, and one a parent pattern can branch on.

Ledger statuses

4 values from src/engine/ledger.rs

The `status` column of a run's `PROGRESS.md` ledger, and the durable record of what a unit came to. Resume re-derives which units are already built from this column, so `DONE` is the one status it skips and every other status is work it will pick up again.

value as the code writes it what it means
done DONE The unit is built and recorded. A resume of this run skips it and moves on to the next one.
amber AMBER Healthy but not finished, reserved for goal verification: the unit made sound progress without declaring itself done.
failed FAILED The unit did not finish. It is also the conservative record for every ending that is not one of the other three — a stop or an abort reads as `FAILED` too — so a resume treats it as work still to do.
oversized OVERSIZED The unit was too big for one agent to finish. Split it into smaller units before resuming, or the resume will hit the same ceiling.

Prompt kinds

4 values from src/domain/mod.rs

What kind of answer a run is waiting for when it asks you a question. A front-end renders the input from the kind; a headless run answers what it can from its flags and fails loudly rather than guessing at the rest.

value as the code writes it what it means
confirm confirm A yes/no confirmation, defaulting to no. A headless run answers it yes only if you passed `--yes`, and otherwise takes the safe no without waiting.
text text A free-text answer. A headless run needs a default configured for it; with none, it says so and stops rather than inventing one.
blocker_investigation blocker_investigation The run is blocked and is asking what to do about it. Its answers are the blocker choices, one of which opens a harness or a shell for you to look first. A headless run answers `stop-run`.
choice choice A pick from a fixed set of options. A headless run has no way to choose, so it says so and stops; answer it from an interactive run.

Blocker choices

4 values from src/domain/mod.rs

The fixed answers to a blocked run's investigation prompt, as the tokens they are written as. Two of them resolve the prompt and let the run move on; the two launchers open something for you to look at and deliberately leave the prompt waiting, so the run is still yours to answer afterwards. The harness launcher's token ends in the id of the harness to open, one token per installed harness.

value as the code writes it what it means
investigate_with_harness investigate-with-harness:<harness-id> Open that agent harness interactively in the run's worktree so you can look at the blocker yourself. It does not answer the prompt: the run is still waiting when you come back out.
let_gantry_try let-gantry-try Hand the blocker to Gantry's own investigation path — the Gantry Agent, in the run's worktree. This answers the prompt: once that path reports the worktree is ready, the run re-enters its gate-verified course.
open_shell open-shell Open a plain shell in the run's worktree. Like the harness launcher it leaves the prompt waiting, so you can inspect and then answer.
stop_run stop-run Stop the run here. The worktree stays on disk with everything the run built, so you can read it, and `gantry` can resume the run later.

Run states

4 values from src/engine/registry.rs

Where a run sits in its lifecycle, as `gantry list` and `gantry status` print it. The distinction that matters is whether the run's isolated worktree is still on disk — that is what makes it resumable.

value as the code writes it what it means
active active The run's isolated worktree is still on disk, so `gantry` would resume it. The same run prints as `orphaned` instead when no live engine holds its lock: nothing is running, and it is yours to resume or clean up.
finished finished Merged back into your branch with every unit recorded `DONE`. Its worktree is gone and there is nothing left to resume.
partial partial Merged back with some, but not all, of its units done. What was built is in your branch; what was not, was not built.
empty empty Merged back, or otherwise on disk, holding no units at all — the run recorded no work.

Process exit codes

4 values from src/engine/reference_vocabulary.rs

What the `gantry` process exits with, for a script that runs it. These four are the whole set Gantry chooses for itself, and a test reads every exit site in the source to keep it that way. The one deliberate exception is `gantry enter`, which runs your shell in the run's worktree and hands back whatever that shell exited with.

value as the code writes it what it means
success 0 Gantry did what you asked: a build run reached its end without stopping, or a management command succeeded.
failed 1 The command ran and is reporting failure — a run that stopped before finishing, a name that matched no run, a confirmation you declined, or `gantry doctor` finding a hard requirement missing.
error 2 Gantry would not go on, and printed why on stderr: an argument it could not read, a plan it could not open, a preflight it could not pass. Read the stderr line; nothing about the run's own progress is implied.
panicked 101 Gantry crashed. This is rustc's conventional status for a panic, which the TUI's panic hook exits with by hand so a crash inside a raw-mode terminal still reports it. It is always a bug — please report it.