skip to content
Replays

Making Sprint Counts Comparable Across Runs

Splitting a run's completion state from the sprint size a person actually scans for.

Gantry milestones

0 milestones 2 sprints 8 agents

3 plan 3 execute 3 review 1 fix

110k peak context

Splitting a run's completion state from the sprint size a person actually scans for.

1h 22m total 9m 46s per sprint

2m 52s plan 8m 50s execute 4m 21s review

21 edits 138 commands

codex harness

This job separated two values that had been sharing one count. Gantry still needs an authoritative unit count to decide whether a run is empty, partial, or finished, but a person scanning run output wants a sprint-sized progress value that compares flat runs, milestone runs, and map-shaped runs on the same terms.

The work was split at the contract boundary. One sprint added the display-only count to discovered runs without changing state classification; the next routed command, TUI, and MCP surfaces to the side of the contract each surface meant to expose.

How this walkthrough is structured

Feature

What did the run build and ship?

Current run records still carry separate completion units and display sprint progress, and the command and MCP surfaces continue to expose that distinction.

Build

How did Gantry structure the work?

The run put the new registry contract before the consumer rewrite, then found its real stress in the routing sprint after the foundation review changed the remaining work.

Sprint Counts

3 agents 9m 14s wall time 110k peak context 1 replan

The registry still carries the split introduced here. `Run` has completion fields for state and separate sprint progress fields for scan displays, and enumeration computes the display value from flat sprint files, milestone read-side data, or the run ledger fallback. The tests still exercise flat, milestone, and ledger-shaped runs, so this contribution remains visible as a named contract rather than only as historical scaffolding.

This sprint had a narrow data-model job: add a display-only sprint progress count while leaving the state-authoritative ledger count untouched. That was a good fit for a fresh agent because the brief named the layouts to compare and the invariant that could not move. The sprint passed its gates, but review then forced a re-plan of the remaining work, which put the consumer changes behind a corrected contract rather than letting the first cut dictate every surface.

Route Sprint Views

8 agents 10m 18s wall time 79k peak context 1 fix

The routed contract is still present, though some surface names have changed since the job. Status output now renders sprint-sized progress separately from unit-based state, and MCP run JSON exposes `state_units` beside `display_sprints` while keeping the old `sprints` key tied to authoritative units. The original TUI line from this sprint is no longer isolated in the current tree, but the command and structured API paths still show the separation the sprint installed.

Once the registry could express both meanings, this sprint had to touch every consumer without mixing the two values back together. That made it a broader but still bounded pass: state readers stayed on authoritative units, while human-facing and structured run-size output moved to display sprint progress. This is where the run came under stress; the gate sent the sprint back, a fix ran, investigation followed, and the sprint was executed again before it settled.