Imported from conforma/review-rot (
AGENTS.md). Install upstream withnpx skills add conforma/review-rot. Copyright stays with the author.
AI Agent Guide
Project overview
review-rot is a PR dashboard. It has three components:
- Go CLI (
cmd/review-rot/main.go) — queries GitHub GraphQL API, outputsdata.json - Static frontend (
frontend/) — vanilla JS + CSS, no build step - GitHub Actions (
.github/workflows/) — publish to GitHub Pages
Repository structure
cmd/review-rot/main.go — CLI entry point
internal/config/ — YAML config parsing (sources + UI)
internal/github/ — GitHub API: auth, repo discovery, PR queries, filtering, leaderboard
internal/model/ — Output data model (Go structs with JSON tags)
frontend/index.html — Dashboard HTML
frontend/css/style.css — Styles
frontend/js/app.js — Frontend logic
config/sources.yaml — GitHub App credentials, orgs, repos, team members, bots
config/ui.yaml — Dashboard appearance (title, logo, accent colors)
Build and test
go build -o review-rot ./cmd/review-rot
go test ./...
Run locally
export GITHUB_PRIVATE_KEY="$(cat private-key.pem)"
./review-rot --config-dir=config --output=data.json
Publish process
.github/workflows/publish.yaml runs every 30 min on weekdays (and on push to main):
- Builds the Go CLI (
go build ./cmd/review-rot) - Runs it with
config/to query GitHub and writeweb/data.json - Copies
frontend/*intoweb/ - Pushes
web/to thegh-pagesbranch viaJamesIves/github-pages-deploy-action
GitHub Pages is configured to serve from the gh-pages branch.
Authentication uses a GitHub App private key from the GITHUB_APP_PRIVATE_KEY
secret, passed as the GITHUB_PRIVATE_KEY environment variable.
Key design decisions
- Go CLI outputs JSON consumed by a static frontend (no server)
- Pre-filtering with three tiers:
- PRs from configured orgs → always included (all authors)
- PRs from watch-all repos (+ prefix) → always included (all authors)
- PRs from other repos → only if author is in the
authorslist
- Bot detection: PRs from authors in the
botslist are flagged as automated - Frontend uses vanilla JS with no dependencies or build step
- Reviewer leaderboard aggregates review/comment activity across PRs of any
state within a configurable data horizon, restricted to the team members in
authors(or every reviewer, ifauthorsis empty); the backend emits each reviewer's PR list with per-PR author and engagement timestamp. The frontend shows it in a separate tab with a client-side interval slider (1..horizon, narrows and re-ranks) and per-row accordions that open a table (PR/repo/author/reviewed date) of the PRs behind each count - Data refreshed every 30 minutes on weekdays via GitHub Actions cron
- Dashboard appearance (title, logo, colors) is configured via
config/ui.yamland injected intodata.jsonasui_settings; the frontend applies them at load time as CSS custom property overrides
Customization
To adapt review-rot for a different team:
- Edit
config/sources.yamlwith your GitHub App credentials, orgs, repos, and team members - Edit
config/ui.yamlto set your dashboard title, logo, and accent colors - Set the
GITHUB_APP_PRIVATE_KEYrepository secret - If
ui.yamlis omitted, defaults are used (title "Review Rot", no logo, neutral blue-grey palette)
Config format
See config/sources.yaml for the full backend configuration. Key sections:
github— App ID and installation IDsources.orgs— orgs to discover repos from (all authors included)sources.repos— explicit repos to monitor- Prefix with
+(e.g.,+owner/repo) to watch all authors - Without
+, only PRs from team members inauthorsare shown
- Prefix with
authors— team members for pre-filteringbots— bot accounts to flag as automatedleaderboard.window_days— data horizon: days of review history to aggregate for the reviewer leaderboard (default 90). The frontend interval selector narrows this further client-side, so it is the widest range shown
See config/ui.yaml for appearance settings:
title— dashboard title (shown in header and browser tab)logo— path to logo image relative to frontend directory (optional)palette— accent, accent_dark, accent_light colors