---
title: "Frazer Reviewer"
description: "Frazer Reviewer reviews code, security and plans with one engine: code review, security review and cold review, one set of settings, one findings model and one ledger; static checks before any model pass, findings inline only with evidence, loops in which the author agent fixes what the Reviewer finds, and an inbox built for one person's thousands of pull requests a day."
url: https://frazer.ai/docs/reviewer
index: https://frazer.ai/docs/reviewer/llms.txt
tokens: 12002
---

> For agents: this page is indexed at https://frazer.ai/docs/reviewer/llms.txt, and every page at https://frazer.ai/llms.txt. Copy commands from this file exactly.

# Frazer Reviewer

Frazer Reviewer reviews what people and agents write, with models of other families than the author’s and evidence before opinions. It has three kinds: **code review** of pull requests and diffs, **security review** of changes and repositories, and **cold review** of plans and documents. All three run on one engine, with one set of settings, one findings model and one ledger, so a finding is never posted twice and every kind learns from the same calibration. Inline comments appear only for findings with evidence: a test failed at the pull request’s head, a verifier of another model family traced the code, a rule you approved matched, or a tool found something new in the diff. Everything else is folded into one summary that is edited in place.

The Reviewer works natively on Fir, as a GitHub App on GitHub, and on any diff or file through the CLI and the API, including on its own with nothing else on Frazer and without write access to your code. Product overview: [Frazer Reviewer](https://frazer.ai/reviewer).

## Three kinds, one Reviewer

| Kind | Reviews | Deterministic first | What comes back |
| --- | --- | --- | --- |
| **Code review** | Pull requests and stack layers at each version; workspace snapshots; local diffs; any diff by API | Build, lint, type check and tests; secrets, licenses and advisories | Findings with an evidence grade, the verdict and **Would approve**, the expected effects of the change, and a run passport |
| **Security review** | Diffs through security lenses; repository and folder scans on a schedule, and deep scans; threat models; plans of risk class R2 and R3; lockfile and dependency diffs; agent configuration; findings imported from other scanners | Static analysis rules, secrets, advisories, licenses, release age, install-script and binary diffs | Findings with their CWE, the attack path, validation evidence and a suggested patch, as SARIF 2.1.0, with a revision stamp |
| **Cold review** | Plans and every engineering record or document (specs, decision records, runbooks, postmortems, agent instruction files), in Fir, on GitHub or as any file; the conformance pass before a plan closes | The plan checks’ static stages | Questions and verdicts, a coverage map and the readings of each criterion compared ([The planning flow](https://frazer.ai/docs/source/planning-flow#cold-review)) |

Tests, architecture and design rules, docs accuracy, performance, infrastructure and UI with a preview are **lenses** inside code review, not kinds of their own. Frazer Context’s **verify** keeps its own name and runs on this engine, and so do the panels of [Frazer Decisions](https://frazer.ai/docs/source/decisions#frazer-decisions) and the verifier of conflict repairs; one fix to the engine reaches them all, and every finding lands in one calibration.

| Kind | In Fir | On GitHub | Any file or diff, outside both |
| --- | --- | --- | --- |
| Code review | Native: findings are objects and the merge policy reads the verdict | The Frazer Reviewer App: review comments and a check run | `frazer review <patch, directory or --remote>`; `reviews_request` with a patch; zero retention available |
| Security review | Native; scans on a schedule per repository; findings on the pull request and in the Security page | The same App; SARIF uploaded to code scanning; on a public repository a finding posts only “a security finding is open, details in Frazer” to people with access | `frazer review scan <dir>`; SARIF out; `frazer review triage <findings.sarif>` |
| Cold review | The `plan/cold-review` check, the record’s page and the Reviewer’s pages | Plan files in a GitHub repository through the Reader App | `frazer review plan.md`, the kind inferred from a Markdown record; `request_cold_review` with a file |

## How a code review works

Each pull request version gets one review:

1.  **Static first.** Build, lint, type check and tests run in Frazer CI, with each class’s preconditions, secrets, licenses and advisories. If any fails, the author fixes it first and the model passes are **held**, with what they would have cost (“held · 1 test failing · saves $0.14”).
2.  **Triage**, without a model: bots, releases, dependency bumps, generated code and stale bases are detected; risk from paths, owners, blast radius and runtime signals picks the depth and whether to run code.
3.  **Lanes**: code; manifests (a GitOps diff for pull requests to environment repositories); dependencies (advisories, changelogs, lockfile-only changes); contracts (proto and OpenAPI changes checked for breaking changes, with the consumers they touch).
4.  **Context** through [Frazer Context](https://frazer.ai/docs/context): what is in force for the diff, the plan item and its done agreement, the hunks and full files, your rules and guideline files, earlier threads, neighbors in the code graph, and by default the other repositories that consume what the change touches.
5.  **A two-stage screen.** A fast pass over every changed hunk marks what needs a deep pass; deep passes run on the flagged hunks and on always-deep paths, on the same cached prefix. Security lenses read the code before the pull request’s description: the description is untrusted data, and a finding that disappears once it is read is kept, marked **framing-sensitive**.
6.  **Verify.** Every candidate of Medium severity or higher goes to a verifier of another family than the one that found it and than the author’s; the executor tries to write a test that reproduces it. The outcome is Reproduced, Verified, Refuted or Unknown.
7.  **Rank and merge.** Findings merge through the ledger; repeated instances of one pattern are one finding with its locations; a finding against a decision in force cites the decision and reads “revisit the decision?”, never “a defect”. **Would approve** is decided by blockers (a High finding, a failing proof, a scope breach), and weighted items (tests, scope discipline, style, standards) score.
8.  **Post, then watch.** One review and one check run. The review writes its **expected effects** (what should move and what must not, from the plan’s success metrics and the handlers the diff touches); after the deploy, Frazer Releases’ canary compares them, a regression is an escape that labels the review, and at the Merge stage it reverts.

Agent-written pull requests are always reviewed, bots included, with no size limit: a large pull request is reviewed in child jobs whose findings post as they finish, with a suggestion to split. A clean review lists what it checked and says that no findings is not proof of no defects; a check without its result line means “no verdict”, never zero findings.

**Depth** is the panel’s ladder, the same for every kind:

| Depth | What a code review runs |
| --- | --- |
| `off` | The deterministic checks only |
| `light` | One pass by another family, and the screen |
| `standard` | Two passes by two other families, and a verifier of a third on Medium-or-higher candidates |
| `deep` | Four passes, two file orders per family, a verifier on the strongest tier, reproducing tests and mutation evidence on the changed lines; with `reads: preview`, smoke tests and screenshots on a preview environment |
| `exhaustive` | Every family, two rounds, every candidate reproduced or refuted, the estimate first |

**Where code runs.** Reviews run in a sandbox, or a microVM when tests need containers or services. Tests run in your project’s devbox image, built from the same `devcontainer.json` or devbox template your engineers use, so “works on my box” means “works in review”; test commands are detected from the devcontainer, CI workflows and Makefiles, or pinned in `.frazer/review.yaml`. A sandbox gets no secrets beyond declared test credentials, no write tokens, and egress only to the package cache and the LLM gateway; one organization per VM node. A preview review uses the preview your environment’s preview policy creates on the project’s staging cluster through Frazer GitOps, behind Frazer sign-in, torn down on merge or close.

## One set of settings

One `review:` block has the same fields for every kind: in the review policy (code and security), in a plan type and the plan approval policy (cold review), and in `.frazer/review.yaml` for the keys a policy marks overridable. Layers go from organization to project, repository or record type, path and target; the stricter wins, and a `locked` floor cannot be lowered.

```yaml
# acme-production · review policy default@v7 (the same keys in a plan type's review: block)
review:
  code:
    depth:      {R0: light, R1: standard, R2: standard, R3: deep}    # the panel's ladder
    strictness: {R0: advise, R1: ask, R2: ask, R3: block}            # what a finding does
    threshold:  normal                                                # quiet | normal | thorough: what is shown inline
    reads:      [diff, repository, history, plan, runtime, other_repositories]
    loop:       {on: agent_authors, max_turns: 8, budget_usd: {R0: 0.50, R1: 2, R2: 4, R3: 15}, final_pass: true}
  security:
    depth:      {R0: light, R1: standard, R2: deep, R3: deep}
    strictness: {R0: ask, R1: ask, R2: block, R3: block}
    scans:      {schedule: weekly, deep: monthly, paths: ["services/payments/**"]}
    blind_first: true                                                 # the description is read after the first pass
  cold:         {inherit: plan_type}                                  # the planning flow's defaults by risk class
  panel:        acme@3                                                # uses code_review, security_review, cold_review
  budget:       {per_project_month_usd: none}                        # the estimate shows before every run
```

| Setting | Values | What it does for code review |
| --- | --- | --- |
| depth | `off`, `light`, `standard`, `deep`, `exhaustive` | How hard the models look (above) |
| strictness | `advise`, `ask`, `block` | `advise`: the check is neutral. `ask`: posted findings of Medium or above need a resolution before merge (fixed, answered, contested with evidence, or dismissed by a person), enforced by Fir. `block`: calibrated findings at or above the policy’s severity fail the check, and a Reproduced High always does |
| threshold | `quiet`, `normal`, `thorough` | What goes inline, at precision targets of 90 %, 80 % and 65 %; new organizations start on `quiet`, and `normal` unlocks after 50 judged findings with less than 25 % refuted |
| reads, lenses | Per kind | Code: `diff`, `repository`, `history`, `plan`, `runtime`, `preview`, `other_repositories` |
| panel | The [panel](https://frazer.ai/docs/source/decisions#the-panel-other-model-families-on-every-decision) with the uses `code_review`, `security_review` and `cold_review` | Families by lineage, never replaced by another family |
| budget, loop | Per review, per loop, per project-month; the loop’s turns and budget | The estimate shows before every review and every loop turn |

The defaults by risk class for every kind sit on the panel’s one settings screen beside decisions and context verify, so a team sees one policy.

## Findings

-   **One shape for every kind**: its kind (`defect`, `question` or `verdict`), class (with its CWE for `security.*`), severity, anchor and quote, evidence and its grade (`reproduced`, `verified`, `rule`, `analyzer`, `diff`, `runtime`, `citation`), a suggested fix, who raised it (sealed, member, family, tier), agreement (“2 of 3”), a fingerprint, its calibrated `p_valid` and `p_act` with their counts, what it blocks, its state and its resolution. Exports: SARIF 2.1.0, annotations and the check’s JSON line.
-   **One ledger per target**, across passes, loop turns, the layers of a stack and the kinds, so code review and security review never post the same finding twice. A finding’s fingerprint follows its anchor through moves and renames; near-duplicates whose wording only partly overlaps are confirmed by an adjudicator of another family.
-   **Dismissals** need a reason and carry a **scope** (this finding, this pattern in this repository, this rule) and an **expiry** (180 days by default for security classes). A dismissal is context for later reviews, never a suppression of a class or a path, and it stops a finding from returning only while its code is unchanged. A share of dismissals each month is adjudicated again, because a dismissal is also a label.
-   **An agent’s pull request carries five facts**: a bounded scope, a rationale with links, evidence beyond CI, the responsible agent and person, and the owner after merge. A missing fact is a deterministic finding before any model pass.

## Security review

| Part | What it does |
| --- | --- |
| On every pull request | Security lenses (where input enters and where it ends up), the description read only after a first pass, at `deep` three families on the strongest tier; exploits reproduced as exploration tasks in Frazer CI; the CWE, the attack path and a patch |
| Thresholds | Calibrated per class like every finding; until a class has 50 labels, automatic reviews post High and Critical and a requested review posts Medium and above |
| Scans | A repository or a folder on a schedule; **deep scans** run several independent scans and combine them; each report carries a **revision stamp**: the commit, the depth, whether uncommitted changes were read, and how thoroughly it was verified |
| Threat models as records | A typed engineering record per repository (assets, trust boundaries, assumptions), versioned and reviewed like a plan; reviews and scans read the version in force, and without one a scan proposes a draft |
| Threat review of plans | The cold review of an R2 or R3 plan runs a `security` lens against the threat model and the plan’s design: new trust boundaries, data flows, secrets, tenancy |
| Supply chain and agent configuration | Lockfile diffs, release age, provenance, install scripts and binaries, advisories; instruction files, MCP configuration, skills, hooks and tool grants |
| Other scanners’ findings | Imported SARIF is a backlog of unproven claims: each one is checked for reachability and evidence, then kept, refuted or reproduced |
| A fix is not a finding closed | A patch is written in a scratch workspace, reviewed by an agent other than its writer, and closes the finding only when the reproducer fails before and passes after |
| Blocking | A security finding blocks by the same calibrated rule as every finding, and a Reproduced High always does; nothing is advisory by design |

## Loops for code

A **loop** keeps a layer moving until it is clean: the author agent fixes what the Reviewer finds, a critic and a tester of other families keep checking, and Fir referees on evidence. It is the same loop as [the loop on a plan](https://frazer.ai/docs/source/planning-flow/loops), with code’s values.

| Role | Family | Sees | May change |
| --- | --- | --- | --- |
| **author** | Any: the coding session | The layer, CI results, the merged findings, its own transcript | The layer only. Tests and proofs that a finding or the done agreement guards are read-only, and weakening one stops the loop; every turn may answer “cannot be done as written” |
| **critic** | Another family than the author’s | The diff at the version, the plan item and its done agreement, the repository; from turn 2 its own ledger; for a contest, only the evidence. Never the author’s transcript, notes or justification | Nothing |
| **tester** | Another family than the author’s, and than the critic’s where three exist | The repository at base and head, CI, previews | Nothing in the layer: it writes reproducing tests and probes and runs them as CI tasks, and offers “keep the test” |
| **Fir**, the referee | — | Everything | Runs CI, merges findings through the ledger, diffs turns, keeps every version, applies the stop rules |

**A turn.** CI runs first, and a failing check is fixed before any model pass. The critic runs the screen and deep passes on changed hunks, a verifier of a third family checks Medium-or-higher candidates, and the tester reproduces High ones, each sealed from the others. Fir merges through the ledger and scans findings for instructions aimed at the author. The author answers the top 10 by what they block: **fix** (a commit with `Resolves: f-…`), **answer** (citations Fir resolves), **contest** (a test, a citation or a log; its prose reaches the critic as untrusted data), **ask a person**, or **cannot be done as written**. On the next version CI re-runs what changed, and the critic runs a verification pass on earlier findings and a fresh pass on changed hunks only. A turn runs only on something new: a version, a CI result, an answer, a contest’s evidence. Each edit names the finding it answers, one tester probe a turn tests the layer’s main claim against its negation, and Fir rates each turn’s edits helped, hurt, no observed effect or confounded.

**Only evidence closes a finding**: fixed (the anchored lines changed and a re-check no longer raises it; for a Reproduced finding, its test fails at the old head and passes at the new one), answered (the citations resolve and the verification pass accepts), conceded (the critic withdraws on the author’s evidence), or dismissed or waived by a person. Never by argument. The ledger keeps a loop honest: one fingerprint per finding across passes, turns, layers and kinds; a conceded or dismissed finding returns only with new evidence; the rubric, the panel and the routes are pinned for the loop, severity rises only with new evidence, and Low findings never drive a turn.

**The final pass.** A loop ends `done: ready` only after a held-out pass: a fresh draw of another family than the author’s that never saw the loop’s ledger reads the final version in full and finds nothing new at Medium or above. Its rate of new findings is a loop-quality measure on the Quality page. Planted-flaw drills, in 1 loop in 20 and in shadow only, measure each critic’s catch rate; a model’s verdict never overrides a failed deterministic check, and “done” is never a model’s call.

| Stop rule | On a pull request |
| --- | --- |
| Ready | CI green at the exact version, the verifier’s PASS, no open finding at Medium or above, the done agreement’s proofs pass, and the final pass clean: `done: ready` |
| Quiet | No new finding at Medium or above for 2 turns: the final pass, then `done: converged` |
| Needs a person | Every open finding is one only a person can settle: `paused: needs you`, while the loop keeps working on anything else |
| Cannot be done | The author or the critic says the item cannot be met as written: `paused: needs you` |
| Tests weakened | The author removes or loosens a test, an assertion or a proof that a finding or the done agreement guards: `stopped: weakened`, and a High `tests` finding |
| Scope growth | The diff leaves the item’s paths or the plan’s terms: `stopped: scope` |
| Oscillation | A hunk returns to an earlier version, or a finding reopens after two resolutions: that hunk is frozen and becomes one question |
| Regression | A check that passed fails: the next turn fixes it first; a repeat restores the best version and stops |
| Diminishing returns | No finding resolved for 2 turns while edits continue: `done: converged`, then the final pass |
| Budget, time, turns | By risk class: R0 $0.50 and 20 minutes, R1 $2 and 30 minutes, R2 $4 and 1 hour, R3 $15 and 4 hours; 8 turns |
| Fresh start | A finding fixed twice and still raised restarts the author from the item and the finding, not from its transcript |

**When a person is asked**: one card with both sides (the finding and the critic’s evidence, the author’s evidence, the view of an adjudicator of a third family, and a recommended answer), after two contests on one finding, on oscillation, when a budget is spent with blocking findings open, or for a question only a person can answer, which becomes a decision row. A credential, a purchase or a registration becomes a [person task](https://frazer.ai/docs/source/person-tasks). A question already open on the same subject elsewhere is linked, never asked twice.

**How a loop starts**: **by default on every layer an agent writes**, in every class and repository (`loop: {on: agent_authors}` is the default, and one setting turns it off); by hand (**Fix until clean**, `frazer review loop`, `reviews_loop`); inside the agent’s own session before the pull request exists, as self-review over MCP; and on any file through the API. People’s own pull requests get one review with fixes offered, never pushed, unless they start a loop. When funds run out, a loop stops between turns as “Paused: no funds” and keeps its best version; it never runs cheaper. Lanes, verdicts, the review ledger and outcomes: [Lanes, verdicts and outcomes](https://frazer.ai/docs/reviewer/lanes).

**Findings become static checks.** Findings that people and agents keep fixing in the same shape become **rule drafts**: a pattern or CEL rule that reproduces the class’s findings on history, with a backtest on a frozen, labeled set at a precision of at least 0.9 before it may block as a deterministic check. The rules’ owners approve each draft, a rule that finds nothing for 180 days is proposed for retirement, and the rules run in CI’s static stage, so the model pass that used to find these is not paid for again.

Demo (`pellwyn/admin#2318` “Release a hold from the console”, item P12.3 of plan `#414`, risk class R2; author `coder` in session `s-3e9a`; critic and tester of two other families; Oct 17; product UI, demo data):

| Time | Turn | What happened |
| --- | --- | --- |
| 10:02 | v1 | CI green. The screen flags 6 of 31 hunks. Turn 1 at `standard`: 14 raw candidates merge into 5 findings. **F1** High `security.authz` “release checks the role, not the hold’s tenant”, reproduced by the tester (`TestReleaseHoldOtherTenant` fails at v1); the description says “tenant checked in middleware”, and one member withdrew F1 after reading it without citing code, so F1 stays, marked framing-sensitive. **F2** Medium “releasing twice writes two ledger entries” (2 of 2). **F3** Medium “no timeout on the ledger call”. **F4** “May a support agent release a hold above $10,000 without a second approver?”: already open as decision `#414 §D1` from the plan’s own loop, so linked, not asked again |
| 10:09 to 10:16 | v2 | coder fixes F1 (and keeps the tester’s test) and F2 (an idempotency key), contests F3 with `ledgerclient/client.go:41` (a 2 s timeout set in `New`), and ships the safe default for F4 |
| 10:16 | — | CI: `TestReleaseAudit` fails, so the model passes are held; coder fixes it in v3 at 10:19 |
| 10:20 | Turn 2 | Verification: F1 fixed (its test fails at v1 and passes at v3), F2 fixed, F3 conceded on the citation. A fresh pass on changed hunks finds **F6** Medium “the key uses the hold ID only; two releases of different amounts collide” |
| 10:26 | v4, turn 3 | F6 fixed: the key adds the hold’s version. Nothing new at Medium or above |
| 10:30 | Final pass | A fresh draw reads v4 in full, with no ledger: clean. `done: ready` at 10:33 |

Three turns, four versions, 31 minutes, nothing to a person but a decision that was already open; the layer merges inside the plan’s terms on its proofs and the verifier’s PASS.

## At 10,000 to 50,000 a day

At tens of thousands of pull requests a day, the Reviewer decides what it may alone, summarizes the rest, and brings a person only what needs one:

| The Reviewer decides alone | It summarizes | It brings to a person |
| --- | --- | --- |
| The verifier’s verdict on every layer | Exception groups by **cause** (“the same missing timeout in 37 layers of the ledger-client campaign” is one row and one decision) | Findings at Medium or above that a loop could not resolve, on paths that need a person |
| Approvals and merges in classes past their gates | A daily digest per scope: lanes, top classes, escapes, loops by stop reason, cost | Disputes after two contests, oscillations, budgets spent with blocking findings open |
| Resolving findings with the author agent in loops | What merged without the person and on what evidence, with one sample to read | Never-automated paths, policy changes, promotions, lifting a kill switch |
| Grouping, ranking, suggesting what to close (never closing it) | Rule drafts with their backtests | Audit samples of automated approvals; decisions raised by findings; person tasks |

Every pull request ends in one **outcome**: merged on its receipt (inside an approved plan’s terms, with the verdict’s pass), merged by an autonomy stage, with agents (a loop or CI running), batch (clean, its class not automated yet: one approval for a group inside one plan’s terms), needs you, audit, or closed. The **Inbox** opens with its counts (“45 need you · 17,600 merged · 1,947 with agents · 8 need others · 400 closed · 20,000 today”, priya at Pellwyn on Nov 17, demo data), a strip of what each kind needs, Needs you as exception groups with “covers 37” and the one action, the budget line (“2 of 25 decided · 8 of 90 min”), and an outcomes table that rolls up by plan level and stack; the Comfortable rows stay as the small team’s view. Agents read the same view as data with `reviews_inbox`. A campaign’s shards are reviewed as one pattern at the campaign’s approval, so they reach a person as one daily campaign review.

## In the console

Engineering › Reviewer has nine pages, one job each:

| Page | Job | Key |
| --- | --- | --- |
| **Inbox** | What needs me now, at any volume | `g i` |
| **Reviews** | Any review of any kind; Pull requests is a saved view (`kind:code`) | `g v` |
| **Security** | Scans, the findings backlog with triage and dismissals, threat models | `g s` |
| **Lanes** | The catalog and your lanes by group, with their states, owners, harness profiles, backtests and learning numbers; learned rules and custom checks are lanes or parts of lanes | `g l` |
| **Loops** | Every loop with its turns, stop reason and cost; exceptions first | `g o` |
| **Outcomes** | Outcome links (told, missed, partial, outside), miss analysis reports and lookbacks | `g c` |
| **Autonomy and audit** | Classes by stage, gates, promotions, kill switches, sampled approvals and adjudications | `g a` |
| **Quality** | One analytics surface for every kind and loop: precision with its interval per kind and class, escapes, reliability diagrams, the cold review’s catch rate, loops’ turns and stop reasons, the final pass’s new-finding rate, dismissals, the model passes static checks held | `g q` |
| **Settings** | One settings model for every kind; repositories are its tab | `g t` |

## Install and turn on review

You need to be an admin of the GitHub organization and of your Frazer organization.

1.  **Install the GitHub App.** Open **Engineering › Reviewer** in the console and choose **Connect GitHub**, or install **Frazer Reviewer** from the GitHub Marketplace. Choose the repositories. Frazer binds the installation to your organization after it checks that you are an admin in both places. Before you install, **Try on a public PR** runs a shadow review that shows only in the console and is never posted.
    
    The App asks for these permissions:
    
    | Permission | Access |
    | --- | --- |
    | Contents, metadata, Actions, commit statuses, members | Read |
    | Pull requests, checks, issues (for pull request comments) | Write |
    
    It listens to pull requests, reviews and review comments, issue comments, check runs, pushes to the default branch and installation changes.
    
2.  **Turn on automatic review** for the repositories you chose.
    
    ### CLI
    
    ```sh
    frazer reviewer enable --repos 'acme/*' --depth standard --trigger open,push
    ```
    
    ### Console
    
    On **Engineering › Reviewer › Inbox**, once the App is installed, pick a policy for the repositories you chose. **Settings › Repositories** then lists each repository with its policy, trigger, depth and coverage.
    
    Automatic review is set by the policy, not by a file in each repository, so every repository the policy matches is reviewed from the first pull request.
    
3.  **Open a pull request.** The `Frazer Reviewer` check run shows the current step and an estimate of the time left (“Verifying 4 candidates”). When it finishes, the pull request gets one summary review, and inline comments only for findings with evidence. A push edits the same summary; a new inline comment appears only for a new finding on a changed line.
    
4.  **Answer it.** Reply `/frazer wrong <why>` or `/frazer useful` on a finding, or ask `@frazer-reviewer <question>` in the thread. Every reply reaches the findings ledger, and a refuted finding is not raised again while its code is unchanged.
    

## Configure a repository

A review policy sets the defaults for the repositories it matches. A repository can change the keys the policy marks overridable with `.frazer/review.yaml`, read from the base branch, so a pull request cannot change how it is reviewed:

```yaml title=".frazer/review.yaml"
version: 1
trigger: { on_open: true, on_push: incremental, drafts: false, skip_authors: ["renovate[bot]"] }
depth: { default: standard, deep_when: { risk: high, paths: ["services/billing/**"] }, light_when: { lines_lt: 20 } }
execute: { tests: auto, preview: on_label("preview"), fork_prs: never }
post: { inline_min_grade: verified, inline_min_severity: medium, max_inline: 8, nits: summary }
paths: { ignore: ["**/*.pb.go", "gen/**"], instructions: [{ glob: "migrations/**", text: "Every migration is reversible." }] }
lanes: { manifests: { app_pattern: "{env}-{service}", policies: [frazer-policy] }, contracts: { buf: true } }
memory: { learn: drafts } # off | drafts
privacy: inherit # the stricter of org and repo wins
```

Apply a policy from a file, and read the plan first:

```sh
frazer reviewer review-policies apply -f review-policy.yaml --dry-run
```

Review policies are also resources in the [Terraform and OpenTofu provider](https://frazer.ai/docs/terraform).

**Guideline files** are read automatically: `REVIEW.md`, `AGENTS.md`, `CLAUDE.md` and the instruction files of other coding agents and review tools, each scoped to the folder it sits in and each with its own switch. A review lists the guideline files that applied to it. **Where a setting came from**: `/frazer config` on a pull request, and **Settings › Repositories** in the console, show the effective configuration with the origin of every key (policy, `.frazer/review.yaml` or default). Keys the policy locks show the policy.

## Read a review

**The summary** is one review per head, at most 15 visible lines, edited in place on every push with a “Since last review” line:

```markdown title="Summary review"
**Frazer Reviewer** · deep · 3 findings with evidence · 1 should be fixed before merge
ConfirmStream skips the new coupon validation and panics (reproduced by a test). The memory limit in platform-envs#322
drops below live p95. One proto field was renumbered.

| Severity | Finding                                | Evidence                              | Where                              |
| -------- | -------------------------------------- | ------------------------------------- | ---------------------------------- |
| High     | ConfirmStream panics without coupons   | Reproduced · test fails at head       | `internal/checkout/confirm.go:142` |
| Medium   | Production memory limit below live p95 | GitOps diff · p95 611 MiB             | `values.yaml:31` (#322)            |
| Medium   | `coupon_code` renumbered 7 → 9         | Analyzer · breaking change · 2 consumers | `checkout.proto:58`             |

<details><summary>Walkthrough · 7 files · effort 3/5 · related: #1902, issue #1877</summary> … </details>
<details><summary>Checks · 4 passed · 1 warning (Linked issue: 1 requirement not covered)</summary> … </details>
<details><summary>What we checked · Not verified (9) · Pre-existing (2)</summary> … </details>
<details><summary>Run passport</summary> models · sandbox · tests · cost · time · fallback · engine · config origin </details>
```

With no findings, the summary is one line, or nothing when the policy sets `post_clean: false`; the check run always reports.

**Inline findings** carry a header (severity, category and evidence badge), a title, why in at most 3 lines, a folded evidence block, a `suggestion` block when the fix is at most 15 lines in one hunk, and a folded **Prompt for AI agents** with the file, line, intent and the name of an acceptance test. At most `max_inline` findings go inline (8 by default), anchored on new lines only. The six badges:

| Badge | Meaning | It carries |
| --- | --- | --- |
| Reproduced | A test or command ran and failed at the head | The command, the output tail and an artifact link |
| Verified | A verifier from another model family traced the code | 2 to 4 `path:line` citations, including callers and guards |
| Rule · name | A rule your organization approved matched | The rule’s precision and a link to it |
| Analyzer · tool | A tool found something that is new in this diff | The tool and its rule ID |
| GitOps diff | The change rendered against live state | The object, the live value and the cost change |
| Runtime | Metrics or an incident on the code it touches | The series, the window and a chart link |

**Check runs.** `Frazer Reviewer` follows the policy’s strictness, and carries the findings table and one machine-readable line:

```text title="Check run summary"
<!-- frazer-review {"high":1,"medium":2,"low":0,"pre_existing":2,"grades":{"reproduced":1,"verified":0,"rule":0,"analyzer":1,"gitops":1}} -->
```

Paused, capped, skipped and failed are explicit conclusions with the reason, such as “Skipped: generated code only”. `Frazer checks` has one row per pre-merge check (Pass, Warn, Fail or Inconclusive, with the reason) and fails only for checks set to Block.

**Pull request commands:**

-   `/frazer review [light|standard|deep] [full]`: review now, at a depth.
-   `/frazer pause`, `/frazer resume`, `/frazer cancel`; `/frazer ignore` in the description skips the pull request.
-   `/frazer summary`, `/frazer explain [n]`, `/frazer diagram`.
-   `/frazer check [name]`: run one pre-merge check.
-   `/frazer wrong|useful|resolve [n]`: feedback that reaches the ledger.
-   `/frazer remember <rule>`: create a rule draft.
-   `/frazer config`: the effective configuration, with the origin of each key.
-   `/frazer fix [n|all]`, `/frazer tests`, `/frazer docstrings`, `/frazer preview`: work by an agent, below.
-   `/frazer run`: let a pull request from a fork run code.
-   `/frazer help`; `@frazer-reviewer <question>` is chat.

## Teach it rules and checks

**Rules from feedback.** After three similar replies, Frazer drafts a rule and records where it came from. Before an admin can approve it, a backtest replays the rule over the findings of the last 50 pull requests in its scope (“would silence 11 findings, 9 of them refuted”). An approved rule’s precision is measured from then on, and a rule that falls below 60 % retires. Nothing is learned silently.

```sh
frazer reviewer review-rules list --state draft
frazer reviewer review-rules approve <rule>
```

`/frazer remember <rule>` on a pull request creates a draft the same way. Rules are served over the Frazer MCP server, so a coding agent on a devbox sees them before it opens a pull request.

**Checks in plain language.** Write a pre-merge check of up to 2,000 characters, choose its scope and the evidence it may use, and set it to Off, Warn or Block. **Save** is enabled only after a backtest on the last 20 merged pull requests in scope. A Block check stops merges only when your branch protection requires `Frazer checks`. Built-in checks cover the title convention, the description template, whether the linked issue (GitHub Issues or Linear) is satisfied, reversible migrations, touched tests, contract compatibility, manifest safety (GitOps diff and Frazer Policy) and new secrets.

**Rules and checks** in the console lists drafts, active rules, retired rules, path instructions, guideline files and silenced fingerprints; **Unsilence** brings a silenced finding back.

## Request reviews and fix findings

Review your local diff, a directory or a branch you have not cloned. Each prints its estimate before it starts, and `--format json` or `--format agent` gives an agent the result with exit codes from the [one table](https://frazer.ai/docs/cli#exit-codes): `0` clean, `11` findings at or above `--fail-on`, `2` a usage error, `7` when it could not finish in time, and `13` when only a person can unblock it (Not run: no funds, or an approval):

```sh
frazer review . --base main --format agent
frazer review --remote acme/storefront --source-branch lena/retry-errors
frazer review scan services/payments --deep
frazer review triage findings.sarif
frazer review loop . --budget 2 --max-turns 8
```

Request a review of a pull request at a depth:

```sh
frazer reviewer reviews request acme/storefront#1931 --depth deep --execute
```

From a finding:

-   **Commit suggestion** applies GitHub’s suggestion block under your own identity. The Reviewer App writes nothing.
-   **Fix with agent** and **Fix all** open a confirm sheet in the console with a cost estimate, then start a loop through the separate Frazer Agents App: tests first, up to 8 turns with a held-out final pass, delivered as a stacked pull request. A link never changes anything until you confirm.
-   **Keep the test** commits the test that reproduced the finding.
-   **Open in devbox** opens the file and line with the prompt loaded.

Pull requests from forks never run code until a maintainer types `/frazer run`.

## Choose models and privacy

Models are reached only through the [LLM gateway](https://frazer.ai/docs/llm-gateway), with your organization’s key or billed by Frazer. The panel picks the families for each use, so the members who find, verify and review never share the author’s family; **Settings › Models** pins model versions and caps monthly spend. “No silent fallback” is on: when a model is unavailable, reviews pause instead of switching models, and every review’s run passport records the models, served deployment, fallback, prompt hash, cost and time.

| Mode | Code | Index | Findings text kept | Models |
| --- | --- | --- | --- | --- |
| Standard | In the sandbox only, deleted when the session ends | Encrypted per organization, rebuilt from Git, deletable | 180 days | Providers that do not train on inputs |
| Zero retention | Same | None; rebuilt for every review, which is slower | Counts and fingerprints only; the text lives on GitHub | Zero-data-retention providers only |
| Private placement | Runs on your own server pool | In your pool | Your choice | Your key or your own model endpoint |

When a repository’s file and the policy disagree on privacy, the stricter one wins. Secrets are redacted from everything sent out.

## Access and audit

-   **The App reads and comments.** It never pushes, approves or merges; fixes go through the separate Frazer Agents App, only after you confirm.
-   **Every review session** is an agent principal acting for your organization; it cannot approve or merge.
-   **Trusted base, untrusted pull request.** Policy, rules and sandbox templates come from the base branch and the Frazer API; the pull request’s text, diff and files are data, never instructions.
-   **Review policies** are edited by the admins of the project that owns them, and are read-only for the projects they are shared with. Each repository is linked to one project.
-   **Rules** are approved by admins after a backtest; an agent can never dismiss a blocking finding or lift a kill switch.
-   **The record**: every review has a run passport; replies, reactions and `/frazer` commands reach the findings ledger next to the rule drafts they produce.
-   **Retention**: findings text is kept 180 days in Standard mode; in Zero retention, only counts and fingerprints.

## Limits and quotas

| Setting | Default |
| --- | --- |
| Reviews per pull request head | 1, edited in place |
| Summary length | At most 15 visible lines |
| Inline findings per review (`max_inline`) | 8 |
| Committable suggestion | At most 15 lines in one hunk |
| Rule draft | After 3 similar replies |
| Rule backtest | The last 50 pull requests in scope |
| Check backtest | The last 20 merged pull requests in scope |
| Precision for a rule finding to go inline | At least 80 % |
| Rule retirement | Below 60 % precision |
| Check instruction | At most 2,000 characters |
| A loop | 8 turns, and the budget of its risk class |
| Dismissal of a security finding | Expires after 180 days |
| Rollout watch after merge | 30 minutes |
| Spend alerts | 50, 80 and 100 % of the monthly cap |
| Findings text | 180 days |

There are no hourly limits per developer. Caps are in dollars only: a monthly cap pauses new reviews and never posts half a review, and organizations get a fair share of capacity.

## Pricing

Frazer Reviewer is priced two ways, by who opened the pull request.

-   **People’s pull requests** are priced per active human committer a month, and the seat costs less when you bring your own model key. Each paid committer adds `light` and `standard` reviews to a monthly pool that the whole organization shares. Reviews above the pool are billed per review, and so are `deep` reviews and reviews with a preview, each with its cost estimate before it starts.
-   **Agents’ pull requests** take no seat and no share of the pool. Each review pays its model tokens at the LLM gateway’s price, or nothing for tokens on your own key, plus a fee by depth: light $0.01, standard $0.05, deep $0.20, exhaustive $0.50. A security review costs 2 times the fee, and later loop turns 40 % of it. A pull request is an agent’s when the identity that opened it is an agent, including an agent acting for a person, and that is fixed when the review is priced. Campaign shards that match their reviewed pattern pay the fee once per pattern.
-   **The estimate first.** `frazer review estimate <pr>` (MCP `billing_estimate`) returns the estimate, and the check row shows it while the review is queued (“est. $0.29 · p90 $0.52 · tokens + $0.05 fee”); the review reserves it, and the receipt gives the tokens by model actually served and the fee. A review that pauses, fails or is canceled before posting bills nothing.

Reviews on public repositories are free.

Every review shows what it cost in its run passport, and the monthly dollar cap pauses reviews before spend surprises you. Models are reached through the [LLM gateway](https://frazer.ai/docs/llm-gateway), with your organization’s key (the lower seat price) or with Frazer’s.

| Frazer Reviewer | On your servers | On the Frazer fleet |
| --- | --- | --- |
| seats | $15 per active committer / month · $7.50 with your own model key | Same · agent pull requests take no seat · public repositories free |
| reviews | 100 per paid committer a month, pooled, then $0.20 each · Deep $1, Deep + Preview $3, estimate first | Same, plus agent runtime for a Deep + Preview sandbox on the fleet |
| agents' pull requests | Model tokens at the gateway's price, or your own key at no fee, plus a fee per review: light $0.01, standard $0.05, deep $0.20, exhaustive $0.50 · security reviews 2× the fee · later loop turns 40 % of the fee · estimate first | Same |

Every line, with the estimator: [pricing](https://frazer.ai/pricing#lines).

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| A pull request got no review | The policy does not cover the repository, the pull request is a draft, the author is skipped, or it changes generated code only | Read the check run’s conclusion and `/frazer config`; type `/frazer review` to review it anyway |
| “Held · 1 test failing” | A deterministic check failed, so the model passes wait | Fix the failing check; the review runs on the next version |
| “Paused: monthly cap reached” | The organization’s monthly review cap is used | Raise the cap in **Settings › Spend**; nothing was half posted |
| “Paused, fallback is off by policy” | The pinned model is unavailable and fallback is off | Wait for the provider, or allow a fallback model in **Settings › Models** |
| A finding is wrong | The evidence did not hold for your code | Reply `/frazer wrong <why>`; it is dismissed with your reason and becomes a label for its class |
| A loop stopped with “weakened” | The author removed or loosened a test that a finding guards | Restore the test, or ask the plan’s approver to change it as its own layer |
| A pull request from a fork has no test results | Forks never run code by default | A maintainer types `/frazer run` |
| A finding shows Verified where you expected Reproduced | The sandbox image failed to build, so the finding fell back to the verifier’s trace | Check the reason in the run passport; pin test commands in `.frazer/review.yaml` |
| A Block check does not stop a merge | Branch protection does not require `Frazer checks` | Add `Frazer checks` to the required checks of the branch |

## Reference

### CLI

| Command | What it does |
| --- | --- |
| `frazer reviewer enable` | Turn on automatic review for the repositories that match a pattern, with a depth and triggers. |
| `frazer reviewer review-policies apply -f` | Create or change a review policy from a YAML file; --dry-run shows the plan. |
| `frazer review` | Review a diff, a directory, a branch or any file as code, security or cold review; the estimate prints first. |
| `frazer review loop` | Loop on a target until it is clean, ending with a held-out pass. |
| `frazer review estimate` | The estimate of a review before it runs (tokens by model and the fee for an agent's pull request), with its p90, at the price list's version. |
| `frazer reviewer review-rules approve` | Approve a rule draft after its backtest. |

All of them: [CLI reference](https://frazer.ai/docs/cli).

### MCP tools

| Tool | What it does |
| --- | --- |
| `reviews_request` | Request a review of a diff, a directory or a file, of a kind, the estimate first. Writes become a plan that waits for approval. |
| `reviews_loop` | Start a review loop on a target, with its budget and turns. Writes become a plan that waits for approval. |
| `findings_list` | List the findings of reviews. |
| `findings_resolve` | Resolve a finding with a fix, an answer or a contest with evidence. Writes become a plan that waits for approval. |
| `rules_list` | List the review rules that apply, so a coding agent sees them before it opens a pull request. |
| `rules_propose` | Propose a rule draft. Writes become a plan that waits for approval. |

All of them: [MCP tools reference](https://frazer.ai/docs/mcp).

### Events

| Event type | When it is sent |
| --- | --- |
| `frazer.review.completed.v1` | A review finished and was posted to the pull request. |

All of them: [Events reference](https://frazer.ai/docs/webhooks).

## Related

-   [Frazer Reviewer product overview](https://frazer.ai/reviewer)
-   [The planning flow](https://frazer.ai/docs/source/planning-flow#cold-review): cold review of plans, and [Loops and learned checks](https://frazer.ai/docs/source/planning-flow/loops)
-   [Decisions](https://frazer.ai/docs/source/decisions): the panel every review draws its members from
-   [LLM gateway](https://frazer.ai/docs/llm-gateway): the models every review uses
-   [Environments and GitOps](https://frazer.ai/docs/gitops): the manifest lane’s GitOps diff
-   [Devboxes](https://frazer.ai/docs/devboxes): the image reviews run tests in
-   [Frazer Agents](https://frazer.ai/docs/agents): the agents that fix findings
-   [Frazer app](https://frazer.ai/docs/app): Reviewer findings next to your session

## Pages in Frazer Reviewer

- [Overview](https://frazer.ai/docs/reviewer.md) (this page)
- [Lanes, verdicts and outcomes](https://frazer.ai/docs/reviewer/lanes.md)
