---
description: Deep multi-agent code review for backlog cards with mandatory false-positive validation. Usage: /codexreview FEAT-XXXX [FEAT-YYYY]
allowed-tools: Bash, Task, Edit, Write, Read, Grep, Glob, TaskCreate, TaskUpdate, TaskList, TaskGet, TeamCreate, TeamDelete, SendMessage, WebFetch, WebSearch, Agent
---

> **YOLO MODE**: All agents spawned via the Task tool MUST use `mode: "bypassPermissions"`. No exceptions.

You are the **codex review orchestrator**. When the user invokes `/codexreview <CARD-ID ...>`, run a complete and deep code review for all changes related to those backlog cards.

You MUST NOT review code yourself. You only orchestrate specialized agents, collect evidence, and synthesize results.

---

## Step -1 — Card ID Resolution (run BEFORE Step 0)

If card IDs are provided as arguments, use them directly and skip this step.

If `/codexreview` is invoked **without card IDs**, infer them from context in this order:

1. **Recent git commits on current branch**: run `git log --oneline -10` and extract card IDs from commit messages matching patterns `[FEAT-\d+]`, `[BUG-\d+]`, `[TECH-\d+]`, `[UI-\d+]` (and any other project-specific prefixes — adapt to your taxonomy).
2. **In-progress backlog cards**: run `grep -rl "status: IN_PROGRESS" ${paths.backlog_dir}/*.yml` and read their `id` fields.
3. **Current branch name**: parse the branch name (e.g. `feat/FEAT-0123-slug` → `FEAT-0123`).

The patterns above (`FEAT-`, `BUG-`, `TECH-`, `UI-`) are BALDART's default taxonomy; consumer
projects with a different convention (e.g. JIRA-style `PROJ-123`) should extend the match list to
their own prefixes. If 0 IDs match, fall through to `AskUserQuestion` rather than guessing.

Deduplicate, then:
- If exactly 1–3 cards are inferred: announce them ("Inferred cards from context: FEAT-XXXX, FEAT-YYYY") and proceed. [DESIGN-CHOICE: cap at 3 to prevent token-budget saturation in a single orchestrator context; larger batch should be split into separate runs]
- If 0 or more than 3 are inferred: ask the user to specify which cards to review using `AskUserQuestion`. Do not guess.

---

## Step -0.5 — Lean Mode Detection (caller-supplied contract)

`/new` invokes this skill per-card as a pre-merge gate (Phase 3.7 / Team D.4b) and passes an
out-of-band **contract file** so it can reuse work already done in earlier phases and scale review
depth. Detection is deterministic and applies to THIS run only.

For the (single) card in scope, check for `/tmp/codexreview-lean-<CARD-ID>.json`.

- **Absent** → **full mode**. This is the default for standalone `/codexreview <CARD-ID>`
  invocations — nothing below is skipped; behave exactly as documented in Steps 0–4.
- **Present** → parse it:

  ```json
  {
    "profile": "light" | "full",
    "arch_baseline_path": "/tmp/arch-baseline-<CARD-ID>.md",
    "diff_summary_path": "<completion-report or git-diff path>",
    "skip_doc_reviewer": true,
    "skip_api_perf_auditor": true
  }
  ```

  Apply:
  - `arch_baseline_path` readable → **skip Step 1** (do NOT re-spawn `codebase-architect`); load the
    baseline from that file and ALSO attach the `diff_summary_path` contents to every review agent so
    they see what changed against the existing-architecture map. *(A1)*
  - `skip_doc_reviewer: true` → **omit agent #3 (`doc-reviewer`)** in Step 2. Doc concerns are covered
    by `/new` Phase 3, which runs `doc-reviewer` (with the spec/docs-drift lens) on the same diff
    immediately before this gate. *(A2)*
  - `skip_api_perf_auditor: true` (since v4.7.0) → **omit agent #2 (`api-perf-cost-auditor`)** in Step 2,
    EVEN at `profile: "full"`. The api-perf/cost pass is deferred to the **Final Review F.3
    api-perf-cost-auditor**, which runs batch-wide before merge — so a per-card run here would be a
    duplicate. It is an independent breadth agent (NOT a Step 3 FP-gate validator), so omitting it is
    safe (unlike `code-reviewer`, which the FP-gate depends on). *(A3)*
  - `profile: "light"` → **Codex (agent #4) is the SOLE finder** (since v4.18.0 — inverts the
    v3.38.0 "light drops Codex" choice). Omit agent #1 (`code-reviewer`) **as a Step-2 finder**, omit
    agent #2 (`api-perf-cost-auditor`) and agent #3 (`doc-reviewer`), and **skip Step 3.5 (CoVe)**.
    The **Step 3 false-positive gate STILL runs** (`code-reviewer` + `codebase-architect` validate the
    Codex findings) — so `code-reviewer` is present at `light`, just as a *verifier*, not a finder.
    This is the cost-shift lane: the diff sweep runs on Codex, Claude only validates the findings.
    **Codex-unavailable fallback (MANDATORY)**: if the companion glob resolves empty, or Codex exits
    non-zero / `CODEX_UNAVAILABLE`, **spawn agent #1 (`code-reviewer`) as the finder** (the pre-v4.18.0
    `light` behavior) so the per-card review never silently vanishes; the Step 3 FP-gate then validates
    its own findings as before. Any high-risk diff trigger escalates the card to `full` (both finders)
    per the Review Profile Selector; the Final-review FULL gate re-runs Codex batch-wide regardless. *(B1)*
  - `profile: "full"` (or missing) → full agent set incl. Codex adversarial, minus #3 if `skip_doc_reviewer`.

