<!-- 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**.

## Final review (after all cards)

> **Primary code reviewer: Codex (a non-Anthropic frontier model, via `codex-companion.mjs`)** — cross-model validation with built-in FP filtering.
> Claude `code-reviewer` is the automatic fallback if Codex is unavailable.
> The `/codexreview` command remains available for standalone reviews on demand.

Once ALL cards are committed in the worktree:

> **Final-review FULL gate (since v3.37.0 — supersedes the v3.35.0 scope-reduction)** — because
> Phase 3.7 may now run a card at `light` depth, the per-card pass can NO LONGER be assumed to have
> full-reviewed every card. The final review is therefore the **unconditional safety gate that makes
> the Phase 3.7 `light` profile safe**: it ALWAYS runs a single FULL `/codexreview` (full agent set)
> over the **ENTIRE batch diff** before merge — **no N=1 skip, no cross-card scope reduction**. Every
> line of every card — including any reviewed at `light` in Phase 3.7 — receives a full-depth Codex
> review at least once before merge.
>
> - Run Steps F.1–F.5 for **EVERY batch, including N=1**. Nothing here is skipped.
> - `review_scope_files` = the **FULL union** of all touched files across all cards (F.1 step 4 —
>   NEVER reduced to the cross-card subset).
> - F.3 invokes the full reviewer set (Codex + doc-reviewer + api-perf-cost-auditor + qa-sentinel)
>   over that union; F.5 runs the final build.
>
> Rationale: this re-introduces the post-batch full pass that v3.35.0 de-duplicated away. That
> de-dup assumed Phase 3.7 had already full-reviewed every card — an assumption broken the moment
> `light` became selectable. The cost of one full batch-diff review is the deliberate price of the
> per-card `light` speed-up (explicit maintainer decision, v3.37.0).

### Step F.1 — Resolve scope

**→ Visibility (batch transition)**: all cards are committed. TaskUpdate `Final review` → `in_progress` and emit a Progress Bar per § "Progress Visibility". Mark `Final review` → `completed` when F.5 finishes (fixes applied, build green).

1. **Read the tracker file** to get the full picture: card IDs, files changed, commit hashes.
2. Gather git evidence in the worktree:
   ```bash
   cd <worktree-path>
   git diff --name-only <base-branch>...HEAD
   ```
3. Read each card's backlog YAML to collect `acceptance_criteria`, `files_likely_touched`.
4. Build `review_scope_files` as the **FULL union** of card-indicated files + git-touched files
   across ALL cards in the batch. **Since v3.37.0 this union is NEVER reduced** (the v3.35.0
   cross-card scope-reduction is removed) — the final review is a full-depth pass over the entire
   batch diff, so cards reviewed at `light` in Phase 3.7 still get a guaranteed full review before
   merge. Record the union in the tracker; downstream F.3 reviews it in full.

### Step F.1.5 — Workflow delegation gate (v4.14.0 — opt-in, additive)

The fan-out of F.2–F.4 (architecture baseline + multi-agent review + finding
consolidation/verification) is a **read-only** pass — it reads the committed batch
diff and emits findings, it touches no git state and asks the user nothing. That
makes it a clean fit for a **dynamic workflow**, which runs the fan-out as a
deterministic script outside this orchestrator's context window.

**Branch (decide once, here).** This is a **MECHANICAL, BINARY decision** — check the two
conditions and act on the result. You have **NO discretion**: if both hold you **MUST** delegate.
A single-card (N=1) batch, a small diff, "the context-economy benefit is marginal here", "a workflow
once degenerated on this project", or "inline is safer / I want full control" are **NOT inputs to this
gate** and **MUST NOT** override it. (Any workflow-degeneration reports concern the `new2`/`new2-resolve`
whole-batch host — a *different* workflow; the canonical guidance is that this read-only F.2–F.4 fan-out
is **exactly** where a workflow fits.) Delegating IS the SSOT-sanctioned path — the workflow mirrors this
prose; the inline branch below exists **only** for installs where the `Workflow` tool is genuinely
absent, never as a judgment-call alternative. If you run inline while the delegation conditions were met,
that is a **gate violation**: log it as
`f.final: GATE VIOLATION — ran inline despite Workflow available + new-final-review.js linked`.

