the PR review router

Every feature that makes AI review predictable.

PURA reads your routing intent in plain English, compiles it once into deterministic rules, and runs one agentic reviewer per pull request — on your own provider keys, metered and capped at your org budget.

Plain-English rulesDeterministic engineAgentic reviewerBYO keys + ZDRCost meterOrg budget caps
pura.md

Routing rules a human can read

No DSL to learn. Describe how each kind of PR should be reviewed in plain English and commit it next to your code.

Two homes for configuration: .pura/pura.md in your repo holds routing intent, while the dashboard owns budgets, caps, allowed models, BYO keys, and ZDR. Repo rules can never escape your org caps.

  • Route by path, label, author, PR size, or remaining budget
  • Pick provider, model, and thinking budget per rule
  • Bigger model wins on conflict — deterministic every time
  • Drafts and trivial bumps can skip review entirely
.pura/pura.md
# PURA routing rules

- payments/ or billing/ over 200 lines:
    Claude Opus, high thinking.
- Code owned by @team/search:
    GPT-5, medium thinking.
- Dependabot PRs: cheapest model.

# budget-aware ladder
- Until 50% of the org cap is spent: GPT-5.
- Between 50% and 75%:               GPT-5-mini.
- Over 75%:                          GPT-5-nano.

- Draft PRs: skip.
- Default: Claude Sonnet, medium.
rules.yaml

A deterministic CEL engine

Translation is the only LLM-driven step. Routing itself is pure evaluation — same PR, same inputs, same decision, every time.

01

Write intent

Authors describe routing in plain English in .pura/pura.md and commit it with the code.

02

Translate once

PURA's Translator compiles pura.md into a deterministic CEL .pura/rules.yaml using PURA-owned keys — not yours.

03

Evaluate per PR

The CEL Engine runs the rules against a fixed pr context to resolve (provider, model, thinking, action). No LLM in the hot path.

.pura/rules.yaml
# generated by PURA — do not edit by hand
- name: payments-critical
  when: >
    pr.paths.exists(p, p.startsWith("payments/")) &&
    pr.changed_lines > 200
  route: { provider: anthropic, model: claude-opus, thinking: high }

- name: dependabot
  when: pr.author == "dependabot[bot]"
  route: { provider: openai, model: gpt-5-nano, thinking: none }

- name: default
  when: "true"
  route: { provider: anthropic, model: claude-sonnet, thinking: medium }
reviewer agent

An agentic reviewer, not a prompt

The reviewer is not preloaded with context. It gets the diff plus filesystem tools and decides what to fetch — reasoning over your codebase like a senior engineer.

read_file(path, start?, end?)

Reads any file at the PR head SHA. Large files require a line range; ranges are clamped.

glob(pattern)

Lists matching paths so the model can find related modules, tests, and call sites.

grep(pattern, path?)

Sandboxed regex search with line numbers — tracing usages and prior art across the repo.

Safe by construction

  • Read-only repo token — no write_file, no delete, no shell, no network beyond the provider API
  • All tool reads pinned to the PR head SHA; a new push starts a fresh run
  • Tool results scanned against PURA's secret-pattern catalog; high-confidence matches are redacted before they ever reach the provider
  • A redacted secret injects a 🔴 P1 finding pointing at the file and line — without echoing the value
  • Structured-output schema is validated; an invalid response is retried once, then escalated
review output

One Codex-style review per PR

Exactly one Pull Request Review per run — line-anchored findings with severity tags and one-click suggestion blocks. The review event is derived from severity, never set by the model.

🔴 P1 — must fix

Correctness bug, security issue, breaking change, or data loss. Any P1 makes the review REQUEST_CHANGES.

🟠 P2 — should fix

Robustness gap, missing test coverage, or a significant style/perf concern worth addressing.

🔵 P3 — suggestion

Minor improvement, polish, or an alternative approach. Only P2/P3 posts as a COMMENT.

No findings? PURA posts an APPROVE with the summary header. Re-reviews dismiss the prior PURA review and link to its successor.

PURA review · src/checkout/cart.ts
PURA Review • routed to claude-opus (high) •
matched rule payments-critical
3 findings: 1 P1, 2 P2 • est. $0.34 • 2.1s

🔴 P1 · Guard against negative quantity in cart total