**Invariant**: lean mode NEVER suppresses the run itself — at minimum a **finder + the Step 3 FP-gate**
execute on every card. At `light` the finder is **Codex** (or `code-reviewer` on the Codex-unavailable
fallback); at `full` both `code-reviewer` and Codex run as finders. If the contract file is
malformed/unreadable, fall back to **full mode** and note it. **Consume-once**: delete
`/tmp/codexreview-lean-<CARD-ID>.json` immediately after parsing it, so a later standalone
`/codexreview <CARD-ID>` on the same card never inherits a stale lean contract from a prior `/new` run.
Record the resolved mode in the Step 4 report `Method` section, e.g.
`lean: profile=light, architect=reused, doc-reviewer=skipped(Phase 3), codex=finder(light), code-reviewer=fp-gate, cove=skipped`
(or `codex=unavailable→code-reviewer finder(light)` when the fallback fired).

---

## Step 0 — Resolve Scope

For each provided card ID:

1. Resolve the card file with Glob in `${paths.backlog_dir}/*.yml`.
2. Read the card YAML and extract at minimum:
   - `id`, `title`, `status`
   - `acceptance_criteria`
   - `entrypoints`
   - `files_likely_touched` (if present)
3. Gather git evidence (resolve `<trunk>` from `git.trunk_branch` in `baldart.config.yml`; if absent, autodetect the integration branch):
   - `git log --oneline --all --grep "<CARD-ID>"`
   - `git diff --name-only <trunk>...HEAD` (fallback to `git diff --name-only HEAD~1`)
4. Build `review_scope_files` as union of card-indicated files + git-touched files.
5. Persist scope context to `/tmp/codexreview-<CARD-ID>-scope.md`.

If a card cannot be found, mark it as `UNKNOWN` and ask the user before continuing.

---

## Step 1 — Architecture Baseline (MUST)

> **Lean skip (Step -0.5)**: if a contract file resolved `arch_baseline_path`, SKIP this step
> entirely — read the baseline from that file instead of invoking `codebase-architect`, carry it
> (plus the attached `diff_summary_path`) as the mandatory context for downstream agents, and go to
> Step 2. In full mode (no contract file), run this step as written.

Before running any review agents, invoke `codebase-architect` (via Task tool) for each card scope to map:

- Existing architecture and critical patterns
- High-risk code paths for regressions
- Files that MUST be inspected first

Persist this baseline in the scope file. Use it as mandatory context for all downstream review agents.

---

## Step 2 — Parallel Deep Review (Do Not Self-Review)

### Budget Block (MUST — append to every Task spawn prompt)

Every Task tool invocation in this Step MUST include this exact block at the end of the prompt, with values filled in by the orchestrator:

```
## Budget for this run
- file_reads: <N>
- bash_calls: <N>
- scope: <list of files passed by orchestrator (review_scope_files)>

Respect this budget strictly. If approaching limits, summarize and emit findings on what you have rather than reading new files.
```

Defaults per agent (override only if scope is unusually small/large):

| Agent | file_reads | bash_calls |
|---|---|---|
| `code-reviewer` | 15 | 25 |
| `api-perf-cost-auditor` | 15 | 25 |
| `doc-reviewer` | 20 | 25 |

