## Review: `review-profiles` branch

**Overview** — Reworks `entire review`/`inspect` into a profile-based system: named profiles with N parallel inspectors + a single consolidating judge, stored in project/local settings; adds a per-inspector timeout, a `local`/`trail` output destination, live model enumeration, and codex error-envelope surfacing. Deletes the old migration path and most of `fix.go`. ~4900 LOC, exceptionally well-documented.

### Findings

**1. Untracked working-tree files risk being committed (actionable)**
Four untracked files are in scope and **not gitignored**:
- `.pi/extensions/entire.ts` — header says _"Auto-generated by `entire enable --agent pi`… Do not edit manually"_. This is a local install artifact, not a source deliverable.
- `prompt-default-tasks.md`, `prompt-inspector.md`, `prompt-synthesis-judge.md` — dev scratch notes dropped at repo root (they just describe where prompt text lives in the Go source).

A `git add -A` would commit all four. Recommend deleting them or adding ignore rules before committing. None are referenced by the Go code.

**2. Parent-cancel vs deadline race in `RunMulti` (minor / negligible)** `run_multi.go:252-255`: `st.timedOut` overrides `status` to `Failed` _after_ `classifyStatus` already returned `Cancelled` for a parent-cancelled ctx. If a user Ctrl+C races with an inspector's deadline firing and the deadline wins (`waitErr == DeadlineExceeded`), that agent reports "timed out" instead of "cancelled". Single-agent `Run` isn't affected (parent cancel surfaces as `Canceled`). Cosmetic, extremely rare — flagging for completeness, not blocking.

### Verified sound
- **Timeout flag** — `--timeout 0` is correctly translated to the `-1` disable sentinel (`cmd.go:214-217`); help text "(0 disables)" matches behavior. The 3-state convention (positive/zero-default/negative-disable) in `inspectorTimeout` is consistent.
- **Single-writer `perAgentState`** — terminal fields routed through `fanIn` as a tagged marker; dispatch loop is the sole writer, post-loop reads are safe by construction. Sound.
- **`OnResult`/`aggregateOutput`** — `SynthesisSink` is a direct sink; `RunFinished` (and thus `OnResult`) runs synchronously inside `RunMulti` before it returns, so the read at `cmd.go:1216` is not racing the deferred `tuiSink.Wait()`. Correct.
- **`modelComponentsMatch`** — boundary-aware matching with the numeric-suffix requirement correctly distinguishes version (`sonnet`→`claude-sonnet-4-5`) from variant (`gpt-4o`→`gpt-4o-mini`); the suffix-exclusion tradeoff is documented.
- **`mergeReviewProfiles`** — pure, non-nil, no input mutation; per-profile merge semantics match the documented intent.
- **Codex `--model` + error envelope** — `failureMsg` only emitted when `!seenTurnComplete`, so stray messages on successful runs are ignored. Correct.

No correctness regressions found in the core logic. The only thing I'd act on before committing is the four stray untracked files.
