skip to content
Replays

Production Pattern Runs Become Durable

The run finished the pattern engine's state, boundary, prompt, CLI, and record contracts.

Gantry milestones

0 milestones 0 tasks

74 execute

The run finished the pattern engine's state, boundary, prompt, CLI, and record contracts.

8h 14m total

This run finished the production pattern engine after the pattern format had been specified. The work moved from language shape into durable behavior: invocation-scoped state, declared task-list directories, full task paths in the ledger, boundary references, paused merge workflow, prompt context, fixed flag startup, generic parameters, map and until production paths, and record honesty. The ledger shows an early milestone retry after absent output, then the run completed through steady green task gates and a final merge conflict resolver.

How this walkthrough is structured

Feature

What did the run build and ship?

Gantry now reads modern pattern runs through invocation-scoped state, full task paths, declared task-list directories, honest pattern events, bundled map and until entry points, and a pause-based partial merge workflow.

Build

How did Gantry structure the work?

The decomposition cut the production world by contract boundary, so state identity, tree movement, agent context, entry parameters, and record honesty could each be carried by small agents before the final merge tested them together.

Milestone 1

invocation-state-and-declared-directories

The current tree keeps `RunShape`, declared task-list directory recording, full task-path ledger reads, and display readers that no longer assume `milestones`. `PROGRESS.md` can distinguish nested tasks with repeated ids, and cold readers use the run's own recorded directory names. TUI and MCP artifact readers now resolve nested task artifacts from the same projected task tree.

This milestone carried the state-shape contract for production pattern runs. Its scope was wide, but each child task owned a separate reader or writer boundary: ledger identity, invocation roots, done checks, engine readers, display readers, and fleet readers. The first milestone attempt failed because expected output was absent and no branch handled that absence, then the retry split the same contract into tasks that completed green.

record-run-shape-contract

`src/engine/run/run_shape.rs` still owns the modern run-shape record. Projection and reconstruction read that shape to resolve task-list directories and nested task paths. Historical records still have an explicit compatibility path instead of being silently read as invocation-scoped records.

This task gave the rest of the milestone a durable shape record to depend on. It was small enough for a fresh agent because it stayed below the UI and prompt layers: record the run shape, read it back, and route projection through that contract. The run facts show a green boundary, so later tasks could treat the record format as available rather than deriving depth again.

scope-production-world-by-invocation

`GenericProductionPatternWorld` now resolves task and invocation state roots through `RunShape` before falling back to historical paths. Called patterns get an `invocations` namespace, while task paths still resolve through declared task-list directories. That state layout is still the source for command environments, prompts, outputs, gates, and artifact lookup.

This task moved production-world state from shared paths into invocation state roots. The brief kept the responsibility concrete: each called pattern invocation needed its own files for outputs, tasks, and gate artifacts. It passed without a recorded repair, which fits work that connected a new root resolver to the world already built by the prior task.

skip-ledger-done-tasks

The ledger reader now exposes `is_done_task_path`, and the production world calls it before admitting a task from a work list. A skipped task gets a pattern event with the task path and a reason. Nested sibling tasks can therefore share a local id without causing resume to skip the wrong work.

This task made resume use the new ledger identity instead of a bare final id. Its boundary was narrow: enumerate tasks, ask the ledger for the full task path, and journal the skip when the latest row was done. The work stayed green, so the collision fix did not have to wait for the display and fleet readers.

declared-directories-for-engine-readers

Repair and artifact resolution still read declared task-list directories through the run shape. Nested task artifact directories are resolved by task path, not by a hardcoded directory name. Engine readers can handle task-list names supplied by the pattern instead of treating `milestones` as the production contract.

This task carried the engine-side readers that had assumed one directory name. It was separable because repair and artifact lookup could be changed against the shape record without changing front-end presentation. The green result made the next task about consumers outside the engine rather than about another state model.

declared-directories-for-display-and-fleet-readers

Fleet records, fleet caches, TUI artifact menus, and MCP artifact tools still read the projected run shape. `list_tasks` and `read_ledger` report task paths from projection, so nested runs and user-authored task-list names show the same structure everywhere. The website and reference data also received the updated vocabulary through generated data.

This task propagated the same state-shape contract to display and fleet readers. It was the right final child for the milestone because the engine could already write the record it needed. The sprint stayed green, then the milestone retry landed with the surface readers included.

Milestone 2

boundaries-rollback-and-pause

Boundary references now include `run-base`, `iteration-start`, and spec-defined `before` semantics. Discarded tree state is parked under recorded discarded refs before reset paths proceed. Live partial merge is no longer advertised; stopped-run merge is reached through pause at boundary and resume.

