Reviews
Start a review on a pull request, read its receipt and findings by one id, and see how the outcome reaches GitHub.
A review is one pass over a pull request by a lineup of reviewers. IonWarp reads the diff, runs each reviewer, merges and dedupes what they found, and — when you ask it to — posts the result on the PR. Reviews start on their own for every watched pull request; the API starts the same review by hand.
Start one
REVIEW_ID=$(curl --fail-with-body "https://ionwarp.com/api/v1/reviews" \
-H "Authorization: Bearer $IONWARP_API_KEY" \
-H "Project-ID: $PROJECT_ID" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: acme-reviews.create-1' \
-d '{"pr":42,"reviewers":["code-review","security-review@google/gemini-3.8-flash"]}' | jq -er '.id')Reviewers are strings. "code-review" runs that reviewer on its governed
model pin; "code-review@google/gemini-3.8-flash" pins the model for this
run; "ionwarp:code-review:auto" is the explicit spelling of the pin. Omit
reviewers and the planner chooses the lineup from the diff. delivery
defaults to "none" — the result is yours to read — and "github" posts it
on the pull request as the product does. The answer is the task
acknowledgement: id, run_id, status_url.
Read it
curl --fail-with-body "https://ionwarp.com/api/v1/reviews/$REVIEW_ID" \
-H "Authorization: Bearer $IONWARP_API_KEY" \
-H "Project-ID: $PROJECT_ID"run is the latest run's receipt — status, timings, usage, cost, a named
error when it failed. findings is null until the run is done and the
finding rows once it is; a done review that found nothing reads [], and a
review with more than the page holds carries findings_truncated: true. The
same rows are the findings ledger: one object
per finding with severity, path, line, and the review task that produced it.
Where a review got to is also stamped on the pull request row —
review_status, last_reviewed_at, last_review_run_id — documented in
Repositories & PRs. GET /reviews lists a project's
API-created reviews; POST /reviews/{id}/runs re-runs one against the PR's
current head, and PATCH /reviews/{id} changes its configuration for the next
run.
What shapes a review
Three project settings: ionwarp.review.enabled turns automatic review on or
off, ionwarp.review.guidance adds project-specific instruction to every
reviewer, and ionwarp.review.budget_usd (default 1) tells the planner how
wide a lineup to buy — a scale signal, not a ceiling. Which reviewers can run,
and with which model, is Reviewers & Models.
A review that cannot run says so by name on the run — read it with Debugging a Run. The project-level brakes that stop one before it starts (pause, approval window, spend cap) are on Control Plane; PR-level skips are recorded on the pull request itself.
The review lifecycle & the GitHub check
Every review moves through one named lifecycle, persisted on the pull request
(review_status) and mirrored by the status pill and the GitHub check run
IonWarp / Review:
push ──▶ TRIGGER ──▶ REVIEW GITHUB CHECK "IonWarp / Review"
(filters, planning queued
dedupe) skipped/errored ──────────▶ skipped · reason in title
reviewing in_progress
reviews_available in_progress (findings post inline)
summarizing in_progress
reviewed ─────────────────▶ P0 → action_required
P1 → neutral · clean → success
⏱ deadline (≤10m) ────────▶ neutral "still reviewing"
→ PATCHed to verdict when doneThe terminal success state is Reviewed. If the review outlives its
deadline (the p75 latency for the PR's size bucket, hard cap 10 min), the check
completes neutral and is updated to the real verdict when the review lands.
A slow review never blocks a merge.
Check conclusions
| Review outcome | GitHub check conclusion | Merge button, if you made the check required |
|---|---|---|
| P0 open | action_required | ❌ blocked — the only blocking state |
| P1 only | neutral | ✅ mergeable |
| Clean / P2 only | success | ✅ mergeable |
| Not reviewed — filtered | skipped · title: "Skipped: draft / release PR / no reviewable diff" | ✅ mergeable |
| Not reviewed — errored | skipped · title: "Skipped: review failed to run — @ionwarp review now to retry" | ✅ mergeable |
With the check not required — the default — every row is mergeable and the
conclusion is informational. The per-severity conclusions are workspace
settings (ionwarp.checks.p0_conclusion / p1 / p2); "not reviewed →
skipped" is fixed — a no-show must never block. Blocking means you mark the
check required in GitHub branch protection; there is no separate IonWarp
switch. The structured fix prompt rides check output.text, so a coding agent
reads it from the Checks API without parsing comments.
Findings survive re-runs: the conclusion derives from the per-PR
open-findings ledger. A finding leaves "open" only by being fixed (its anchor
outdated by a push and not re-found) or dispositioned — reply
wontfix: <reason> on the finding thread and the check re-computes without a
new run.
PR commands
A bare @ionwarp comment replies with this list:
@ionwarp review off [reason]— disable automatic review for this PR@ionwarp review on— re-enable and review now@ionwarp review now— one review without changing the setting@ionwarp review force— re-review even on an unchanged head SHA@ionwarp review status— the PR's current review state@ionwarp help— the command list
Replying to a finding thread: wontfix: <reason> dismisses it (the check
re-computes), fix this opens a fix task.
Autofix contract (for coding agents)
The AGENTS.md section IonWarp hands you (Add IonWarp to Agents.md) tells a coding agent, after pushing to a PR:
wait for the "IonWarp / Review" check to finish (findings + summary) or its deadline:
finished → triage each finding with the summary as context:
helpful → reply "✔ fixing", fix it · wrong → reply "wontfix: <reason>"
then post ONE "⚡🛸 IonWarp autofix round 1" comment (✅ fixed / 🚫 wontfix
lines + a "✅ Verified:" line naming what was run) and push all fixes as
ONE fixpack commit (re-review resolves the ledger, tagged autofix)
deadline passed → proceed without IonWarp (never block on it) · max 2 roundsNext: Reviewers & Models to choose who reviews and with which model · Repositories & PRs for the PR objects reviews hang off · Scorecards for repo-wide rubrics instead of per-PR passes.