Repository navigation
Hook fleet (3) scorecard dashboard - #1334
Merged
Merged
Conversation
`report.py --scorecard` folds runs.jsonl into one row per (phase, event type) and prints procs/event, cpu_ms/event, wall_ms/event, timeout%, crash% and spoke-rate. Rows are split into "before" and "after" by whether the row carries a `dispatch_path`, and grouped into events by `event_uid` (falling back to the row index when a row has no uid), so one harness event counts once no matter how many detectors ran under it. The phase split and the proc count read the row field the runner actually writes, `dispatch_path`. An earlier draft of this fold read `dispatch_mode`, which no row has: every post-dispatcher row then landed in the "before" bucket and the after-phase proc count never credited the dispatcher, so the scorecard showed no change at all. `--days N` is accepted alongside `--since` so the canary window can be given in whole days. Tests: two cases in engine/hooks/_runner/tests/test_report.py drive the CLI over a fixture ledger holding one pre- and one post-dispatcher event; they assert the per-phase numbers and the printed column header. Both fail against the base report.py with "unrecognized arguments: --scorecard --days 14". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
….py --html folds runs.jsonl and events jsonl once into summary.json and emits a static dashboard.html on demand, with no server and no change to any hook behavior. Review lane: behavior Safety invariant: Hook stdout and exit codes stay the same. This slice does not change the other four claims. Files: engine/hooks/_runner/report.py Change types: bugfix Acceptance criteria: The branch contains only this claim, and the review step publishes one pull request. Exit code: 0 Invoker-Finalize-Id: e5a0edf3-e934-4a17-8242-75988f61e013
…478-adac8c27 — Review claim: report.py --html folds runs.jsonl and events jsonl once into summary.json and emits a static dashboard.html on demand, with no server and no change to any hook behavior. Review lane: behavior Safety invariant: Hook stdout and exit codes stay the same. This slice does not change the other four claims. Files: engine/hooks/_runner/report.py Change types: bugfix Acceptance criteria: The branch contains only this claim, and the review step publishes one pull request.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 2437a82c-e2e3-4708-ac77-d4af674eb33e) |
Contributor
|
Queued — the merge queue status continues in this comment ↓. |
Owner
Author
|
@Mergifyio queue |
Contributor
Merge Queue Status
This pull request spent 1 hour 53 seconds in the queue, including 59 minutes 58 seconds running CI. Required conditions to merge
|
15 tasks done
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
Small checker scripts run each time an agent acts. Each run is logged. This adds a table that shows what those runs cost, per kind of moment.
The problem: a new way of starting the checkers is coming. Nobody could see whether it is cheaper or safer than the old way.
The cause: the log had the numbers, but no view grouped them into old way and new way.
The fix: one new view sorts each logged run into before or after. It then shows how many were started, how long they took, and how often they failed.
It prints text or data only. It does not build a web page or save a file.
Review Claim
A new read-only view groups logged checker runs into old way and new way, and prints cost and failure numbers for each kind of moment.
Review Lane
behavior
Review Unit
engine-runtime
Safety Invariant
Hook stdout and exit codes stay the same. The new code runs only when someone asks for
--scorecard; it readsruns.jsonland writes nothing. No hook, runner, or dispatch file is in the diff.Assumptions: this text comes from the workflow plan and was not confirmed by a person in this headless run.
Slice Rationale
This is one of five claims split out of the Hook fleet dispatcher branch. It only reads the ledger, so it can be reviewed without the dispatcher changes that write the
dispatch_pathfield.Non-goals
--htmlflag, nosummary.json, and nodashboard.html. The workflow claim named those; this diff does not contain them. It ships the--scorecardtext and--jsontable only.runs.jsonlis read.--events,--runs,--judge,--skills, or--harness-gapmodes.Measured
Command:
python3.12 engine/hooks/_runner/report.py --scorecard --days 14report.py: error: unrecognized arguments: --scorecard --days 14(exit 2, atorigin/main0adc86f)before PreToolUse 5465 5465 1.0 765.7 765.7 1.3 0.0 0.00(exit 0, at f74048a, first rows below)The head run read the live ledger on this machine and printed 12 rows, all in the
beforephase and none inafter:The
afterphase is exercised by the fixture tests in the Test Plan, not by this live run.Test Plan
Test Plan
python3.12 -m unittest engine.hooks._runner.tests.test_report—Ran 21 tests in 1.428s/OKpython3.12 -m unittest engine.hooks._runner.tests.test_report -k scorecard -v—test_scorecard_compares_before_and_after_dispatch_path_rows ... ok,test_scorecard_prints_dashboard_columns ... ok,Ran 2 tests in 0.116s/OKpython3.12 engine/skills/make-pr/scripts/preflight.py --base origin/main --commit-only --dry-run—unit engine-runtime: 2 file(s)/ok preflight passedpython3.12 scripts/ci/check_hook_test_coverage.py engine/hooks/_runner—check_hook_test_coverage: OK (1 hook(s) checked)ruff check --select E9,F engine/hooks/_runner/report.py engine/hooks/_runner/tests/test_report.py—All checks passed!beforerows only.python3(3.9.6) printedModuleNotFoundError: No module named 'tomllib'andFAILED (failures=20). The runs above usepython3.12.Revert Plan
Revert Plan
git revert <merge sha of this PR>--scorecardand--daysflags stop being accepted.🤖 Generated with Claude Code
Note
Low Risk
Read-only CLI reporting on existing metrics logs; no hook execution or ledger writes, isolated to
--scorecard.Overview
Adds a
--scorecardmode toreport.pythat readsruns.jsonland prints a before/after comparison of hook detector cost and reliability, keyed by event type.Runs without a
dispatch_pathland in before; runs withdispatch_path(e.g.sdk,subprocess_fallback) land in after. Rows are grouped by phase, event, session, andevent_uid, then aggregated into per-(phase, event) metrics: event count, detector runs, processes per event (with post-dispatch counting one main proc plus subprocess fallbacks), CPU and wall time per event, and timeout/crash/spoke rates. Output is a text table or--json.Also adds
--daysas an optional positive float window (overrides--sincewhen set) for scorecard and shared time parsing.format_decimalformats one-decimal columns in the table. Unit tests cover before/after math and printed headers.Reviewed by Cursor Bugbot for commit f74048a. Bugbot is set up for automated code reviews on this repo. Configure here.