Skip to content
IonWarpRouterTry for free
IonWarp Docs
API

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 done

The 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 outcomeGitHub check conclusionMerge button, if you made the check required
P0 openaction_required❌ blocked — the only blocking state
P1 onlyneutral✅ mergeable
Clean / P2 onlysuccess✅ mergeable
Not reviewed — filteredskipped · title: "Skipped: draft / release PR / no reviewable diff"✅ mergeable
Not reviewed — erroredskipped · 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 rounds

Next: 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.