PR review bot
A deterministic GitHub App that posts one useful comment per pull request: a before-you-merge checklist, a change-map diagram, code-health deltas, hotspots, hidden coupling, dead code, change risk, and an optional merge gate. Zero LLM calls, free for OSS.
The Repowise PR bot is a GitHub App that runs the same intelligence layers as the CLI and dashboard against every pull request, and posts one deterministic comment, only when there is something worth saying. No prompts, no hallucinations, no per-PR tokens. It is free forever for public / OSS repos; private repos need the Pro plan.
Install it from the GitHub App page: github.com/apps/repowise-bot. Pick individual repos or a whole org. There is also a marketing overview and you can manage installs from the dashboard.
Install
Install the GitHub App. Open github.com/apps/repowise-bot, choose the repos (or the whole org), and approve. The bot indexes each default branch through the same pipeline the hosted dashboard uses, usually a few minutes.
Open a pull request. On opened / synchronize / reopened, the bot
re-parses the changed files, computes the health delta between base and head,
and decides whether to comment.
Read the report. Each comment links back to the live snapshot on
repowise.dev for the full graph, hotspots, and marker drill-downs.
Permissions requested: Contents: Read · Pull requests: Write · Metadata: Read · Issues: Write (GitHub treats PR comments as issue comments). The optional merge gate additionally needs Checks: Write; existing installs re-consent when you turn it on.
The silence rule
Most PR bots are noise. This one stays silent unless there is a measurable signal worth interrupting a reviewer for. A green PR with no findings gets no comment at all. When the bot does comment, improvements are shown alongside problems so cleanup gets credit. It posts when any of these fire:
- net repo health degrades, or any modified file's score drops;
- a hotspot file (high churn + many dependents) is touched;
- a top co-change partner of a modified file is missing from the PR;
- new dead code is introduced (or removed, which is a win);
- a modified file is on a declining-health trajectory;
- a changed file carries substantial recent bug-fix history;
- the diff's change-risk score lands in this repo's high band.
The bot edits its existing comment when new commits land rather than posting a wall of duplicates; if the silence rule fires after an earlier comment, the stale comment is deleted.
What's in the comment
Each section is independent and only renders when it has something to say:
| Section | What it shows |
|---|---|
| At a glance | A one-line factual summary of what the PR touches (files, hotspots, findings, scope), with a per-module drill-down when the PR spans several. |
| Before-you-merge checklist | Every signal restated as an action, as a tickable task list: the tests that depend on the changed files, co-change partners missing from the PR, and the docs that usually track this code. |
| Change map | A deterministic Mermaid diagram of the PR's structural impact: changed files on the left, the code that imports them on the right, with guarding tests and co-change gaps attached. Wide PRs collapse to a module-level flow so the map stays legible. |
| Health delta | Repo-level score change across the three signals (defect · maintainability · performance) plus a per-file table of which files dropped, with the concrete markers behind each drop. |
| Change risk | The just-in-time defect-risk score for the diff (the same signal as repowise risk), banded against this repo's own commit history. |
| Review priority | The changed files ranked by recent bug-fix history. Defects cluster, so these deserve the closest look. |
| Hotspot touches | When the PR modifies a high-churn, high-dependent file, surfaces its primary owner and suggests adding their review. |
| Hidden coupling | Files that historically co-change with a modified file but are absent from this PR, which catches partial refactors before they break the next deploy. |
| Declining-health alert | Files trending down across recent snapshots that also regressed in this PR. |
| Dead code | New unreachable code the PR introduces, plus cleanup celebrated when it removes existing dead code. |
| AI vs human | When the diff mixes AI- and human-authored hunks, the bot attributes the health delta by authorship: "the AI-authored files account for the larger share of the regression." Built on the agent-provenance layer, the one signal a generic linter cannot produce. |
Every finding is deterministic: health scoring is tree-sitter + git + the calibrated marker scorer, and refactoring suggestions are template strings keyed off the marker type. Nothing is generated by an LLM, so every comment is reproducible.
The merge gate
Beyond commenting, the bot can post a GitHub Check Run that a branch
protection rule can require, turning code health into a merge gate. It is
off by default and configured per repo (health_gate.mode):
off: no check is created.advisory: always concludesneutral. The verdict is visible on the PR but never blocks. The safe default to start with.blocking: concludesfailurewhen a rule trips, which a required check will block the merge on.
The rules (evaluated only in blocking mode) let you adopt a clean-as-you-code
policy without forking any constants:
| Rule | Blocks when |
|---|---|
repo_drop_block | The repo health score drops by more than this many points (default 0.3). |
min_new_file_score | A changed file scores below this floor. |
block_on_introduced | The PR introduces any new marker in its added lines. |
block_ai_regression | AI-authored files account for the larger share of the regression (the provenance wedge). |
Or start from a named profile and nudge single knobs: health_gate.profile
accepts warn-only, block-new-file-floor, block-any-decline, or
block-on-ai-regression. The profile seeds the rules; any explicit key set
alongside it wins.
Because the bot already re-scores the repo at both the base and head commits, the gate and the AI-vs-human attribution need no extra index; they read the same per-PR analysis the comment is built from.
Configuration
Two ways to configure, with the dashboard taking precedence:
1. In-repo .repowise/bot.yaml (committed, versioned with the code):
bot:
enabled: true
comment_mode: on_signal # or "always" to post a clean bill of health
verbosity: standard # compact | standard | detailed
show_dead_code: true
show_change_risk: true
apply_labels: false # opt in to repowise:* PR labels (default off)
ignore_paths:
- "vendor/**"
- "**/*.generated.*"
health_gate:
mode: advisory # off | advisory | blocking
repo_drop_block: 0.3
min_new_file_score: 7.0
block_on_introduced: false
block_ai_regression: falseYou can toggle any section (show_summary, show_health, show_hotspots,
show_ownership, show_coupling, show_dead_code, show_refactoring,
show_declining_alert, show_change_risk, show_review_priority,
show_checklist, show_change_map), set the comment threshold, choose the
verbosity, and ignore paths.
PR labels (opt-in)
With apply_labels: true the bot also applies repowise:* labels, created on
demand and reconciled on every run — a label is removed once its signal clears,
and labels outside the repowise: namespace are never touched.
| Label | Applied when |
|---|---|
repowise:gate-failed | A blocking gate you configured actually tripped |
repowise:risk-high | Top tercile of this repository's own commit-risk distribution |
repowise:missing-tests | A file with recent fix history changed, and no test that imports it was touched |
repowise:size-xl | Too large for granular analysis |
They are off by default, and the list is short on purpose. A label is permanent, binary, and public in the pull-request list, so it reads as a verdict on the author in a way an editable comment does not — which means it has to be reserved for things that are actually rare. Signals that fire on ordinary work (a repo score that dipped, a hotspot touched, a moderately-sized diff) stay in the comment, where they carry their context with them.
2. The hosted dashboard (Settings → PR Bot). The dashboard config overlays
the YAML: any field set there wins, fields it omits keep the YAML/default value,
and ignore_paths is unioned (the dashboard can only add scope, never silently
un-ignore a path the repo author chose to skip). A malformed value is skipped,
never wedging the analyzer.
Pricing
Free forever for public / OSS repos: no LLM tokens, no PR cap. Private repos require the Pro plan (it matches the rest of Repowise hosted). Private installs still index on connect, so the snapshot is ready the moment you upgrade. See the pricing page.
How it relates to the rest of Repowise
Same engine, different surface. The bot reads the code-health,
git-intelligence, and
dependency-graph layers, and every
comment links to the live dashboard snapshot, where the same data is queryable
by humans (the web UI) and by AI agents (the MCP tools,
including get_health for a pre-PR self-check).
Dashboard tour
What lives behind sign-in at repowise.dev/dashboard: the hosted control plane for your indexed repos, workspaces, MCP keys, billing, and team.
Connecting your IDE
Mint an API key on the hosted dashboard and paste a snippet. Claude Code, Cursor, Claude Desktop, VS Code, and Windsurf supported.