Have a different AI review the code the first AI wrote. Simple idea, awkward plumbing: pull the diff out of one window, paste it into the other, carry the findings back, fix, repeat. The manual handoff was costing more than the review.
So I wired Codex and Claude Code together directly and closed cross-model review in one shot. Two things came out of it that are worth more than the convenience.
Originally published in Japanese on September 2, 2026. This English version was written in September 2026.
The two directions are not symmetric. One is an official OpenAI plugin. The other is a local wrapper I wrote around a documented CLI. Conflating them would make it sound like anyone can install a bidirectional setup, and they cannot.
And adding a second model does not move the truth decision off the human. A finding that arrives in a valid JSON schema is still a finding you have to reproduce yourself.
What the copy-paste was actually costing
Before this, finishing an implementation meant writing a review brief for the other model: the diff, the areas to check, the conditions that must not change. Then carrying the answer back. The more careful I was, the longer the brief got.
The paste count was not the real problem. The problem was the room it left for the scope to drift, for a stale diff to go across, or for a review result to be adopted as a fix instruction without challenge.
A human needs to be in the loop. A human does not need to be the transport layer.
Claude → Codex: an official OpenAI plugin
For asking Codex to review from inside Claude Code, I used OpenAI’s official codex-plugin-cc.
Its /codex:review command can target the current working tree or the diff against a base ref. OpenAI’s own command definition states it is review-only and instructs the model not to fix issues or apply patches. That constraint is theirs, not mine.
The plugin drives the locally installed Codex CLI and Codex app server, reusing the same authentication state and configuration. The app server is a JSON-RPC interface handling thread start, resume, and similar operations.
My verified combination was Claude Code 2.1.236, codex-plugin-cc 1.0.6, and Codex CLI 0.148.0. Measurements here apply to that combination only. codex-plugin-cc 1.0.6 is still the current release as of September 2026; Codex CLI has since moved on to 0.153.4.
What I cannot tell you about the Claude → Codex direction
OpenAI documents that Codex’s model and reasoning effort are configurable, and that ChatGPT sign-in versus API key sign-in changes the allowance, billing, and data-handling boundaries.
I did not capture which model and effort were actually selected for these reviews. Tokens, cost, and the real billing path are unconfirmed. What is configurable and what a given run used are separate questions.
So I cannot write “this model ran at this price” for this direction. Nor can I assume that because the plugin is official, the run drew on a ChatGPT allowance. Unverified values stay unknown.
Codex → Claude: a local wrapper, not an official plugin
There is no equivalent official plugin in the other direction.
To ask Claude for review from Codex, I use a read-only wrapper that invokes the Claude Code CLI exactly once. The CLI’s print mode supports --json-schema for schema-conforming output, and --no-session-persistence to avoid saving the run as a resumable session. Those are documented Anthropic features and the wrapper uses them as documented.
The wrapper itself is my local setup. It is not an Anthropic “Codex integration plugin.” Official are the Claude Code CLI and its structured-output specification. Fixed scope, exactly-once execution, and read-only enforcement are my implementation choices.
The distinction matters. Blur it, and it reads as though installing one plugin gets you a bidirectional setup. In reality one side is an official OpenAI plugin and the other is a local wrapper over a published CLI.
6 → 5 → 1 → 0 is not two models converging on truth
Reviewing from Claude toward Codex, findings went 6, then 5, then 1, then 0.
Read as a sequence, that looks like two AIs iterating toward a correct answer. It was not what happened.
Whenever a material finding came back, I reproduced it myself before fixing anything. Does the defect actually occur? Is it inside the contracted scope? Is it a suggestion that would break existing behavior? Only reproduced findings got fixed, and the sequence is what re-review returned after each of those rounds.
Zero findings is not proof of safety. It is an endpoint meaning that for the specified diff, under those review conditions, no further findings were produced.
The reverse direction: 3 of 4 findings reproduced
For the one-shot review from Codex toward Claude, I requested Opus 5 at high effort.
| Metric | Value |
|---|---|
| Execution time | 161,770 ms |
| Observed cost | 0.735708 USD |
| Findings returned | 4 |
| Findings I reproduced | 3 |
| Retries / model fallbacks / reviewer writes | 0 |
These are one local run. Not an average, not a benchmark, not a cost you should plan against.
The unreproduced finding was a scope artifact: I had limited the review target to tracked files, so untracked assets never entered the comparison. Calling that a model error would be wrong. The range I handed to the reviewer did not represent the whole implementation.
Run once, receive the result structured, reproduce it as a human. In that order, adding reviewers does not cost you control of the work.
A schema is not a truth detector
A JSON Schema lets you fix the fields you want back: severity, target, rationale, how to verify. Re-extracting findings from free prose largely disappears, and passing results to a downstream step gets easier.
A schema-conforming response is not a correct response. Anthropic’s structured outputs constrain the output format through constrained decoding — valid JSON, required fields present, correct types. They do not certify that a defect reproduces, that a claim matches the specification, or that the scope was appropriate.
For the same reason I do not use finding counts as a model leaderboard. A model that returned 4 is not therefore better than one that returned 1. Different scope, instructions, prior knowledge, and false-positive rates change what a count even means.
What matters is whether a human could reproduce the material findings, and whether any ship-blocking finding remains in the fixed, narrowed scope. The numbers are a work log, not a ranking.
Five boundaries that let a cross-model review close
- Read-only. The reviewer investigates and returns findings. It does not patch the source.
- Fixed scope. Working tree, branch, base ref — decide what is being compared before starting.
- Exactly once. Do not stack repeat reviews on a failure or a non-response without first checking state.
- Structured result. Severity, rationale, target, and reproduction come back in the same shape every time.
- Author reproduction. The implementer reproduces every material finding before fixing it.
None of these improve model performance. They stop a review from spreading into a long conversation where nobody can tell who decided what.
They also only work together. Read-only is useless if the scope is wrong. A clean schema still lets false positives into your fixes if nothing is reproduced. The set is what closes, not any one of them.
Not a permanent gate — one shot, on material diffs
The official plugin also offers a review gate that runs a Codex review when Claude Code stops. OpenAI’s own README warns that this can create a long-running Claude/Codex loop and drain usage limits quickly, and says to enable it only when you plan to actively monitor the session.
I do not gate every small change. I reserve it for diffs with real blast radius: authentication, data loss, publication paths, rollback, changes spanning multiple files. There, a one-shot review is a useful extra layer.
Adding reviewers does not make the process safer. Add models while the target and the exit condition stay vague, and organizing findings and re-running reviews simply becomes a new job. The copy-paste was one thing I wanted gone; the never-finishing state was the other.
Starting small: one direction, one diff
You do not need to build both directions.
If you use Claude Code, try the official plugin’s read-only review on a single working tree. If you want to call another reviewer from the Codex side, fix the conditions first: no writes, a defined target diff, defined output fields, exactly one run.
The goal is not more findings. Check three things: does the scope stay intact without copy-paste; can you reproduce the findings yourself; and when it hits zero, what exactly are you treating as done? Answer those and you can decide whether to extend it to the next change.
If you cannot make time for reproduction, do not add the review. This is not machinery for skipping human checks. It is machinery for narrowing where the human has to look.
The human closes the review
Cross-model review removed the work of ferrying diffs and findings between windows. The two directions are still built differently: Claude → Codex through an official OpenAI plugin, Codex → Claude through my own local read-only wrapper.
And a result from another model is not an answer. Keep schema conformance and finding correctness as separate questions. Do not race counts. Reproduce the material findings yourself.
Read-only, fixed scope, exactly once, structured result, author reproduction. Automate the review however you like — the person who wrote the code still closes it.