Grill your plans before implementation
Codex reviews your implementation plan for wrong assumptions, missing files, ordering risks,
security and perf gaps. Claude validates every finding against the real code, edits the plan,
re-presents it via ExitPlanMode.
- CONFIRMED / REFUTED / UNVERIFIABLE
- Loop converges in ≤7 iters
Usage
The plan path is optional in both commands — pass nothing and codexgrill grills the plan
from this session's ExitPlanMode automatically.
One pass. Codex reviews the plan once. Claude validates every finding against real code.
The plan is updated and re-presented via ExitPlanMode.
/codexgrill:plan-once # grills this session's plan
/codexgrill:plan-once path/to/plan.md # grills the given file
/codexgrill:plan-once --effort=xhigh # override reasoning effort
/codexgrill:plan-once --model=gpt-5.4 # override model
Best for fast sanity checks before implementation. One round-trip with Codex, full plan inlined.
Also reachable via the router: /codexgrill:once → pick "Plan validation".
Iterate until clean. Loops Codex review + Claude validation + plan edits until both models agree
the plan is sound, or --max rounds run out.
/codexgrill:plan-loop # grills this session's plan
/codexgrill:plan-loop path/to/plan.md # grills the given file
/codexgrill:plan-loop --max=10 # bump the cap (default 7)
/codexgrill:plan-loop --effort=xhigh # override reasoning effort
/codexgrill:plan-loop --model=gpt-5.4 # override model
Pins Codex to one thread (so context + cache are preserved across iters) and sends a
unified diff of plan changes after iter 1 — keeping each later turn small enough for large plans.
Also reachable via the router: /codexgrill:loop → pick "Plan validation".
What you'll see in chat
Verbatim. First-line verdict (SOUND / NEEDS REVISION / FUNDAMENTAL ISSUES), then bulleted findings with severity + path:line citations.
Each finding gets CONFIRMED / REFUTED / UNVERIFIABLE with the exact path:line Claude just read. No memory shortcuts.
An independent fresh-eyes pass from Claude — catches issues Codex didn't flag.
If revisions were needed, the updated plan is shown and re-presented via ExitPlanMode. Otherwise the original goes through.
How it works
Two models, working against each other. Codex tries to find faults; Claude validates each one against the actual code. Disagreements are resolved by reading the file, not by debate.
-
1
Codex reads your plan
The wrapper sends the plan to
codex execwith a strict review prompt. Codex returns findings — wrong assumptions, missing files, ordering risks, security and perf concerns, stale facts. -
2
Claude validates each finding
For every finding, Claude invokes
Readon the cited file. Every claim is marked CONFIRMED, REFUTED, or UNVERIFIABLE — never accepted from memory. Cross-file claims dispatch parallelAgentcalls; external claims useWebSearch/WebFetchagainst primary sources. -
3
The plan is edited
CONFIRMED findings are applied (Claude's chosen action may differ from Codex's fix). REFUTED ones are dropped. UNVERIFIABLE items are flagged to you in chat.
-
4
plan-loop— repeat with a pinned threaditer 1 captures the
thread_idfrom Codex's JSONL stream. Every later iter passes that UUID tocodex exec resume <id>to preserve conversation context and prompt-cache savings. Resume iters send only a unified diff of plan changes plus the path to the current plan file — Codex pulls full context on demand.Falls back transparently to inlining the full plan if the prior snapshot is missing, the diff is empty (no edits this iter), or the diff would be pathologically large (>80% of plan body).
-
5
Re-present via ExitPlanMode
Loop exits when Codex says SOUND and Claude has no remaining findings. The revised plan goes back into plan mode, ready to implement.
Containment & revert
Codex runs with --dangerously-bypass-approvals-and-sandbox because the read-only sandbox blocks
legitimate read commands (git log, grep, etc.) and breaks any serious review.
Two mechanisms enforce read-only behaviour anyway.
1. SHA256 working-tree containment
The wrapper hashes every Git-visible dirty + untracked path in the working tree before and after every Codex call. Any change → exit 2 (WORKING_TREE_CHANGED), loop halts, you decide what happened.
2. Prompt-level read-only contract
The review prompt's <action_safety> block explicitly tells Codex that any modification will cause the entire run to be REJECTED and the output discarded.
Scope — what gets checked
The containment hash covers everything except:
- Paths matching
.gitignore— standard git behaviour (git statusandgit add -Aboth skip them). - The wrapper's own
$RUN_DIRartifacts (it's writing those during the run). - A default list of IDE/OS auto-mutating paths:
.idea/**,.vs/**,.vscode/**,*.swp,.DS_Store, etc.
The full list lives in DEFAULT_IGNORED_PATTERNS at scripts/lib/codex-exec.mjs.
Revert safety net
Before each iteration the wrapper builds a content snapshot of the working tree — a single git commit holding
the union of tracked + untracked content, pinned under a permanent ref like
refs/codexgrill/<run-id>/iter-<N>-pre. Built via a temporary index
(GIT_INDEX_FILE), so your real index, working tree, and stash list are untouched.
If something looks wrong, revert with two commands:
git restore --source=<preIterStash.hash> --staged --worktree -- :/
git clean -fd
One known limitation
Originally-untracked files re-appear as staged additions after restore — every file's bytes match the pre-run state, but git status will look slightly different. We chose content fidelity over staging-state fidelity; this matches 95% of "Codex broke something, get the bytes back" use.
Manage snapshots: list with git for-each-ref refs/codexgrill/; remove with
git update-ref -d <ref>.
Run artifacts
Every run drops artifacts under .claude/temp/codexgrill/<run-id>/ (gitignored).
Useful for debugging, audit trails, and replaying what Codex saw.
plan-once runs
| file | description |
|---|---|
prompt.txt | Exact prompt sent to Codex. |
final.txt | Codex's final review message. |
codex.jsonl | Full JSONL event stream from codex exec (every tool call, every reasoning step). |
result.json | Wrapper summary — thread_id, exit_code, token usage, paths, preIterStash hash. |
plan-loop runs
Each artifact above gets an -iter<N> suffix, plus:
| file | description |
|---|---|
state.json | Run state — pinned codex_thread_id, per-iter verdicts, validation counts, unverifiable_items (load-bearing UNVERIFIABLE findings carried per iter for the finalization batch-question). |
refuted-log.txt | Cumulative refutations, prepended to each iteration's prompt so prior REFUTED findings aren't re-raised without new evidence. |
plan-snapshot-iter<N>.md | Verbatim copy of the plan body sent to Codex in iter N. Used as the baseline for iter N+1's diff. |
plan-diff-iter<N>.diff | Unified diff of plan changes vs the prior iter's snapshot. |
Each result-iter<N>.json also records resumePromptMode
("diff" / "full-plan-fallback" / "no-change" / null),
planSnapshotPath, planDiffPath, and planDiffStats
(addedLines, removedLines, planBytes, diffBytes) for observability.
Tuning for large plans
codex exec has no auto-compaction — a single review turn that overruns the per-turn context window
aborts with an error instead of retrying. If you see "Codex ran out of room in the model's context window":
- The most common cause is
model_reasoning_effort = "xhigh"in~/.codex/config.toml. Reasoning tokens count toward the per-turn budget. - Pass
--effort=highto override the config for this run only (one notch belowxhigh— usually frees enough context without giving up reasoning depth). Valid levels:none,minimal,low,medium,high,xhigh. - Or trim the plan body and re-run.
No silent retries
The plugin never auto-retries on context exhaustion or rate-limit errors. It surfaces the diagnostic and waits for your call. No surprise extra spending.
Want a security audit too?
Codex + Claude can also audit your codebase for vulnerabilities. Same safety contract, same loop convergence.