Which PRs get reviewed
Each review covers new commits only. Filter which pull requests get reviewed by repository, branch, path, author, and draft status.
Two rules decide what gets reviewed. Every review covers only the commits since the last review, never the whole pull request again. And once you commit a pipeline file, its filters are authoritative: a pull request the file does not match gets no review at all.
New commits only
The first review of a pull request covers everything on it, including commits pushed before it was opened. Every review after that covers only the commits since the last review that posted:
base ── A ── B ── C ── D ── E commits on the PR branch
└─────────┘
review 1: base...C the PR is opened at C; the first
review reads the whole PR (A, B, C)
└────┘
review 2: C...E D and E are pushed later; the next
review reads only D and E, and never
re-comments on A, B, or CWhen priya-shah opens "Expire pending trades on account deactivation" and pushes twice more over the afternoon, the pipeline runs three times, each time reading only what that push added. If the third push drops a rest-period check, the comment lands on that line, with no repetition of the earlier reviews.
Two properties follow:
- A review that fails does not count as coverage. If a review errors or hits its budget, the commits it was reading stay unreviewed, and the next review covers everything since the last one that actually posted. Nothing is silently skipped.
- A clean review still counts. A review that finds nothing posts a one-line summary rather than invented nitpicks, and the commits it read are covered.
Each review anchors to the exact commit it reviewed, so its comments stay attached to the right lines as the pull request grows. The reviewed range is visible on every review: the dashboard shows the commits each review covered, and the API reports it as scope.watermark (the last reviewed commit) and scope.head.
Repo scoping
Two independent fields name repositories, and they answer different questions:
pull_requests.repositoriesis the watch set: which repositories' pull requests trigger reviews.sandbox.repositoriesis the context set: extra repositories cloned into the reviewer's sandbox. The pull request's own repository is always cloned, so it never needs listing.
ellipsis:
version: v1
kind: code_review
name: API review with web context
pull_requests:
repositories: [splitshift-api]
sandbox:
repositories:
- name: splitshift-webOnly splitshift-api pull requests are reviewed, and splitshift-web is on disk while reviewing, so a change to an API response shape is judged against the client that consumes it.
The watch set is an include-minus-exclude filter. A bare list is shorthand for include; an empty or omitted include means every repository of the installation, so an exclude-only filter reviews everything except the listed repositories, and stays correct as repositories are added to the organization later:
pull_requests:
repositories:
exclude: [sandbox-experiments, splitshift-docs]A committed file makes its watch set authoritative. Scoping review to splitshift-api means "and nothing else": a pull request in splitshift-mobile gets no review, rather than falling back to the built-in pipeline. Ellipsis never reviews, or bills you for, something your file excluded.
Pull request filters
Beside repositories, the pull_requests: block filters on branch, draft status, labels, changed paths, and author. All declared filters must pass; an omitted filter passes everything.
ellipsis:
version: v1
kind: code_review
name: API release review
pull_requests:
repositories: [splitshift-api]
base: [main, "release/*"]
draft: false
paths: [src/**, sql/**]
for:
users: true
bots: falseAgainst that file:
priya-shah's "Reject overlapping shift trades" intomain, touchingsrc/trades.py: reviewed.- The same change opened as a draft: not reviewed (
draft: false), until it is marked ready and the next push lands. - A Dependabot bump into
main: not reviewed (bots: false, which is also the default). marcus-lee's README-only change: not reviewed (no changed file matchespaths).
Field by field:
baseandheadmatch the target and source branch. Each entry is an exact name, a prefix glob likerelease/*, or the literaldefaultfor the repository's default branch whatever it is named.draftunset reviews drafts and non-drafts alike;trueorfalserequires that state.labelspasses a pull request carrying at least one listed label, matched exactly including case. Labels are read when the review triggers, on the open or a push; adding a label to an open pull request does not trigger a review by itself.pathsare include-only globs over the pull request's full changed-file set; any matching file passes. A pattern with a slash is repository-root-relative,**crosses directories, a slashless pattern matches at any depth, and a leading/anchors to the root. Negated patterns (!foo) are a validation error.forgates on the pull request's author, the account that opened it, for the pull request's whole life. Humans are included and bots excluded by default; each side takestrue, a list of logins,false, or an include-minus-exclude mapping. Sobots: ["renovate[bot]"]reviews Renovate's pull requests and no other bot's, and a commit someone else pushes onto an excluded author's pull request is still not reviewed.
Every field, type, and default is in the configuration reference.
Per-reviewer filters
The pipeline's pull_requests: decides which pull requests get reviewed at all. Each reviewer can carry its own pull_requests: block deciding which of those it bothers reading, with paths, base, and head only:
ellipsis:
version: v1
kind: code_review
name: Backend review with a migration specialist
pull_requests:
repositories: [splitshift-api]
include_default_reviewers: true
review:
- 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/**"]On a pull request that touches a migration, both the built-in reviewer and migration-safety run. On any other pull request, only the built-in reviewer runs, and the specialist costs nothing: no sandbox starts, no model call is made, and its share of the run budget goes to the reviewers that did run.
A reviewer's block takes paths, base, and head only; repositories belongs to the pipeline, which owns the watch set. To turn a reviewer off entirely, remove it from review:; to run only your own reviewers, declare review: without include_default_reviewers and the built-in one is replaced. See Reviewers.
When reviews are skipped
A push produces no review when:
- Code review is off. The organization-wide setting gates every path in; see the quick start.
- Your pipeline file does not match the pull request. A committed file's filters are authoritative, so a non-matching pull request gets nothing rather than the built-in pipeline. A file with
enabled: falsecounts the same way: it declares intent, so it suppresses the built-in pipeline rather than falling through to it. - There is nothing new. A push whose head was already covered by the last posted review is skipped before anything starts or costs anything. Re-delivered or out-of-order events are absorbed the same way.
- The pipeline is over its trailing budget.
budget.dayandbudget.weekare checked before a review starts, so a push storm cannot turn into a bill; reviews resume when the window rolls. See budgets. - A review of the pull request is already running. The push does not start a second review. When the running one finishes, Ellipsis re-checks the pull request and immediately reviews anything that landed in the meantime, so the commits are covered by the next review rather than lost.
- Every reviewer's own filters excluded the pull request. A pipeline whose only reviewer is scoped to
sql/**reviews nothing on a pull request that touches no SQL. That shows up as a cancelled review on the reviews dashboard, the commits stay uncovered, and a later push that does touchsql/**shows the specialist the whole accumulated range.
In every case above the incremental rule holds: commits nothing reviewed stay unreviewed, and the next review that runs covers all of them. The one deliberate exception is a pre_review agent you configured cancelling a review: that is a judgment that the range needs no review, so it counts as coverage and the next review starts after it.
Review a branch without a PR
agent review with no pull request number reviews the work in your tree, before any pull request exists. The CLI snapshots your working tree and pushes it to a sidecar branch (ellipsis/review/<your-branch>, never the branch you are working on), and Ellipsis finds or creates one reusable draft pull request to hold it, because a review is structurally a pull request review: the range, the checkout, and the comments all need one.
$ agent review
✓ pushed 4f2c9a1b07d3 to ellipsis/review/rest-period-rules
✓ reviewing splitshift-hq/splitshift-api#519 (crun_8Kw2mVq4Tj9e)
review: crun_8Kw2mVq4Tj9e
pr: splitshift-hq/splitshift-api#519 https://github.com/splitshift-hq/splitshift-api/pull/519
status: completed
scope: base...4f2c9a1
cost: $3.87
completed: 2026-07-31 18:22
Reviewed the rest-period rule changes. One finding worth a look; details inline.
src/scheduling/rest_period.py:84 [4/5 correctness]
The 11-hour rest check compares shift start times in the venue's
timezone but the previous shift's end time in UTC, so a worker
crossing midnight UTC can be offered a shift 3 hours after clocking
out.
Convert both timestamps with venue.tz before subtracting.How the draft pull request behaves:
- It is titled
[ellipsis review] <branch>, opened against the repository's default branch, authored by the Ellipsis bot, and marked as opened for review, never to merge. - It is reused: later reviews of the same branch push to the same sidecar and review the same draft pull request. Nothing is auto-closed; close it when the work lands.
- Branch reviews from the CLI post nothing to GitHub. The findings print in your terminal instead.
- A branch review always covers the branch's full range, since the sidecar's contents are replaced on every push.
agent review --branch <name> reviews a branch you already pushed, skipping the snapshot. The same flow is available over the REST API by passing branch instead of pull_request_number to POST /v1/reviews.
Configuration YAML
Every field, type, and default in kind code_review pipeline files. No YAML is required to enable reviews; a file customizes reviewers, the gatekeeper, and budgets.
Reviewers
One built-in reviewer, bugs, reads every pull request on Claude Opus 5. Add reviewers with their own prompts, models, and filters, or replace it.