- **IF** the `Workflow` tool is available to you **AND** the script
  `.claude/workflows/new-final-review.js` is present (linked by the framework on
  Claude-enabled installs) → you **MUST delegate F.2–F.4** to it (not optional — see the
  no-discretion rule above):

  ```
  Workflow({ name: 'new-final-review', args: {
    firstCardId, worktreePath, baseBranch,        // from Phase 0 / tracker
    cardPaths,                                     // backlog YAML paths
    reviewScopeFiles,                              // the FULL union from F.1
    archBaselinePaths,                             // per-card baselines if ALL present (F.2 dedup), else null
    hasApiDataFiles,                               // true unless NO scope file falls under paths.api_* / data-model
    config                                         // the parsed baldart.config.yml
  }})
  ```

  The workflow returns `{ codexEngine, findings, gateTable, summary }` where
  `findings` are already consolidated and classified (`VERIFIED` /
  `NEEDS_MANUAL_CONFIRMATION`; `FALSE_POSITIVE` already dropped) and `gateTable`
  is the qa-sentinel PASS/FAIL/SKIP table. **Skip the inline F.2/F.3/F.4 below**
  and carry those results straight into **Step F.5** (fix application + final
  build + the `AskUserQuestion` gates — which stay HERE, in the skill, because a
  workflow cannot prompt the user). Log `f.final: delegated to new-final-review
  workflow (engine: <codexEngine>)` in the tracker.

- **ELSE** (no `Workflow` tool — older Claude Code, `disableWorkflows`, or a
  Codex install where workflows have no equivalent) → run the **inline F.2–F.4
  below exactly as written**. This prose is the SSOT and the always-available
  fallback; the workflow is only an accelerator that mirrors it.

> **Drift note (maintainers):** `new-final-review.js` encodes only the
> *orchestration shape* of F.2–F.4; its agent briefs cite THIS module for the
> review *semantics*, so the SSOT for what each reviewer checks stays here. When
> you change the F.2–F.4 reviewer set, gates, or classification rules, update the
> workflow's phase/agent wiring to match.

### Step F.2 — Architecture baseline

5. **Reuse per-card baselines before re-spawning (dedup).** Phase 1 step 5b already persisted one
   `/tmp/arch-baseline-<CARD-ID>.md` per card. Before spawning `codebase-architect` for the batch
   scope, check whether every card in the batch already has a readable baseline file:
   ```bash
   MISSING=()
   for c in <ALL-CARD-IDS>; do [ -s "/tmp/arch-baseline-$c.md" ] || MISSING+=("$c"); done
   printf '%s\n' "${MISSING[@]}"
   ```
   - **All present** → do NOT re-spawn the architect for the full batch. Set `${ARCH_BASELINE_PATHS}`
     to the newline-separated **list of `/tmp/arch-baseline-<CARD-ID>.md` paths** (they already cover
     every touched file across the batch) — do NOT read or concatenate their contents inline (per
     § "Context economy" → pass paths, not concatenations; Codex Reads them on demand). Proceed to F.3.
     Log `f.2-arch: reused N per-card baselines (no re-spawn)` in the tracker. This avoids the N+1
     architect invocations the per-card persistence was designed to prevent.
   - **Any missing** (a card was added late, or a baseline was purged) → invoke **codebase-architect**
     ONCE over the batch scope to map existing architecture, critical patterns, and high-risk code
     paths for regression. Persist its output to `/tmp/arch-baseline-batch-<FIRST-CARD-ID>.md` and set
     `${ARCH_BASELINE_PATHS}` to that single path. Log `f.2-arch: re-spawned (missing baselines: <list>)`. Do NOT spawn
     the architect more than once for the batch — it is the single grounding context for all
     downstream review agents.

### Step F.3 — Codex deep code review (primary) + Claude agents (support)