This milestone carried tree movement: boundary references, rollback safety, and operator pause. The child tasks were ordered so the engine first learned what a boundary means, then preserved discarded work, then exposed the pause and partial-merge contract. It ran green as a milestone after its child tasks had already isolated the hazardous parts.

boundary-references-mean-the-spec

The pattern runtime still records and resolves `run-base`, `iteration-start`, `previous-step`, and `before` references. Agent diffs and restore operations consume those boundary tokens through one engine path. Tests in the interpreter and pattern runtime cover the off-by-one boundary case that this task corrected.

This task fixed the meaning of boundary references before rollback work could depend on them. Its scope was intentionally semantic: resolve the named boundary from the interpreter record instead of collapsing every request to current `HEAD`. The run facts show no repair for this task, so the spec change became a stable base for the rest of the milestone.

park-discarded-tree-state

The production world now journals discarded project state through `DiscardedRefRequest` before restoring an attempt tree or protected paths. Worktree helpers create discarded refs for abandoned commits. Cleanup reads the identity journal before removing recorded discarded refs, so preserved state is a recorded artifact rather than an untracked side effect.

This task handled the destructive side of rollback. It was a good isolated cut because every reset-like path could first park the abandoned state and journal that parking, without changing the policy that chose the reset. The sprint stayed green, so later pause work could rely on recoverable discarded refs.

pause-boundary-and-live-merge-contract

`GenericProductionPatternWorld` now turns a requested boundary pause into an operator-pause stop before the next step runs. `gantry merge` documentation and capability reporting describe pause, stopped-run merge, and resume as the supported workflow. A live merge request refuses rather than trying to change a run whose engine still owns its in-memory rollback baselines.

This task joined operator control to the boundary machinery. The work was scoped to checking a pause latch between interpreter steps and changing live merge into an immediate refusal. It passed green, and the milestone then landed with stopped-run partial merge as the only advertised workflow.

Milestone 3

agent-context-and-plan-change-handling

Review, fix, troubleshoot, and plan-change prompts now get the diff and gate output their shipped templates name. Plan-derived files are watched through engine state, and prompt rendering rejects unfilled shipped markers. The current prompt catalog no longer carries production placeholders that the engine cannot fill.

This milestone restored what production agents need to act on the right evidence. Its child tasks separated ordinary diff and gate context, plan-change watch handling, and prompt-marker validation. The run facts show green task boundaries, so the work reads as context plumbing rather than recovery from failed implementation.

agent-diff-and-gate-context

Agent prompt construction still fills `DIFF` from the requested boundary and `GATE_OUTPUT` from the latest gate result. Review and recovery steps can compare against `iteration-start` instead of receiving an empty or stale context. Pattern tests cover review and fix prompts receiving the intended diff.

This task restored the ordinary context fields used by production agent steps. The brief kept it below prompt policy: provide boundary diffs and failed gate output where the step declared those inputs. It passed without repair, leaving plan-change behavior for the next task.

on-plan-change-watch-set

The production world still fills `PLAN_CHANGE_DIFF`, `SOURCE_PLAN`, and `SCOPED_PLAN_FILES` from the watched-set machinery. Frozen source plan mutations remain tamper violations, while derived brief edits route through the plan-change handler. Handler execution is followed by another observation pass, so a still-dirty watched set is not treated as resolved.

This task owned the spec contract for `on_plan_change`. It was not a prompt rewrite; it was the engine path that derives watched files from the frozen source plan and derived briefs, observes changes, runs the handler, and observes again. The green boundary let the prompt-marker task assume real plan-change data existed.

shipped-prompt-marker-guard

The shipped prompt files and agent-prompt reference now match the marker names filled by the production world. `REMAINING_PLAN` is gone from the prompt catalog, while the surviving plan-change markers are backed by live data. The prompt guard remains in the pattern tests, so a bundled prompt cannot ship with an unexpanded marker.

This task made shipped prompts match the engine's actual filler set. Its boundary was mechanical but important: remove markers with no production source and test that bundled pattern prompts render cleanly. It stayed green, and the milestone close only regenerated reference surfaces.

Milestone 4

map-until-and-cli-parameters

Fixed flags now bind bundled patterns before run creation, command steps receive absolute environment bindings, `map` writes and checks an orchestration-relative roster, and `until` consumes `max_cycles` as an ordinary parameter. The CLI docs and pattern spec describe `--param` for entry parameters. The current bundled patterns remain TOML definitions rather than special drivers.

This milestone made the bundled `map` and `until` entry points runnable through the production pattern path. The tasks were split by startup binding, environment visibility, map roster flow, and authored recursion ceiling. It stayed green, which matters because these tasks touched public CLI behavior and shipped pattern files.

cli-parameter-and-flag-startup

