| 1 | ACCEPT WITH FIXES |
| 2 | |
| 3 | ## Finding verdicts |
| 4 | |
| 5 | 1. **ADDRESSED — Ratchet read errors fail closed.** `internal/release/ratchet.go:118` now distinguishes absence from read errors and invalid file types; `Admit` refuses unknown state at line 100. Fresh-instance tests cover unreadable `own` and `also` directories at `internal/release/ratchet_test.go:212`. |
| 6 | |
| 7 | 2. **ADDRESSED — Resign requires channel authority.** `internal/console/apidigests.go:121` checks deploy scope, stable, pipeline passkey and approval requirements. The authorization runs inside `WithAppMutation` through `internal/release/claim_app_writes.go:59` and `internal/release/resign.go:107`. The legacy-head substitution regression is covered at `internal/console/apidigests_test.go:300`. |
| 8 | |
| 9 | 3. **ADDRESSED — History-target refusals survive marker removal.** The checks at `internal/release/release.go:810` and `:1273` no longer require the marker. Emission remains marker-dependent. Ordinary and approval-path rollback tests appear at `internal/release/writers_test.go:390` and `:405`. |
| 10 | |
| 11 | 4. **ADDRESSED — Incomplete reports cannot announce readiness.** Failed channel reads produce explicit errors at `internal/release/digests.go:183`. Both consumers propagate them into account errors (`internal/console/apidigests.go:243`, `channels_digests.go:312`), suppressing readiness through `channels_digests.go:235`. |
| 12 | |
| 13 | 5. **ADDRESSED — Ratchet paths no longer collide.** `internal/release/ratchet.go:77` encodes each channel into one flat filename. Regular-file checks appear at lines 133 and 160. Both collision orders and restart behavior are covered at `internal/release/ratchet_test.go:159`. |
| 14 | |
| 15 | 6. **NOT ADDRESSED — Production integration coverage remains incomplete (Minor).** Replay and require-flag coverage now uses `fastPassOpts` and the production-configured static handler (`internal/host/pointerdigests_test.go:151`, `internal/edge/staticdigest_test.go:153`). However: |
| 16 | - Failed-persistence coverage still constructs options manually at `internal/host/pointerdigests_test.go:60`. |
| 17 | - The new static-handler tests at `internal/edge/staticdigest_test.go:241` and `:281` never exercise failed persistence. |
| 18 | - The host replay test at `internal/host/pointerdigests_test.go:165` checks the live version, without substituting bytes or asserting that staging never occurred. |
| 19 | |
| 20 | Complete those cases through the existing production test fixtures, including assertions that refusal prevents staging/extraction and that a later digestless replay remains refused. |
| 21 | |
| 22 | 7. **ADDRESSED — Draft-dependent assertions removed.** `channels_digests_test.go:117` derives the header from its constant; lines 343 and 357 derive status expectations from constants and actual timestamp/error values. The unsafe literal-length slice is gone. |
| 23 | |
| 24 | 8. **ADDRESSED — Existing responses are shared.** `internal/console/apicli.go:1222` and `:1243` centralize the shipped responses, reused by the digest handlers. The moved wording is outside this review. |
| 25 | |
| 26 | ## New breakage |
| 27 | |
| 28 | No new Critical or Important breakage found in `bb343ec3..d04e7634`. |
| 29 | |
| 30 | `git diff --check` passes. Tests and builds were not rerun because they create files; the fix report’s execution results remain independently unverified. No files changed. |
| 31 | |
| 32 | ## Out-of-scope observations |
| 33 | |
| 34 | Non-blocking: the documented stable-resign example now requires the direct-store operator path. The controller explicitly accepted that restriction; documentation reconciliation remains with the pending copy review. |