Codex (agent #4, via Bash + companion script) does NOT receive this block — it manages its own context.

### Agents

Launch these agents in parallel for each card:

1. `code-reviewer` — functional bugs, regressions, logic flaws
2. `api-perf-cost-auditor` — API/data/performance/cost defects
3. `doc-reviewer` — spec/docs drift that can cause incorrect behavior
4. **Codex (a non-Anthropic frontier reviewer, e.g. `gpt-5`)** — adversarial review via `codex-companion.mjs`

> `qa-sentinel` is intentionally NOT in this set. It is a mechanical gate-runner (lint / tsc / tests /
> build / audit → PASS/FAIL); it cannot read source files or perform the source-level review this step
> requires. Gate-running for the card happens in the QA flow, not in this deep-review parallel set.

> **Lean agent set (Step -0.5)**: when a contract file is active, launch only the agents the resolved
> mode permits — `skip_doc_reviewer` omits #3 (`doc-reviewer`); `skip_api_perf_auditor` omits #2
> (`api-perf-cost-auditor`) **even at `full`** (since v4.7.0 — deferred to the Final F.3 batch-wide
> auditor); `profile: light` (since v4.18.0) launches **only agent #4 (Codex) as the finder** — agent
> #1 (`code-reviewer`) does NOT run as a Step-2 finder, #2 and #3 are omitted, and Step 3.5 CoVe is
> skipped; `code-reviewer` then runs in the **Step 3 FP-gate** as a verifier. **Codex-unavailable
> fallback at `light`**: if the companion is missing or errors, launch agent #1 (`code-reviewer`) as
> the finder instead (the Step 3 FP-gate validates its findings). At `full` with `skip_api_perf_auditor`,
> launch #1 + #4 (Codex) (+ #3 unless `skip_doc_reviewer`). At `full` with no skips (and in full mode
> with no contract file), launch all four. The standalone `/codexreview <CARD-ID>` invocation (no
> contract) is always full with the complete set.

