implement-review-57f8a1 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited implement-review-57f8a1 (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A review loop for staged changes. Claude Code detects the content type, sends the changes to one or more reviewers, categorizes the feedback, revises, and iterates. Codex is the primary reviewer via three channels: terminal relay (manual copy-paste, default on every platform), Auto-terminal (opt-in subprocess dispatch), or IDE plugin. The Auto-terminal channel also supports explicit cross-vendor reviewer backends for GitHub Copilot CLI, Claude Code, and Gemini through Antigravity CLI. Other reviewers are driven ad-hoc by the user through their own UI and only need to honor the Review-<AgentName>.md save contract defined in Phase 1c. Reviewer defaults and coordinator rewrites follow Path selection.
Any complex task benefits from a plan review BEFORE execution, not only writing or code. Plan-first catches architectural holes while they are still cheap to fix. The scope includes: system design, refactors, paper outlines, proposal structure, data-pipeline redesigns, multi-stage debugging strategies, teaching / curriculum planning, release-process changes, migration plans, and anything else where the shape of the work precedes and constrains the execution.
Plan-review is a Phase 0 before the staged-change loop below. If the user asks for a plan review, or if the task clearly meets the signals below, do not apply the staged-change prerequisite in Phase 1 yet. Tell the reviewer to read the plan file directly (or paste the plan contents via the terminal path when the reviewer cannot access the file) and critique the design, not git diff --cached. After the plan has no High findings and no new design blockers, execute the work and resume the normal staged-output review flow at Prerequisites / Phase 1.
Signals that the round-trip pays off:
PLAN-<identifier>.md in the most natural location for the task (repo root for code, paper-repo root for Overleaf-style docs, a local scratch directory beside the deliverable for tasks that do not live in git). If the plan lands inside a git worktree, add it to .git/info/exclude so git add -A does not accidentally stage it; outside git, keep it as a clearly named scratch file outside the final deliverable and delete it after review.git diff --cached. A reviewer with direct repository access reads the named files once. A snapshot backend (Antigravity) sees only the exported index, so a gitignored plan, an untracked evidence note, or an untracked local override is pasted into the request once, each under a --- SUPPLIED INPUT: <path> --- heading that names its source path; the reviewer reads the supplied copy and never the original worktree. Use the normal "Save your complete review to Review-<AgentName>.md" save-contract from Phase 1c.Plan-review must be adversarial about plan purpose and shape, not about low-probability edge cases. The single biggest plan-review failure mode in this maintainer's history was not "the plan had a bug" — it was "the plan's scope was over-conservative, deferring user value across an extra release cycle worth of process tax." Examples:
v0.5.7 = ref bump only; defer compact to v0.6.0) → the user's real projects would have stayed on large AGENTS.md files for another release cycle. The apparent product ask was a one-line bundled manifest flip, but existing-consumer delivery also required bundled-default drift detection in aa plus real-project upgrade tests. The scope challenge should force reviewers to price both parts: user value now, and the smallest code path that actually delivers it.The plan-review prompt must instruct the reviewer to take an explicit position on:
Plan-review must not default to "no blocker, ready to implement" on the first round when scope is multi-axis or when the plan defers a user-facing axis. The reviewer must either raise a scope challenge OR explicitly state why the scope is calibrated. Skipping the explicit position on these three questions counts as an incomplete review.
Anti-patterns the reviewer must NOT pursue:
The Phase 1c prompt template Scope-challenge focus: line below carries this contract into every plan-review send.
The point is not which category -- it is whether the shape of the work precedes and constrains the execution.
In the agent-config 0.1.9 release cycle, two plan-review rounds caught a High-severity design flaw before implementation. The later execution-review rounds were limited to documentation and test polish, avoiding a likely post-ship hotfix.
Three paths to Codex are supported. Default is Terminal-relay (manual copy-paste). Auto-terminal (codex exec subprocess) is opt-in via the trigger rules in Path selection below. Plugin is user-initiated. The skill picks the channel based on those rules.
The user has a Codex interactive terminal window open alongside Claude Code. Claude Code prepares a copy-pasteable review prompt (summary, diff, lens, round number) and presents it as a fenced text block. The user copies it into the Codex terminal, then relays the feedback back to Claude Code.
When the user opts in via the trigger rules in Path selection below, Claude Code dispatches Codex via codex exec --sandbox danger-full-access as a background subprocess (Bash on POSIX, a transient <state-dir>/run-codex.cmd helper invoked through cmd /c on Windows; see the Script contract invariants subsection for the rationale). The dispatch script writes the prompt to a per-dispatch temp file under %TEMP% / $TMPDIR, feeds it on stdin (codex exec -), and emits a state-dir path to stdout for Phase 2 to consume. Codex writes its review to Review-Codex.md per the save contract; the same Phase 1d auto-watch fires on file appearance.
Trust model and the sandbox flag: Auto-terminal aligns its trust model with Terminal-relay by passing --sandbox danger-full-access to codex exec. In Terminal-relay the user is typing into their own Codex window with full fs / network / shell access; in Auto-terminal Claude Code starts the same Codex on the user's behalf, so granting the same access keeps the two channels behaviorally equivalent. The sandbox flag is also a hard requirement for the channel to work on Windows: Codex 0.130.0's default workspace-write sandbox runner hits CreateProcessAsUserW failed: 1312 when Codex spawns its own git / grep / pwsh subprocesses, which makes the review come back as "could not access files" and surfaces through Phase 2.0 Check 7 / 8 / Substance-2 as a tool-sandbox failure. Scope discipline (review-only, save findings to Review-Codex.md, no commits / pushes / branch operations) is enforced at the prompt level, identical to how Terminal-relay enforces it. For CI / shared / multi-tenant environments where this trust posture is too broad, set CODEX_DISPATCH_SANDBOX to a stricter mode (workspace-write / read-only); the dispatch script honors the env var.
Backend permission parity: Reviewer selection changes the model family, not whether the reviewer can validate its claims. Every Auto-terminal backend runs unattended with its backend's broad execution switch: Codex danger-full-access, Agy accept-edits plus --dangerously-skip-permissions, Claude bypassPermissions plus --tools default, and Copilot --allow-all. Each may run tests, experiments, benchmarks, shell commands, and necessary network verification. The review prompt, not a crippled tool allow-list, keeps commit, push, publish, external-system mutation, and destructive cleanup out of scope. Agy and Claude perform potentially write-producing verification in disposable staged snapshots when export succeeds, so ordinary experiment artifacts do not touch the source checkout.
The primary Auto-terminal dispatch preserves the byte-identical prompt invariant with Terminal-relay: the assembled prompt bytes are the same regardless of channel. The extra -c developer_instructions=... value is a Codex CLI configuration argument, separate from the review prompt on stdin, so it does not change those bytes. The dispatch script must NOT call codex exec review, codex exec review --uncommitted, or any other Codex exec subcommand, because those carry Codex's own built-in review prompt template which would compete with the skill's lens-aware prompts. The embedded-diff retry described below is the explicit exception: it is used only after a health-checked Auto-terminal run shows that Codex's own shell tool cannot inspect the repo, usually because CODEX_DISPATCH_SANDBOX has been narrowed in a CI / sandbox-strict environment, but also for the same class of failure if a future Codex version regresses under the relaxed default sandbox.
The Auto-terminal path requires codex on PATH. Probe before dispatch; if absent, warn and take the next probed entry of the Phase 1c failover queue, reaching Terminal-relay only when none is available. Phase 1c's backend-probe step is the single authority for a backend that is absent, as its failover paragraph is for one that failed. A non-zero codex exec exit, a timeout, or a stdin-pipe failure (rare on Windows with PowerShell quirks or Bitdefender input-stream interception) is a confirmed failure; route it through the failover queue in Phase 1c, which is the single authority for that destination. Do NOT add a truncated positional-argument fallback, which would break the prompt invariant. Sticky downgrade applies session-wide once that queue is empty: subsequent rounds default to Terminal-relay until the user re-opts-in explicitly.
Auto-terminal has no incremental-checkpoint guarantee. The save contract requires a complete per-round review published atomically, but it does not require intermediate checkpoints. The Codex dispatcher snapshots the prior review mtime and propagates codex exec's exit code, and it does not validate that a fresh review was published. A child that exits 0 without saving therefore leaves <state-dir>/tail and no fresh review, which Phase 2 health checks 1 through 3 reject as missing, stale, or wrong-round. That rejection costs a full Codex run.
Configuration boundary: the dispatched Codex inherits only the `model` of the user's `config.toml`. Under the default MCP isolation, the dispatch script passes --ignore-user-config and re-passes -c model=<M> and -c model_reasoning_effort=$CODEX_DISPATCH_REASONING. M is CODEX_DISPATCH_MODEL when set. Otherwise it is the top-level model in $CODEX_HOME/config.toml (default ~/.codex), so a model switch there reaches reviews without a repository edit. Failing both, it is the Codex model AGENTS.md names. A config value counts only when it is quoted and made of A-Za-z0-9._:/-. Under a top-level model_provider other than openai, the config model is set aside too: isolation drops that provider, and its model names would reach the default one. Such a setup needs CODEX_DISPATCH_MODEL or CODEX_DISPATCH_ISOLATE_MCP=off. <state-dir>/review-model records the model and which source won. Reasoning defaults to xhigh. Independently of that isolation choice, every dispatch passes a separate -c developer_instructions=... argument telling the child reviewer to skip bootstrap and shared configuration refresh commands and to use the configuration already on disk. The child reads the injected AGENTS.md chain (Codex discovers one instruction file per directory: AGENTS.override.md, then AGENTS.md; it does not discover AGENTS.local.md or agents/codex.md on its own), and Codex injects at most project_doc_max_bytes of it, a 32 KiB default that a composed consumer file exceeds. Every dispatch therefore also passes -c project_doc_max_bytes=262144, outside the isolation branch, so the whole file reaches the reviewer with isolation on or off; a value set in ~/.codex/config.toml alone would not survive --ignore-user-config. All project instructions in that file, including the agent-style banned-word list and any NSF rules, remain in force. Everything else in ~/.codex/config.toml is dropped for the dispatched run: model_reasoning_effort, service_tier, [features].fast_mode, a profile's settings, and any custom provider settings. The MCP-isolation fix drops these settings on purpose, which is easy to miss. Under default isolation, the reasoning setting in config.toml does not reach reviews. Set CODEX_DISPATCH_MODEL or CODEX_DISPATCH_REASONING to change a review. To hand the dispatched run the full user config instead, set CODEX_DISPATCH_ISOLATE_MCP=off, which is the documented opt-out and also restores the user's MCP servers and plugins.
Reasoning effort is a one-way ratchet: xhigh is the floor, not a target. The dispatching agent may raise a single round to max by passing CODEX_DISPATCH_REASONING=max on that dispatch when it judges the change under review hard enough to earn deeper reasoning: changes that span mirrored copies of one file, touch caching or state lifetime, or would fail silently rather than loudly. It must never pass a value below xhigh. Raising the tier is not free: it roughly doubles wall-clock, so raise the dispatch timeout in the same step, or the round is killed before it writes anything. The asymmetry is deliberate. An agent choosing how hard to review its own work creates a self-grading loop, and its confidence is highest exactly where a quiet error hides. Its discretion therefore runs upward only, so the worst case is a round that was not deepened rather than one that was weakened.
Depth against another round: when the budget would buy either one deeper round or two at the floor, prefer another round while the artifact is still changing. The later round reads the revised state and carries the prior findings with it, so its budget is spent on what the last round actually produced. Raise the tier for the closing round, or when the change is subtle enough that a first read is unlikely to reach it. The relative yield of the two has not been measured, so treat this as a default rather than a finding.
Python interpreter resolution and the verification contract: Before it creates dispatch state or spends a Codex round, dispatch-codex finds a working Python interpreter in this order: ANYWHERE_AGENTS_PYTHON; project .venv or venv; the activated VIRTUAL_ENV; active and discovered conda or Miniforge roots and environments; py -3; then every python3 and python entry on PATH. A configured but broken ANYWHERE_AGENTS_PYTHON is a hard preflight failure. Every candidate must run an isolated probe, return an absolute sys.executable, pass the nonempty-file and non-WindowsApps checks, and execute successfully again through the resolved path. The dispatcher writes the absolute path to <state-dir>/python-interpreter and includes it in the child developer_instructions; the reviewer must use that exact path for Python commands. Resolving nothing at all is a degradation rather than a dispatch failure: the dispatcher warns on stderr, omits the marker file so its absence is unambiguous, tells the reviewer that no interpreter was pre-resolved, and proceeds. The probe exists to keep a reviewer from claiming verification it never ran, and check 10 enforces that independently by refusing a PASS or BLOCK verdict without a VERIFIED status. Reviews also run on repositories whose verification is not Python at all, so a missing interpreter must not make those repositories unreviewable.
PowerShell `7` (`pwsh`) resolution: The probe enumerates PATH only because Codex's tool router shells out to pwsh by name. It rejects a candidate when its path contains WindowsApps or when the file has zero length. This is a structural check rather than an execution probe because a Microsoft Store App Execution Alias succeeds from an interactive shell and fails only under the dispatched spawn context, where it dies with NTSTATUS 0xC0000142 (-1073741502) in about 30 ms and is retried indefinitely. The dispatcher writes a resolved absolute path to <state-dir>/pwsh-interpreter and names it in the child developer_instructions. Finding nothing is a soft degradation that tells the reviewer to prefer bash, Windows PowerShell 5.1 (powershell.exe), or plain git, as it does for a missing Python interpreter. The Copilot and Claude reviewer backends pass no developer instructions today, so they carry neither the Python nor the pwsh probe; extension to those backends is deferred.
Every saved review must include one standalone Verification status: VERIFIED or Verification status: UNVERIFIED line. VERIFIED is permitted only after at least one relevant verification command completed, and Verification notes must list the exact commands and outcomes. A run with no completed verification uses Verification status: UNVERIFIED together with Commit verdict: UNVERIFIED; it cannot issue PASS or BLOCK. Health check 10 rejects an UNVERIFIED status or verdict, a PASS or BLOCK verdict without VERIFIED, conflicting markers, and VERIFIED paired with notes that explicitly report no execution. A caller can therefore distinguish an execution-backed block from an unsupported one: PASS check-10 verdict=BLOCK verification=VERIFIED plus concrete command outcomes is admissible; FAIL check-10 verdict=BLOCK verification=MISSING or FAIL check-10 verdict=BLOCK verification=UNVERIFIED is a hard intake failure. Review formats that give no labeled verdict remain backward compatible in the health check. For a Commit verdict or Plan verdict label, the health check takes the value from anywhere after the label or from the first nonempty line within the next four. A bare Verdict label, including a heading, counts only when its value is the first word, and the next line is read only when the label stands alone.
Embedded-diff retry for Codex tool-sandbox failure (sandbox-strict environments only): With the default --sandbox danger-full-access Codex can inspect the repo directly and this retry path should never fire. The retry exists as a defensive fallback for two cases: (1) CODEX_DISPATCH_SANDBOX has been narrowed to workspace-write or read-only in a CI / shared environment, and Codex hits windows sandbox: runner error: CreateProcessAsUserW failed: 1312 or a similar internal sandbox error; (2) some future Codex version regresses the same class of failure under the relaxed sandbox. Symptom: dispatch exits 0 and Review-Codex.md is fresh, but the review body says Codex could not run git diff --cached or inspect files; Phase 2.0 flags this through Check 7, Check 8, or Substance heuristics. Procedure: retry Auto-terminal once with an embedded-diff prompt before downgrading to Terminal-relay. Generate the diff from Claude Code's shell by running the exact diff command chosen in Phase 1b, and include it after the normal save contract, summary, lens, focus, and prior findings. Mark the round line with this content: Round N (RETRY: codex-exec sandbox blocked tool access; diff is embedded inline below.) Then add this sentence: Do NOT run git diff or any shell command -- use the embedded diff as the source of truth. The retry may be larger than the primary prompt; keep it limited to the Phase 1b in-scope paths and do not include unrelated staged or working-tree content. Run the same dispatch, auto-watch, and health-check sequence on the retry. Important quality caveat: the retry sees only the embedded diff hunks, not the surrounding file context. Treat retry findings as diff-scoped — they are reliable for hunk-self-contained issues (test coverage gaps, naming, in-hunk regressions) but prone to false positives for claims that depend on non-diff code (e.g., a "this is missing X" finding when X actually exists elsewhere in the file). Because of this elevated false-positive rate, Medium findings from a retry-channel review are subject to mandatory Phase 2.5 verification before being applied (see Phase 2.5 trigger). If the retry produces a usable review, proceed with that review under the Medium-verify discipline; if it also fails or only records blocked verification, treat that as a confirmed failure and route it through the Phase 1c failover queue.
Script presence is also required: if any of the dispatch-codex / health-check / stall-watch scripts for the current platform is missing (e.g., Phase B has not landed yet in a given checkout), this path is documented-only — Phase 1c automatically downgrades to Terminal-relay without setting sticky downgrade, because the absence is design state, not a runtime failure. See the "Auto-terminal path (opt-in)" subsection in Phase 1c for the script-presence probe specifics.
Self-review guard: dispatch-codex.{sh,ps1} exits 2 with the message dispatch-codex: refusing to dispatch (orchestrator=codex; self-review) when IMPLEMENT_REVIEW_ORCHESTRATOR is codex (case-insensitive). It also exits 2 when that variable is unset or empty and CODEX_THREAD_ID or CODEX_SESSION_ID is set, which Codex does in its tool subprocesses. Any other orchestrator value proceeds. Phase 1c step 5 tells coordinators to set the variable on every dispatch; a launch that omits it reaches the fallback. The PowerShell check lives in the sibling _codex_guard.ps1 for the same AV reason as _claude_guard.ps1. This guard exists because a Codex coordinator must never dispatch Codex. On a case-insensitive filesystem, the dispatch-Codex.sh named by a skill copy with Claude rewritten to Codex resolves to dispatch-codex.sh.
The Auto-terminal channel has a second dispatch backend that runs GitHub Copilot CLI as the reviewer instead of codex exec. It exists for the agent-fungibility case in AGENTS.md § "Agent Fungibility": when Claude Code is unavailable and Codex (or the user) is the primary implementer, Codex cannot review its own work and Claude is absent, so Copilot is the reviewer. It is opt-in only via the triggers in Path selection below.
The backend is a drop-in. Apply the entire Auto-terminal path (opt-in) mechanics below — script-presence probe, prompt assembly, dispatch invocation, STATE-DIR capture, Phase 1d auto-watch, the Phase 2.0 Health checks, Substance heuristics, and Phase 1d coordination — with two substitutions and one probe swap:
dispatch-codex.{ps1,sh} → dispatch-copilot.{ps1,sh}Review-Codex.md → Review-GitHub-Copilot.mdcodex PATH probe → a copilot PATH probe (falling back to gh copilot)Everything else is reviewer-agnostic: the STATE-DIR contract, the flags passed to health-check and to await-review (--state-dir, --round, --review-file Review-GitHub-Copilot.md), the stopped-task resolution rule, the silent-advance gating, and the downgrade / sticky-downgrade rules are identical. The save contract already normalizes GitHub Copilot → Review-GitHub-Copilot.md (Phase 1c), so Phase 2 intake needs no change.
Copilot-specific dispatch details, all handled inside dispatch-copilot (no caller change):
dispatch-copilot re-executes from a private temp copy. It uses the shared IMPLEMENT_REVIEW_DISPATCH_REEXEC sentinel and IMPLEMENT_REVIEW_DISPATCH_SOURCE_DIR source-directory handoff, removes the copy after exit, and propagates the child status. Preflight and the main run still resolve stall-watch from the deployed source directory.-p "@<prompt-file>"; Copilot reads the file as its prompt. A long literal -p argument fails, so the file reference is mandatory -- this replaces Codex's exec - stdin feed.copilot; fall back to gh copilot when copilot is not on PATH. Override with COPILOT_BIN / GH_BIN.--allow-all grants tools, filesystem paths, and URLs without confirmation, while --no-ask-user keeps the run unattended. This matches the verification capability of the other Auto-terminal reviewers, including shell experiments and current-fact checks. Scope discipline remains prompt-enforced: review and verify, but do not commit, push, publish, mutate external systems, or run destructive cleanup. Copilot writes Review-GitHub-Copilot.md itself per the save contract, exactly as Codex writes Review-Codex.md.GIT_PAGER=cat is set so Copilot's own git diff does not stall on a pager.COPILOT_PREFLIGHT=auto, each dispatch first sends a small live prompt that runs git --version and must return COPILOT_PREFLIGHT_OK before the full review starts. This checks the stored credential, network path, JSON stream, and git-shell permission. It costs one small Copilot request per dispatch because Copilot CLI 1.0.78 exposes no non-interactive auth-status command. COPILOT_PREFLIGHT=force applies the same check to a wrapper; COPILOT_PREFLIGHT=off skips it.--no-ask-user --no-auto-update --stream on --output-format json --no-color keep the run unattended and expose live tool events to stall-watch and postflight. --no-auto-update prevents an in-flight CLI self-update.COPILOT_PREFLIGHT=force, a tool permission denial or known authentication or shell-runner failure rejects the review with exit 70. A nominally successful run also exits 70 unless the expected review file exists, is at least 500 bytes, starts with the exact <!-- Round N --> marker, and has an mtime strictly newer than both dispatch start and any pre-dispatch copy.Copilot inspects the repo directly, so there is no embedded-diff retry unique to Copilot; the same Phase 2.0 checks apply with the review-file name swapped.
The Agy backend gives the review loop an independent Google model family. It runs the official Antigravity CLI in headless mode. Use agy as the canonical reviewer token because it names the CLI and is fast to type; gemini and antigravity remain accepted aliases. When IMPLEMENT_REVIEW_DEFAULT_CHANNEL=auto, /vet agy is the complete invocation. With no reviewer token, the Auto-terminal default is Codex unless IMPLEMENT_REVIEW_DEFAULT_REVIEWER names others.
Dispatch uses <python> dispatch-gemini.py --prompt-file <path> --round <N> --expected-review-file Review-Antigravity.md. The script is cross-platform and handles these details:
ANTIGRAVITY_BIN, then agy on PATH. On Windows, also check %LOCALAPPDATA%\agy\bin\agy.exe, because an installer updates the user PATH registry but cannot update an already-running Claude Code process.gemini-*-argon-high the signed-in account lists, at high effort, the highest tier Antigravity CLI 1.3.4 lists for Argon. DEFAULT_MODEL (gemini-4-argon-high) is a family template. The preflight's agy models listing supplies the newest Gemini Argon version in the high tier, so a new Argon release is picked up without an edit. An account that lists no Argon model falls back to the newest Gemini Flash (FALLBACK_MODEL, gemini-3.8-flash-high), recorded as a MODEL-FALLBACK ... reason=template-unlisted line on stderr. When ANTIGRAVITY_DISPATCH_EFFORT is unset, the effort follows the chosen slug's tier, because Agy rejects a conflicting --effort. A MODEL-RESOLVE from=... to=... line on stderr records the switch. With ANTIGRAVITY_PREFLIGHT=off there is no listing, and the template runs as written. A model named in ANTIGRAVITY_DISPATCH_MODEL runs verbatim and never falls back; ANTIGRAVITY_DISPATCH_EFFORT overrides the effort. Argon replaced Flash after a 2026-10 replay of seven saved paper-review rounds, scored against the Codex review of each. In that replay, Argon high matched the Codex verdict in 3 rounds and Flash in 2, and Argon raised no false block on the control round. It still passed 4 of the 6 rounds Codex blocked, so it stays the second reviewer. Seven rounds are routing evidence only.<python> dispatch-gemini.py --print-model prints the slug and effort a round would run on, separated by a space, then exits. It needs no staged diff and applies the same environment overrides and preflight; a preflight failure exits with the code a dispatch would return. A skill that calls Agy directly passes those two values as --model and --effort, which keeps its reviewer on the /vet agy model. Without --model, Agy uses its interactive default model instead.ANTIGRAVITY_PREFLIGHT=auto checks agy --version, agy models, authentication, and exact model availability before spending a review request. force has the same behavior for wrappers; off skips it. ANTIGRAVITY_PREFLIGHT_TIMEOUT_SECONDS defaults to 60.<state-dir>/staged-snapshot, appends git diff --cached --no-ext-diff to a relay prompt, and runs Antigravity with --mode accept-edits --dangerously-skip-permissions --add-dir <staged-snapshot>. Agy's tool shell starts in its own scratch directory even when the process cwd points elsewhere, so the relay names the exact snapshot path as the place for source-file tools and verification commands and requires shell commands to change to it first. The relay also states that the embedded diff is the review input, so the reviewer does not obtain a second copy from the snapshot or git diff, and that unrelated .gemini and .system_generated material is skipped. Gemini can run tests, experiments, benchmarks, shell commands, and network verification, including tools that create normal generated artifacts inside the disposable snapshot. It must not recreate files from the embedded diff if snapshot access fails; that condition is a blocked verification. The prompt still forbids commit, push, publish, external-system mutation, and destructive cleanup. Gemini is never given the original worktree as an added directory: an unsuccessful diff capture, Git-root lookup, or snapshot export aborts the dispatch and records the reason in git-diff.stderr. The export runs under a per-command core.longpaths=true, because the state-dir prefix plus a long indexed path crosses the 260-character Windows limit and the export then fails with Filename too long. The whole index is exported on purpose: the snapshot has to stay a working copy the reviewer can run the repository's own verification inside, not only the changed files.PLAN-*.md, an untracked evidence note, or an untracked local override never reaches it. The coordinator pastes each such input into the request once under a --- SUPPLIED INPUT: <path> --- heading (plan-review step 3); the relay tells the reviewer to read those copies and never the original worktree, and supplied policy stays distinct from repository material, which the relay treats as untrusted.--input-format stream-json --output-format stream-json; it never becomes a Windows command-line argument. ANTIGRAVITY_DISPATCH_TIMEOUT_SECONDS defaults to 2700 and is passed as --print-timeout.Review-Antigravity.md. Stdout remains the single STATE-DIR <abs-path> line; model events and errors stay in tail and tail.stderr-tmp.SUCCESS is rejected with exit 70, unless the recovery below applies. A missing or blank status keeps the legacy success behavior. Antigravity exits 0 when it stops on a quota limit, and that event still carries the model's opening narration, which would otherwise become the round's review. The recovery covers a response with review structure. That structure is this round's marker on its own line, followed by a standalone Verification status: line and a labeled verdict, the lines the health check reads. Lines inside closed triple-backtick blocks or single-line inline code do not count, the same exclusions the health check applies. A tilde fence or an unclosed fence is not recognized as quoted code. A server error such as UNAVAILABLE (code 503) can end a run after the review is written, and on 2026-09-15 four finished reviews were discarded that way. Such a response is published, and the dispatcher names the error on stderr and in <state-dir>/backend-failure. The structure makes a recovery candidate. It is not a complete Markdown parse, and it does not show the findings are finished. Check 8 therefore warns whenever backend-failure is present. Phase 2 reads the error reason and inspects the recovered review for placeholders, narration, and truncated findings before accepting its verdict.STALL at 600 seconds, or ALIVE from await-review, is expected in that window. Keep waiting until the round deadline.stall-watch starts with its working directory inside the state directory, not the reviewed repository. If the dispatcher disappears, the watcher uses its existing identity-checked parent/worker contract. Silence alone still never kills a reviewer.IMPLEMENT_REVIEW_ORCHESTRATOR=agy, gemini, or antigravity. Path selection must rewrite that case to Codex before dispatch.The old gemini CLI is not this backend. Personal Google AI Pro and Ultra subscription access is routed through agy; using a Gemini API key or a Google Cloud project is a separate billing path.
A second cross-vendor backend mirrors the Copilot one with the reviewer swapped: Codex (or the user) implements, headless Claude Code (`claude -p`) reviews. Use when Claude is preferred as the reviewer voice, the human orchestrator runs Codex as the primary implementer, or fungibility scenarios where Codex cannot self-review and Copilot is absent. The Claude backend is opt-in only, through Path selection.
Self-review guard (mechanical). Path selection treats the invoking runtime as authoritative. When this skill is running inside Claude Code, the orchestrator is claude; /implement-review auto claude is rewritten to Codex (or Copilot if Codex is unavailable on PATH) BEFORE any dispatch-claude script is launched, with one user-visible line: Claude backend skipped: Claude Code cannot review its own implementation; using <backend> instead.
The script-level guard in dispatch-claude.{sh,ps1} enforces the same refusal for direct callers that bypass SKILL.md path selection. The scripts exit 2 with the message dispatch-claude: refusing to dispatch (orchestrator=claude; self-review) when ANY of these holds:
IMPLEMENT_REVIEW_ORCHESTRATOR=claude (case-insensitive), ORIMPLEMENT_REVIEW_ORCHESTRATOR is unset/empty AND CLAUDECODE=1 (Claude Code's documented subprocess marker, set in Bash / PowerShell / hook / tmux / status-line subprocesses).IMPLEMENT_REVIEW_ORCHESTRATOR=codex and IMPLEMENT_REVIEW_ORCHESTRATOR=user proceed regardless of CLAUDECODE. The CLAUDECODE=1 fall-through exists so a direct script launch from a Claude Code session without setting IMPLEMENT_REVIEW_ORCHESTRATOR does not bypass the guard. The path-selection rewrite + script-level env exit together make the refusal mechanical at both layers; prose alone is not enforceable.
Dispatch detail mirrors the Copilot backend with a relay-save variant:
claude on PATH (override via CLAUDE_BIN); no fallback binary.dispatch-claude re-executes from a private temp copy. IMPLEMENT_REVIEW_DISPATCH_REEXEC prevents a loop, and IMPLEMENT_REVIEW_DISPATCH_SOURCE_DIR retains sibling-script lookup at the deployed source directory. The wrapper removes the copy and propagates the child exit status.CLAUDE_PREFLIGHT=auto (the default) runs claude auth status --json for the official CLI and skips opaque wrappers. API-key, gateway, Bedrock, Vertex, Foundry, and bare modes use claude --version as an availability probe because first-party login state does not describe those credentials. force applies the probe and strict postflight checks to a wrapper; off skips the probe. CLAUDE_PREFLIGHT_TIMEOUT_SECONDS sets the positive-integer timeout, default 60 seconds. A rejected preflight exits 70, or 124 on timeout, before a model request is sent.claude -p --permission-mode bypassPermissions --tools default --add-dir <staged-snapshot> --setting-sources project,local --effort max --strict-mcp-config --mcp-config <state-dir>/empty-mcp-config.json --output-format text. This gives Claude the same unattended test, experiment, shell, write-tool, and web-verification capability as the other reviewers. The empty MCP config is still required for cross-agent review: a user-level Codex MCP server must not auto-start inside the Claude reviewer backend, or the reviewer can recurse into Codex and hang with empty output. Excluding user settings also keeps user-level hooks out of the headless review path. It also drops the effort set in their env block. Without another applicable effort setting, the reviewer would use the model's default, so the dispatcher passes --effort max. The flag requests max review effort; CLAUDE_CODE_EFFORT_LEVEL in the environment or an effort cap can change the applied level. CLAUDE_DISPATCH_BARE=1 may opt into --bare only in environments that provide ANTHROPIC_API_KEY or an explicit apiKeyHelper; do not enable it by default because Claude Code 2.1.153 disables OAuth and keychain auth in bare mode. No --sandbox flag (Codex-only). The long prompt is fed via stdin (POSIX redirection; PowerShell ProcessStartInfo.RedirectStandardInput, avoiding ARG_MAX), but dispatch-claude first wraps it in a relay prompt. This embedded diff covers every staged path, because the dispatcher has no scope argument; use the Claude backend only when the entire staged set is in scope. The dispatcher exports the Git index to <state-dir>/staged-snapshot with git -c core.longpaths=true checkout-index -a, which keeps the export from failing on a path past the 260-character Windows limit, and launches Claude from that directory; if export fails or the directory is not a git worktree, it falls back to the original working directory and records the reason in git-diff.stderr. The relay permits tests and experiments, including generated-file writes inside the disposable snapshot, while forbidding commit, push, publish, external-system mutation, and destructive cleanup. The dispatcher writes Claude stdout to Review-Claude-Code.md; stderr remains in <state-dir>/tail.stderr-tmp for diagnostics. On save, the dispatcher trims any preface before <!-- Round N -->; if Claude omitted the marker, the dispatcher inserts it so Phase 2 intake has a stable first line. --strict-mcp-config plus the empty MCP config keeps user MCP recursion isolated without reducing built-in verification tools. PowerShell side note: dispatch-claude.ps1 decomposes its self-review env-check into a sibling _claude_guard.ps1 helper alongside it. Some Windows AV products (e.g., Bitdefender) score the combination of env-check + stderr-write + non-zero exit + cmdBody construction in a single .ps1 as a malicious-orchestration signature and AMSI-block the file at parse time. Splitting the guard into a tiny helper file decouples the two patterns and clears the block on a typical Bitdefender install. dispatch-claude.sh keeps the guard inline because POSIX AV scanners do not have the same heuristic.<state-dir>/tail and <state-dir>/tail.stderr-tmp while Claude is running, so stall-watch sees liveness before process exit. After a nominal exit 0 from an official or forced run, known authentication, API, stream, connection, timeout, rate-limit, and overload errors in stderr write <state-dir>/transport-failure, reject the review, and exit 70.chatgpt.com/backend-api/codex/responses error followed by Codex's tokens used trailer. Claude's --output-format text stream has no equivalent terminal record, so that immediate classifier was not ported. Claude uses the stderr transport postflight after process exit. The shared watcher still records 600 seconds of silence and performs identity-checked reaping when the dispatcher exits.Review-Claude-Code.md. Phase 1c name normalization already maps Claude Code to Review-Claude-Code.md; Phase 2 intake needs no change.State-dir, stdout contract (STATE-DIR <abs-path> single line), state files (pre-mtime / timestamp / tail / tail.stderr-tmp), and the stall-watch launch match the shared dispatch contract. For Claude, tail growth supplies liveness; the Codex-only terminal suffix is not a Claude completion record.
Scope: This subsection applies only when Codex is the coordinator and Claude Code is the current reviewer. It overrides conflicting waiting instructions below only for that pair, in Codex App or Terminal. Other coordinator/reviewer pairs keep their existing dispatch, waiting, health-check, and failover behavior. In a mixed /vet claude agy queue, apply this subsection to the Claude slot only; handle the Agy slot under the existing rules. Under Codex, /vet both resolves to that queue.
Start dispatch-claude through a resumable exec tool and retain its handle and emitted STATE-DIR. Claude's text output can stay empty until the final response. Empty tails, ALIVE, and a pre-publication STALL therefore leave this review pending, even after 15 minutes. A tool yield or expired wait window does not establish reviewer failure. Do not conclude the review, drop the Claude slot, or cancel the dispatcher/reviewer merely to end the turn, including through terminate: true, Ctrl-C, or kill. Coordinator cancellation is not a backend failure that permits Single-source completion.
Low-token waiting: Prefer a confirmed native completion notification if the host provides one. Otherwise keep the turn open and wait directly on the retained Claude dispatcher session with empty-input write_stdin; it returns on success or failure, including failure without a report. Before the first wait, use await-review.py --timeout 0 with this dispatch's state directory, round, and absolute Review-Claude-Code.md path to establish the original deadline. Request yield_time_ms=180000 when supported and permitted by host instructions, capped by the remaining round budget and any smaller tool or host limit. Output or completion can return early, so this is a maximum wait window, not a fixed three-minute delay. If an outer execution cell yields earlier, retain and resume that cell without terminating it. On each completed tool wait, consume any dispatcher exit status first: a non-zero exit is a confirmed failure under the existing routing; exit 0 requires the existing report and health checks. While the dispatcher is still pending, make one brief await-review.py --timeout 0 check for publication or the deadline, then continue the same dispatcher handle unless a documented checkpoint is reached. ALIVE never overrides an observed dispatcher exit. If the handle is lost, use Phase 1d's existing resolver recovery, with the original deadline. Do not wait exclusively on a long-running resolver: it cannot observe a dispatcher exit without publication. Do not add a fixed sleep, reread growing logs, or repeat unchanged progress messages. Quiet waiting generates no model tokens; returning to the model still costs tokens. Codex documents a default 300000 ms ceiling for empty terminal polls in the configuration reference; the actual exposed tool and host instructions control the usable window.
If the user selects scheduled background monitoring and this host exposes thread heartbeats, use the requested interval instead of concurrent active-turn polling. Confirm registration and save the repository, round, Claude state directory, original deadline, reviewer queue, and unconsumed tool handles before returning an explicitly pending status. Each wakeup uses await-review.py --timeout 0 and consumes available dispatcher completion status. Stay quiet on unchanged ALIVE or STALL. Heartbeats are an optional host-specific handoff; do not assume Terminal provides them or promise automatic resumption without a registered mechanism. A background hook alone cannot provide that handoff: its completion does not start a new turn.
DONE or resolver REVIEW-READY permits reading the current Claude report and running the existing Phase 2 checks. In sequential mode, start the next reviewer only after the Claude dispatcher returns or identity-checked evidence shows its worker exited; publication alone is not process-completion evidence. In parallel mode, launch the other reviewer after the memory check without waiting for Claude's dispatcher to exit. Consume any available dispatcher exit before marking the Claude slot complete, and route a non-zero exit through the existing failover queue. Preserve the existing health checks and warning checkpoints. A pre-publication silence warning is not permission to abandon the reviewer; assess any saved stall warning after publication under the existing health-check rules. A published report or exit 0 alone is not a final review conclusion.
Use the original 60-minute Phase 1d deadline unless the user specifies another budget, with no shorter harness kill timer. Pass a custom --round-budget on the first resolver call, before its immutable deadline is stamped. Preserve the deadline across tool yields and scheduled wakeups. At TIMEOUT or REAP-UNKNOWN, report the specific incomplete state and pause scheduled monitoring; do not kill the reviewer or invent a new deadline. A user-requested stop also pauses monitoring without treating silence as failure. Stop monitoring this Claude slot after its result is handed to the existing intake/queue flow; do not change how that flow runs the other reviewers.
Codex runs as an IDE plugin with direct access to the repo. The user tells Codex to review in the plugin sidebar (e.g., "review the staged changes"). Codex can see the repository and run the exact diff command chosen in Phase 1b, so no diff needs to be copy-pasted. Plain git diff shows the working tree against the index rather than the staged patch this skill reviews. The user relays Codex's feedback back to Claude Code.
IMPLEMENT_REVIEW_DEFAULT_CHANNEL is set (case-insensitive) to auto, cli, or auto-terminal, the synonyms the slash args accept, Auto-terminal becomes that user's default and no per-invocation opt-in token is needed. Read the variable once at Phase 1c entry. It is a per-user, per-machine setting, deliberately not a change to the shipped default. Claude Code reads it from the env block of ~/.claude/settings.json, and Codex from [shell_environment_policy] set in ~/.codex/config.toml. Agy has no such setting and sees only the environment it was started in.codex PATH probe and the dispatch-script presence check still run, and a failed probe still routes through the Phase 1c backend-probe step.IMPLEMENT_REVIEW_DEFAULT_REVIEWER, read and set the same way, supplies the reviewer tokens when the invocation names none: both, or any of codex, claude, agy, and copilot, space-separated and case-insensitive. The item 2 rules then apply as if it had been typed, so both resolves against the coordinator. A reviewer token in the invocation wins. Unset, empty, or unrecognized keeps Codex, and an unrecognized value adds a clause to the channel line./implement-review cli, /implement-review auto, and /implement-review auto-terminal are equivalent synonyms; auto is the most natural keyword and is accepted.When .claude/commands/implement-review.md forwards slash arguments through Command arguments from the slash invocation: $ARGUMENTS, evaluate that forwarded argument string the same way as the original slash invocation. Manual override tokens still win before Auto-terminal opt-in tokens.
cli mode, use cli, auto codex, use codex exec, AND no negation word (do not, don't, no, not, avoid, manual) within 4 words before the matched phrase.agy, gemini, or antigravity, use dispatch-gemini.py and expect Review-Antigravity.md. The canonical invocation is /vet agy; /vet gemini, /vet antigravity, the compatible /implement-review forms with auto or cli, and plain phrases such as use agy as reviewer, use gemini as reviewer, or review with antigravity are aliases under the same negation guard. A reviewer token does not need an auto token when Auto-terminal came from IMPLEMENT_REVIEW_DEFAULT_CHANNEL=auto. If the orchestrator is Agy, Gemini, or Antigravity, rewrite to Codex before dispatch and state why.tokens are a set rather than a single choice. When the invocation names more than one, dispatch each named backend for the same round. both selects the two backends from claude, codex, and agy that are not coordinating. Under Claude Code it is codex agy, under Codex claude agy, and under Agy codex claude. Any other coordinator gets codex agy. Resolve both using the coordinator identity passed to dispatchers in Phase 1c step 5. Do this before the self-review rewrites in the other reviewer-backend items. The resolved pair excludes the coordinator, so those rewrites leave it unchanged. When both includes Claude, Auto-terminal requires every staged path to be in scope; see Phase 1b. both means that pair specifically rather than every backend that exists, so Copilot is never part of it; name the tokens explicitly for any other combination. An invocation or plain phrase naming the resolved pair is equivalent to /vet both under the same negation guard. Under Claude Code, examples are /vet codex agy and review with codex and agy. The channel lines name the coordinator and the resolved pair, for example both → claude agy (coordinator: codex). The same token reaches different reviewers depending on who runs the skill, and those lines keep the target visible. Everything downstream already takes a set. The expected reviewer set is the comma-separated normalized list: Codex,Antigravity under Claude Code, Claude-Code,Antigravity under Codex, and Codex,Claude-Code under Agy. Each reviewer gets its own watcher on its exact Review-<Name>.md. Phase 2's multi-reviewer consolidation classifies each finding as Convergent or Single-source. With a single reviewer, nothing here changes.
Dispatch them in parallel when memory allows, one after another otherwise. Before the second dispatch, check available memory. On macOS, multiply the system-wide free percentage from memory_pressure -Q by sysctl -n hw.memsize; Linux reports MemAvailable in /proc/meminfo, and Windows reports FreePhysicalMemory (in KB) through Win32_OperatingSystem. With at least 16 GB available, dispatch the reviewers in parallel. Below that, or when the check fails, dispatch them sequentially. With 4.5 GB free on a 32 GB workstation, two concurrent dispatches were once both killed for low memory, and neither produced a review. Sequential dispatch survived the same conditions.
In both modes the watcher is a wait-for-any helper. auto-watch exits as soon as one file matching its glob appears, so a single watcher over Review-*.md would report the round finished while the second reviewer was still working. Run one dispatch, one watcher and one health check per reviewer, each with that reviewer's own STATE-DIR and its exact Review-<Name>.md rather than the wildcard. Where a later step names a single reviewer, a single DONE, or a whole-round fallback, apply it per reviewer in a multi-reviewer round. A failing reviewer goes through the failover queue while the other slots continue, and consolidation waits for every expected reviewer.
In sequential mode, before launching the next reviewer, require that the previous dispatcher returned, or identity-checked evidence that its worker exited. DONE, REVIEW-READY and a clean health check authorize intake only: all three are computed from the review file's freshness and quietness, and each was reproduced while the worker was still alive, so none of them is a statement about the process. Repeating await-review after REVIEW-READY cannot help, because it keeps returning the same publication result. Where the harness has been lost and termination cannot be established, hold the existing bounded checkpoint and ask, rather than reading REVIEW-READY as permission to launch: a file appearing is not proof the previous worker exited, and launching on that signal alone would defeat the memory sequencing this mode exists for. Phase 1d's DONE instruction resumes Phase 2 immediately for a single-reviewer round. During an unfinished multi-reviewer round it means this reviewer is ready for intake, and in sequential mode the next dispatch is the next step. Advance to Phase 2 only once every reviewer in the round has finished.
Keep the full expected set for consolidation, so Phase 2 still classifies findings as Convergent or Single-source. If a reviewer fails, still run the rest; when the round ends with one healthy current-round source and the others confirmed failed, that source is complete intake, labelled Single-source, and the manual follow-up and direct-paste steps Phase 2 otherwise asks for when several reviewers were expected do not apply, because a confirmed dispatch failure already answers what they ask. Emit one channel line per reviewer so the user can see which backend each round actually reached.
codex, keep the normal dispatch-codex backend and expect Review-Codex.md. This makes the pointer-file hint explicit without changing the no-token default. When Codex coordinates this skill, a codex token or the Codex no-token default is rewritten to the Claude backend before dispatch. If the Claude probe fails, try Agy and then Copilot, skipping any backend whose probe fails. One user-visible line states why. Phase 1c step 5 then sets IMPLEMENT_REVIEW_ORCHESTRATOR=codex on every dispatcher call, so the script-level guards apply.codex exec. Triggers: slash args /implement-review auto copilot, /implement-review copilot auto, or /implement-review copilot; plain phrases use copilot as reviewer, copilot as reviewer, auto copilot, review with copilot, under the same negation guard; and role-reversal wording naming Codex as the implementer and Copilot as the reviewer. A reviewer token does not need an auto token when Auto-terminal came from the user-scoped default. With no reviewer token, Auto-terminal selects Codex or the user-scoped reviewer default. When Copilot is the backend, dispatch uses dispatch-copilot.{ps1,sh} and the expected review file is Review-GitHub-Copilot.md (see Auto-terminal Copilot backend above).dispatch-claude only when BOTH of the following hold: (1) the selected channel is Auto-terminal and the slash args include claude (e.g., /implement-review claude, /implement-review auto claude, or /vet claude), OR a plain phrase matches the patterns use claude as reviewer, claude as reviewer, review with claude, or role-reversal wording naming Codex as implementer and Claude as reviewer, all under the same negation guard on the line above; AND (2) the orchestrator running this skill is NOT Claude Code. A reviewer token does not need an auto token when Auto-terminal came from the user-scoped default. With no reviewer token, Auto-terminal selects the no-token default. Orchestrator detection keys on a single documented signal: when this skill is interpreted by Claude Code, the orchestrator is claude by definition (the skill is running INSIDE the CC session). The script-level dispatch guard separately checks CLAUDECODE=1 so a script launched as a Bash / PowerShell subprocess from a CC session also detects it. When orchestrator is claude and the slash args / phrase ask for the Claude backend, rewrite the selection to Codex (or Copilot if Codex is unavailable on PATH) BEFORE any dispatch script is launched, and emit one user-visible line: Claude backend skipped: Claude Code cannot review its own implementation; using <backend> instead. Pair this with the script-level IMPLEMENT_REVIEW_ORCHESTRATOR / CLAUDECODE=1 exit-2 in dispatch-claude.{sh,ps1} so direct callers that bypass path-selection cannot self-dispatch either. The script-level test covers the four enforceable cases in tests/test_dispatch_claude.py::_DispatchContractMixin guard methods; the path-selection rewrite itself is prose-level (no parser / selector function exists to call), so its verification is the negative live test in Ta~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.