## Verdict
**ITERATE**

## Claim Checks

- The immutable target was read in full. The RALPLAN index records `stage-28-revision.md` as revision stage 28 with SHA-256 `f489a4b446e9e661e8e97c9af7e7d77d1512e06c8dd88fd02aa77099e93f12ed`, matching the assignment.
- The final addendum closes most prior blockers. It selects a separate dormant diagnostic Telegram process, makes the configured profile root the isolated root, fixes compiled root containment, defines spec and bot digest canonicalization, makes Topic-59 the sole persistent control route, defines prepare/activate/revalidate/close transitions, defines two atomic dynamic role routes plus the persistent operator route, limits the source gateway change to authenticated bounded export, names source ledgers and revision tokens, fixes promotion root identity, and gives exact test/report commands and state-specific preflight outcomes.
- The topology fits the current gateway. `TelegramAdapter` currently owns one bot/application and lazily constructs the ordinary `NutritionCoachingCoordinator`; `NutritionCoachingCoordinator._configure_registry` exposes only enabled customers and also creates the legacy trainer-DM bridge. A separate dormant adapter with no ordinary coordinator, followed by activation of one marked enabled isolated registry and installation of only two dynamic role routes, is a coherent way to satisfy the enabled-only runtime without weakening ordinary startup or retaining the DM bypass.
- The registry and preflight changes are placed at the correct boundaries. Current `CustomerSpec`/`RegistryDocument` enforce distinct full triples/spaces rather than distinct users, `load_runtime_customer_registry` is the ordinary committed-activation gate, and `GateDPreflightReceipt` has a closed v1 shape. The plan preserves same-user/distinct-full-triple legality and v1 while adding marked-registry rejection, a capability-gated diagnostic loader, and a separate closed diagnostic receipt.
- The capability/session and crash protocol is representative enough to implement: bounded one-use capabilities, exclusive 60-minute expiry, random per-process boot epoch, predecessor/digest journals, activation-before-route-install with compensating cleanup, route removal before disable/terminal append, and restart recovery all have named outcomes and row/provider expectations.
- Promotion and verification are materially stronger than earlier revisions. The plan fixes host-owned root derivation, exact marker files, an empty v1 migration allowlist, a digest-pinned policy resource, named docs/hash tests, focused and full gateway commands, profile full/compile commands, a closed report shape, race coverage, and a human-only live boundary.
- One load-bearing contradiction remains in the exact evidence-reader contract. Revision 28 explicitly requires `WizardStorage.locked()`, `AdaptiveEventStore.locked()`, and public `schedule_delivery_ledger()` for source reads. In the current files these are not read-only locks: `WizardStorage.locked()` runs `mkdir`, `chmod`, and opens/creates `.wizard.lock` in append mode; `AdaptiveEventStore.locked()` runs `mkdir`, `chmod`, `touch`, and opens `.adaptive.lock` read/write; `schedule_delivery_ledger()` enters `_schedule_lock`, which `touch`es/chmods and opens the schedule lock read/write. That conflicts with the retained byte-for-byte/read-only evidence principle and full-tree non-mutation check, and can create lock artifacts during an audit. The earlier `profile_authority_read_lock` requirement does not fix these subsystem calls or establish a shared, non-creating source-module read lock.
- The new package resource is also not yet deployably scoped. `checkin_cli/policies/diagnostic-promotion-policy.json` is required to be installed and digest-validated, but current `pyproject.toml` has no explicit package-data rule and the implementation file list does not name `pyproject.toml`, `MANIFEST.in`, or an installed-wheel/resource test. The named digest test can pass against the source tree while a built installation omits the JSON resource.

### Representative implementation simulation