`computeTotal` multiplies `item.price` by `item.qty`
without validating `qty >= 0`, so a crafted payload
can produce a negative order total and refund credit.

```suggestion
const qty = Math.max(0, item.qty);
```
byo keys · zdr

Your keys, your data, your control

Inference runs on your provider keys and is billed by your provider — never by PURA. PURA's own keys are used only to translate pura.md into rules.yaml.

Bring your own keys

Supply keys for any provider in PURA's catalog — Anthropic and OpenAI today. Scope them per project or fall back to an org-wide pool.

Encrypted with per-org KMS keys

Every key is encrypted at rest in PURA's backend under a per-org key-encryption key in a KMS. Plaintext is never displayed after creation.

Zero Data Retention by default

Only ZDR-eligible models are allowed while ZDR is on. Turning it off is an explicit, audit-logged dashboard action — never a pura.md setting.

cost meter · budget guard

Metered per call, capped per org

Every provider call writes one cost-meter row attributed to a project. Soft thresholds alert; hard caps downgrade — runs are never silently skipped.

Cost meter

Each row records tokens, an estimated USD cost from a versioned price catalog, latency, matched rule, key id, and project_id = (org, repo) — so finance can split the bill by team.

  • Cost by repo, review counts, and average cost per PR
  • Model-usage breakdown and routing-decisions audit
  • Filter by date range, repo, model, or matched rule
  • Export to CSV or JSON; rows retained for 24 months

Org-cap overlay

After the Engine picks a model, the overlay runs to guarantee compliance. It only ever downgrades — never upgrades — and records the reason on the review header.

  1. 01Allowed-model check downgrade to the most powerful model on your org's allowed list
  2. 02ZDR check downgrade to the most powerful ZDR-eligible model
  3. 03BYO-key check downgrade to a provider that has a working key for the repo
  4. 04Budget pre-dispatch downgrade to the cheapest allowed model that fits the cap
  5. 05Hard-cap floor if a cap is already breached, force the cheapest allowed model
monorepos

One repo, many model preferences

Different paths route to different models without forking the repo. CODEOWNERS, paths, labels, and authors all feed the routing decision.

In a monorepo, a Dependabot bump and a payments rewrite should not hit the same model. PURA lets every team express its own preference in one shared pura.md, and the cost meter still attributes every call back to its project.

  • Per-path and per-team model selection in one file
  • Cheap models for low-stakes diffs, the best for high-stakes ones
  • Org admins can narrow the allowed-model list per repo
  • Spend is attributed per project for clean chargeback
incoming pull request
payments/** · 350 linesclaude-opus · high
code owned by @team/searchgpt-5 · medium
docs/** · typo fixgpt-5-mini · low
dependabot bumpgpt-5-nano · none
reliability

Predictable when things go wrong

PURA fails loudly and recoverably. You always know what was reviewed, on which commit, and what to do when a run can't complete.

Re-review on every push

A new commit triggers a fresh run pinned to the new head SHA. The prior PURA review is dismissed and superseded — never duplicated.

Retry once, then escalate

On a transient failure PURA retries exactly once. There is no automatic model fallback — alternatives are expressed as separate rules in pura.md.

Manual-review-needed

On a second failure or a non-retryable error, PURA posts a single comment with a stable error id. Nothing is silently dropped.

Determinism guarantees

Idempotent webhook handling and a fixed pr context mean duplicate deliveries and re-runs never change the routing decision.

dashboard

The org control plane

GitHub-OAuth-scoped to a single org, the dashboard owns everything pura.md cannot: keys, allowed models, ZDR, budgets, and the full audit trail.

Setup

  • Org key pool and per-repo key selection
  • Allowed models, org-wide and per repo
  • ZDR toggle with confirmation + audit
  • Per-repo status and rules.yaml SHA

Budgets

  • Org monthly cap and MTD spend
  • Per-project caps and soft thresholds
  • Alert recipient distribution list
  • Projected end-of-month spend per project

Reports

  • Cost by repo and average cost per PR
  • Model-usage and routing-decision audit
  • Per-PR audit view of every decision
  • CSV / JSON export of any report
Three tabs, one source of truth — repo rules can never escape these caps.

Ship one reviewer that gets it right.

Install PURA, drop a pura.md in your repo, and route your next pull request in minutes — on your own keys, capped at your org budget.

BYO keys · Zero Data Retention by default · 14-day free trial