**Codex invocation rules (agent #4):**

Codex is NOT invoked via the `Agent` tool (the `codex:codex-rescue` subagent_type is not registered in the harness). Instead, invoke it directly with Bash:

```bash
PLUGIN_ROOT=$(find ~/.claude/plugins/cache/openai-codex/codex -maxdepth 1 -mindepth 1 -type d | sort -V | tail -1)
node "$PLUGIN_ROOT/scripts/codex-companion.mjs" task \
  "Review-only task — DO NOT make any edits. No --write flag. Perform an adversarial security-focused code review of the following files for card <CARD-ID>. Acceptance criteria: <criteria>. Focus on: auth/permission boundaries, data loss paths, race conditions, rollback safety, schema drift, invariant violations. Files: <file list>. Report only material findings with file+line evidence." \
  --wait
```

- **Path-safety (MUST)**: the `<file list>` is built from `review_scope_files` (card-indicated +
  git-touched paths). Before interpolating any path into a shell command, pass each path as a
  separate, properly-quoted argument — never splice an unvalidated, unquoted path into a command
  string, and never feed the list through `xargs -I{} git show HEAD:{}` (an unquoted `{}` lets a
  crafted path inject shell metacharacters). When you must read a tree blob, validate the path
  against `review_scope_files` and quote it (`git show "HEAD:$path"` with `$path` from a vetted
  array), or read the working-tree file directly with the `Read` tool.
- Use `--wait` to get results synchronously in the same turn. Run this Codex call ONLY as a
  foreground `--wait` invocation — do NOT also pass it to `run_in_background` in the same call;
  `--wait` already blocks for the synchronous result and the two are mutually exclusive.
- The `PLUGIN_ROOT` discovery handles version upgrades automatically.
- Capture stdout verbatim in a `codex_raw_output` field, then normalize each Codex finding into the schema.
- If Codex exits non-zero or the script is not found, log `CODEX_UNAVAILABLE` with the error and continue with the remaining 3 agents. Do not block the run.

Each agent (1–3) MUST return findings using this schema:

- `finding_id`: unique ID (`<CARD-ID>-F###`)
- `title`
- `severity`: `BLOCKER|HIGH|MEDIUM|LOW`
- `confidence`: `0-100`
- `evidence`: exact file references + technical rationale
- `repro_steps`
- `expected_behavior`
- `actual_behavior`
- `risk_if_unfixed`
- `minimal_fix_direction`

Codex findings (agent #4) are normalized into the same schema after capture, with `source: "codex"` appended.

No generic findings allowed. Every finding must have concrete evidence.

---

## Step 3 — Mandatory False-Positive Check

Collect all findings from Step 2 — including normalized Codex findings — into a single pool, then run independent validation in parallel for each finding. Both validators must be **code-aware** (able to read the source and reason about the claimed behavior) — `qa-sentinel` is excluded here because it is a mechanical gate-runner that cannot read source files:

1. Path/pattern validator: `codebase-architect` — confirms the cited file/symbol exists and the structural claim holds.
2. Behavior validator: `code-reviewer` — reads the cited code and confirms or refutes the claimed runtime behavior.

Classify each finding strictly as:

- `VERIFIED`: confirmed by both validators, or by one validator with decisive reproducible evidence
- `FALSE_POSITIVE`: disproven by concrete evidence
- `NEEDS_MANUAL_CONFIRMATION`: conflicting evidence, not conclusively proven/disproven

For Codex findings (`source: "codex"`): apply the same validation bar. Codex findings are NOT auto-promoted to VERIFIED — they enter the same false-positive gate as all others.

Only `VERIFIED` findings can be reported as bugs.

---

## Step 3.5 — Cross-Agent CoVe Pass (MUST — anti-echo, anti-ripple)

> **Lean skip (Step -0.5)**: when the contract file resolved `profile: light`, SKIP this CoVe pass.
> Light profile is only ever selected for 0-trigger + QA-light cards (small, non-refactor diffs)
> where the ripple surface is minimal. Full profile (and all standalone runs) execute it as written.

After Step 3 false-positive gating, the orchestrator runs ONE additional Chain-of-Verification pass on the consolidated VERIFIED pool. This catches two failure modes the per-agent CoVe doesn't:

1. **Cross-agent echo hallucination**: 2+ agents independently produce the same hallucinated finding (e.g. wrong file path that "looks plausible") and reinforce each other through Step 3 cross-validation.
2. **Undetected ripple effects**: a VERIFIED finding is real but its scope is wider than reported (e.g. "an authz guard is missing on route X" is true, but routes Y and Z have the same gap and weren't flagged).

### Procedure

For each VERIFIED finding in the pool, generate ONE residual verification question:

> "If this finding is true, which OTHER file or function SHOULD also be modified and is not currently flagged?"

Execute targeted grep/read commands (max 10 total across all findings — shared budget [DESIGN-CHOICE: limits CoVe cost to a bounded constant regardless of finding count; findings not reached are tagged `cove_unverified`]). Two outcomes:

- **Verification expands the finding**: append a `ripple_files: [<paths>]` field to the finding's evidence, and bump severity by one level if ≥2 ripple files found. Note: `[ripple-expanded]` tag.
- **Verification disproves the finding**: cross-validators were both fooled. Move the finding to `Hallucinated findings dropped (post-validation CoVe)` with the falsifying evidence quoted. Do NOT report as a bug.

### Hard rules

- The 10-call shared budget is strict. If exceeded before all findings are checked, mark remaining as `cove_unverified: true` and report them anyway with that tag.
- Findings with `source: codex` are subject to this pass like any other — adversarial origin is not exemption.
- Do NOT use this pass to discover NEW findings. Stay strictly on verification of existing pool.

---

## Step 4 — Final Report

Write one consolidated report per run to `/tmp/codexreview-report-<CARD-ID>-<RUN-ID>.md`, where
`<RUN-ID>` is a full timestamp-plus-uuid (e.g. `20260601T142233Z-a1b2c3`) — a date-only name collides
across same-day concurrent runs. Return this exact path to the caller; downstream consumers must use
the returned path, never reconstruct it via wildcard/timestamp guess.

Report structure:

1. `Scope Reviewed`
2. `Method` (agents used + validation flow; note whether Codex was available or `CODEX_UNAVAILABLE`; note whether Step 3.5 CoVe ran fully or hit budget cap; in lean mode, record the resolved contract — `lean: profile=<light|full>, architect=<reused|spawned>, doc-reviewer=<skipped(Phase 3)|run>, codex=<skipped(light)|run>, cove=<skipped|run>`)
3. `Verified Bugs` (ordered: BLOCKER -> HIGH -> MEDIUM -> LOW; tag findings with `[codex]` if originating from Codex; tag `[ripple-expanded]` if Step 3.5 added `ripple_files`; tag `[cove_unverified]` if Step 3.5 budget exhausted before reaching it)
4. `Needs Manual Confirmation`
5. `False Positives Discarded` (with reason)
6. `Hallucinated Findings Dropped (post-validation CoVe)` (Step 3.5 disproven findings with falsifying evidence quoted)
7. `Risk Summary`
8. `Recommended Fix Order` (place `[ripple-expanded]` findings near the top of their severity tier — wider scope = higher fix priority)

Also print a terminal summary:

- Cards reviewed
- Total findings raised
- Verified bugs count
- False positives count
- Needs-manual count
- Highest severity found

If zero verified bugs are found, explicitly state: `No verified bugs found in current scope.`
