second-opinion
Get an independent model to attack the current work. The value is uncorrelated failure: Codex/GPT was trained differently than Claude, so it catches blind spots Claude systematically shares with itself. This is adversarial review, not consensus voting — a second model agreeing means little (correlated priors); a second model finding a real hole is the whole point.
Claude stays the driver. Codex is an on-call consultant invoked as a subprocess.
GATE — don't fire on routine work
Only worth the round-trip when the work is high-stakes or hard to reverse: a security/money path, a migration, a tricky invariant or proof, a load-bearing refactor, a claim that's expensive if wrong. Routine CRUD, config tweaks, obvious fixes → skip it, say so in one line, move on.
If the user invoked this explicitly, honor it regardless of stakes.
Preflight
command -v codex— if missing, stop and tell the user:npm i -g @openai/codex, then eithercodex login(ChatGPT account) or setOPENAI_API_KEYin your environment.- First run only:
codex exec --help | head -30to confirm the flag names below match the installed version, and adapt if they drifted.
Run
Default target is the uncommitted working diff. Let Codex read the repo itself:
codex exec --sandbox read-only "You are an adversarial code reviewer. Review the uncommitted changes (run 'git diff' and 'git diff --staged') in this repo. Hunt ONLY for: correctness bugs, wrong assumptions, missing edge cases, race conditions, security holes, silent failures. Be concrete: file:line + the exact failing input/scenario. Rank most-severe first. Skip style, naming, and formatting entirely. If you find nothing real, say so — do not manufacture findings."
- Checking something other than the diff (a claim, a design, a specific file)? Swap the target clause; keep the "hunt for holes, be concrete, don't manufacture" framing.
--sandbox read-onlykeeps Codex from editing files — it reviews, Claude decides.- Large diff or Codex can't see it? Pipe explicitly:
git diff | codex exec --sandbox read-only "Adversarially review this diff from stdin: ...".
Reconcile — this is the actual work
Codex's output is an input, not a verdict. For each finding:
- Real + Claude missed it → fix it, credit the catch.
- Real but already handled → note why it's covered, drop it.
- Wrong / hallucinated → say so plainly with the reason. Codex hallucinates too; don't launder its confidence into yours.
Then report to the user, tight: what Codex flagged, which held up, what you changed. Disagreement between the models is the signal — surface it, don't average it away.
Keep it small
This is a subprocess call, not a framework. No multi-model voting, no consensus tally, no wrapper script — if it grows one, it's over-built. One model, one adversarial pass, Claude reconciles.