Record-Derived Run Surfaces
Cold projection, fleet records, and resume completion now read the same durable facts.
0 milestones 0 tasks
14 execute
50m 42s total
This run repaired two record-authority defects. Cold display paths for pattern-language runs had drifted from what the journal actually wrote, and a resume path could claim completion before the home branch contained the run branch.
The work was a single milestone because both defects ended at the same boundary: run displays and completion routes must read records and repository facts, not cheaper local proxies. The finished tree keeps the projection repair, the fleet-record reconciliation, and the already-complete completion guard in place.
How this walkthrough is structured
Feature
What did the run build and ship?
Cold projection, fleet records, and completion routing now preserve the run shape and completion state from recorded data and repository checks.
Build
How did Gantry structure the work?
The cut kept the record-read repairs and the resume-route repair in one milestone, then split the work by the surface that consumed the authoritative fact.
Milestone 1
Record-authoritative run surfaces
The milestone left three standing areas of behavior. `projection::cold` normalizes composed pattern paths into task paths while keeping legacy bare paths stable. `fleet_records::fold_run` derives shape and outcome summaries from displayed task records and declared levels. `EngineContext::already_complete` and `finish_run_complete` now write the same durable completion tail as the ordinary merge path.
This milestone carried both live defects because they shared one rule: a display or completion route must not infer state from a cheaper representation. The projection work read task identity from composed execution paths and declared structure records. The resume work waited for the repository fact that the run branch had reached the home branch. The run facts show no retry or re-plan, with one resolve stage at the integration boundary.
read-composed-task-paths
`normalized_task_path` now reads task identity out of `for:` path segments and discards `pattern:` and `step:` segments when they are only execution position. The current test suite keeps a legacy colon-bearing bare task path unchanged, so older records are not reinterpreted as composed paths. The contribution is still isolated in `projection.rs`.
This sprint carried the narrowest projection fault first. Its boundary was a pure parser rule: recover task ids from `for:` segments and ignore execution-position segments that are not tasks. A fresh agent could hold that because it changed normalization and a focused projection regression, not the surrounding display model. The gate stayed green, so later count work could depend on the repaired task path.
record-declared-structure
`PatternEvent::Structure` is documented as the task hierarchy journaled as task-list depths appear. Current `fleet_records` reads the last structure declaration from the projection view and turns its levels into fleet shape labels. The sprint's code change was documentation-level, but the behavior it named is still consumed by the record fold.
This sprint made the structure record describe what cold readers needed after task paths were repairable. Its change was small because the code already had a `PatternEvent::Structure` variant; the sprint corrected the documented contract to match when structure is journaled. That made the next sprint's fleet work legitimate: it could read level labels from the record instead of guessing.
reconcile-record-count-surfaces
`fold_run` now builds progress records from the deepest displayed task paths and uses that result for lifecycle, shape, and outcome counts. Detailed task rows still include parent nodes, so fleet JSON keeps the full tree while summary surfaces describe displayed work. The current tree retains the helper functions that compute displayed paths and declared levels from the projection.
This sprint carried the shared count defect after projection and structure facts were available. Its boundary was the fleet fold: choose which projected task rows count as progress rows, then feed lifecycle, shape, and outcome from that same set. A fresh agent could hold it because it stayed inside `fleet_records` and added one regression around nested level labels and deepest displayed work.
guard-already-built-resume
`finish` checks `main_contains_ref` before taking the already-merged completion path, and `already_complete` now calls `finish_run_complete` instead of emitting only live completion events. `finish_run_complete` avoids duplicating an existing completion record before it appends the durable tail. The regression for an absent worktree with an unmerged run branch asserts that the route stops and names the branch instead of emitting `RunComplete`.
This sprint carried the resume bug after the display repairs were done. Its boundary was the already-complete route and merge finish path: do not emit completion unless the home branch contains the run branch, and make true already-complete runs write the same completion record as ordinary merges. The run facts show the sprint itself stayed green; the later resolve stage belongs to integrating the finished work with main.