fix(observability): add additive audit_events-backed review-activity panels - #5872
Conversation
…panels (JSONbored#3717) Part 1 (JSONbored#4134) clarified the wording on the snapshot panels. This is part 2: the true additive event-count panels the issue asks for. The six existing stat panels all count rows in `review_targets`, whose `status`/`verdict` are mutable current-state fields overwritten as a PR's disposition changes. `manual`/`commented`/`ignored` are transient for most PRs, so a PR that was held for manual review and then merged inside the same window is counted ONLY under Merged -- never under Manual review. Those panels answer "how many PRs are currently sitting in this state", not "how many times did a PR enter it", and so they structurally under-report for a maintainer who actively drains the queue. That is exactly the reported symptom. `audit_events` is append-only and already records the transitions: `agent.action.hold` when a PR is held for manual review (processors.ts), and `agent.action.${actionClass}` for every executed action (agent-execution.ts). Nothing new needs to be emitted -- the log was already there, and the dashboard simply never queried it. Adds a "Review activity (additive, from audit_events)" row with three stats (manual reviews entered, merges executed, closes executed) and a stacked per-day breakdown, all windowed on `created_at` so a day's count never changes retroactively. Existing panels are untouched; the new row is appended, so no panel shifts position. Scoping to the selected repo goes through `target_key LIKE '<repo>#%'` rather than a `repo` column, which `audit_events` does not have. That also means these counts cannot exclude bot-authored PRs the way the review_targets panels do -- stated plainly in the panel descriptions rather than papered over. Tested: 8 assertions pin the panels to audit_events (never review_targets), to `created_at` (never `updated_at`), to the real emitted event types -- including a drift guard that every event_type the panels query is one AGENT_ACTION_CLASSES can actually produce, so renaming an action class cannot silently leave these panels reading zero forever.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
CI failure here is infrastructure, not this PRAll six Codecov is now rejecting tokenless uploads. Because that step runs with This is repo-wide for fork PRs, not specific to this one. At the time of writing, every open fork PR shows the identical signature — #5870, #5871, #5872, #5873, #5877, #5879 — while owner-authored PRs (#5874, #5878, #5881) are green. Since the gate closes a contributor PR on any failing check, correct and fully-tested fork PRs are being auto-closed for a reason unrelated to their content. A fork PR can't see repo secrets, so its Codecov upload is inherently best-effort. Setting I'd be glad to open that workflow fix, but a PR here requires a linked open issue and issue creation is restricted for non-maintainers, so I can't file one to link. Happy to pick it up if you open an issue for it. For this PR specifically: the change is dashboard JSON plus one test file, so it adds no coverable lines — |
|
Caution 🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥 🛑 LoopOver review result - fixes requiredReview updated: 2026-07-14 21:33:33 UTC
🛑 Suggested Action - Fix Blockers Review summary Nits — 4 non-blocking
CI checks failing
Linked issue satisfactionPartially addressed Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
|
Gittensory is closing this pull request on the maintainer's behalf (CI is failing (validate, validate-tests (2), validate-tests (1), validate-tests (6), validate-tests (5), validate-tests (3), validate-tests (4))). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed. |
Closes #3717
Summary
Part 1 (#4134) clarified the wording on the existing snapshot panels. This is part 2 — the true additive event-count panels the issue asks for, which the maintainer explicitly left for a contributor.
The bug, restated
All six stat panels on this dashboard count rows in
review_targets, whosestatus/verdictare mutable current-state fields, overwritten as a PR's disposition changes — not an append-only log. Andmanual/commented/ignoredare transient states for most PRs.So a PR that was held for manual review and then merged inside the same window is counted only under Merged — never under Manual review. The panel answers "how many PRs are currently sitting in this state as of their last update in-window", not "how many times did a PR enter this state". For a maintainer who actively drains their manual-review queue, it structurally under-reports — which is exactly the reported symptom ("I've definitely had more than 21 manual reviews").
The fix
The append-only log already existed; the dashboard simply never queried it.
audit_eventsalready records the transitions:agent.action.hold— emitted when a PR is held for manual review (src/queue/processors.ts)agent.action.${actionClass}— emitted for every executed action (src/settings/agent-execution.ts)So no new event emission is needed, and no application code changes. This PR adds a
Review activity (additive, from audit_events)row with:agent.action.holdevents in the windowagent.action.mergeevents in the windowagent.action.closeevents in the windowEvery panel windows on
created_at(when the event happened), neverupdated_at— so a day's count never changes retroactively when a PR's status later moves on. That is precisely what thereview_targets-backed panels cannot show.The existing panels are untouched, and the new row is appended (
y: 34), so no existing panel shifts position. The diff is 52 added lines and zero deleted ones.Two things I want to be upfront about
audit_eventshas norepocolumn. Repo scoping goes throughtarget_key LIKE ${repo:sqlstring} || '#%'(the key isowner/repo#number), rather than therepo = …equality thereview_targetspanels use.audit_eventsrecords the action the agent took, not the PR's submitter, so thesubmitter NOT LIKE '%[bot]%'filter the snapshot panels use has no equivalent here. Rather than silently produce a subtly different number, this is stated plainly in the panel descriptions, so a maintainer comparing the additive panel against the snapshot above it knows exactly why they differ.Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run typechecknpm run selfhost:validate-observabilitynpm run engine-parity:drift-checknpm run docs:drift-checknpm audit --audit-level=moderateNew suite
test/unit/selfhost-grafana-additive-review-events.test.ts(8 tests) pins the panels to:audit_events, neverreview_targets;created_at, neverupdated_at(the whole point — an append-only window);agent.action.*event_type the panels query must be oneAGENT_ACTION_CLASSEScan actually produce, so renaming an action class can never silently leave these panels reading zero forever;queryText/rawQueryTextkept in sync, as the SQLite datasource requires.It also asserts the six original
review_targetspanels are still present and unmodified, and that panel ids stay unique.The existing dashboard suites (
selfhost-grafana-dashboard,selfhost-grafana-no-dollar-underscore-sentinel) pass unchanged — 51 tests green across the three files.codecov/patchhas no coverable lines in this diff: the change is dashboard JSON (not in the coverage include set) plus a test file (codecov-ignored).If any required check was skipped, explain why:
Safety
UI Evidencesection. Not applicable — see below.UI Evidence
Not applicable — this is a Grafana dashboard JSON definition, not an application UI surface. It renders inside a self-hosted Grafana against the operator's own
loopover-db, so there is no reviewable app screenshot to capture and noapps/loopover-ui/code is touched. The panel definitions are asserted directly in the new test suite instead.Notes