Codex reviews each Claude Code commit in a read-only sandbox, and any review that doesn't end on Verdict: ACCEPT or Verdict: CHANGES REQUIRED counts as failed. So does a crash. The merge check in my free gate also refuses an ACCEPT that came from the engine that wrote the code.
The writer answers every finding, each new commit gets a fresh review, and later the roles swap so each engine spends time on both sides of the diff.
This is the setup I use on my own projects, with the CLI flags taken from the official Claude Code and Codex docs. The reasons I use Claude Code and Codex together are in an earlier post.
1. Give each engine one job
Claude Code is the default writer. Writing is where context piles up: the plan, the files touched, the tests run. A review needs far less, only the diff and the project rules. A reviewer trained by a different company also has different blind spots, and that's why I use two engines instead of asking one to check itself.
Start the writer in its own git worktree, so its edits never touch the checkout you review from:
claude -w feature-auth
The -w flag starts Claude Code in an isolated worktree at <repo>/.claude/worktrees/<name>. Reviews always run on a commit, never on loose edits, so tell the writer to commit each finished change and stop.
2. Run Codex as a read-only reviewer
codex exec is the non-interactive mode of the Codex CLI, and its default sandbox is read-only. I pass the sandbox flag anyway, so nobody has to remember the default:
codex exec -s read-only -c model_reasoning_effort=high \
--color never --output-last-message .ai/last-review.md \
- < review-prompt.md
-
-s read-onlylets Codex read files and run read-only commands such asgit diff, but not write. -
-coverrides any config key for one run. Here it sets the documentedmodel_reasoning_effortkey tohigh. The review script in the Two Engines Kit defaults toxhigh, one level above. - The output-last-message flag saves only the final message to
.ai/last-review.md, and the verdict is read from that file. - The
-on the last line makes Codex read the prompt from standard input.
If an MCP server in ~/.codex/config.toml can change things outside the sandbox, set enabled = false on its table for the review run.
3. Force a verdict line
My review prompt asks Codex to end on one of two exact lines:
Verdict: ACCEPT
Verdict: CHANGES REQUIRED
It sets four more rules:
- Every finding carries a severity (blocker, should-fix or nit), a file and line, and a concrete failure scenario.
- Blockers and should-fixes need a concrete, reproducible failure. Style preferences stay at nit level.
- Codex lists every finding in this one pass, so the next round doesn't surface old problems.
- The review stays under 600 words.
The review script reads the verdict only from that saved final message, never from the log. It also checks that Codex exited with code 0 and that the checkout is unchanged afterwards. A crash or a missing verdict line counts as a failed review. The result is saved under the commit hash it reviewed, so a later commit can't borrow an old ACCEPT.
4. Make the writer answer every finding
The reviewer has no say in what gets merged beyond its findings. The writer and the person running the loop decide.
For each finding, the writer either fixes it in a new commit or disputes it with evidence: a test that passes, a file and line that shows the case is handled, or a command whose output contradicts the claim. Don't let it accept every finding by default. A reviewer can be wrong, and a fix for a problem that doesn't exist adds risk of its own.
I follow three round rules from the kit workflow:
- Round 1 lists everything.
- Round 2 confirms that the fixes landed.
- From round 3 on, only blockers and security findings hold the merge. Nits go into a follow-ups file to handle later.
I wrote more about briefs and disagreement in how I brief Codex to review Claude Code commits.
5. Swap the roles
In my free gate, two-engines-gate, setting BUILDER=codex flips the roles, so Claude Code reviews and Codex writes.
As the writer, Codex needs a sandbox that allows edits inside the workspace:
codex exec --sandbox workspace-write \
- < task.md
As the reviewer, Claude Code runs in print mode with a short list of read-only tools. The gate makes this call:
claude -p "Do the review described on standard input." --restricted --strict-mcp-config \
--permission-mode dontAsk --tools "Read,Grep,Glob" --allowedTools "Read,Grep,Glob" \
--disallowedTools "Bash,Edit,MultiEdit,Write,NotebookEdit,WebFetch,WebSearch,Task,Agent"
With only Read, Grep and Glob available, Claude Code can't run commands, git included, and can't edit or write files. That's why the gate puts the commits and the full diff into the prompt itself. The strict MCP config flag with no MCP config loads no MCP servers, and permission mode dontAsk denies anything that would otherwise ask for approval.
The merge check I opened with refuses an ACCEPT from whichever engine wrote the code.
6. Keep one rulebook for both engines
Claude Code reads CLAUDE.md and Codex reads AGENTS.md. Put the same short section in both:
- Commit each change and stop.
- Never merge.
- Stay read-only when reviewing.
- Leave the review records folder alone.
Codex limits how many bytes of AGENTS.md it loads (the project_doc_max_bytes setting), so keep that section short and put long reference material elsewhere.
What the loop doesn't replace
Your tests have to run on the exact commit that got the ACCEPT. My free gate checks for both a test pass and an ACCEPT on that commit before it allows a merge. A reviewer on high reasoning effort catches a lot, but it only reads the diff you gave it.
Running it on your own repository
If you want it running without doing the wiring yourself, I set up Codex to review your Claude Code commits before they merge. The Codex review setup is written from scratch for each repository, its stack and its conventions, then the first review runs on one of your real branches. Nothing is copied from a template or from the Two Engines Kit.
To start from the files I use and wire it up yourself, get the Two Engines Kit. It packages the review script, the gate, the merge check, the review prompt and the workflow rules from this post, for WSL2, Linux and macOS. It's the setup I run on my own projects, built on information gathered since the first Codex and Claude CLIs.
Top comments (0)