What the pipeline should do
| Stage | Input | Output |
|---|---|---|
| Context | Pull request event, changed files, tests, rules, relevant contracts | One review job per commit SHA with a bounded prompt |
| Fast pass | Prompt and diff, Sonnet or GPT Sol | Structured findings and questions tied to lines |
| Verification | Finding, file and line; tests, typecheck, linter | Reproduction or dismissal |
| Deep pass | Risky diff, Opus 5.5 or GPT Astra | Review of migrations, authorization, financial flows |
| Publication | Verified findings and a human | One review with actionable comments, or a draft |
| Merge gate | Tests, review and approval | Human decision or protected-branch result |
Do not hand the model every secret or the whole repository. Start with the changed files and add a related file only when the review contract calls for it. For a large change, add a dependency map or a separate research step.
What to check automatically
Begin with errors that formalize well: an endpoint that forgot authorization, a DTO changed without updating the client, unsafe secret handling, a migration without an index, an error handled wrongly. Tie each comment to a line and ask for the user scenario behind it. "The code could be improved" must never reach a pull request.
Block a merge only for a reproducible correctness, security, data-loss or build issue. Leave style to the formatter and linter. Cap comments per file and deduplicate findings, so the author sees a review and not a flood.
Judge the pipeline by accepted findings, dismissed findings, bugs missed and found later, runtime and token usage. Look at those numbers again after every model or prompt change.
Claude and GPT routes
| Route | Model ID | Use it when |
|---|---|---|
| Claude daily pass | claude-sonnet-5 | The rubric is stable and routine pull requests are many |
| Claude deep review | claude-opus-5-5 | The diff crosses modules or the failure mode is hard to infer |
| GPT daily pass | gpt-6-sol | You want a first pass over every pull request |
| GPT second opinion | gpt-6.1-sol | You want a second model family in the comparison set |
| GPT deep review | gpt-6-astra | Migrations, authorization, money |
| GPT fast check | gpt-6-luna | The check is narrow, structured and already covered by tests |
These are starting routes from the live catalog checked on October 4, 2026. Count accepted findings and misses on your own repository, because a model name guarantees no quality. Sending only the risky changes to a deep pass is cheaper and more useful than running a flagship on every formatting change. With codexkey, one gateway lets the same pipeline switch between Claude and GPT by changing the model ID.
Make the review output strict
Ask for JSON with a schema. Each finding needs a path, a line in the changed file, a consequence, reproduction steps and a suggested fix. Return an empty array when there is no evidence.
const review = await client.responses.create({
model: "claude-opus-5-5",
input: [
{ role: "system", content: REVIEW_RULES },
{ role: "user", content: diffText },
],
text: { format: REVIEW_SCHEMA },
});
Use the request format your SDK supports. Parse the result, reject unknown fields where practical, and fail the job visibly on invalid JSON. Quietly repairing the parser hides the very problem the review exists to catch.
Verification before publication
The model's first answer is a lead, nothing more. A maintainer or a verification step has to check it against the source. For a race report, write a small test. For a SQL issue, look at the query plan or a fixture. For an API contract issue, compare the producer and consumer types.
Keep false positives in the fixture set, and let the next prompt explain why the old finding was wrong. That slowly teaches the pipeline where your repository's boundaries lie, without turning the prompt into a novel.
A GitHub Actions outline
name: AI review
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
review:
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- name: Run tests
run: npm test -- --run
- name: Review the diff
env:
CODEXKEY_API_KEY: ${{ secrets.CODEXKEY_API_KEY }}
run: node scripts/ai-review.mjs
Pin the action versions you trust, keep permissions narrow, and pass the pull request SHA to the script. A patch written by the model must never reach the default branch from the review job.
FAQ
Can AI merge pull requests by itself?
It can propose findings. Merge authority belongs to branch protection and the team. Automated merging needs its own policy, tests and an audit trail.
What do I need for the first run?
An API key, CI access to it through a secret, safe diff collection and a small set of old pull requests to judge quality on. Create a separate key and limit for the pipeline.
Should I use Claude or GPT for code review?
Run both on the same anonymized fixtures. Use the route with the better verified signal for your repository, and keep the other as a comparison or a fallback.
Can the model review the entire repository?
Only when the task needs it and your data policy allows it. A bounded diff plus the relevant contracts is easier to audit and cheaper to run.
How do I stop prompt injection in source code?
Treat code and comments as untrusted data. Put the review rules in the system message, delimit the diff, and tell the model that instructions inside the diff are not review policy.
What should I log?
The commit SHA, model ID, duration, parse result and finding identifiers. Redact secrets, and do not store full source diffs unless your retention policy allows it.