1. **Dormant start and activation:** validate the strict roots/spec/test-bot identity, construct `DiagnosticControlService` without the ordinary coordinator, register only the review route, consume prepare then activate capabilities, transactionally mark/enable the isolated customer, build the child coordinator with the diagnostic loader, and atomically install customer/trainer routes. Current enabled-only coordinator behavior and trainer-DM code are accounted for by the separate adapter contract.
2. **Expiry/close race:** the adapter route lock gives install/remove one winner; lookup snapshots a typed route and current-session revalidation before dispatch prevents a stale route from reaching a reservation. Detach removes routes first, then disables and terminalizes under the profile transaction; startup recovery covers crashes on either side.
3. **Source export:** capability consumption, bounded validated reads, before/after revision fencing, in-memory schema/forbidden-value validation, and O_EXCL/O_NOFOLLOW atomic output are specified. Execution becomes ambiguous at the named subsystem lock calls because following the plan literally can mutate/create source lock state, while replacing them requires inventing new reader APIs and their interaction with writers.

## Missing Evidence

Definitely missing:

1. A named non-creating, non-chmodding shared read-lock API for wizard, adaptive, and schedule evidence sources, including behavior when the required lock does not already exist and tests proving writers and snapshot readers synchronize on the same inode.
2. An explicit package-data inclusion change and verification that `diagnostic-promotion-policy.json` is available through `importlib.resources` from a built/installed package, not only from the source checkout.

Possibly unclear, but not independently blocking after those fixes: `DiagnosticRoleRoute` should state explicitly that lookup authenticates the incoming `user_id` against the stored full triple, not merely the `(chat_id, topic_id)` map key; the surrounding full-triple and live-pin invariants imply this, but the exact adapter method contract currently only spells out destination lookup.

## Approval Boundary

Execution may rely on the selected separate-process topology, ordinary-loader compatibility boundary, session/transition model, route install/remove ordering, bounded capability fields, evidence schemas/revision tokens, synthetic replay provenance, promotion allowlist, exact preflight states, verification commands, and human-only live boundary. Do not implement or approve production/source snapshot reads using the current mutating `locked()`/schedule APIs, and do not claim the digest-pinned policy is installable until package-data inclusion is explicit and tested. No live Telegram, credentials, manual P2-P6, real-customer operation, or deployment is approved.

## Summary

- **Clarity:** High overall; exact evidence locking still contradicts the read-only invariant.
- **Verifiability:** Strong state/route/report matrix; missing synchronization and installed-resource proofs.
- **Completeness:** Nearly complete, with two bounded but load-bearing implementation gaps.
- **Big Picture:** Separate process/root/bot plus bounded source export fits the isolation goal and avoids ordinary authorization weakening.
- **Principle/Option Consistency:** Topology and authority choices are consistent; mutating source-module locks are not consistent with read-only evidence.
- **Alternatives Depth:** Separate process, hot attach, bespoke implementation, master bypass, and three-account-only alternatives are adequately compared.
- **Risk/Verification Rigor:** Strong crash/race/forbidden-data coverage; source-read lock behavior and packaging need exact tests.

## Required Changes

1. Replace each exact evidence-reader use of `WizardStorage.locked()`, `AdaptiveEventStore.locked()`, and `schedule_delivery_ledger()` with named read-only APIs that open an already-existing regular 0600 lock file using `O_NOFOLLOW|O_RDONLY` and `LOCK_SH`, never mkdir/touch/chmod/create/recover. Make the corresponding writers use the same lock inode with `LOCK_EX`; missing/unsafe locks must fail closed with `snapshot_unstable` or `corrupt_state` and no final artifact. Add before/after tree tests for missing-lock rejection and successful reads, plus a writer-vs-snapshot race test.
2. Add the packaging metadata file to the implementation scope, explicitly include `checkin_cli/policies/diagnostic-promotion-policy.json` as package data, and add a build/install or wheel-inspection test that loads the bytes with `importlib.resources` and verifies the embedded SHA-256.
3. In the adapter contract, define `DiagnosticRoleRoute` with its exact full triple and require `_lookup_diagnostic_role_route` to compare the update sender `user_id` as well as `(chat_id, topic_id)` before returning a route; retain provider/product row zero on mismatch.