> **Primary reviewer: Codex (a non-Anthropic frontier model, via `codex-companion.mjs`)** — cross-model validation. This is a SINGLE-MODEL Codex pass over the batch diff (scope + review + self-FP-check in one task) — it is NOT the full multi-agent `/codexreview` command pipeline (no sub-agent spawning, no Step 3.5 CoVe). The full per-card `/codexreview` already ran in Phase 3.7; this final pass is the cross-model batch-wide sweep. Claude agents (doc-reviewer, api-perf-cost-auditor) provide doc review and supplementary checks; qa-sentinel runs gates only.

6. **Launch Codex code review** via `Bash` with `run_in_background: true` and `timeout: 600000` (10 min). **The companion script is invoked WITHOUT `--wait`** so the Bash call returns immediately and the orchestrator can fire the parallel Claude agents in step 7; poll `$REVIEW_FILE` for completion in F.4 (it is redirected to the file with `> "$REVIEW_FILE" 2>&1`, so it fills as Codex runs and is complete when the background task finishes — no inline `tee` copy, per § "Context economy"). Combining `run_in_background: true` with `--wait` would block the shell and defeat the parallelism — do NOT pass `--wait` here.

   ```bash
   REVIEW_FILE="/tmp/codexreview-batch-<FIRST-CARD-ID>-<SESSION-ID>.md" && \
   CODEX_SCRIPT="$(ls -d ~/.claude/plugins/marketplaces/openai-codex/plugins/codex/scripts/codex-companion.mjs ~/.claude/plugins/cache/openai-codex/codex/*/scripts/codex-companion.mjs 2>/dev/null | sort -V | tail -1)" && \
   [ -z "$CODEX_SCRIPT" ] && echo "CODEX_NOT_FOUND" > "$REVIEW_FILE" && exit 1; \
   node "$CODEX_SCRIPT" task "
   Run a deep multi-agent code review for these backlog cards. This is a post-implementation
   review — the code is already written and committed. Your job is to find bugs, regressions,
   security issues, and quality problems.

   Cards to review (read each file):
   ${CARD_PATHS}

   Files changed (review ALL of these):
   ${REVIEW_SCOPE_FILES}

   Architecture baseline files (read each — they hold file paths, type signatures, patterns, high-risk paths):
   ${ARCH_BASELINE_PATHS}

   Follow the /codexreview protocol:
   1. For each card, read its backlog YAML for acceptance_criteria and entrypoints.
   2. Read every changed file in full.
   3. Check for: functional bugs, logic flaws, regressions, cross-card inconsistencies,
      security issues (auth gaps, input validation, multi-tenant isolation),
      performance issues (unbounded reads, N+1, missing pagination),
      missing error handling on external boundaries.
   4. For each finding, return:
      - finding_id: <CARD-ID>-F###
      - title: short description
      - severity: BLOCKER | HIGH | MEDIUM | LOW
      - confidence: 0-100
      - evidence: exact file:line + code quote
      - minimal_fix_direction: what to change
   5. Run mandatory false-positive check: for each finding, ask 'What is the strongest
      argument this is a false positive?' Suppress if the FP argument is convincing.
   6. Classify surviving findings as VERIFIED, FALSE_POSITIVE, or NEEDS_MANUAL_CONFIRMATION.

   Return ONLY verified findings. If zero verified bugs: state 'No verified bugs found.'
   " > "$REVIEW_FILE" 2>&1
   ```

   **Variable interpolation** (build the command string before execution):
   - `${CARD_PATHS}`: newline-separated list of backlog YAML paths
   - `${REVIEW_SCOPE_FILES}`: newline-separated list from Step F.1
   - `${ARCH_BASELINE_PATHS}`: newline-separated list of per-card baseline file paths from Step F.2 (Codex Reads them on demand — do NOT inline their contents)

