CodeRabbit review
Run one CodeRabbit CLI pass over the current changes, then triage it against this repo's conventions, verify each finding is actually reachable, and act on what survives both. CodeRabbit runs 40+ static analysers, security scanners and a codegraph — a different class of check from an LLM reading the diff. Its findings are claims to verify, not verdicts to apply, and the verifying is your job, not a figure of speech.
Optional argument selects the scope: committed, uncommitted (default), all,
or --base <branch>.
Which mode you are in — decide this first
Standalone — the user invoked you directly. You own the whole job: run, triage, verify, fix, report.
From ship-it — step 1a of that skill invoked you. You run, triage and
verify, then hand the surviving findings back and stop. Do not fix anything.
The adversarial review in ship-it step 1b is the single fixer for that run;
two fixers editing the same diff produce conflicting edits and a report nobody
can reconcile.
The budget rule — read this first
CodeRabbit is rate-limited per developer, per rolling hour, shared across every repo: 3 CLI reviews/hr on Free, 5 on Pro, 10 on Pro+. There is also a 150-file cap per review on Free and Pro (300 on Pro+), and adaptive throttling down to 1/hr for accounts exceeding 60 reviews in 7 days.
So:
- Run exactly once per invocation. Do not run it again after applying fixes unless the user explicitly asks for a second pass. The "review → fix → review" loop that CodeRabbit's own docs suggest will exhaust an hour's budget on a single feature.
- Never poll or retry on a rate-limit response.
- If the diff exceeds the file cap, say so and offer to scope the review to a subdirectory rather than firing a call that will be rejected.
0. Preflight
command -v coderabbit || command -v cr
If neither exists, stop and tell the user:
curl -fsSL https://cli.coderabbit.ai/install.sh | sh # or: brew install coderabbit
coderabbit auth login
Do not attempt to install it yourself. Auth tokens expire after ~90 days, so an
auth error means coderabbit auth login again, not a broken install.
The CLI must run from inside a git repository and needs network access.
1. Resolve the flags — do not hardcode them
The flag surface has changed between releases and the published examples
disagree. Read coderabbit review --help (or cr review --help) and use what
that prints. As of the last check the documented set was:
| Flag | Meaning |
|---|---|
--uncommitted | staged and unstaged edits to tracked files |
--committed | committed changes only |
--include-untracked | also review files not yet added to git |
--base <branch> | compare against this branch |
--agent | structured JSON — the documented mode for agent integrations |
--light | faster, shallower review policy |
--show-prompts | print the prompts from the last local review |
Older posts and third-party skills use --plain, --prompt-only and
--type <scope> instead. If --agent is absent from --help, fall back to
--prompt-only, then to the plain default. Say in your report which mode you
actually used.
2. Scope the review
- Default scope is
--uncommitted --include-untracked— the point of the local CLI is catching things before they are committed. committedargument →--committed.all→ both.--basecomes from the argument if given; otherwise from${CLAUDE_PROJECT_DIR}/.claude/ship-it.md(its "Branch and PR policy" section names the repo's base branch — it is notmaineverywhere); otherwisemain.- Count the files first (
git diff --name-only …). Over the cap → stop and ask.
3. Run it — once
coderabbit review --agent --uncommitted --include-untracked --base <base>
Expect it to take a while and to give no progress output. Do not kill it early; do not run a second invocation concurrently.
Rate limit. The CLI reports {"errorType":"rate_limit","waitTime":"N seconds"}.
On that: report the wait time, state plainly that no review ran, and stop. Do not
wait it out, do not retry, do not fall back to pretending you reviewed. The
user's remaining budget is a shared resource across all their repos and they may
want to spend it elsewhere.
Any other non-zero exit: report the stderr verbatim and stop.
4. Triage — does this repo care?
Group the findings by severity (critical / warning / info) and then filter.
CodeRabbit does not know this codebase's conventions. Before acting on a finding,
check it against ${CLAUDE_PROJECT_DIR}/.claude/ship-it.md and CLAUDE.md:
- Deliberate patterns it will flag anyway — a repo with no formatter and
mixed indentation, a legacy
protected $castson Laravel 10, string constants that are deliberately not enums, a frozen verbatim port that must not be "cleaned up". These are not defects here. Say so and move on. - Pre-existing debt in untouched lines — out of scope for this change.
- Style opinions where the project already made the opposite choice.
This step answers "would we want this fixed?" — not "is it true?". That is the next step, and skipping it is how a static analyser's false positive becomes a confident, unnecessary edit.
5. Verify — is the finding actually real?
A finding is a claim, not a verdict. Static analysers over-report: a null-dereference warning on a path that cannot be null, an injection flag on a parameterised query, a race on code that already holds a lock, an unhandled exception on a branch that is unreachable.
For each finding that survived triage, trace the actual code path and establish
that the failure is reachable with real inputs. State the concrete scenario:
which input, which state, which call order produces the bad outcome. Where the
finding is behavioural and the repo has tests, the strongest form of this is a
failing test that reproduces it — write that before writing the fix, the same
rule ship-it applies to its own review findings.
Then:
- Reproduced, or the path is plainly reachable → confirmed. Carry it forward.
- Cannot reach it, or the guard CodeRabbit missed is right there → discard it and say which guard makes it safe. Do not "fix" it defensively just because a tool raised it; that adds dead code and teaches you to trust noise.
- Genuinely unclear after a real attempt → keep it, marked unverified, and say so rather than silently dropping or silently fixing it.
Rank the confirmed set: security, authorization, data loss, money and fiscal correctness first.
6. Fix — or hand off
From ship-it: stop here. Return the confirmed findings, each with its
verification scenario, plus the discard counts. Fix nothing.
Standalone: fix the confirmed findings. For anything needing a judgment call — a behaviour change, a schema change, a fix that widens scope — surface it and let the user decide rather than applying it silently.
Do not re-run CodeRabbit to confirm the fixes. Verify them the normal way: run the affected tests.
Output
Report, in this order:
- Which mode you ran in (standalone or from ship-it), the command, and the output mode you actually used.
- Counts through the funnel: raised → survived triage → confirmed, with the reason for each drop. This is the most useful line in the report: it tells the user whether CodeRabbit is earning its rate limit on this repo, and separates "we do not care about that here" from "that was not true".
- Each confirmed finding: what it is, the scenario that makes it real, and — standalone only — whether you fixed it and how.
- Anything left unverified, flagged as such.
- What you deliberately left alone, and what needs a decision.
- If rate-limited or skipped: say so plainly, with the wait time. A ship that proceeds without this pass is fine — say that too, rather than implying the code was scanned when it was not.