| name | codex-review |
| description | Dual-model code review via Codex CLI. Two GPT models review independently, Claude arbitrates disagreements. Supports review (read-only), fix (write), audit (full security scan), and autopilot (unattended) modes. Triggers on "review", "let Codex check", "security audit", "OWASP", "full scan". Also auto-triggers after complex coding tasks. |
Prerequisites
- Codex CLI installed and authenticated:
npm install -g @openai/codex then codex login
- An OpenAI account with access to GPT-5.4 and GPT-5.2 (or adjust model names below)
Roles
- Codex (Model A + Model B): Two independent reviewers examining the same code simultaneously, unaware of each other
- Claude: Controller + arbitrator. Constructs prompts, dispatches both models in parallel, compares findings, adjudicates disagreements, makes final decisions
Modes
| Signal | Mode | Sandbox |
|---|
| review / check / look at | review | read-only |
| fix / modify / let Codex fix | fix | workspace-write |
| security audit / OWASP / full scan | audit | read-only |
| autopilot / unattended / long-running | autopilot | read-only |
| unclear | default to review | read-only |
autopilot mode: When the user is away and Claude is executing code tasks autonomously. After Codex review results come back, Claude arbitrates and decides whether to fix without asking the user. Decision criteria:
- PRD documentation is the ultimate judge — if the PRD explicitly states something, follow the PRD
- If the PRD doesn't cover it, check existing code behavior before deciding
- Only record items needing confirmation when they involve product direction / business logic tradeoffs; batch-report at the end
Autopilot is not the default — requires explicit user request ("autopilot", "unattended", "run without me").
Post-Arbitration Action Classification
After arbitration, Claude handles each finding by these rules:
Fix directly (don't ask the user):
- Code bugs, compile/runtime errors
- Documentation wording / phrasing contradictions (not direction choices)
- Inconsistencies with explicit PRD decisions
- Security vulnerabilities
Must ask the user (don't skip any):
- Product/business decisions needed (feature tradeoffs, scope changes)
- User-provided information needed (credentials, domains, third-party service configs)
- Choices affecting user experience not covered by PRD
- Cost/budget decisions
In autopilot mode, "must ask" items are accumulated and batch-reported at the end without interrupting execution.
Dual-Model Parallel Review
Each review dispatches two parallel codex exec calls via Bash, one per model:
codex exec -m "gpt-5.4" -s "read-only" -C "$REPO_DIR" \
--skip-git-repo-check --ephemeral \
-o /tmp/codex-review-a.md \
- <<'PROMPT'
[constructed prompt here]
PROMPT
codex exec -m "gpt-5.2" -s "read-only" -C "$REPO_DIR" \
--skip-git-repo-check --ephemeral \
-o /tmp/codex-review-b.md \
- <<'PROMPT'
[same prompt here]
PROMPT
Both calls use the same prompt but different models. Wait for both results before entering arbitration.
For fix mode, only one model executes the fix (default Model A), but the review phase still uses both models:
codex exec -m "gpt-5.4" -s "workspace-write" -C "$REPO_DIR" \
--skip-git-repo-check --full-auto \
-o /tmp/codex-fix.md \
- <<'PROMPT'
[fix prompt here]
PROMPT
To resume a session (for review-fix-review cycles):
codex exec resume SESSION_ID "follow-up prompt here"
The session ID is printed in the codex exec output header (look for session id: xxx).
Arbitration: Claude as Judge
When both sets of findings arrive, Claude processes them in three zones:
Consensus zone — Both models flagged the same issue. Essentially confirmed; adopt directly. If fix suggestions differ, pick the one with harder evidence (file:line + code quote > vague description).
Single-source zone — Only one model flagged it. Claude reads the code to verify:
- Hard evidence (specific line + reproducible logic chain) → adopt
- Soft evidence ("might be a problem" without pinpointing) → downgrade to suggestion, don't force fix
- Claude judges it's a false positive → discard, explain reasoning in output
Conflict zone — Two models disagree (A says problem, B says fine). Claude reads the code and rules. If unresolvable (e.g., business logic judgment), escalate to user.
Output format: Tag each finding with its source — [A+B] consensus, [A] or [B] single-source, [Conflict→Claude] conflict. User sees at a glance which findings are iron-clad vs. single opinions.
Invocation Parameters
-C must be set to the current working directory (Codex needs access to the same codebase).
Don't embed file contents in the prompt — Codex can read files itself. Only provide absolute paths in the prompt and let Codex read them. Save the token budget for review requirements, context, and focus areas.
Use --ephemeral for one-shot reviews (no session persistence needed). Omit it when you plan to do review-fix-review cycles.
Use --skip-git-repo-check when the target directory isn't a git repo.
Maximize initial review input — On the first call, give Codex the full review scope up front. Locating code is the most expensive phase of the first review; specific paths and ranges skip it entirely:
- Required: Complete file path list (not vague like "the marketing-related files")
- Required: Line ranges of interest (
path:line-range) or precise diff range (<base>..<head> commit range / direct patch)
- Required: Hard boundaries — which files/modules are context vs. review targets
- Required: Internal checks already run (lint / typecheck / key grep results), so Codex doesn't repeat them
- Principle: The more specific the file list in the first prompt, the shorter the review runs. Put the detail in the first prompt — don't wait for Codex to ask.
⚠️ Hard constraint — the path list is a locator, not a scope cap:
The prompt must tell Codex explicitly — the file list/line ranges are locators to help you find entry points quickly, NOT a scope lock restricting your review to only these paths. Codex's review must be as comprehensive as possible:
- Follow call chains; inspect files outside the list if they are affected
- Check cross-file side effects, error paths, edge cases — don't constrain yourself to the listed paths
- If you find issues outside the list, report them. Do NOT skip findings with "not in the given scope" reasoning
Include language like this in the prompt:
"The file list above is a locator to save you from scanning the repo from scratch. It is NOT a scope lock. Your review must be comprehensive — follow call chains, inspect files outside the list if they are affected, and report any issues you find there. Do not limit findings to the listed paths."
Prompt Construction
Before constructing the prompt, assess the scenario and read the corresponding reference file:
| Scenario | Reference |
|---|
| Security audit (full scan) | references/security-audit.md |
| Security-sensitive (auth/payment/data/crypto) | references/code-security.md |
| Non-code (docs/config/prompts) | references/non-code.md |
| Other | references/general.md |
| Before every prompt | Scan references/experience-log.md for known pitfalls |
XML Block Structure
All prompts sent to Codex use XML blocks, each with a fixed responsibility:
| XML Block | Purpose | Principle |
|---|
<task> | Define the task and review objective | One run = one task, no mixing |
<context> | Code/content/diff/project background | Facts only, no judgments; paths for Codex to read |
<instructions> | Review dimensions + per-finding output format | Require evidence: file:line + issue + reason + fix |
<grounding_rules> | Inference vs. confirmation boundary | Inferences must be labeled "Inference:"; never stated as confirmed |
<verification_loop> | Anti-rubber-stamp | Final check: each finding is material, supported, reproducible |
<dig_deeper_nudge> | Second-order check list | Guide Codex to check cross-file impact, edge cases, error paths |
<review_coverage> | Review scope declaration | Explicitly state what was and wasn't checked |
<verdict> | Final judgment | Pass / Conditional pass / Fail |
<default_follow_through_policy> | Behavior on missing context | Write "Cannot verify: [reason]" when uncertain; don't guess |
<action_safety> | Fix mode only | Restrict change scope, no unrelated refactoring |
Block selection by mode: review/audit must include grounding_rules + verification_loop + dig_deeper_nudge + review_coverage + verdict; fix mode adds action_safety, removes dig_deeper_nudge.
Anti-rubber-stamp: If either model returns "No issues found", check review_coverage scope adequacy. If scope is too narrow, do one more round. Both models say clean + adequate scope → pass.
Review-Fix Cycle
- Claude finishes implementation → constructs prompt → parallel dispatch to both models
- Both findings arrive → Claude arbitrates (consensus / single-source / conflict)
- Adopted findings → Claude fixes
- After fix → parallel dispatch both models again for re-review
- Both pass + adequate review scope → cycle ends
- Max 3 rounds. Beyond 3 → stop and report to user
Re-review prompt (resume session, or new session with diff):
Re-review's bottleneck isn't "finding the entry point" — it's verification. Codex has to confirm every fix actually landed and check for second-order problems. A natural-language summary ("fixed the AuthModal logic") forces Codex to locate code on its own, wasting its most expensive time.
You must provide a "Fix Evidence Index" structured at file:line granularity:
Fixed the previous round's findings. Fix evidence index below:
## Finding → Fix Mapping (finding → file:line → reason, all three required)
Every entry must include all three pieces: **what the finding is + where it landed (file:line) + why this fix**. A bare `file:line` without a reason forces Codex to reconstruct the "root cause → fix" logic chain on its own — defeating the purpose of the index.
- **[Finding-1 title]** → `<path>:<line-range>` [VERIFIED FIXED]
- Reason: <what was done + why this approach; one line connecting root cause → fix>
- **[Finding-2 title]** → `<path>:<line-range>` [VERIFIED FIXED]
- Reason: <...>
- **[Finding-3 title]** → [ACCEPTED — not fixing]
- Reason: <why not fixing: risk/cost/unnecessary, or decided in earlier round>
- **[Finding-4 title]** → `<path>:<lines>` [PARTIALLY FIXED]
- Reason: <what portion was fixed, why the rest is deferred, next-step plan>
(Reason is what Codex uses to judge whether the fix is on-target — not decoration. Without it, re-review either skips verification or spends time re-deriving the fix logic from code. Either way defeats the index.)
> **⚠️ Hard constraint — Reason is Claude's self-report, not Codex's conclusion**:
> The prompt must tell Codex explicitly — **the Reason field is Claude's own claim about the fix rationale (an unverified premise), NOT a fact you can cite as your conclusion**. Codex must:
> - Independently read the code at `<path>:<line-range>` and judge on its own whether the fix addresses the root cause
> - If agreeing with the Reason, produce **its own independent evidence from reading the code** (line number + code quote + reasoning for why this evidence supports the Reason). "Reason looks correct" or simply echoing Claude's wording is NOT acceptable.
> - If disagreeing, state exactly what's wrong and provide counter-evidence
> - ACCEPTED / PARTIALLY FIXED entries also require independent verification of whether the stated justification holds
>
> Include language like this in the prompt:
> > "The Reason field is Claude's self-reported fix rationale — treat it as an unverified claim, not a conclusion. For each VERIFIED FIXED entry, read the code at the stated path:line and produce your OWN independent evidence (line number + code quote + reasoning) for why the fix does or doesn't address the root cause. Echoing Claude's Reason without independent evidence is not acceptable."
## Files Changed This Round
- <path1>: <one-line summary of change>
- <path2>: <one-line summary of change>
(List only files actually touched this round. No vague summaries like "mainly updated marketing files".)
## Diff Range
Commit range: <base>..<head> or patch below
[Optional: inline diff]
## Verifications Already Run This Round
- `<command>`: <key result>
- `<command>`: <key result>
(e.g., `tsc --noEmit`: no errors; `rg "@gsap/react"`: 0 matches)
Please re-review based on this index:
1. For each [VERIFIED FIXED], confirm it actually landed (read the corresponding file:line)
2. Check for second-order issues (did changing A affect B?)
3. Evaluate whether ACCEPTED decisions are reasonable
4. Assess whether PARTIALLY FIXED remainders are critical
Why this format: Real Codex feedback shows ~70-80% of re-review time is spent on "locating and cross-referencing code", only 20-30% on actual thinking. A structured index front-loads the verification paths into the prompt so Codex can jump straight to file:line without translating natural-language descriptions into search targets.
Session Continuity
After each review, report both session IDs to the user:
Model A session: SESSION_ID_A
Model B session: SESSION_ID_B
When to Trigger
Review needed: New features (>=2 files or new functions), refactoring, complex bug fixes, user explicitly requests, high-risk scenarios.
Skip: Typos/naming/comments, single-line simple fixes, formatting adjustments, user asks for quick turnaround.
Interaction Language
- To Codex: match the user's language (Chinese prompt → Chinese review)
- To user: match the user's language