agentleFS
aarontzengaarontzeng/dev-lead/skills/codex-adversarial-review/SKILL.md

codex-adversarial-review

Skill3 starsChanged 7 days agoMITView on GitHub

Run a read-only Codex challenge review of a git diff with `codex exec` and the suite's adversarial framing (the Codex companion's adversarial-review is the fallback), then verify each finding against the code. Use when the user asks for an adversarial or challenge review from Codex/GPT, wants a second opinion on a design or implementation, or needs the review gate after codex-implement.

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 3 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Run the review as codex exec in a read-only sandbox, with the lead's lens wrapped in the suite's adversarial framing …

    line 8
  2. Very specific:

    Before this recipe, complete the frozen-target triage step in dev-lead Phase 2.

    line 90
  3. Very specific:

    Use it only when codex exec is unavailable, and say so in the report.

    line 150
  4. Distinctive:

    If either check fails, stop and report the unexpected mutation before trusting the review output.

    line 216
  5. Very specific:

    Never write scratch files into the frozen target.

    line 223
  6. Distinctive:

    Ask to falsify each property under concurrency, partial failure, retries, stale state, malformed input, and boundary conditions relevant to …

    line 247
  7. Very specific:

    When Codex implemented the change, this review is a fresh context but not model diversity — it does not satisfy the cross-family rule at …

    line 276
  8. Distinctive:

    Treat Codex output as hypotheses.

    line 295

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Codex adversarial review

Run the review as codex exec in a read-only sandbox, with the lead's lens wrapped in the suite's adversarial framing (references/adversarial-framing.md) and the effort set per run. Since 0.6.28 this is the default: in an equivalence test on three frozen targets with known answers (codex-runtime.md, 2026-09-23) it matched or beat the companion's adversarial-review on known-answer recall and false positives, read the base revision in every run where the companion did in fewer than half, and — unlike the companion — takes the effort the roster or triage asks for. The companion stays as the fallback below. This is a challenge review: inspect chosen boundaries, assumptions, failure modes, and trade-offs, not only local defects.

Before the first run of a session

Read references/codex-runtime.md (same directory). It holds the family-level mechanics shared with codex-implement — companion resolution, the --background launcher-output trap, status lying about liveness, the lossy-pipe report loss, report recovery from session rollouts, sandbox limits, and the model/effort plumbing. Every item was paid for with an incident; this file assumes them and covers only what makes a run a review.

Establish an immutable review target

One frozen directory per reviewer, at the exact commit, that nothing else touches — no lead activity inside it. Not "whenever possible": a reviewer reads the WORKING TREE, not your commit. Measured — a round ran mutation testing in the same worktree mid-review and the reviewer opened a CRITICAL on a mutated, non-compiling file it was never meant to see.

Freeze it with the suite's tested helpers instead of hand-rolling the shell; every bug ever found in this step was in a hand-rolled copy. The suite-root resolver and both calls — freeze-target.sh to create it, verify-target.sh before AND after the run — are in dev-lead Phase 2, and the reasoning is in methodology.md §7. Everything below assumes $REVIEW_TARGET_DIR is that frozen directory and $REVIEW_HEAD is the SHA it was frozen at.

Capture the exact base SHA and require a clean review target before launch:

git status --short
BASE=$(git rev-parse HEAD~1)
REVIEW_HEAD=$(git rev-parse HEAD)

For a worktree created by an implement skill, use its recorded BASE. For a single committed change use HEAD~1. Do not review a moving or partially staged implementation; finish and commit first.

For a multi-commit topic branch, BASE is the merge-base — never the branch it targets. BASE=$(git merge-base origin/main "$REVIEW_HEAD"). Writing BASE=origin/main is the natural move and it is wrong the moment the target has advanced past the branch point: the range then carries the author's change plus the reversal of everything the target gained meanwhile, so the delegate reviews other people's commits as if they were the author's.

