# Reviewer Termination Isolation and Diagnostics Implementation Plan

## Goal

Isolate parallel reviewer failures, recover retryable terminations with the same specification, capture structured execution diagnostics, validate the subprocess resolved model, and produce attributable failure reports. Closes issue #4.

## Tasks

1. Introduce `AgentOutcome` and `ResolvedModel` types carrying `ok`, `text`/`errorMessage`, `stopReason`, `partialText`, `resolvedModel`, and `piRetryAttempts`.
2. Rewrite `runPiAgent` to aggregate JSONL state across events, capture `model_select`, retain the first partial text, and return `AgentOutcome` instead of throwing on terminal stops.
3. Change `AgentExecutor` to return `Promise<AgentOutcome>`; thread `attempt` (optional, default 1) and `label` through `AgentExecution`.
4. Add `AgentExecutionError` with `ExecutionDiagnostics` and `validateResolvedModel` that fails on `provider/id` mismatch using the real stage and label.
5. Replace the reviewer stage `Promise.all` with `Promise.allSettled` via `runReviewers`; preserve successful results and collect structured failures.
6. Add `runSingleReviewer` and same-spec recovery (one external retry, `attempt` 2) for retryable `terminated`, reusing the exact task, coverage, repair contract, and expected files.
7. Render attributable failure reports via `formatReviewerFailures` naming stage, reviewer, model, thinking, attempt, Pi retry attempts, stop reason, and reviewers completed.
8. Surface `reviewer-recovery-retry` in `ReviewProgressEvent` and the progress presenter.
9. Add regression tests for recovery success, recovery exhaustion, sibling preservation, structured report fields, model capture, model mismatch, partial text, and the progress event.
10. Update README, CHANGELOG, and this design/plan documentation.
11. Run `npm run check`, `npm test`, `npm run pack:check`, and a `/code-review` self-review on the PR.

## Acceptance Criteria

- One reviewer `terminated` no longer cancels the batch; other reviewers complete and their results are preserved.
- A retryable `terminated` recovers once with identical model, thinking, prompt, tools, manifest, and coverage contract; 5/5 then proceed to validation.
- Recovery exhaustion stays `incomplete` and unpublished; the report names the reviewer, model, thinking, attempt, stop reason, Pi retry attempts, and reviewers completed.
- Partial output never enters findings, validation, or aggregation.
- A subprocess resolved `provider/id` that differs from the request fails the review before validation with an attributable `model mismatch` error and the correct stage/label.
- Five-way concurrency, model selection, thinking, coverage contract, and 80-point threshold are unchanged.
- `npm run check`, `npm test` (81 passing), and `npm run pack:check` are clean.
