Journal events
Every event a run raises, and the name each record carries on the wire where the run journal or the headless stream writes one.
The event vocabulary
Journal event vocabulary — 3 sets exported from
src/engine/reference_vocabulary.rs
Run events
29 values from src/domain/mod.rs
The engine's event stream on the durable run journal at `.gantry/<plan>/history.jsonl` and the live headless `--json` stream. A record's token is its `t` field. The two surfaces carry different subsets, so a token says only that some surface writes the event and each value says which. Journals written before the task rename carry record names nothing writes any more — `chunk_started`, `chunk_finished`, `milestone_chunks_planned`, `roster_updated` — because a journal is git-tracked and travels with a merge: the decoder still reads them, into the same shape a record written today carries. A value with no token at all is an event that reaches a front-end in process and is written to neither surface — a reader of a file will never meet it. The rows describe record names and meanings; the encoder defines payload fields.
| value | wire name | what it means |
|---|---|---|
| run_started | run_started | The run began with the plan name and generated project title and description. Task lists arrive in separate records. The journal does not keep it; a cold reader rebuilds it from the run's own record on disk, so it is a record only the headless stream carries, and the attach endpoint and resolved configuration the event holds in process are encoded on neither surface. |
| task_list_announced | task_list_announced | A task list was announced with each task's id and title under the repetition's task path. `preview = true` is a display-only preview; a real enumeration writes `preview = false`. Real announcements are repeated when the list is re-enumerated, including after a later directory binding. Tasks already recorded as done are omitted on resume. A reader reconciles children under that path, so repeating an unchanged list changes nothing. |
| task_started | task_started | A task became the active focus, named by its whole path from the run's root. It attributes nothing by itself: every stage record carries the task path it belongs to, and a run-level stage carries none. |
| stage_started | stage_started | A stage began. It opens a card with the stage, task path, detail, headline, and blurb; agent identity and log path are present where available. |
| stage_progress | — | A heartbeat for the stage running right now: how long it has been going and what it is doing. It is never written to either JSONL surface, so a reader of a file sees a stage start and then finish with nothing in between. |
| stage_finished | stage_finished | The stage closed with an outcome, summary, blurb, metrics, and optional gate coverage. |
| agent_retrying | agent_retrying | An agent stage hit a transient failure and is waiting before its next attempt. The run is waiting rather than hung and the task's status has not changed; the stage still finishes normally if a later attempt succeeds. |
| gate_lock_waiting | gate_lock_waiting | A gate is waiting for or has acquired the per-repository gate lock. The gate has not started yet. The journal does not keep it; a resumed run contends for the lock again. |
| checkout_lock_waiting | checkout_lock_waiting | A merge is waiting for or has acquired the per-checkout merge lock. It is not journaled, so a resumed run contends for the lock again. |
| task_finished | task_finished | A task reached a terminal state, carrying the status it is being recorded under and, where it was built, the commit it produced. The ledger on disk holds the same verdict durably. |
| sandbox_visibility | sandbox_visibility | The run observed an unavailable managed process fence, custom wrapper, or disabled wrapper. It carries the host availability, effective wrapper state, and reason. Journaled, so a run read back cold still says how it was fenced; the headless stream does not carry it. |
| pattern_journal | — | One pattern journal record, delivered live beside the run stream so an in-process consumer can follow the executing structure as it happens. It is never written to either JSONL surface: the pattern engine writes those records itself, durably, and they are the pattern journal records set below. |
| prompt_needed | prompt_needed | The run needs a human answer before it can go on, and is waiting for one. It carries the question and the prompt kind that says what sort of answer will do. The journal does not keep it; a resumed run asks again live. |
| prompt_resolved | prompt_resolved | A waiting prompt was answered or resolved without an answer. The source says whether the answer came from a person, an abort-and-backstop default, or a disconnected command channel. Like the ask, only the headless stream carries it. |
| assistant_console_up | — | The run's Gantry Assistant console is up and can take chat turns, under the harness and model named. It is never written to either JSONL surface — it tells a front-end its assistant affordances are live, and a file has none. |
| assistant_console_skipped | — | The run deliberately has no assistant console, and this is the reason to show wherever one would have been offered. Like the console coming up, it is never written to either JSONL surface. |
| assistant_selection_pending | assistant_selection_pending | A front-end requested an assistant identity, and the console stored it for the next turn. A reply already in flight keeps its captured identity. |
| assistant_selection_activated | assistant_selection_activated | The pending assistant identity was taken up for a turn just submitted, and is now the one answering. |
| assistant_selection_failed | assistant_selection_failed | A front-end requested an assistant identity the console cannot use. The reason says why; no current or pending selection changed. |
| agent_reply_identity | agent_reply_identity | The harness and model that are about to produce the assistant reply for a chat turn. It is journaled, so a transcript read back later attributes each answer to what actually wrote it rather than to whatever is selected now. |
| agent_reply_started | agent_reply_started | The assistant began answering a chat turn. A successful turn closes with `agent_reply_finished`; a failed turn closes with `agent_reply_failed`. |
| agent_reply_chunk | — | One fragment of an assistant reply still streaming in. It is never written to either JSONL surface — the whole text arrives when the turn finishes — so a reader of a file sees complete replies only. |
| agent_reply_finished | agent_reply_finished | The assistant's answer to a chat turn is complete, and this carries the whole of it rather than the last fragment. The assistant transcript keeps the conversation after an engine restart. |
| agent_reply_failed | agent_reply_failed | An assistant turn failed before it produced a complete answer, and the reason says why. Only that turn is lost: the run, and any prompt awaiting an answer, are untouched. |
| settings_write_completed | — | A settings change asked for from a front-end finished, and the refreshed catalog to redraw from comes with it. It is never written to either JSONL surface: it answers a front-end's own request, and belongs to no run's history. |
| reconciled | reconciled | An integrate completed, with files that required reconciliation and commits folded from the home branch. It is written for every integrate, clean or not, so the merge remains auditable. |
| stopped | stopped | The run stopped and handed back to the operator, with a diagnosis and, where written, a fuller report path. Both JSONL surfaces carry this terminal event; the identity journal also records the typed stop record. |
| pause_pending | pause_pending | The operator asked the run to pause at the next safe boundary. The current task keeps running, and the terminal operator-pause stop arrives before the run admits more work. The headless `--json` stream carries this event; the run journal does not. |
| run_complete | run_complete | Every task is built and merged back. This terminal record goes to the headless stream rather than the journal. |
Pattern journal records
4 values from src/domain/mod.rs
The pattern engine's own durable journal, one record per line in `.gantry/<plan>/pattern-events.jsonl`. It sits beside the run journal rather than inside it: the run events carry the cards a front-end draws, and these records carry the shape the interpreter actually executed — the declared hierarchy, and the task-id path of everything that happened under it. Every positioned record carries that path, so a reader takes the structure from the path rather than inferring it from the order records arrive in. The token is the record's own discriminant, from the `record` tag its serde derive writes.
| value | wire name | what it means |
|---|---|---|
| structure | structure | The shape the run is about to execute: which pattern is running, how many task levels it can open, and what those levels are called, outermost first. The first is declared from the pattern text before anything is enumerated and names no level at all, because a level is named only when its list is read; the record is journaled again each time a deeper level becomes known. A reader takes its vocabulary from this rather than assuming every run is milestones and tasks. |
| step | step | One step of the pattern reached a lifecycle phase at one task-tree position. The record carries its routing kind, detail, replay state, and, where the interpreter resolved one, title. |
| script_result | script-result | A command the pattern ran finished, recorded whole: what it exited with, what it printed, and the verdict the run drew from it. A replay of the run reads the result from here rather than running the command a second time. |
| work_list_inserted | work-list-inserted | An already-announced directory work list was enumerated again and had grown: the ids that appeared, under the path of the list's container. A list enumerated for the first time produces no such record. |
Step phases
3 values from src/domain/mod.rs
Which point of a step's life a journaled step record is at. `started` and `finished` bracket a step that ran; `note` is for a record made without ending the step, and nothing in the engine writes one today. The token is the serde derive's own kebab-case spelling.
| value | wire name | what it means |
|---|---|---|
| started | started | The step began; a `finished` record at the same position closes it. |
| finished | finished | The step is over, including one that stopped the run: a stop records the halt and its reason as the step finishes. |
| note | note | The step recorded something without ending — nothing failed and the run kept going. Nothing in the engine writes this phase today; it is read back for journals that carry it. |