Repository navigation
Spec: Console Metrics view for Run metrics, Fleet trends, and failure attribution - #2080
Merged
Merged
Conversation
…ccount Commands (#2065) Turn /metrics into a server-rendered Console page (jump m) backed by metrics --json and /api/v1/metrics: daily or weekly buckets, 7d/30d/12w/all presets, preceding-window comparisons with n and observed/missing counts, per-kind Succeeded/Failed/Paused/Stopped stacks that leave out pass-through Pickup runs and skipped Passes, kind/harness/model/account filters, and readable Other-account Commands tagged by OS account.
… form keeps repeated filters (#2065) Signal rows now leave out pass-through Pickup runs and skipped Passes and count a crashed record as died, leaving missing_outcomes to live runs. The Metrics form shows one field per repeated filter value. The outcome kind list is shared with the page, Snapshot capture names its past-metrics flag, and docs/code-navigation.md points at the new owners.
Console Metrics page: outcome stacks, daily/weekly windows, deltas and Other-account Commands (#2065)
…ship-safe efficiency and friction (#2066) Add four paired signal groups to metrics --json, /api/v1/metrics and the Console Metrics page: per-kind kept pull-request survival read from github-inbox.json alone, confirmed Bug origins by merge, calibrated weekly Scores pass rates, Needs you and Stop counts, Succeeded-only duration, Repairs and CI rounds with first-pass clean rate, time and spend per succeeded delivery by Harness and Model and wasted share, and stages above their Usual range with per-Session friction and Security holds. Each line carries per-bucket values for a static sparkline and, when bounded, its change from the preceding window. Setup rows' means now cover Succeeded Commands only.
…Scores and merged cohorts in daily windows, n beside deltas (#2066) Open the Yield group whatever the window, filter Scores as exactly as Commands, bucket a Scoring week by its last day, date an unkept merged pull request by its Command's end, show each window's n with the changes, name intervention counts as the glossary allows, give headline values a unit, share the pull-request URL identity and a template macro, and point code navigation at the new owners.
Metrics signal groups: kept PR survival, post-merge quality, survivorship-safe efficiency and friction (#2066)
…drilldown (#2067) Command records keep thirdshift_version at start and stopped_at with a failure_category (held, waiting, crashed, stage_failed) at a failure ending. Older records recover their version from Session traces through the retained Session-signals cache and fall back to their last stage and died or failed. metrics and /metrics filter by --version / version=, break outcomes down by version, mark version (and, when narrowed, Harness and Model) transitions on the timeline, and group Failed Commands as Where runs failed, linking each cluster and Failed bucket to History filtered to those Commands and each name to its details.
…he view, failed_commands in JSON, Ending type (#2067)
Record thirdshift version and failure attribution, with a Where runs failed drilldown (#2067)
…ge default, and saved peer snapshots (#2068)
… trimmed to the window, another window's snapshot stands in, a machine named fleet is choosable (#2068)
… whose read saved it (#2068) A peer refuses a Console person missing from its sign-in list, but once it went offline or was removed, its saved summary showed to every viewer. Snapshots are now kept per machine and reader.
Fleet Metrics: metrics --fleet and --machine, Fleet as the Metrics page default, and saved peer snapshots (#2068)
…--push, a push after each Command, and reported machines read-only on Metrics (#2069)
…ch snapshot slot's merge, share the whoami probe, list writer and view keys, name person scopes (#2069)
Outbound Fleet reporting: report token scope, metrics --push, push after each Command (#2069)
…lures carry repository and link, requeued Stops leave Needs you, lone sparkline points draw, help line ends whole (#2036) - After a Command, push the whole history by day before the default view, so a reporting machine appears in 7d and 30d Fleet windows too. - Failure summaries carry the repository and the pull request's or issue's URL; the Fleet page links an https one for cached or reported machines. - A Stop that requeued its issue counts as a Stop but not as Needs you. - A sparkline point without neighbours draws a dot, not a bare moveto. - `metrics` help ends in a whole sentence; the guide lists `version` among the API filters, with an API/CLI parity row for it.
JacobStephens2
marked this pull request as ready for review
November 12, 2026 08:59
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This makes Metrics a first-class Console view, twinned with
metricsand/api/v1/metrics(ADR 0016, ADR 0026):reporttoken lets a sleeping or NATted machine push its own summary to an always-on Console.sequenceDiagram participant Laptop as Laptop VM (report token) participant Hub as 24/7 Console participant Peer as Paired Fleet peer Laptop->>Hub: POST /api/v1/metrics/report (after each Command, metrics --push) Hub->>Peer: GET /api/v1/metrics (bounded, parallel) Peer-->>Hub: bucketed summary → saved under logs/fleet-metrics/ Note over Hub: Fleet view merges this machine, live peers, cached peers and reported machines (read-only)What each Ticket added:
This review added these changes:
The
metricshelp line now ends in a whole sentence, and the guide listsversionamong the API filters.Evidence
Execution evidence
Each review fix was written test-first:
cargo test --test console an_automatic_push_shows_the_worker_in_daily_fleet_windowstest result: ok. 5 passed; 0 failed(cargo test --test console metrics_report)cargo test --test console metrics_push_shows_the_worker(assertingfailed["repository"] == "acme/widgets")cargo test --test console metrics→test result: ok. 20 passed; 0 failedcargo test --test metrics a_requeued_stop_is_a_stop_but_not_needs_youtest a_requeued_stop_is_a_stop_but_not_needs_you ... okcargo test --bin thirdshift logs::metrics::groups::tests::sparklinestest result: ok. 3 passed; 0 failedcargo test --test command_surface help_says_what_metrics_push_sendstest result: ok. 21 passed; 0 failedWhole-branch validation:
scripts/affected-tests mainpassednpm test --prefix site,cargo build --lockedandnpm test --prefix console.cargo test --no-fail-fastpassed with no failures.npm run docs:check --prefix siteandcargo clippy --all-targetscame back clean.One existing test is flaky on
mainas well as here:tests/process/findings.rsmerged_fix_is_rechecked_after_a_later_fix_failsfailed 8 of 10 runs onorigin/main, and this branch doesn't touch it.Visual evidence
Both pairs use the same fixture of twelve Commands over 30 days. Before is
main's/metrics, which is a raw JSON dump;mainhas nowindowkey, so it is shown at plain/metrics. After is/metrics?window=30d.Desktop 1440×900, This machine:
Mobile 390×844, This machine:
Unaddressed findings
Standards
args.rs,scope.rs,fleet.rs,console/metrics.rsandopenapi.rswould touch every Ticket's code without changing behaviour. For S15, CODING_STANDARDS points to codebase-design. Its rules are a preference, and the same behaviours are also covered through the CLI and Console intests/console/metrics.rsandtests/console/metrics_report.rs.tests/metrics.rs). Not reproduced. The reviewer gave no failing command, since each child process restarts the clock, and the full suite passed.Spec
needs-triage).FleetPage::detailsinsrc/console/metrics.rsprovides those links.reportwire format with signal groups, giving History amachine=scope, and adding a harness-version filter (which the Spec's Implementation Decisions filter list leaves out) are Spec decisions.interruptedrun with no Stop counts as Failed. The reviewer did not assert this is wrong. The Spec defines Stopped as "human Stop" and Failed as including crashed runs, andoutcomes.rsclassifyfollows that.Security
reporttoken scope and/api/v1/metrics/reportreceiver, the binding of each report to its holder and its saved slot, the outbound push's address and redirect checks, escaping in the Metrics and Fleet templates, and thehttps-only links to reported failures.Security review outcome
No unaddressed introduced findings.
Review coverage
Both reviewers read every changed file.
site/docs/index.htmlwas not read: it is generated fromdocs/guide.mdbysite/generate-docs.mjs, andnpm run docs:check --prefix sitepasses.src/logs/metrics/fleet/tests.rslines 120–415 were skimmed by test names and assertions rather than read line by line.Merge Danger
Door: two-way
Rolling back is safe for stored data. New Command record fields (
thirdshift_version,stopped_at,failure_category) are optional, older readers ignore them, andlogs/fleet-metrics/snapshots are a cache. Areporttoken issued while this is deployed stays in the token store, though, and should be revoked if the change is rolled back.Blast Radius: moderate
report-tokenPOST /api/v1/metrics/reportendpoint widen the Console's API surface, though each holder writes only its own slot.metrics --jsonshape changes.Closes #2036
Built with claude 2.1.314 · opus · default effort
Tickets