Guard · Review analytics

Review analytics

How review actually behaves on your repo. Four rollups folded from the shape-only PR-review events RepoOps already ingests, joined to merged PRs from git history. No new ingestion, and review bodies are never read.

Where to find it

  • Localhost: /review-analytics.html?repo=<id> - a sub-tab of the Review queue (sidebar: Guard → Review queue → Review analytics)
  • API: GET /api/review-analytics (optional repo, windowDays 1 to 365, periodDays 1 to 90)
  • Keyboard: K then review analytics

The four rollups

Cycles to merge.Each change-requested review forces another round, so a reviewed PR's cycle count is its change requests plus one. A PR that went straight to approval merged in one cycle. Reported as average and median over reviewed PRs.
Reviewer load.Per reviewer: review events, approvals, change requests, comments, and distinct PRs touched. Each reviewer carries a human, agent, or bot kind from the same classifier the attestation pipeline uses, so agent reviewers are visible, not folded into the humans.
Review depth.Substantive reviews (approvals plus change requests) per merged PR. A comment-only pass is counted in reviewer load but does not count as depth.
Open to first review.Hours from PR open to the first review of any state. Honest-null when a timestamp is missing; a negative delta never fabricates a number.

Honest nulls

A merged PR with no stored review never enters an average: it reads n/a, not zero, and only lowers the coverage percentage (reviewed share of merged PRs). Averages over an empty set read null, never 0. Before any review events exist the tab renders its honest zero state and points at the real prerequisite below.

Prerequisite: the review-event pull

Review events arrive shape-only through the GitHub App webhook on the hosted side; the local store fills once you add a prReviewsPull block (the hosted export address plus a device token) to the repo's entry in repos.config.json. Off by default; a half-configured block never fires. The window select offers 30, 90, or 180 days, with daily, weekly, 2-week, or monthly buckets.

Read more