<!-- Modulo on-demand di /new — NON un file installato a sé. Caricato via Read dalla § "Routing" del SKILL.md core. -->

> **Modulo `/new`** — eseguilo, poi torna al core § "Routing" per la fase successiva. I `§ "..."` (Context economy, Context Tracking, Trivial-card fast-lane, Risk-signal detector, Fix Application Log) vivono nel **core SKILL.md**.

### Phase 3.7 — Pre-Merge Codex Review Gate (MANDATORY — UNCONDITIONAL)

> **Workflow-delegation carve-out (v4.34.0)**: if the review cluster was delegated to the
> `new-card-review` workflow (see `references/review-cycle.md` § "Phase 2.5x — Review-cluster workflow
> delegation gate"), this Phase 3.7 is **already covered** — the workflow ran the cross-model Codex pass
> (agent-launched binary, `code-reviewer` fallback) at the card's profile depth as part of the cluster,
> and the FP-validated findings were already fix-applied. **SKIP this gate**; log
> `codex-review: covered by new-card-review workflow`. This carve-out applies ONLY when the delegation
> branch was taken; on the inline fallback (no `Workflow` tool) this gate runs in full as written below.
> The unconditional **Final-review FULL gate** (Codex over the whole batch) remains the cross-card net
> in both paths.

**This gate runs for EVERY card with code to review before the Phase 4 commit.** A per-card `/codexreview` MUST run BEFORE the Phase 4 commit, regardless of file paths or perceived risk. The historical conditional High-Risk Path detector is preserved below — but only as a **signal-logging step** to record *which* triggers matched in the tracker. It NEVER suppresses the `/codexreview` invocation. Even if zero triggers match, `/codexreview` runs.

> **Single carve-out — `IS_TRIVIAL` fast-lane (since v4.6.0)**: a card that is `IS_TRIVIAL` on its ACTUAL committed diff (`review_profile=skip` + non-source diff + 0 Step-A triggers — § "Trivial-card fast-lane") **skips this gate**, because there is no code for Codex to review. Its adversarial coverage is carried by the SAME unconditional **Final-review FULL gate** the `light` path already relies on (it runs Codex over the entire batch diff, including every trivial card's files, before merge). This is NOT a `time budget` skip — it is the deterministic `IS_TRIVIAL` gate reason, and the guard means a single source file in the diff flips the card back onto this gate. Log `codex-review: SKIPPED (trivial — non-source diff; covered by Final FULL gate)`.

**Rationale**: leaving the gate conditional caused it to be silently skipped on the majority of cards, defeating the AGENTS.md "MUST run BEFORE merge" requirement. The gate itself is unconditional — what varies is its DEPTH (`light` vs `full`). Since v4.18.0 **both depths run Codex per-card**: at `light` Codex is the SOLE finder and `code-reviewer` validates in the FP-gate; at `full` both run as finders. So the BUG-0530-class "missed blocker on a low-risk path" guard is now carried directly (Codex sweeps every non-trivial card), reinforced by (1) the Step A detector escalating any risky diff to `full`, and (2) the unconditional **Final-review FULL gate** running Codex over the entire batch diff before merge. The Codex-unavailable fallback (`light` degrades to `code-reviewer` finder) keeps the merge gate intact when the companion is absent.

#### Step A — Detect (signal-logging only, NEVER gates the next step)

Run the **§ "Risk-signal detector" del core SKILL.md** (rilocato lì perché anche la
§ "Trivial-card fast-lane" lo usa a Phase 1). È lo stesso identico detector bash
(trigger #1 high-risk module / #2 dead-code resurrection / #3 reference-aliasing):
produce la lista `TRIGGERS`. Logga quali trigger hanno fatto match; **non
short-circuita mai** lo Step B/C — `/codexreview` parte unconditional.

#### Step B — Log detector result (never skips)

Log the detector output in the tracker for traceability. **This step never short-circuits Step C — `/codexreview` runs unconditionally regardless of whether `TRIGGERS` is empty or populated.**

- If `TRIGGERS` is empty: log `## Pre-Merge Codex Review: no high-risk triggers matched (gate still runs unconditionally)` and proceed to Step C.
- If `TRIGGERS` is non-empty: log the matched triggers (see Step C step 1) and proceed to Step C.

#### Step C — Invoke per-card `/codexreview` (ALWAYS)

For EVERY card (no conditional skip — the gate ALWAYS runs; only its DEPTH varies):

0. **Select the Codex review profile (deterministic — Review Profile Selector)** by mapping the
   card's review profile (read from the card's `review_profile` field per the QA Profile Selector
   above — since v3.38.0; fallback-computed only for legacy cards) and the Step A detector:
   - **`light`** ⟺ the card's profile ∈ {`skip`, `light`} **AND** Step A matched **zero**
     high-risk triggers.
   - **`full`** ⟺ otherwise — i.e. the card's profile ∈ {`balanced`, `deep`}, **OR** any Step A
     trigger matched.

   **Escalation-only invariant (since v3.38.0)**: the Step A detector runs on the ACTUAL diff and
   can only ever **escalate** `light` → `full` (a high-risk path surfaced at implementation time
   that the card's authored profile didn't anticipate). It can NEVER downgrade `full` → `light`.
   The card's `review_profile` is the deterministic floor; the diff detector is the safety net on
   top of it.

   `light` is **NOT** a skip. **Since v4.18.0 the per-card Codex pass runs at `light` as the SOLE
   finder** (inverting the v3.38.0 choice that deferred Codex to the final cross-check). At `light`
   `/codexreview` launches **Codex (finder)** + the **Step 3 false-positive gate** (`code-reviewer` +
   `codebase-architect` validate the Codex findings) — dropping the breadth agents (qa-sentinel,
   api-perf-cost-auditor, doc-reviewer) AND Step 3.5 CoVe. So `code-reviewer` is still present at
   `light`, but as the *verifier*, not the finder: the diff sweep moves off Claude onto Codex (the
   cost-shift), Claude only validates. `full` is unchanged (Codex adversarial + `code-reviewer` both as
   finders + the full agent set, minus the duplicate doc-reviewer).
   **Codex-unavailable fallback (MANDATORY).** If the companion glob resolves empty or Codex errors,
   `light` degrades to **`code-reviewer` as the finder** (the pre-v4.18.0 behavior) + the FP-gate — the
   per-card review never silently vanishes.
   **Where the BUG-0530 invariant now lives.** The "never miss a blocker on a low-risk path" guard is
   now carried **directly** — Codex sweeps every non-trivial card per-card — reinforced by two nets:
   1. **Escalation-only (Step A)** — any high-risk trigger on the ACTUAL diff promotes `light` → `full`,
      so genuinely risky paths (auth/payment/permission/schema/…) get BOTH finders per-card.
   2. **Final-review FULL gate (since v3.37.0)** — the **Final review ALWAYS runs a single FULL
      `/codexreview` over the entire batch diff before merge** (no N=1 skip, no scope reduction — see
      "Final review → Final-review FULL gate"). So every line of every card is re-swept by Codex
      batch-wide before merge.
   Net effect: `light` per-card = Codex finder + `code-reviewer` FP-gate (or `code-reviewer` finder on
   the Codex-unavailable fallback). To revert per-card Codex off `light`, restore the v3.38.0 `light`
   branch of `/codexreview` Step -0.5 (`code-reviewer` finder only).

   Then dump the card diff (reviewer grounding) and write the lean contract `/codexreview` consumes:
   ```bash
   cd <worktree-path>
   # $TRUNK = the trunk branch resolved in Phase 0 (git.trunk_branch)
   git diff "$TRUNK...HEAD" -- <card files from ownership map> > /tmp/diff-<CARD-ID>.txt 2>/dev/null \
     || git diff HEAD~1..HEAD > /tmp/diff-<CARD-ID>.txt
   ```
   Write `/tmp/codexreview-lean-<CARD-ID>.json`:
   ```json
   { "profile": "light|full", "arch_baseline_path": "/tmp/arch-baseline-<CARD-ID>.md",
     "diff_summary_path": "/tmp/diff-<CARD-ID>.txt", "skip_doc_reviewer": true,
     "skip_api_perf_auditor": true }
   ```
   `skip_doc_reviewer` is ALWAYS true: Phase 3 already ran `doc-reviewer` on this diff (with the
   spec/docs-drift→bug lens since v3.35.0), so `/codexreview` agent #3 would be a duplicate.
   `skip_api_perf_auditor` is ALWAYS true (since v4.7.0): the per-card api-perf/cost pass is deferred
   to the **Final Review F.3 api-perf-cost-auditor** (batch-wide), so `/codexreview` agent #2 would be
   a duplicate of the final sweep. (At `full` `/codexreview` would otherwise spawn it; at `light` it is
   already dropped.)

1. **Log gate invocation** in the tracker under `## Pre-Merge Codex Review`:

   ```
   ## Pre-Merge Codex Review
   - Triggered: unconditional (mandatory pre-merge gate)
   - Profile: light | full — reason: <review_profile=<skip|light|balanced|deep> (from card | computed); triggers=0 | trigger #N matched (escalated light→full)>
   - Matched high-risk triggers: <list from detector, or "none">
   - Action: invoking /codexreview <CARD-ID> (per-card, pre-merge gate; lean contract written)
   ```

2. **Invoke `/codexreview`** for the single card via the Skill tool:

   ```
   Skill: codexreview
   args: <CARD-ID>
   ```

   `/codexreview` Step -0.5 consumes `/tmp/codexreview-lean-<CARD-ID>.json`: reuses the Phase-1
   architecture baseline (no re-spawn), drops the duplicate doc-reviewer, and for `profile: light`
   runs **Codex as the sole finder** (since v4.18.0) + the Step 3 FP-gate (`code-reviewer` +
   `codebase-architect` validate), dropping qa-sentinel + api-perf-cost-auditor + Step 3.5 CoVe. On
   Codex-unavailable, `light` degrades to `code-reviewer` finder. Step 3 FP-gate + Step 4 report ALWAYS
   run. (`full` = standard pipeline incl. Codex adversarial + `code-reviewer` finder, minus the
   duplicate doc-reviewer.)

3. **Read the consolidated report**. `/codexreview` writes it to `/tmp/codexreview-report-<TIMESTAMP>.md` and RETURNS that exact path in its Skill-tool result — use the returned path, do NOT guess the timestamp. If the return value did not surface the path, locate the newest report whose body names this `<CARD-ID>` (`grep -l "<CARD-ID>" /tmp/codexreview-report-*.md | xargs ls -t | head -1`), never just the newest file by mtime (a parallel card's report could be newer). Extract:
   - Verified BLOCKER count
   - Verified HIGH count
   - List of `[ripple-expanded]` findings (Step 3.5 widened scope). At `light` profile Step 3.5 CoVe does not run, so this list is structurally empty — log `ripple-expanded: 0 (CoVe not run at light)` rather than a bare `0`, so audits can tell "not attempted" apart from "attempted, none found".

4. **Apply fix sub-loop** (mirror of Phase 3.5 retry pattern):
   - If 0 BLOCKER and 0 HIGH → log `verdict: PASS — proceeding to Phase 4` in tracker. Done. (MEDIUM/LOW findings are advisory at this per-card gate; they are not silently lost — the post-batch **Final-review FULL gate** applies every VERIFIED finding ≥ MEDIUM. Log the MEDIUM count in the tracker so it is visible.)
   - If 1+ BLOCKER OR 1+ HIGH → spawn `coder` agent with the report path + list of VERIFIED bugs. **At `full` profile** the report contains Codex-suggested inline patches: pass them and have the coder **apply the suggested patches** with the right system prompt (project conventions, naming, testing patterns) — it does NOT re-do the analysis or re-grep (since v3.28.3), BUT it MUST first confirm each patch still applies against the current file state (prior fix-loop iterations may have shifted line offsets); if a patch no longer applies cleanly, the coder re-locates the target by content and applies the equivalent edit rather than a stale-offset verbatim paste. **At `light` profile** (since v4.18.0) the findings come from **Codex** (the sole finder) — the report carries Codex's `minimal_fix_direction`; brief the coder to apply it (treat it like the `full`-profile Codex fix direction). **On the Codex-unavailable fallback** the `light` findings come from `code-reviewer` instead — brief the coder to apply the `code-reviewer` fix direction (no Codex patches to paste). After coder fixes, **re-write the lean contract `/tmp/codexreview-lean-<CARD-ID>.json` (it is consumed-once and deleted by `/codexreview`)** and re-invoke `/codexreview` via the Skill tool with `args: <CARD-ID>` (NOT a bare prose mention — the card ID MUST be passed so the retry reviews THIS card, not an inferred one). Repeat **max 2 times**.
   - If still BLOCKER/HIGH after 2 retries → log in `## Issues & Flags` and **ask the user** whether to proceed, escalate, or stop. The Phase 4 commit MUST NOT happen until the Pre-Merge Codex Review verdict is PASS or user explicitly overrides.
   - **Telemetry** — for EVERY codex finding processed (verified BLOCKER, verified HIGH, or false-positive-filtered), append one row to `## Fix Application Log`: `3.7 | codex-<security|correctness|other> | est_lines=<n> | decision=<coder|skipped> | applied_by=<coder|-> | severity=<BLOCKER|HIGH|FALSE-POSITIVE> | retry=<n>`. Classify domain: `security` for findings touching RLS / auth / permissions / payments; `correctness` for logic / data integrity / race conditions; `other` for everything else.

5. **Update tracker**: phase = `3.7-codexgate DONE` (the gate runs unconditionally for every card — the legacy `3.7-highrisk` name implied it only fired on high-risk cards, which is no longer true), log final verdict, retry count, list of fixed findings, and the report path.

6. **E2E re-run obligation check (enforces the Phase 2.6 re-run trigger HERE)** — if this Phase 3.7 fix sub-loop modified any file under `${paths.app_dir}`, `${paths.components_primitives}`, or any `*.css` / `*.scss`, you MUST re-invoke `/e2e-review` (programmatic mode, same `.baldart/e2e-review/<CARD-ID>/` state dir) BEFORE the Phase 4 commit and resolve its verdict per the Phase 2.6 gating-logic table. Log `e2e-rerun: triggered` or `e2e-rerun: not-needed (no UI files touched in 3.7)` in the tracker so Phase 4 can assert it. Do NOT defer this to "it's documented in Phase 2.6" — the check fires here, where the fixes happen.

#### Why deterministic detector + agent pipeline

The detector (Step A) is bash + grep — guaranteed to run, no LLM skip. The downstream pipeline (Step C) is the existing `/codexreview` skill — fully tested, includes Codex adversarial review and Step 3.5 cross-agent CoVe. This combination ensures the AGENTS.md "MUST run BEFORE merge" rule is enforced reliably.

**Crash handling**: if `/codexreview` (or its fix-loop `coder`) crashes mid-phase, apply the "Sub-agent failure protocol" (below). Treat this gate as a **mandatory gate, NOT a non-domain-override fallback** — `/codexreview` covers the `security` domain (auth/payment/permission findings), so a crash that cannot be recovered by one retry STOPS the pipeline and routes to `AskUserQuestion`; do NOT rationalize it as "non-domain-override" and inline-bypass the merge gate.
