A self-hosted, open-source AI code reviewer — the CodeRabbit alternative you run yourself.
Point it at a GitHub pull request and it posts a real review — a sticky verdict plus inline comments — written by a read-only Claude Code agent running on your machine. Your code never leaves your infrastructure, there's no per-seat SaaS bill, and nothing about it is a black box: you own the prompts, the model, and the data.
The thing most AI reviewers get wrong? Precision. OpenReviewer is built to stay quiet unless it's genuinely confident — every finding has to survive a second pass whose only job is to disprove it. So your team reads signal, not a wall of nitpicks.
Three things it does, all on your own infrastructure:
- Code review — reviews a PR and posts a sticky verdict + inline notes. A two-pass reviewer (correctness + security) behind a grounded "refute-or-drop" judge, tuned so it stays quiet unless it's confident.
- Bug triage — when a bug is filed, it explores your repos and posts three genuinely different readings of what's wrong, each with its own fix path, as one comment.
- Auto-fix (optional) — turn a chosen reading into a draft PR written by the agent in a throwaway worktree. It never merges; a human always reviews.
Licensed under Apache-2.0. Requires Node ≥ 20 and the
claude CLI.
npm install
cp .env.example .env # set GITHUB_TOKEN and REVIEW_BOT_LOGIN
claude login # authenticate the agent (once)
npm run review -- <pr-number> --repo <name> # review a PR, post sticky + inline
npm run review -- 42 --repo backend --no-post # print the verdict, post nothing
npm run review -- 42 --repo backend --security-only
npm run eval # score the reviewer on the golden bug setThe reviewer works as a manual CLI with just GITHUB_TOKEN. To make it always-on
(auto-review every PR push via webhook), see deploy/README.md.
LLM bug detectors have a low recall ceiling and a nasty false-positive habit, so this one is built to maximize precision and signal-to-noise, not raw catch count:
- Two focused passes — a general correctness pass and a dedicated security pass with enumerated threat classes, an exclusion list, a mandatory exploit scenario, diff-scoped, and a confidence floor. (Single "find everything" prompts tank signal-to-noise.)
- Grounded judge — a second read-only pass adversarially tries to disprove every finding;
a finding survives only with a concrete
file:linereceipt that clears the floor. This is the precision engine — refute-or-drop. - Blast-radius context — it greps callers/dependents of changed symbols, so cross-file and tenant-scoping bugs that are invisible in a raw diff become reachable.
- Risk-tier gate — changes touching sensitive surfaces (payments / webhooks / migrations /
auth / rbac / tenants / secrets / PII) require human sign-off. The bot is advisory and
never approves — inline comments post as
event=COMMENTonly. - Incremental re-review — on a new push it diffs against its own prior findings (fingerprinted in a hidden marker) so it doesn't re-nag unchanged issues and can mark resolved ones outdated.
- Deterministic tool pre-pass (opt-in) — folds in hits from linters/scanners (e.g.
golangci-lint,gitleaks,ast-grep) over just the changed lines, labeled as candidates. - Eval harness —
npm run evalscores precision / recall / SNR / line-anchoring on a checked-in golden set of common bug classes. Missed must-catch findings are logged loudly — no silent caps.
npm run triage -- <TEAM-123> # explore → post the 3-readings comment
npm run triage -- <TEAM-123> --no-post # render to stdout, post nothing
npm run triage -- <TEAM-123> --repos=web # restrict to a subset of configured reposIt fetches the issue, skips already-triaged/empty issues, spins up a throwaway worktree per
repo, and has the read-only agent return three distinct theories of the bug (root-cause → plain
fix → technical → effort/risk/test → files last). Worktrees are torn down in a finally, so a
failed run never leaks disk.
After a human replies go with A/B/C on a triage comment, the fix agent implements that reading
in a throwaway worktree (read-write, but sandboxed to the worktree) and opens a draft PR —
which the reviewer above can then review. It never commits to your branches and never merges.
Copy .env.example → .env and set what your feature needs. Highlights:
| Var | For | Notes |
|---|---|---|
GITHUB_TOKEN |
review, fix | Read for review; PR-write to post/open PRs. Prefer a GitHub App token. |
REVIEW_ENABLED |
review | Master switch for the reviewer. |
REVIEW_BOT_LOGIN |
review | The bot's GitHub login — enables identity-based state detection. |
LINEAR_API_KEY |
triage, fix | Only needed for Linear features. |
LINEAR_PROJECT_ID |
triage | Empty = fail-closed (nothing auto-triaged until set). |
TRIAGE_REPOS |
triage, fix | name=/abs/path:base_ref, comma-separated. |
*_WEBHOOK_SECRET |
dispatcher | Mandatory; the dispatcher fails closed without it. |
Every knob has a safe default in src/config.ts — that's the source of truth.
- The review/triage agent is read-only by construction (allowlisted to
Read/Grep/Glob, no Bash/Write, never--dangerously-skip-permissions). The auto-fix agent is read-write but confined to a throwaway worktree and never merges. - The diff is treated as untrusted input (prompt-injection guard).
- Secrets are read via required-env helpers with no fallbacks; missing config fails closed.
- Webhook signatures are mandatory and constant-time; stale deliveries are dropped.
- Code-executing tools are opt-in (
REVIEW_TOOLS_EXEC) — an RCE surface, off by default.
See SECURITY.md for the full deployment threat model and how to report issues.
| Area | Files |
|---|---|
| Config / infra | config.ts (fail-closed env), repos.ts (worktrees), queue.ts, store.ts |
| Code review | review.ts (orchestrator), reviewagent.ts (passes), judge.ts (grounded judge), context.ts (blast radius), risktier.ts, prdiff.ts, reviewstate.ts (incremental), reviewgh.ts, reviewcli.ts |
| Reviewer inputs | describe.ts, guidelines.ts, instructions.ts, tools.ts, issuecontext.ts, feedback.ts, telemetry.ts |
| Triage / fix | triage.ts, worker.ts, comment.ts, cli.ts, fix.ts, fixworker.ts, pr.ts, decision.ts |
| Dispatcher | dispatcher.ts, webhook.ts, ghwebhook.ts, ghapp.ts, reviewcommands.ts |
| Eval | eval.ts + eval/fixtures/*.json (golden bug set) |
npm run typecheck # tsc --noEmit
npm test # ~360 unit tests, no network
npm run eval # offline reviewer scorecardSee CONTRIBUTING.md. Contributions are Apache-2.0.