## Summary
Revision 30 materially strengthens the prior plan: provider attempts and detachment now share one admission lock through terminal persistence, and the promotion policy digest is correctly defined over raw installed-resource bytes before parsing. However, its asserted exact source-lock map is false for two live writer paths, so the evidence snapshot cannot yet satisfy its shared-inode/no-torn-read acceptance criteria.

## Claims
- The immutable RALPLAN index records `stage-30-revision.md` with SHA-256 `700d443d4570a32a42e3a2d92dd6758cd59cfbd109f48f65d9c5c2a489ab7e3c`, matching the assigned revision.
- The addendum defines non-mutating readers with `O_RDONLY|O_NOFOLLOW|O_CLOEXEC`, metadata/inode checks, `LOCK_SH`, non-recovering validation, and no simultaneous subsystem locks (`stage-30-revision.md:110-128`).
- It linearizes the full diagnostic attempt by holding `DiagnosticHost._admission_lock` from final validation through reservation, provider invocation, receipt/unknown persistence, and bounded completion; detach uses that same lock (`stage-30-revision.md:130-151`).
- It requires SHA-256 over raw `importlib.resources` bytes before decode/schema validation, and a network-disabled wheel build/inspect/temp-target import test (`stage-30-revision.md:153-156`).
- `OverlayJournal`, not `AdaptiveEventStore.locked()`, owns overlay writes with `root/.authority-transition.lock` (`checkin_cli/adaptive_nutrition.py:5633-5640,5704-5716`).
- The live canonical path is `customer_root/wizard/events.jsonl` (`checkin_cli/customer_admin.py:3659`); `EventStore` writes it under `wizard/.events.lock` (`checkin_cli/store.py:54-55,413-424`), while `CanonicalSequenceJournal` is constructed against the same event path with `adaptive_root/.events.lock` (`checkin_cli/customer_admin.py:3731-3735`; `checkin_cli/adaptive_nutrition.py:5353-5380`).

## Analysis
### Provider/detach linearization
The conservative one-lock choice closes the Stage-28 route/revalidation gap. If delivery acquires first, the durable terminal result is completed before detachment can linearize; if detach acquires first, it durably marks `detaching`, removes routes, and subsequent admission has zero reservation/provider delta. The explicit cancellation, timeout, crash-recovery, and close-first/provider-first tests make the intended boundary implementable. Serializing diagnostic sends is a sound tradeoff in the single-owner isolated runtime.

### Raw wheel resource digest
The previous source-tree/serialization ambiguity is closed. Comparing raw resource bytes before any decode means the runtime validates exactly what the installed wheel exposes; explicit package-data inclusion plus hermetic wheel inspection/import catches source-only success. Limiting the release claim to the wheel correctly avoids an unsupported sdist assertion.

### Exact source-lock mapping
The table still merges files that do not share the listed writer inode. Overlay rows are written through `OverlayJournal._append()` under `.authority-transition.lock`, so a new shared reader on `.adaptive.lock` does not serialize with their mutation. Separately, `canonical_events_path` has two writer lock domains in the existing code: EventStore's wizard `.events.lock` and CanonicalSequenceJournal's adaptive-root `.events.lock`. A `CanonicalSequenceJournal.read_locked()` that claims to cover both canonical events and sequence under only the latter lock does not synchronize with EventStore's append.

The strongest antithesis is that full before/after revision fencing can detect cross-source change. It cannot satisfy the plan's stronger per-source shared-inode guarantee or prevent a read from seeing a writer's in-progress append; it is a cross-domain coherence check, not a substitute for the lock used by each writer. Fencing remains useful after the domains are split, but cannot repair an incorrect lock map.

## Root Cause
The addendum classified records by owning facade rather than tracing each concrete writer's lock inode. `AdaptiveEventStore` delegates overlay writes to `OverlayJournal`, and the canonical event file is both an EventStore file and an input to a sequence journal with a different lock. Thus the proposed reader domains do not match all current writer domains.

## Findings
1. **HIGH (reported P1) — `stage-30-revision.md:118-122`: overlay lock mismatch.** The table places `overlay_path` in the `.adaptive.lock` read domain, but `OverlayJournal._append()` mutates that file under `.authority-transition.lock`. A snapshot under `.adaptive.lock` can race the append and cannot prove no torn evidence. **Fix:** add an `OverlayJournal` non-mutating shared reader using the verified `.authority-transition.lock`, or explicitly migrate every overlay writer to `.adaptive.lock`; make that decision and writer/read race test part of the table.
2. **HIGH (reported P1) — `stage-30-revision.md:123-126`: canonical event/sequence lock mismatch.** `CanonicalSequenceJournal.read_locked()` is assigned both `canonical_events_path` and `canonical_sequence_path` on one `.events.lock`, while EventStore appends the canonical event file under the wizard-root `.events.lock`; the sequence journal uses adaptive-root `.events.lock`. The exact-lock claim is therefore untrue. **Fix:** snapshot canonical event data under EventStore's writer lock and sequence data under CanonicalSequenceJournal's actual writer lock as separate domains/tokens, validate/retry their relationship without nesting locks; alternatively redesign all writers onto one declared inode and prove it.

## Recommendations
1. Revise the evidence table and named APIs before implementation: make overlay a distinct `.authority-transition.lock` domain unless its writer is deliberately migrated.
2. Split the canonical event and canonical sequence domains, including their exact root-qualified paths, writer ownership, revision tokens, rejection reasons, and deterministic writer/read barrier tests. Do not say one reader protects both until there is one actual shared writer inode.
3. Retain the admission-lock attempt/detach protocol, full-triple/generation propagation, raw-byte resource digest, explicit wheel package-data inclusion, and offline install verification unchanged.

## Architectural Status
BLOCK

## Code Review Recommendation
REQUEST CHANGES

## Tradeoffs
- **Split readers by present writer inode (recommended):** preserves existing writer boundaries, needs one extra snapshot/token and relation retry; fulfills read-only and same-inode guarantees.
- **Unify writers onto a new lock inode:** produces a simpler table but changes ordinary locking/concurrency behavior across EventStore, canonical sequence, and overlay paths; requires careful migration and broader regression tests.
- **Keep `.adaptive.lock`/sequence-lock readers plus revision fencing:** lower implementation work, but does not synchronize with the actual writers and violates the stated acceptance contract; reject.