The same trap hides in the diff spelling, because the two ranges look identical: git log A..B is genuinely "commits in B not in A" and is the range you want, but git diff A..B means git diff A B — not merge-base. Use git diff A...B (three dots) or diff against the captured BASE.

Nothing errors, and the HEAD assertion below still passes — it proves you launched at the right commit, not that the delegate read the right span. Measured: a target 10 commits ahead of the branch point turned a 3-file review into one that also read two other teams' files. Confirm the span before launching, not after:

git diff --stat "$BASE" "$REVIEW_HEAD"    # file list must match the change under review

Launch the review: codex exec with the suite's framing

Compose it with leg-cmd.sh, which emits both steps chained with &&: the builder wraps the brief (the LENS, in $RUN_DIR/prompt.md) in the framing, then codex exec reads the framed prompt from stdin:

Before this recipe, complete the frozen-target triage step in dev-lead Phase 2; the review launcher requires its record for this exact commit.

DEV_LEAD=${DEV_LEAD_ROOT:-$(ls -d "$HOME"/.claude/plugins/cache/dev-lead/dev-lead/* 2>/dev/null | sort -V | tail -1)}
eval "$("$DEV_LEAD/scripts/leg-cmd.sh" codex review --model <model> --effort <tier> \
  --base "$BASE" --target "$REVIEW_TARGET_DIR" --run-dir "$RUN_DIR")" > "$RUN_DIR/review.log" 2>&1

What the script emits, spelled out (for a lead without it): an export RUN_DIR=…, a guard that the brief exists and is not empty, then the builder and the run chained with &&. Nothing else -- the checks under it are the lead's, before and after.

# export RUN_DIR=<the --run-dir, made absolute>   -- emitted first, on its own line
test -n "$RUN_DIR" && test -s "$RUN_DIR/prompt.md" || { echo 'leg-cmd: RUN_DIR unset, or brief empty/missing:' "$RUN_DIR/prompt.md" >&2; false; } &&
python3 "$DEV_LEAD/scripts/review-prompt.py" --adapter codex --base "$BASE" --target "$REVIEW_TARGET_DIR" \
  < "$RUN_DIR/prompt.md" > "$RUN_DIR/framed-prompt.md" && \
codex exec -C "$REVIEW_TARGET_DIR" -s read-only -m "$MODEL" -c "model_reasoning_effort=$TIER" \
  -o "$RUN_DIR/review.md" -- - < "$RUN_DIR/framed-prompt.md"

Around it, the lead runs (these are NOT in the emitted command):

"$DEV_LEAD/scripts/verify-target.sh" "$REVIEW_TARGET_DIR" "$REVIEW_HEAD"   # before: frozen at the right SHA
rm -f "$RUN_DIR/review.md"                                                 # a stale report cannot pass for this run
rc=0; eval "$(…leg-cmd.sh codex review …)" > "$RUN_DIR/review.log" 2>&1 || rc=$?
"$DEV_LEAD/scripts/verify-target.sh" "$REVIEW_TARGET_DIR" "$REVIEW_HEAD"   # after: nothing touched it
[ "$rc" -eq 0 ] || { echo "codex exec exited $rc; see review.log" >&2; exit 1; }
used=$(sed -n 's/^reasoning effort: //p' "$RUN_DIR/review.log" | head -1)
[ "$used" = "$TIER" ] || { echo "effort used '$used', wanted '$TIER'" >&2; exit 1; }
[ -s "$RUN_DIR/review.md" ] || { echo "no review written" >&2; exit 1; }
  • $RUN_DIR lives outside the frozen worktree; $BASE, $REVIEW_HEAD and $REVIEW_TARGET_DIR are set as above. Quote $MODEL: an unquoted <…> placeholder is a shell redirection.
  • The builder (scripts/review-prompt.py, shared by every framed leg since 0.6.30; codex-review-prompt.py is its codex name) substitutes in one pass, so a {{HEAD}} inside the lens stays literal; it refuses an empty lens, an unknown placeholder or an unreadable HEAD, and the && stops the paid run.
  • The prompt goes on stdin (-- -): no argv length cap, a prompt that starts with - stays text (a -s workspace-write first line did not change the sandbox; codex-cli 0.156.1), and codex never waits on an inherited stdin.
  • -C must name a directory inside a git repository; outside one codex prints Not inside a trusted directory … and exits without reviewing.
  • review.md holds the final message only; review.log holds the tool calls and the reasoning effort: header — the only record of the effort that actually ran, and where "did it read the base revision" is checked.
  • codex exec review --base is not a substitute: it refuses a custom prompt together with --base (codex-cli 0.156.0), so neither lens nor framing can ride on it. Inlining the diff into the prompt showed no gain.

The report ends with a plain Verdict: approve or Verdict: needs-attention line, which scripts/leg-log-check.sh accepts; check it before reading.

Fallback: the companion's adversarial-review

Use it only when codex exec is unavailable, and say so in the report. It supplies its own framing and tracks the run as a job, but it has no effort flag: the review runs at model_reasoning_effort from the machine's ~/.codex/config.toml, whatever the roster or triage asked for. Read that value and report it; do not assert one.

Resolve the newest installed plugin without hardcoding a home or version:

REVIEW_WORKTREE=/absolute/path/to/target-worktree
SCRIPT=$(ls -d "$HOME"/.claude/plugins/cache/openai-codex/codex/*/scripts/codex-companion.mjs \
  2>/dev/null | sort -V | tail -1)
[ -n "$SCRIPT" ] || { echo "codex plugin not installed"; exit 1; }

cd "$REVIEW_WORKTREE" && \
  [ "$(git rev-parse HEAD)" = "$REVIEW_HEAD" ] && \
  node "$SCRIPT" adversarial-review \
    --background --base "$BASE" --scope branch --model <model> "$FOCUS"

The identity assertion between the cd and the launch is not decoration — measured: a launch composed without the cd (a stale shell cwd pointing at a DIFFERENT repo) started a real, billed review of the wrong tree, caught only by a human noticing before it finished. An in-command HEAD check makes a wrong target fail loud in milliseconds instead.

Launch under the host's own background mechanism with output redirected to a file, per the runtime's launcher rules (--background does not guarantee a prompt return; a lossy pipe can destroy the only copy of the report).

Running this leg as a subagent? You are a leaf — block, do not "wait". Nothing will wake you when the job finishes; ending your turn on "waiting for the notification" abandons the review. Poll to terminal inside a single tool call, and issue another such call immediately if it times out (dev-lead Phase 2).

Model choice

The exec path takes both --model and the effort: use the roster's review leg, raised to triage's effort for the change when it gives one (the table only raises). The companion fallback takes --model only and runs at the machine's config effort (runtime file has the plumbing). Pick per your calibration journal, with two measured priors:

  • Review is the highest-leverage step — when quota allows, spend the strongest tier here rather than on implementation.
  • Match the model to the ROLE. A fast tier that underperforms at defect hunting produced the deepest finding of a five-round sequence when given the challenge brief ("is this the right approach at all, what assumption is unexamined") — while a stronger model on a sequence brief returned an under-evidenced HOLDS on the same question. When you spend multiple legs, change the brief, not just the model; identically-briefed legs buy redundancy, differently-briefed legs' findings overlapped zero percent.

Omitting --model inherits the user's codex-config default — pass it explicitly rather than inheriting silently.

Both paths run read-only (-s read-only on exec; the companion enforces it); do not add any bypass flag. After the run, verify the review itself changed nothing — verify-target.sh in the block above, or by hand:

test "$(git rev-parse HEAD)" = "$REVIEW_HEAD"
test -z "$(git status --porcelain)"

If either check fails, stop and report the unexpected mutation before trusting the review output.

  • Materializing evidence the frozen tree does not contain — another revision's copy, a merge-base baseline — has cross-family rules on where it goes and what guarantees it carries: docs/materializing-evidence.md. Never write scratch files into the frozen target; a leg that genuinely cannot keep them elsewhere declares those exact paths to verify-target.sh instead.

Write a useful focus prompt

The framing already tells the reviewer to read every touched file at the base revision with nl -ba, to stay read-only (no tests, builds, MCP or external tools), to separate introduced from inherited defects, to check whether a later check mitigates a hazard, to answer each posed claim with HOLDS / BROKEN / NOT REACHED, and to end with a plain verdict line. The lens you write supplies the rest (on the companion fallback, include all of it):

  • Declare first-party, pre-merge review; do not use third-party attack framing.
  • Require read-only behavior: no edits, commits, pushes, or recursive CLI invocation.
  • Name the claimed properties and the files that implement them — and when the code is a declared approximation (a heuristic, a parser-shaped regex, a best-effort masker), the property must state its BOUNDARY, not just its intent. An unbounded property cannot converge — each round legitimately finds one more case, forever (see docs/methodology.md §5). The boundary belongs in the code's own docstring too, so the reviewer checks declared-vs-actual instead of declared-vs-infinite.
  • Ask to falsify each property under concurrency, partial failure, retries, stale state, malformed input, and boundary conditions relevant to the change.
  • Require each finding to include a trigger, observable consequence, severity, and file:line; ask which claims still hold.
  • State fixes already made so the review targets the current diff.
  • Ask what the tests do not enumerate, in those words: "name any property claimed above that no test actually exercises, and any test that passes for the wrong reason." Measured: that one line produced the most valuable output of its round — a coverage note ("your tests only cover the A→B transition, never A→∅ or ∅→B") that explained why two real defects had survived a mutation-tested, fully green suite.
  • Evidence gate with unguessable anchors (per file: line count + verbatim last line; per claim: quoted code; NOT REACHED acceptable, HOLDS-without-quote not). A file:line alone is not this: a fabricated citation costs a reviewer nothing, which is why the anchor has to be something it could not have guessed without reading.
  • Tell it to read files with nl -ba, not bare sed -n. Measured 2026-09-06: the same account went from 43/50 citations exact to 35/35 on the next round, and the only change was this line in the preamble. Every earlier miss was a 2-4 line shift in the one or two files it had read without line numbers and counted by eye. Costs a word; buys a citation round you do not have to re-resolve.
  • Forbid praise and generic summaries.
  • Tell it NOT to query MCP/memory tools: "the diff and this focus text are the complete context." The reviewer inherits the user's full codex config and, measured, spends its opening turns on tool discovery it then discards; this line skips that for free.

When Codex implemented the change, this review is a fresh context but not model diversity — it does not satisfy the cross-family rule at any risk level (docs/methodology.md §1). Use it as a supplement; the gate reviewer must be non-GPT, and never present two Codex jobs as independent models.

Watching the run and reading the report

The exec path runs in the foreground of whatever backgrounds it: its exit status, review.md and the reasoning effort: line in review.log are the whole record, and a large target can take 10–25 minutes at xhigh (measured, 2026-09-23). The companion fallback is a tracked job with its own traps — all in the runtime file: liveness is log mtime (never status), the two delivery modes, the ~20-minute patience rule around wait tools, truncated captured messages, and the interim-message grep that rescues findings from "empty" rounds. Follow them; do not re-learn them.

Verify and report

Treat Codex output as hypotheses. Verify every finding against the code and, when possible, an executable trigger. Report findings faithfully, identify false positives explicitly, and separate evidence discovered by the host from the reviewer's claims. This skill is review-only: do not apply fixes unless the user asks.

Pairing rule across the suite: the reviewer must come from a different model family than whatever implemented the change. When quota is tight, spend the scarce model on review rather than implementation — review leverage is higher.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.