A deep-dive panel for a run's stats and git history
Turning the monitor's one-line stats glance into a full panel, a commit-activity view, and a pager every drill-down reads through.
When you watch a Gantry build in the terminal, the monitor's Stats menu shows a handful of one-line aggregates: how many units are done, how long things have taken. That is a glance, and it was all there was — no way to open the whole quantitative story of a run on one screen, no view of what the run had actually committed to the repository, and only a shallow scroller for reading the logs and reports behind those numbers.
This job built the depth behind the glance. It added a full-screen stats panel that lays out a run's per-unit timeline, where the time went stage by stage, token usage, the sequence of test-suite runs, and every retry and pause on a usage limit. It added a git activity view that lists the commits a run has made and lets you read any of them down to the full patch. And it upgraded the plain text viewer into a proper reading surface — search, tail-following for growing files, line wrapping, and light awareness of whether it is showing a diff, a JSON record, or Markdown — so that every drill-down from the new panels opens in that one viewer rather than a second one built to match.
Build
The build split into three milestones, and the ordering was the decision that mattered: the shared text viewer was upgraded first because both later views depend on it for their drill-downs.
The plan cut the work into three milestones in a deliberate order — the upgraded pager, then the stats panel, then the git activity view — and the reason the pager came first is what holds the decomposition together. The stats panel opens gate reports and stage logs; the git view opens commit patches. Both of those drill-downs are just text a reader scrolls, and the pager brief is explicit that they must route through one viewer and not fork a second. Had the panels been built before the reading surface they lean on, each would have grown its own scroller, and the run would have finished with two viewers to reconcile instead of one to reuse. Building the shared surface first is what let the later milestones reuse it.
That shared piece is also where the run came under stress. The pager milestone was the only one whose interior boundaries were redrawn while it ran: after the sprint that moved the pager's keys onto the shared action registry, and again after the search sprint, a review re-planned the milestone's remaining work. Two re-plans in the earliest, most-depended-on milestone is the signal for where the difficulty actually lived — the piece three things route through was the piece whose shape kept moving as the first sprints landed. The git activity milestone hit its own snag: a support stage errored and the milestone was re-planned before its first sprint ran a second time, locating a second point of friction at the boundary where the view shells out to read-only git.
By contrast the stats-panel milestone — the centerpiece deliverable, and the largest — ran its four sprints clean. Its brief pinned the hard part down in advance: every number must derive from the event stream the monitor already receives, accumulated cheaply, and a replayed history must produce the same panel as a live run. With that correctness property specified up front, the difficulty was dissolved into the plan rather than surfacing as a red gate.
Feature
The tree gained a full stats-panel modal, a commit-activity view, and a reading surface with search and structure awareness — all still present at today's HEAD and still sharing one viewer.
Before this job, the monitor's numbers stopped at a summary line and its text viewer stopped at scrolling. What could not be done: open a run's whole quantitative breakdown, see which commits the run had produced, or search and tail-follow inside a log. The design that answers this is a small set of new modules with a clear division of labour. A shared proportional-bar helper draws the panel's horizontal bars from plain block characters. A much larger stats module extends the existing aggregation to accumulate the per-unit and per-stage data the panel needs, kept identical whether fed from replayed history or live events. A git-activity module keeps a pure, canned-input parser apart from the thin runner that invokes read-only git off the render thread, so the correctness lives in a directly testable function. A structure module holds the cheap line classifiers — is this a JSON record, a diff, a Markdown heading — that give the pager its awareness without pulling in a highlighting engine.
Standing in the tree today, all of it is still there. Every file the job touched exists at HEAD, and the modules it introduced carry most of their original lines. The stats module remains the largest single addition and is largely intact. The git-activity module still keeps the parser-versus-runner split its own header describes. The panel and the git overlay are wired into the render path, their menu entries still open them, and the pager still holds the tail-follow scroller the plan reused for growing files. The core monitor files the job extended — the render, state, and top-level TUI modules — have been built on heavily by later work, which is what you would expect of the busiest files in the app, but the additions from this job survive within them. The design still holds: the drill-downs from both new panels open in the one upgraded pager, not a second implementation grown alongside it.