7. **In parallel with Codex**, launch Claude support agents (single message):

   | Agent | `subagent_type` | Focus | Output |
   |-------|-----------------|-------|--------|
   | **doc-reviewer** | `doc-reviewer` | Cross-card doc consistency, ssot-registry completeness, invariants | Findings: `finding_id`, `title`, `severity`, `confidence`, `evidence`, `minimal_fix_direction` |
   | **api-perf-cost-auditor** | `api-perf-cost-auditor` | API/data/performance/cost defects (skip if no API/data files in scope) | Same findings schema |
   | **qa-sentinel** | `qa-sentinel` | **Mechanical gates ONLY** over the batch scope (lint, tsc, full test suite, build, `npm audit`, markdownlint) | A PASS/FAIL gate table — NOT a findings list. qa-sentinel does not read source files, does not emit severities, and does not do edge-case/reproducibility analysis (its system prompt forbids it). A gate FAILURE feeds the fix-loop the same way a VERIFIED finding does. |

   The two code-aware agents (doc-reviewer, api-perf-cost-auditor) receive: card IDs, YAML, `review_scope_files`, codebase-architect baseline, and a Budget Block per the `/codexreview` Step 2 contract (`framework/.claude/commands/codexreview.md`). qa-sentinel receives only the worktree path + the changed-file list and runs gates. Code-correctness/edge-case analysis is Codex's job (and the per-card `/codexreview` already ran) — do NOT ask qa-sentinel to produce code findings.

   **Fan-out completion barrier (BLOCKING before F.4).** The three Claude agents write to a shared
   findings pool that F.4 step 9 fans in. Before F.4 reads ANY finding, you MUST have collected the
   return value of ALL THREE Task invocations from step 7 (doc-reviewer, api-perf-cost-auditor,
   qa-sentinel) — never start the merge while a Task is still in flight. Because step 7 launches all
   three in a single message, the harness returns when all three complete; do NOT proceed to step 9
   on a partial set. (The Codex background task has its OWN barrier — step 8 below polls `$REVIEW_FILE`
   for completion. The two barriers are independent: wait for BOTH the three Claude Tasks AND the
   Codex background task before merging.)

### Step F.4 — Collect & merge findings

8. **Read Codex findings** from `$REVIEW_FILE` after the background command completes (the background
   task was launched with `timeout: 600000` in step 6 — that 10-min window is the max wait).
   - If file exists and contains findings → use as **primary code review source**.
   - If file is empty, missing, or contains `CODEX_NOT_FOUND` → **fallback**: spawn `code-reviewer`
     agent (subagent_type: `code-reviewer`) with the same scope and instructions. Log fallback
     reason in tracker: `"Codex unavailable — fallback to Claude code-reviewer"`.
   - **TIMED_OUT branch:** if the 10-min window elapses and `$REVIEW_FILE` still has no terminal
     output (no findings block and no `CODEX_NOT_FOUND`), treat the Codex pass as **TIMED_OUT** — do
     NOT block the merge gate waiting indefinitely and do NOT leave the task silently "in-progress".
     Log `f.3-codex: TIMED_OUT` in `## Issues & Flags` and take the SAME `code-reviewer` fallback as
     the unavailable case, so the final merge gate still gets a full code review.

9. **Merge all findings** (Codex + Claude agents) into a consolidated list.
   - **Each domain specialist OWNS its lane end-to-end** — it runs its OWN false-positive check in the finding pass (doc-reviewer for doc, api-perf-cost-auditor for api/perf/data, and the Codex/`code-reviewer`-fallback engine for code), so its surviving findings are **already validated**. Do **NOT** cross-validate a doc or api finding by spawning `code-reviewer` (that is the WRONG specialist judging another domain), and do **NOT** re-run the same specialist over its own findings (self-judge — no model diversity). Codex findings are likewise already FP-validated (Step F.3 protocol includes it).
   - **Residual only:** a finding the originating specialist explicitly leaves UNRESOLVED (`confidence < 80`) is routed to the finding's **domain specialist** (by `domain`: doc→doc-reviewer, api/perf→api-perf-cost-auditor, security/migration→security-reviewer, test→qa-sentinel, else code-reviewer) over the cited file:line. If that domain specialist **is** the originating finder (it already had its pass), classify `NEEDS_MANUAL_CONFIRMATION` instead of re-spawning it — never self-judge, never silently drop.
   - Classify: `VERIFIED` | `FALSE_POSITIVE` | `NEEDS_MANUAL_CONFIRMATION`.
   - `VERIFIED` findings proceed to fixes. **`NEEDS_MANUAL_CONFIRMATION` findings are NOT discarded** — list them in `## Issues & Flags` and surface them to the user via `AskUserQuestion` (treat as VERIFIED, treat as FALSE_POSITIVE, or hand off) before merge. Only `FALSE_POSITIVE` are dropped.

