REJECT

**Findings, ranked by severity**

1. **Important — Ratchet read errors fail open.** [internal/release/ratchet.go:109](internal/release/ratchet.go:109) treats every `os.Stat` failure as an absent mark. After a process restart, `EACCES` or `EIO` reading either mark directory can therefore admit a legacy pointer for a previously protected channel. Adoption then takes the unchecked staging path, reopening #253. Make `marked` return an error; only confirmed absence may admit a digestless pointer. Test unreadable marks in both `own` and `also`, using a fresh ratchet instance.

2. **Important — Resign bypasses the channel’s release authority.** [internal/console/apidigests.go:25](internal/console/apidigests.go:25) requires membership but applies neither stable’s passkey requirement nor pipeline approval rules. The corresponding rollback checks exist at [internal/console/apicli.go:1131](internal/console/apicli.go:1131) and line 1188.

   Under #253’s threat model, replay a legacy pointer naming a pruned-and-reshipped head, then confirm resign with a member bearer token. `PlanResign` computes the replacement manifest’s digest, and the console signs it. Even an already-ratcheted box can now accept that pointer. No subsequent rollback is necessary. Resign grants authority over bytes despite preserving the version string. Apply the channel’s passkey/approval requirements to confirmation, with authorization checked inside the admitted mutation. Add a legacy-head substitution test.

3. **Important — Removing the marker disables the required digestless-history refusal.** [internal/release/release.go:1267](internal/release/release.go:1267) conditions refusal on `marker != nil`; the history-target promote check at line 810 does likewise. Thus a channel with signed digests can roll back onto an unsigned history entry after emission is suspended.

   §4.6 says such an entry is **never** a rollback target once its channel has any digest. Suspending emission does not require suspending this refusal. Keep digest fields absent when the marker is absent, but enforce the target restriction independently. Cover ordinary and approval-gated rollback with the marker removed.

4. **Important — An incomplete report can declare the fleet ready.** [internal/release/digests.go:177](internal/release/digests.go:177) silently skips every channel that fails to read or verify. The report returns success, allowing [channels_digests.go:234](channels_digests.go:234) to announce that every channel carries digests and the fleet-wide flag can be enabled.

   A transient read failure on a digestless channel is sufficient. This undermines §4.6’s rollout prerequisite. Return an account error or an explicit unknown channel state and suppress readiness. Test successful listing followed by a failed channel read.

5. **Important — Valid channel names collide in ratchet storage.** [internal/release/ratchet.go:70](internal/release/ratchet.go:70) maps `foo` to `foo.digests`, while `foo.digests/bar` requires that same path to be a directory. Both names pass `ValidChannel`. Marking `foo` first permanently prevents the other channel’s digest-bearing pointers from being admitted. In the opposite order, `note` accepts the directory as `foo`’s mark.

   Use a collision-free channel encoding and validate mark file type. Test both creation orders. The existing `canary`/`canary/x` test does not cover this collision.

6. **Minor — Security tests bypass the production integration they claim to protect.** [internal/host/pointerdigests_test.go:60](internal/host/pointerdigests_test.go:60) constructs options manually, so removing the ratchet from `fastPassOpts` leaves it green. [internal/edge/staticdigest_test.go:126](internal/edge/staticdigest_test.go:126) calls `Admit` directly instead of presenting a replay to the handler.

   Add behavioral coverage through the production option builders and static handler: replay refusal, failed persistence, and the require flag on a fresh box. Assert that substituted bytes are neither staged nor extracted, with a successful control case.

7. **Minor — Tests still depend on draft copy.** [channels_digests_test.go:330](channels_digests_test.go:330) hard-codes the status wording; line 339 slices a formatted constant using a draft literal’s length, which can panic after a shorter copy edit. Line 119 also hard-codes the new header label. Derive expectations from the constants and actual timestamp/error values.

8. **Minor — Two added string literals contain em dashes.** [internal/console/apidigests.go:31](internal/console/apidigests.go:31) and line 111 are the only hits in the added-Go-lines check. They reproduce existing wording, but still violate the plan’s added-string gate. Reuse a shared existing response definition rather than adding duplicate literals; no wording review is needed for that refactor.

**Ruling disagreements**

- **P9: disagree.** Finding 3 follows the spec’s unconditional history-target restriction. The ledger’s suspension rationale cannot override that higher authority.
- **P11: disagree.** Finding 2 disproves the premise that resign cannot change the effective build. App-member eligibility does not eliminate stronger channel authorization requirements.
- **Task 11’s em-dash exception: disagree with the implementation exception.** Preserving shipped wording is reasonable; duplicating prohibited literals is unnecessary.

The remaining rulings are sound within this branch’s scope:

| Ruling | Assessment |
|---|---|
| Task ordering and deferred approved-copy record/test | Accepted as explicitly authorized for this review. |
| P1 | Mechanical compilation corrections are appropriate. |
| P2 | Fixture ordering correctly preserves legacy pointers before enabling emission. |
| P3 | Resign’s `WithAppMutation` wrapper is necessary and present. |
| P4 | Exact-key, valid-account Put/Delete classification is appropriately bounded. |
| P5 | Census, fixtures, probes and service-credential exclusions are appropriate. |
| P6 | Adding the missing copy ID is correct; the eventual pin must include the subsequently added IDs too. |
| P7 | Correct protection for approval-gated rollback through promote, subject to finding 3’s marker-off correction. |
| P8 | The heuristic is reasonable; it cannot reliably identify an old writer. |
| P10 | Binding live-sibling backfill to the available signed digest is correct. |
| P12 | Replacing the rewritten extraction diagnostic’s em dash is correct. |
| Task 7 staging duplication | Acceptable temporary composition choice. |
| Task 7 held-materialization scope | Acceptable Plan 1 boundary; promotion-record authorization remains Plan 2 work. |
| Task 9 agent/edge directory resolution | Correct: matching paths share disk marks; separate processes retain separate memory. |
| Task 10 legacy account binding | Correct and necessary for resigning pre-account pointers. |

**Deferred minors that must be fixed before merge**

- Task 6’s read-side fail-open and channel-path collision: promote both to **Important**, as above.
- Tasks 8–9’s production-wiring and static refusal coverage.
- Task 12’s draft-dependent assertions.
- Task 5’s marker-off rollback/history-promote coverage, alongside the P9 correction.

The remaining deferred items can follow separately: marker timestamp preservation on retry, CAS retry ergonomics, error wrapping, transient temporary-file races, repeated sibling writes, raw planning-error classification, partial multi-account operations, repeated marker reads, cache cleanup, and smaller test-strengthening opportunities. The console already supplies the resign audit missing from the release-layer actor argument.

Reviewed through `bb343ec3`; `git diff --check` is clean. No files changed. Tests and darwin/windows/linux-arm64 cross-compiles were not run because they write files, so those checks remain unverified.