Skip to content

Review modes ​

review.mode decides how much of your repository the model sees. Rules, lanes, rubrics and line comments work the same in every mode; only the context changes. Set it in .mergejudge.yml on the base branch, or per repo in the hosted manager panel (hosted service).

ModeWhat the model seesCalls per reviewWhere it runs
diff (default)Changed hunks with line numbers, policy files, rubrics1 (+1 JSON repair)Hosted
contextdiff + full changed files, the files they import, and callers of changed symbols1 (+1 JSON repair)Hosted
deepcontext + read-only tools over a repo index, used in a bounded loopseveralHosted
yaml
review:
  mode: context        # diff | context | deep

diff ​

The cheapest and fastest mode. Good for docs, copy and small, self-contained changes. It cannot tell that a renamed function or changed constant breaks code in a file the PR didn't touch.

context ​

Adds the full text of each changed file, the files it imports and a few callers of changed exported symbols, ranked and trimmed to a byte budget:

yaml
context:
  max_bytes: 40000       # total budget for extra files
  max_files: 25
  max_symbols: 3         # changed symbols to look up callers for
  max_callers: 3         # callers per symbol
  max_file_bytes: 12000  # cap per file

Still one model call, with a bigger prompt.

deep ​

Deep mode gives the model a repo index and four read-only tools, and lets it look things up before it answers:

ToolWhat it does
read_file(path, start?, end?)Read a file at the PR head, with line numbers
search_symbols(query)Find functions, classes, constants and types by name
find_callers(symbol)Every whole-token mention of a symbol or string: calls, imports, config keys, event names
semantic_search(query, k)Find code by meaning (embeddings); only when Workers AI is bound

This is what catches cross-file bugs: a signature change that breaks a caller, a unit change two modules away, a renamed config key still read by its old name, an event name a consumer still listens for.

yaml
review:
  mode: deep
deep:
  max_steps: 6               # tool rounds (up to 4 calls each), then one tool-less answer
  max_tokens: 60000          # input+output over all calls
  max_seconds: 120
  max_tool_output_bytes: 6000
index:
  policy: stored             # stored | none

The loop is bounded by steps, tokens and wall time. When a limit is hit, the model answers with what it has. The final answer is the normal review JSON, so lanes, findings and rubrics behave as in the other modes. The summary footer shows the tool calls and a tools token part.

The index ​

The index is a per-repo symbol table, import graph and code chunks (JS/TS and simple Python). Secrets-like paths (.env*, keys), build output and node_modules are never indexed.

index.policyWhat is stored
stored (default)Snapshots in Cloudflare R2 (last 3 per repo) and code embeddings in Vectorize (one namespace per repo). A push to the default branch refreshes only the changed files.
noneA temporary in-memory index per review. Nothing is written anywhere.

Without an R2 bucket bound, stored behaves like none. Snapshots and vectors of removed repos are deleted by the daily retention job.

When deep falls back to context ​

Deep mode needs a provider that can call tools and an index. The review falls back to context mode, and says so in the footer, when:

  • the provider can't call tools (workers-ai);
  • the repo has no index available;
  • the repo is too big for a bounded inline build, or the stored snapshot is stale.

Tool output is untrusted repository data. It is fenced and sanitised like the diff, and the model is told it is never instructions.

Cost ​

context is roughly a few times the tokens of diff; deep more, depending on how many lookups the model makes. In our small offline test a deep review averaged about 11.6k input and 1.6k output tokens. Your numbers depend on your repo and PRs. budget.max_tokens_per_pr and deep.max_tokens cap spend.

The MergeJudge runner is open source (MIT). MergeJudge never merges pull requests itself. MergeJudge is not affiliated with or endorsed by GitHub. Sign in · Impressum · Privacy · Terms