`PendingPatternInvocation` now derives a plan source for fixed flag patterns and carries raw parameter arguments into binding. The CLI accepts `--param` pairs for declared entry parameters and rejects unknown or repeated names. The spec and docs describe the same parameter surface that the parser implements.

This task handled run startup before any pattern worktree existed. Its brief kept the cut to selection and binding: fixed flags needed the same bound invocation path as named patterns, and generic parameters needed validation at startup. It passed green, making later pattern behavior able to read ordinary bound inputs.

visible-output-environment-paths

The production world builds command environments from parameters, task fields, readable outputs, and the current step's outputs. Valueless file and directory outputs become absolute orchestration paths. Command gates use the same environment path code before journaling their script result.

This task fixed command and gate environments. It was scoped to visibility: a process should receive absolute paths for every readable output it can see, not only outputs declared by its own step. The green result let the map roster task depend on shell commands seeing the paths the engine writes.

map-roster-production-flow

`config/patterns/map.toml` now writes a roster under orchestration state, checks for task files and gates, rewrites from a complaint when needed, and runs each task through agent, gate, repair, and verdict command steps. The map roster prompt tells workers that declared outputs are orchestration-relative. Headless and TUI projection still detect the remaining task-list record events produced by this path.

This task moved the bundled `map` pattern from draft shape into a runnable production flow. The cut covered roster writing, roster checking, complaint-driven rewrite, and serial task execution, all inside pattern TOML. It passed green, so no engine-only map driver was needed for this path.

until-max-cycles-parameter

`config/patterns/until.toml` declares `max_cycles`, carries completed cycle state through recursive calls, and uses a command output to branch to continue, ceiling, or invalid input. The spec says recursion is unbounded by language semantics and bounded only by lifecycle controls or authored parameters. The current CLI docs show `--param max_cycles` as the operator surface for that bundled pattern.

This task kept recursion bounded through authored pattern data instead of a new engine word. The brief required the parameter contract to be settled in the spec first, then consumed by bundled `until`. The task and milestone share the same final commit because this was the capstone of the milestone.

Milestone 5

record-honesty-and-structural-guards

The current tree has a smaller live event vocabulary, command gate script records, a live producer for inserted work-list tasks, and tests that stop unused event variants from reappearing. The pattern spec now describes spend guards honestly, and bundled patterns are interpreted against a mock world. The production record surfaces therefore describe events that actual code can produce.

This milestone cleaned the event record after the production paths existed. The split separated event vocabulary cleanup, gate and retry honesty, producer sweeps, and bundled-pattern structural guards. It stayed green, so the final milestone read as verification and record cleanup rather than a late redesign of the engine.

live-record-event-surface

`PatternEvent::Structure` remains in the domain because production still writes structure declarations. Producerless statistics fields and reader paths named for deletion are gone or tombstoned where the plan required that treatment. Pattern-format docs and replay metadata were updated to match the smaller live surface.

This task removed or tombstoned event vocabulary that no live producer supported. It was a reader and vocabulary boundary, not a runtime behavior change, so it could land before the record producer sweep. The green boundary narrowed what later tests needed to prove.

gate-and-retry-record-honesty

Command gates now run through the script execution path, write gate logs, and journal `PatternEvent::ScriptResult` with stdout, stderr, verdict, and selected value. Retry briefing no longer depends on a record shape that current pattern runs do not write. Environment and pattern tests exercise the record shape used by the current recovery path.

This task made gate and retry records describe what production actually writes. It was sequenced after the event cleanup because it needed the surviving record vocabulary and the stop-and-resume redesign text. The green result left command gates and retry notes aligned with current data instead of with retired assumptions.

event-producer-sweep-guard

The root test suite now includes an event-producer sweep over the domain event vocabulary. `PatternEvent::WorkListInserted` has a live producer in work-list re-enumeration, and inserted tasks are journaled when a later enumeration sees new ids. Future event additions must either be produced by production code or fail the structural guard.

This task converted the event cleanup into a permanent guard. It was deliberately test-focused: every surviving event variant had to have a live constructor outside codecs and tests. The sprint stayed green while deleting weaker root tests that no longer matched the post-purge policy.

bundled-pattern-structural-guards

Interpreter tests now load bundled pattern files and drive them with absent outputs in a mock world. The guard catches dead-on-arrival patterns, missing branches, bad prompt markers, and structural mistakes before a live run spends agent work. The restored multi-milestone, non-`milestones`, prompt-marker, event-producer, and map smoke checks remain part of the root gate.

This task proved the bundled pattern corpus against the mock world. It belonged last because it depended on the previous milestone's runnable `map` and `until` files, the prompt marker guard, and the record cleanup. The task and milestone share the final commit, making the structural guard the close of the run.