### Step F.5 — Apply fixes and final build

10. **Persist verified findings** to `/tmp/batch-final-review-<FIRST-CARD-ID>.md`.
11. **Merge-blocking gate (mirrors the per-card Phase 3.7 gate this final pass backstops):** if any VERIFIED **BLOCKER or HIGH** finding exists, it MUST be resolved before Phase 6 merge. Apply fixes by **domain owner** (since v3.40.0 — same Domain-Override routing as the per-card phases), then re-verify; if a BLOCKER/HIGH cannot be resolved in a single apply + one retry, log it in `## Issues & Flags` and invoke `AskUserQuestion` (override with reason / escalate to a follow-up card / halt) — do NOT proceed to Phase 6 with an unresolved BLOCKER or HIGH. VERIFIED findings of severity MEDIUM are also applied (advisory below that). Partition the verified findings by the **Domain-Override match rules** ("Domain-Override Domains"):
    - **`doc`-domain findings** (file path matching the `doc` match rule — `*.md` under `${paths.references_dir}`/`${paths.prd_dir}`, `CHANGELOG.md`, `ssot-registry.md`) → invoke the **doc-reviewer** agent once in write mode to apply them. NEVER route doc fixes to coder.
    - **`security`-domain findings** (path in `paths.high_risk_modules`, or RLS-policy SQL) and **`migration`-domain findings** (SQL under the migrations dir) → route to **coder**, but apply the Sub-agent failure protocol's STOP-on-crash rule for these domains (never inline-fallback on a security/migration fix). These are NOT collapsed into a generic "everything else" bucket.
    - **All remaining findings** (other code, perf, test) → invoke the **coder** agent once to apply them in a single pass.
    Run in the order doc-reviewer → coder (or skip either if its partition is empty). Pass only the verified findings, not false positives.
12. Run final build: `npm run lint && npx tsc --noEmit && npm run build` (redirect each to `/tmp/final-<gate>.txt` per § "Context economy"; surface only exit code + bounded extract on failure).
    If any check fails, apply self-healing retry loop (up to 3 times).
13. **Update tracker** with final review results:
    - Review engine: Codex (a non-Anthropic frontier model, resolved at runtime by `codex-companion.mjs`) (primary) | Claude code-reviewer (fallback)
    - Total findings raised / verified / false positives / needs-manual
    - Fixes applied count
    - Build status (pass/fail + retry count)
    - Highest severity found
    - **Phase-8 producer (named counters)** — ALSO write the structured line `review_findings: total=<R> verified=<V> blockers=<B>` to the tracker `## Final Review` section, where `R` = all findings raised (Codex + Claude agents, pre-FP), `V` = VERIFIED count, `B` = VERIFIED-BLOCKER count. These are the single named producers for Phase 8's batch-level `findings_total` / `findings_verified` / `blockers_count` — Phase 8 reads THESE keys, never re-parses prose. (Per-card Phase 3.7 codex counts stay in `## Pre-Merge Codex Review`; Phase 8 uses the batch-level `review_findings` line here as the canonical total so the QA-findings and codex-findings counts are not conflated.)

### Step F.6 — Post-review wrap-up (SSOT summary, sync, hand-off to Phase 6)

> This is a distinct sub-section from F.1–F.5 (its own list); the numbering below restarts and does NOT continue the F.5 counter.

1. **SSOT & Documentation Activity** (MANDATORY — run BEFORE merge):

   Summarize all documentation and SSOT updates performed during the batch:

   ```
   ## Aggiornamenti SSOT & Documentazione

   ### Documenti aggiornati
   - `${paths.references_dir}/api/<module>.md` — N nuovi endpoint aggiunti
   - `${paths.references_dir}/ui/<domain>.md` — N nuove route aggiunte
   - `${paths.references_dir}/data-model.md` — N nuove collection
   - `${paths.references_dir}/ssot-registry.md` — N entry aggiornate/create
   - `${paths.references_dir}/project-status.md` — contesto aggiornato

   ### ADR creati
   - `${paths.adrs_dir}/ADR-YYYYMMDD-<slug>.md` — [titolo] (o "Nessun ADR creato")
   ```

