Auto Review
Run a structured second-model review as a closeout check before commit, push, or ship, then loop until the review reports no accepted/actionable findings. This is code review, not PR merge/approval routing.
This skill is the discipline layer. It does not ship its own reviewer; it drives available review tooling and adds the "verify every finding, fix at the right boundary, re-review until clean" loop on top.
- Default engine:
codex review. It is a concrete CLI command and supports local/branch/commit review modes. - Alternative engine: Claude review tooling when the current Claude Code environment provides
it, such as
/code-reviewor/code-review ultra. Treat these as environment-specific, not repo-local commands. - Cursor review tooling when the current Cursor session provides
/review,/review-bugbot, or/review-security. Treat these as availability-checked host tools, not portable requirements. - For PR-comment triage (reacting to review comments already on a GitHub PR), use
.agents/skills/address-review/SKILL.md; Claude Code exposes it as/address-review.
Use when:
- user asks for "autoreview", "codex review", "Claude review", "second-model review", or a final review before commit/ship
- after non-trivial code edits, before the final commit/push/PR
- reviewing a local working tree, a branch, or a single landed commit after fixes
Contract
This is the portable core. Hold it regardless of which engine runs.
Apply Initial-Pass Optional-Nit Cutoff before accepting findings in every engine/pass, including a final whole-branch or second-engine review. Carry the existing phase into the review prompt and triage; a rerun cannot create another optional repair pass.
- Treat review output as advisory. Never blindly apply it.
- Verify every finding by reading the real code path and adjacent files before acting.
- Read dependency docs/source/types when a finding depends on external library/framework behavior.
- Reject unrealistic edge cases, speculative risks, broad rewrites, and fixes that over-complicate the code.
- Reviewer severity informs triage; it does not by itself establish scope. An accepted expansion must map to an original acceptance criterion or a direct safety property.
- Stop the automatic fix loop when an accepted finding requires a new grammar, protocol, or schema category beyond the intended mechanism, or accepted findings broaden scope across two review waves. Re-evaluate proportionate alternatives: an authoritative source, a maintained dependency, a bounded guard, or a checklist with replay. Continue only with an option that preserves the required criterion or safety property; seek a decision when none is clearly proportionate.
- Prefer small fixes at the right ownership boundary; no refactor unless it clearly improves the bug class. This matches
AGENTS.md: never refactor unrelated code. - Structural drift ("is this making the codebase worse?" — file growth, scattered conditionals, thin abstractions, layer violations, feature-flag branching debt) is out of scope for this gate and does not loosen the rule above. It belongs to
structural-review, a separate explicitly-invoked axis. Route a structural observation there instead of accepting a broader change here. - Keep going until the review returns no accepted/actionable findings; once it comes back clean, stop. Do not run an extra review just to get nicer "clean" wording or a redundant second opinion.
- If a review-triggered fix changes code, rerun the focused tests for the changed surface and rerun the review.
- Security perspective is always included, but it must not cripple legitimate functionality. Report a security finding only when the change creates a concrete, actionable risk or removes an important safety check.
- When the diff touches
.github/workflows/**, a compositeaction.yml/action.yaml, ortrusted_actionsin.agents/agent-workflow.yml, activate thesecure-github-actionslens and run its read-onlybin/secure-github-actions-scan <repo-root>gate from the trusted pack. Its clean result is necessary but not sufficient: still review permissions, triggers, untrusted checkout/execution, credential exposure, and whether each exacttrusted_actionsentry is justified. Never execute the changed workflow or action as part of this lens. - Record a compact risk and coverage receipt for every completed non-trivial review:
autoreviewsource, committed or uncommitted target kind, human base ref, immutable base SHA, head SHA, engine invocation, applied or unavailable risk lenses, included and excluded paths, and material limitations. Report actual coverage, not requested coverage. An uncommitted target is mutable, so its receipt is always partial or unknown with that limitation recorded. - Treat P0/P1 findings, plus any lower-severity finding with material correctness, security, compatibility, data-loss, or release-process consequences, as consequential. Require an independent validation receipt before clearing or acting on one; primary-review agreement is not independent evidence.
- When independent validation of a consequential finding is unavailable, times out, or returns malformed evidence, keep the finding blocking or
unknownand record validation as degraded. Never silently drop it. - Be patient.
codex reviewruns an external model when available and can take several minutes on a large diff. Progress that looks quiet is usually still working; do not kill it before about 5 minutes unless it has clearly errored. - Do not launch multiple reviewers by default. One selected engine, one structured result, then verify it.
- A gated second-engine pass is appropriate only when the user asks or the diff falls into the
high-risk / hosted-CI-ready / force-full hosted-CI / benchmark categories described by
.agents/agent-workflow.yml. Run it after the primary review is clean, keep it to one extra pass, and verify its findings the same way. - If you reject a finding as intentional/not worth fixing, add a brief inline code comment only when it documents a real invariant or ownership decision a future reviewer should know.
- Do not push just to review. Push only when the user asked for push/ship/PR. Follow
AGENTS.mdgit boundaries (never force-pushmain/master).
Step 1 - Pick the target
Inspect what changed and choose the diff scope. Resolve the base branch from
.agents/agent-workflow.yml key base_branch, or from PR metadata when a PR is
open.
base=$(ruby -ryaml -e 'p=(YAML.safe_load(File.read(".agents/agent-workflow.yml"), aliases: false) || {}); puts(p.fetch("base_branch", "main"))')
git status --short --untracked-files=all
git diff --name-only "origin/$base...HEAD"
git diff --stat "origin/$base...HEAD"
git diff --stat
git diff --cached --stat
git ls-files --others --exclude-standard
Use these states when deciding the target. If available, resolve
AUTOREVIEW_SKILL_DIR to the installed or repo-local directory containing this
SKILL.md, then run the read-only helper:
AUTOREVIEW_SKILL_DIR="${AUTOREVIEW_SKILL_DIR:-.agents/skills/autoreview}"
"${AUTOREVIEW_SKILL_DIR}/bin/autoreview-target-state" --text
| State | Trigger | Disposition | Target |
|---|---|---|---|
LOCAL_UNTRACKED_ONLY |
Only untracked files are present. | ready | codex review --uncommitted |
LOCAL_DIRTY_ONLY |
Staged or unstaged local work is present without committed branch diff. | ready | codex review --uncommitted |
BRANCH_PLUS_DIRTY_LOCAL |
Committed branch diff and dirty local work both exist. | not_ready | Commit first, or run both branch and uncommitted reviews; staging alone does not put changes in the branch diff. |
BRANCH_PR_DIFF |
A branch diff exists and gh pr view found a PR base. |
ready | codex review --base "origin/$pr_base" |
BRANCH_NO_PR_DIFF |
A branch diff exists and gh pr view reports no PR for the current branch. |
ready | codex review --base "origin/$base"; this expected non-zero gh state is not a failure. |
NO_REVIEW_TARGET |
No dirty work and no committed branch diff. | not_ready | Stop or pick an explicit commit; a clean local review only proves there is no local patch. |
DETACHED_HEAD |
HEAD is detached. |
blocked | Attach a branch or use codex review --commit <sha> intentionally. |
DEFAULT_BRANCH_WITH_LOCAL_COMMITS |
The configured base branch itself has local commits. | blocked | Create a feature branch or review the specific commit explicitly. |
PR_BASE_UNKNOWN |
PR base probing failed for reasons other than "no PR". | UNKNOWN | Resolve gh auth/network/state before selecting a branch target. |
BASE_DIFF_UNKNOWN |
Git cannot compare origin/$base...HEAD. |
UNKNOWN | Fetch or repair the base ref before selecting a branch target. |
The state table is the source of truth for dirty local work, branch/PR work, and branch plus dirty local work. Do not duplicate those target decisions elsewhere in this skill.
- Single landed commit (already on the configured base branch, or one commit in a stack): review
that commit's diff (
git show <sha>). Reviewing a clean base branch against its remote is an empty diff after push; point at the commit instead.
Tell the user which target you picked and why.
Step 2 - Format and lint first
Consume applicable local results using Verification evidence reuse. Do not repeat a passing check merely because workflow stages changed; rerun affected checks after changes and honor every repository-required repeat. This reuses local command results only, not independent review verdicts.
Carry the same reference's delivery coverage report into review: phase, candidate/base identity, selected/full checks, required results, omissions, and the trusted selection reason. A repository-selected local gate does not reduce independent review or current-head CI requirements. Promotion requires complete candidate evidence and separate authority. Existing repair limits pause for disposition with unresolved findings still blocking.
Formatting that moves line locations will stale the review and the engine's line references.
Use AGENTS.md, .agents/bin/README.md, and /verify for the actual check set. Before a closeout review:
- Resolve the PR/configured base from Step 1, then run
git diff --check origin/$base...HEADfor committed branch content, plusgit diff --checkandgit diff --cached --checkwhen there is local dirty work. - Run the repo's format/autofix command or
.agents/bin/lintwhen formatting or autocorrectable lint failures are present or likely; let those autofix tools make formatting/autocorrect changes instead of hand-formatting. - Run the narrow lint/test checks that cover the changed surface. Before committing, include the
CI-equivalent lint gate(s) required by
AGENTS.md, including any package-specific lint that applies only when that package's files or its linter config changed.
Step 3 - Run the structured review
Default to Codex. Verify it is available first (command -v codex); if not, fall back to the Claude
review tooling described in the intro. If neither engine exists in the current environment, stop and
tell the user which review engines are missing instead of improvising a different review scope. Pick
the command that matches Step 1:
# Dirty local patch, including staged, unstaged, and untracked files.
codex review --uncommitted
# Branch or PR diff.
base=$(gh pr view --json baseRefName --jq .baseRefName 2>/dev/null || ruby -ryaml -e 'p=(YAML.safe_load(File.read(".agents/agent-workflow.yml"), aliases: false) || {}); puts(p.fetch("base_branch", "main"))')
codex review --base "origin/$base"
# Single commit.
codex review --commit <sha>
Prefer explicit target selection over custom focus text. Some Codex CLI versions reject a custom
prompt when --base, --uncommitted, or --commit is present. If that happens, keep the explicit
target command and continue without the prompt rather than accidentally reviewing the wrong diff.
When the installed CLI accepts focus text with the selected target flag, keep the same target from Step 1 and append the prompt there:
codex review --base "origin/$base" "Focus on performance- or framework-sensitive regressions (per AGENTS.md), generated output, and repo workflow correctness."
For longer instructions, create an ignored scratch file, for example
.context/autoreview-focus.md if your workspace provides .context/, or substitute another ignored
path. Read from stdin only when the selected review engine supports that mode without dropping the
target:
codex review --base "origin/$base" - < .context/autoreview-focus.md # create this ignored scratch file first
Never silently switch the engine the user asked for. If the requested engine hits model capacity, retry the same engine a few times rather than swapping it.
Before running the engine, select uniquely named risk lenses from the actual diff and repository policy.
Correctness and security are always present in the receipt; add testing/coverage, compatibility,
reliability, performance, data migration, release/process, or another bounded lens when the
changed surface warrants it. A lens that does not apply still belongs in the receipt with a
short reason. Mark unavailable or incomplete lenses degraded or unknown; do not infer
coverage from a successful process exit alone.
High-risk second pass
For high-risk changes in the hosted-CI-ready, force-full hosted-CI, or benchmark
categories described by .agents/agent-workflow.yml, or when the user asks
for a panel/second model, run one additional review after the primary review is clean:
- If the primary review used
codex review, use available Claude review tooling such as/code-reviewor/code-review ultra. - If the primary review used Claude review tooling, use
codex reviewwhen the current environment makes it available, with the same target and any focus instructions the installed CLI supports. - If no second engine is available, say so and continue with the clean primary review plus local verification.
Do not run a panel for small focused PRs unless the user asks. This matches AGENTS.md: use at
most one inline-commenting AI reviewer for small PRs.
Step 4 - Verify, fix, and loop
For each finding the engine returns:
- Open the real code path and adjacent files. Confirm the finding is true here, not generic.
- Accept only concrete, actionable findings (correctness bugs, real regressions, genuine security gaps, clear inconsistencies with adjacent code). Consider useful cheap initial nits only under the canonical cutoff; reject late optional churn, speculation, and broad rewrites. Severity alone does not authorize a broader mechanism.
- Before acting on a consequential finding, use a fresh independent reviewer or validator
context to check it against the same diff and cited code path. Give it the finding,
target/base/head, and relevant diff, but do not present agreement as the desired outcome.
Record the validator identity, status, and evidence:
confirmed: continue to the fix or explicit disposition;rejected: do not fix from that finding; record the rejected disposition and evidence;degraded: do not fix or clear it automatically; keep itmust_fix,needs_decision, orunknownuntil independent validation succeeds or a maintainer decides it. The primary session's inspection may supplement this check but cannot replace independence.
- Fix accepted non-consequential findings and independently confirmed consequential findings with the smallest correct change at the right boundary.
- Rerun the targeted tests for the changed surface, then rerun the review. Use
/verify's Scope Guide and.agents/bin/README.mdto pick the narrowest covering tests for the changed surface, e.g. the unit spec for a library-code change, the integration/app spec for an integration change, and the package test plus type-check/lint for touched TypeScript. Also rerun any signature/type validation when typed interfaces changed.
Loop Steps 3-5 until the review returns no accepted/actionable findings. Once a rerun comes back clean, stop; do not spend another long review cycle on redundant confirmation. When a finding would trigger the complexity-escalation stop in the Contract, do not patch the new category as the next loop iteration. First re-evaluate the listed alternatives and record the acceptance-criterion or direct-safety-property mapping; seek a maintainer decision if the proportionate choice is unclear. If the same finding recurs after two fix attempts, or the review starts cycling through speculative issues, stop, report the loop, and ask the user whether to continue.
Parallel closeout (optional)
After Step 2 formatting is done, it is fine to run the focused tests and the review concurrently to save wall-clock. If either forces a code edit, rerun the affected tests and re-review until clean.
Final report
Report:
- diff target reviewed (local / branch / commit) and base
- review engine used (
codex reviewor the available Claude review command) - risk and coverage receipt: source, target kind/base ref/base SHA/head SHA, invocation provenance, each selected or not-applicable lens and why, included/excluded paths, and limitations
- tests/proof run, with pass/fail
- findings accepted vs rejected, briefly why
- independent-validation outcome and evidence for every consequential finding, including any degraded validation that remains blocking or unknown
- PR label recommendation from
.agents/agent-workflow.yml(none, the hosted-CI-ready label, the force-full hosted-CI label, a benchmark label, or a valid combination of these) when the work is headed to a PR - the final clean review result, or why a remaining finding was consciously left unfixed
Do not run another review solely to improve the report wording. If the final review came back with no accepted/actionable findings, report that run as clean.
When machine-readable findings are requested, emit the same receipt and consequential-finding
validation using docs/review-finding-schema.md. The additive receipt does not require another
review engine for ordinary clean reviews and does not transfer commit, push, PR, or merge
ownership to review tooling.
Populate optional receipt provenance.model, provenance.effort, and provenance.usage only from host-reported evidence for the actual review run.
Use literal UNKNOWN for unavailable values; never infer them or treat prompt text or model self-report as binding evidence.
Copy usage counters without guessing or recalculation, and do not store raw prompt, response, or
transcript data in the receipt.