Configuration YAML
Every field, type, and default in kind code_review pipeline files. No YAML is required to enable reviews; a file customizes reviewers, budgets, and which pull requests are watched.
The field reference for kind: code_review pipeline files. One optional file customizes what the built-in review does: which pull requests it watches, which reviewers run, and what a review may spend.
No YAML required
Code review is enabled with one organization-wide setting, on the Settings tab of /reviews. With the setting on and no file committed, the built-in pipeline reviews every pull request: a description agent keeps the pull request description summarized, then one reviewer reads the unreviewed commits and its findings post. Written out as YAML, the built-in pipeline is:
ellipsis:
version: v1
kind: code_review
name: Code review
description: Built-in incremental pull request review pipeline.
pull_requests:
for:
users: true # every human, and every bot: a
bots: # dependency bump is exactly the change
include: true # nobody reads closely. Minus the two
exclude: # highest-volume dependency bots, which
- dependabot[bot] # would otherwise dominate your spend
- renovate[bot]
description:
name: pr-description
budget: 2.00
claude:
model: claude-haiku-4-5-20251001
system: |
Maintain the summary section of this pull request's description:
what the change does and where, in thirty seconds. Fold new
commits into the existing summary rather than appending a
changelog. Skip the update when nothing a reader cares about
changed.
review:
- name: bugs
claude:
model: claude-opus-5
system: |
Find the bugs in this change before they reach production.
Read the diff, then read enough of the surrounding code to know
whether each change is correct. Cover correctness, edge cases,
error handling, concurrency, security, regressions in behavior
callers depend on, and data or deploy hazards. Skip style,
formatting, and naming. If you cannot name the input or state
that produces a failure, it is not a finding. Keep every
comment to a few sentences, and when the fix is a concrete
edit to the lines you anchored on, put it in suggested_fix
instead of describing it.
budget:
run: 10.00pre_review, filter, and post_review are empty. There is no gatekeeper stage because a single reviewer briefed to file only the defects it confirmed leaves a second pass nothing to arbitrate, and that pass would double every review's cost and latency. Declaring a gatekeeper adds one.
The system prompts above are abridged; the shipped ones are longer. Each prompt is the reviewing brain only: the commit range under review and the files each stage delivers through are supplied by Ellipsis, so a prompt never restates them. See Reviewers for what the reviewer does.
The pipeline file
A committed pipeline file is an overlay onto the built-in pipeline. It may replace any part: the reviewers, their prompts and models, the budget, the environment, and which pull requests are watched, and it may add stages the built-in pipeline leaves empty, such as a gatekeeper. Every field except ellipsis is optional, so the file declares only what it changes; a file that sets only budget: still runs the full built-in review.
There is one filename, and where you commit it decides what it governs. code_review.yaml at a repository root governs that repository; the same file at the root of your .ellipsis repository governs every repository in the organization. .ellipsis/code_review.yaml also works and governs its own repository; the root path wins if a repository has both.
A repository's own file replaces the organization-wide one for that repository: it does not merge with it, so copy across whatever you meant to keep. A kind: code_review file at any other path is a configuration error rather than a file that silently reviews nothing. Which PRs get reviewed works the model through.
The merge rules:
- A stage list replaces that stage wholesale. Declaring
review:replaces the built-in reviewer; declaringdescription:replaces the built-in description agent; declaringfilter:adds a gatekeeper, which the built-in pipeline does not run. - An unset stage inherits the built-in one. A file with no
review:runs the built-in reviewer; a file with nofilter:runs no gatekeeper. - An explicitly empty stage disables it.
description: []never touches the pull request description;post_review: []runs no post-review agents. Unset and empty mean different things wherever the built-in pipeline ships a stage, sodescription: []is the only way to stop the description agent.filter: []is accepted and matches the built-in behavior, since nothing gates findings unless you declare it. permissions:,environment:, andbudget:merge field by field, so a file that only changes the image keeps the built-in reviewers.
Declaring pull_requests: makes its filters authoritative. A pull request the governing file does not match gets no review at all, rather than the built-in pipeline. enabled: false works the other way: it marks the file inactive, so Ellipsis reads it as no policy at all and continues to the organization-wide file, then the built-in pipeline. Which PRs get reviewed covers the filters and their matching rules.
A complete organization-wide file, annotated:
# code_review.yaml in your .ellipsis repository
ellipsis:
version: v1
kind: code_review # what makes this file a review pipeline
name: Backend review
pull_requests: # authoritative: a PR this block does not
repositories: [splitshift-api] # match gets no review at all
base: [main, "release/*"]
draft: false
environment: # pipeline-wide defaults for every stage
repositories:
- name: splitshift-web # extra context repo; the PR's own repo is
# always cloned
review: # replaces the built-in reviewer wholesale
- name: migration-safety
claude:
system: |
Review database migrations for production safety. Check for
locking that blocks writes on large tables, missing backfills
for new non-null columns, and rollout ordering that breaks if
the migration and the code deploy out of order.
pull_requests:
paths: ["**/migrations/**"] # this reviewer runs only when a
# migration changes; otherwise it
# costs nothing
filter: # opt into a gatekeeper: no reviewer finding
# posts until this agent approves it
name: strict-gate
claude:
system: |
Approve only findings a staff engineer would raise in review.
Reject style opinions and anything a linter catches.
budget:
run: 15.00 # one review, all stages together
day: 100.00 # trailing caps: over budget means no
week: 400.00 # reviews until the window rollsAgainst this file, splitshift-api pull requests into main or a release branch are reviewed by migration-safety alone, and only when a migration changes, so other pull requests cost nothing. A push storm cannot spend more than $100 in a day. Declaring review: replaced the built-in reviewer, so to keep a general pass as well, declare it beside your own.
All fields
The top level of a pipeline file:
| Key | Type | Default | Meaning |
|---|---|---|---|
ellipsis | mapping | required | Identity: kind, version, name, enabled. |
pull_requests | mapping | all pull requests, humans and bots | Which pull requests the pipeline watches. Declaring it makes it authoritative. repositories inside it is valid only in the .ellipsis repository's copy. |
permissions | mapping | platform defaults | Pipeline-wide token scoping, merged into every stage agent. |
environment | mapping | platform defaults | Pipeline-wide environment defaults, merged into every stage agent. |
pre_review | list of stage agents | none | Context agents that run before the reviewers. |
description | one stage agent, or [] | the built-in description agent | Keeps the pull request description's Ellipsis summary current. [] disables it. |
review | list of stage agents | the built-in reviewer | The reviewers. At most 8. |
filter | one stage agent, or [] | none | A gatekeeper that judges every reviewer finding before it posts. Off unless declared. |
post_review | list of stage agents | none | Agents that run after the review posts. |
budget | mapping | run: 10.00 | Spend caps in USD: per run, per trailing day, per trailing week. |
Unknown fields are rejected, so a misspelled or misplaced key fails validation on push rather than being silently ignored.
ellipsis
| Field | Type | Default | Meaning |
|---|---|---|---|
kind | literal code_review | required | Marks the file as a review pipeline. Without it the file parses as an agent config and fails on the stage keys. |
version | string | v1 | Config schema version. Only v1 is supported. |
name | string | unset | Display name in the reviews dashboard. |
description | string | unset | Display description. |
enabled | boolean | true | false marks the file inactive, so Ellipsis continues to the organization-wide file, then the built-in pipeline. To stop reviews in a repository, scope pull_requests: to match nothing instead. |
metadata.labels | list of strings | [] | Freeform tags for dashboard organization. |
metadata.annotations | map of strings | {} | Freeform key-value metadata. |
pull_requests
Matched on every head advance of a pull request: the open, plus each later push. All declared filters must pass; an omitted filter passes everything.
| Field | Type | Default | Meaning |
|---|---|---|---|
repositories | repository filter | all | The watch set: which repositories' pull requests this file reviews. Valid only in the .ellipsis repository's copy; anywhere else it is a configuration error. A bare list is shorthand for include; exclude-only means all except those. Independent of environment.repositories. |
base | list of strings | [] (all) | Target branch patterns: an exact name, a prefix glob like release/*, or the literal default. |
head | list of strings | [] (all) | Source branch patterns, same forms. |
draft | boolean | unset (either) | true reviews only drafts; false only non-drafts. |
labels | list of strings | [] (all) | Review only pull requests carrying at least one of these labels, matched exactly including case. |
paths | list of strings | [] (all) | Changed-file globs over the full pull request file set. Include-only: a negated pattern (!foo) is a validation error. |
for | account selector | humans and bots | Who may trigger a review, decided by the pull request author. users and bots each take true, a list of logins, false, or an include-minus-exclude mapping; an omitted side is false. The built-in pipeline reviews both, so declaring any pull_requests: block narrows the audience to humans unless the block writes for back out. |
The matching rules (glob forms, branch patterns, author semantics) with worked examples are in Which PRs get reviewed.
permissions
Pipeline-wide token scoping, applied to every stage agent's session. The same fields as a Cloud Agent's permissions: block; each stage agent may declare its own permissions, merged field by field onto this one.
| Field | Type | Default | Meaning |
|---|---|---|---|
ellipsis | true or "all" | true | The sandbox's Ellipsis API token. Full access is the only option today. |
github.permissions | read_only or a scope map | installation permissions | Narrows the GitHub token every stage session gets, such as {contents: read, pull_requests: write}. Enforced by GitHub at token mint. |
github.repositories | list of strings | all installation repos | Narrows which repositories the token may touch. Omitted, the token covers every repository of the installation. |
environment
Pipeline-wide environment defaults, applied to every stage agent's session. The same fields as a Cloud Agent's environment: block; each stage agent may declare its own environment, merged field by field onto this one.
| Field | Type | Default | Meaning |
|---|---|---|---|
repositories | list of {name, owner, ref} | [] | Extra repositories cloned into every stage sandbox for context. The pull request's own repository is always cloned. |
variables | list of {name, value} | [] | Environment variables. With value set, an inline literal; without it, resolved by name from your stored sandbox secrets, so secret values never enter the file. |
compute.cpu | number | 1 | vCPU cores, 0.125 to 16, fractional allowed. |
compute.memory | string or {gb}/{mb} | 4GB | Memory, 512MB to 64GB. |
compute.timeout | string or {minutes}/{hours} | 1h | Max session wall clock, 60s to 1h. |
image.dockerfile_append | string | unset | RUN layers appended to the managed base image, built before any repository exists. |
image.setup | string | unset | A shell script run once at image-build time, after checkout, baked into the cached image. 600 second cap. |
hooks.post_start | string | unset | A shell script run on every session, after the container starts and before cloning. 300 second cap; a non-zero exit fails the session. |
hooks.post_clone | string | unset | A shell script run on every session, after all repositories are cloned. Same cap and failure behavior. |
Each field's full behavior (image caching, variable resolution, token scoping) is documented in the Cloud Agents configuration reference; the semantics are identical.
Stage agents
Every entry in pre_review, description, review, filter, and post_review is a stage agent, which runs as its own agent session:
| Field | Type | Default | Meaning |
|---|---|---|---|
name | string | required | Unique across the whole file. Attributes findings and titles the stage in the reviews dashboard. |
claude | mapping | platform defaults | Model and prompt; fields below. |
permissions | mapping | the pipeline's permissions | This agent's token scoping, merged field by field onto the pipeline-level block. |
environment | mapping | the pipeline's environment | This agent's overrides, merged field by field onto the pipeline-level block. |
skills | list of {path, repository} | [] | Claude Code skills installed for this agent, resolved from a repository directory containing a SKILL.md. |
budget | number (USD) | split evenly | This agent's per-session cap. Agents without one split the remainder of budget.run. |
pull_requests | mapping | unset (all) | This agent's own narrowing: base, head, and paths only. |
The claude block:
| Field | Type | Default | Meaning |
|---|---|---|---|
system | string, {file} ref, or a list of both | required | The agent's instructions. Must be non-empty for every stage agent; a {file: path} entry reads a repository file. |
model | string | claude-opus-5 | The model this agent runs on. |
effort | low, medium, high, xhigh, max | model default | Reasoning effort. |
fallback_model | string | unset | Used when the primary model is overloaded. |
max_turns | integer > 0 | uncapped | Hard cap on agent turns. The budget still bounds the session. |
settings | {path, repository} | unset | A Claude Code settings.json in a repository, applied to the session. |
A stage agent's pull_requests decides which of the pipeline's pull requests this one agent reads. An agent that filters out costs nothing: no sandbox starts, and its share of the run budget goes to the agents that do run. repositories, labels, draft, and for are not accepted here; those scope the pipeline. See per-reviewer filters.
pre_review
Agents that run before the reviewers, one session each. Each writes context that is handed to every reviewer, and any one of them can cancel the review, a deliberate judgment that the range needs no review, which counts as coverage. By default none run.
pre_review:
- name: linear-context
claude:
system: |
Fetch the Linear issue this branch names and summarize its
acceptance criteria for the reviewers.description
One agent that keeps the pull request description's Ellipsis summary current. It runs after pre_review and before the reviewers, and Ellipsis applies its output to the pull request body the moment it finishes: the summary updates within the review, not after it.
The summary lives in a branded, marked section of the description. Ellipsis only ever rewrites between its own markers, so the author's text above and below survives every update. On every push the agent is shown the current summary and the new commits, and rewrites the summary to describe the pull request as it now stands. It can also conclude the current summary still holds and skip the update, or that the pull request should carry no summary, which removes the section.
Three shapes:
- Unset: the built-in
pr-descriptionagent runs. - A single agent mapping: your description agent replaces the built-in one.
description: []: the pipeline never touches the pull request description.
description:
name: pr-description
claude:
system: |
Summarize the change for reviewers. Never mention documentation-only
changes in the summary.description is exactly one agent, not a list. A list with entries is a validation error; [] is the disable idiom.
See Pull request descriptions for what lands on the pull request and prompt guidance.
review
The reviewers. Each reads the unreviewed commit range in its own sandbox and proposes findings; Ellipsis collects, deduplicates, and posts the survivors as one pull request review. Reviewers run in parallel, so several cost latency only once.
Declaring review: replaces the built-in reviewer wholesale. A pipeline may declare at most 8 reviewers, and each name must be unique across the file. A pipeline whose reviewers all filter out of a pull request reviews nothing on it: the review is cancelled, and the commits stay covered by the next review that runs.
See Reviewers for prompt guidance and worked examples.
filter
A gatekeeper: one agent that judges every reviewer finding and decides what posts. Findings it rejects are recorded but never reach the pull request. Three shapes:
- Unset: no gatekeeper runs, and every reviewer finding posts. This is the built-in pipeline.
- A single agent mapping: your gatekeeper runs, and nothing posts until it approves.
filter: []: no gatekeeper runs. Accepted, and identical to unset: an explicit statement that this pipeline gates nothing.
filter is exactly one agent, not a list. A list with entries is a validation error.
filter:
name: strict-gate
claude:
model: claude-opus-5
system: |
Approve only findings a staff engineer would raise in review.
Reject style opinions and anything a linter catches.See Gatekeeper for when it earns its cost and how to write one.
post_review
Agents that run after the review posts, one session each. Use them for follow-up work such as notifications. A post_review failure never affects the posted review. By default none run.
budget
| Field | Type | Default | Meaning |
|---|---|---|---|
run | number (USD) | 10.00 | Caps one review: every stage agent of one pass, together. |
day | number (USD) | 1,000.00 | This pipeline's trailing 1-day spend cap. |
week | number (USD) | 10,000.00 | This pipeline's trailing 7-day spend cap. |
The day and week defaults are the platform ceilings; a value above the ceiling is lowered to it. When every stage agent declares its own budget, their sum must fit under budget.run; that contradiction is a validation error.
Budgets
Review budgets are three caps, each with a different failure mode.
budget.run caps one review end to end: every stage agent of one pass, together, not per stage. Each agent gets its declared budget if it set one; the agents that did not split the remainder evenly. An agent that hits its share stops where it is. The review still posts with the findings written by then, headed "Incomplete review" and stating that the remaining lines were not checked, because those commits count as covered and will not be re-read unless new commits land. Raise budget.run when reviews of large diffs stop early.
budget.day and budget.week are trailing windows over everything this pipeline spent, checked before a review starts. A pipeline at or over a cap reviews nothing until the window rolls; the skipped commits stay uncovered, so the next review that does run covers all of them. This is the guard against a push storm: forty pushes in an afternoon cannot turn into forty full-price reviews.
You can see what every review cost on the reviews dashboard, with a per-stage breakdown on each review's page, and on the API as the review's cost.
Review budgets are separate from session budgets. A Cloud Agent's budget.session caps one agent session, and its day/week/month fields cap one agent config's trailing spend; a review pipeline's budget.run spans several sessions in one review, and its trailing caps meter the pipeline. Both draw from the same account balance and count toward your account-wide spend limits. See code review budgets in Billing for how review spend is metered and billed.
budget:
run: 25.00
day: 100.00
week: 400.00