2. **Knowledge Base Sync** (OPTIONAL — only if the project has an external knowledge corpus, e.g. an Obsidian vault, Confluence space, or Notion workspace):

   If the project ships a `knowledge-sync` corpus agent (declared in `.baldart/overlays/new.md`), invoke it after doc updates so the external corpus stays aligned. If no such agent exists, skip this step with a one-line notice (do NOT dispatch a non-existent agent).

3. **Proceed to Phase 6** (post-batch merge & cleanup).
4. Present a **single summary report** to the user per card (and a batch summary at the end):
   - **Files changed** (short list per card)
   - **Test results** (new tests + existing tests count, pass rate at each iteration)
   - **Build/lint status** (pass + retry count if any)
   - **Fix cycles** (total number of self-healing retries across phases)
   - **Final review** (findings: N raised / M verified / K false positives | fixes applied: N | highest severity)
   - **UX testing** (PASS/FAIL/SKIP | test file path if written)
   - **QA result** (profile: skip/light/balanced/deep | verdict: PASS/FAIL/SKIP | confidence % | failing gates: which of lint/tsc/test/build/markdownlint, or "none" | findings file path). E2E is reported separately (Phase 2.6 e2e-review), not by qa-sentinel.
   - **Issues needing user attention** (anything unresolved, partially wired, or flagged)
   - **Commit hashes** (from tracker)
   - **Merge commit hash** (from Phase 6)
   - **Card status reconciliation** (Phase 6b: N cards verified DONE, K force-updated)
   - **Worktree cleanup status** (success/failed)
   - **Knowledge-corpus sync status** (from Step F.6 item 2 "Knowledge Base Sync" — COMPLETED/FAILED/PARTIAL, or SKIPPED if no corpus-sync agent is configured)
   - Overall implementation status

4b. **Next Steps & Launch Command** (MANDATORY section — always present):

   Check for remaining not-yet-DONE cards in the same epic group (match "not DONE",
   not a hard-coded status value — see the `status enum` SSOT in REGISTRY.md):

   ```bash
   # Find parent epic's cards that are NOT yet DONE (TODO | READY | IN_PROGRESS | BLOCKED)
   grep -l "parent: <EPIC-ID>" ${paths.backlog_dir}/*.yml \
     | xargs grep -L "status: DONE"
   ```

   Present the section:

   ```
   ## Prossimi Passi

   ### Lancio implementazione (copia e incolla)
   ```
   /new FEAT-XXXX-05 FEAT-XXXX-06 FEAT-XXXX-07
   ```

   ### Card rimanenti nell'epic
   | Card | Titolo | Status | Gruppo parallelo |
   |------|--------|--------|-----------------|
   | FEAT-XXXX-05 | [title] | TODO | 2 |
   | FEAT-XXXX-06 | [title] | TODO | 2 |

   ### Card completate in questa sessione
   | Card | Titolo | Commit |
   |------|--------|--------|
   | FEAT-XXXX-01 | [title] | abc1234 |
   | FEAT-XXXX-02 | [title] | def5678 |
   ```

   If ALL cards in the epic are DONE:
   ```
   ## Prossimi Passi

   Tutte le card dell'epic **FEAT-XXXX** sono state completate, e la card epic stessa è
   stata marcata `DONE` (chiusura automatica in Phase 6b, step 5e).
   Pronto per il deploy: `/deploy` o `git push origin <trunk branch>` (il `git.trunk_branch` configurato)
   ```

   > Nota: la chiusura della card epic è eseguita dal gate Phase 6b (epic-parent closure),
   > non da questo step di reporting — qui la si riporta soltanto. Se l'epic risultasse
   > ancora `TODO`/`IN_PROGRESS` mentre tutti i figli sono `DONE`, è un fallimento di
   > Phase 6b step 5e da segnalare in `## Issues & Flags`.

5. **Proceed to Phase 7** (production readiness checklist).

---
