| Previous finding | Round 9 assessment |
|---|---|
| R1-1: flat tenant borrows a nested socket | Fixed by the peer-cgroup check (§5.4). |
| R1-2: aliases and path routes remain public | Fixed by checking the final upstream (§5.1). |
| R1-3: new box starts public | Fixed for the reported missing-mirror case (§5.1). |
| R1-4: revoked grants return after restart | Fixed for retained local state; fresh-box replay remains an explicit residual (§5.3). |
| R1-5: door exceptions fail across routing | Resolved by removing the owner exception and defining the identity transition (§5.4). |
| R1-6: socket lifecycle conflicts | Fixed by instance-level listener ownership (§5.4). |
| R1-7: transport and body limits | Resolved at spec level (§5.5). |
| R2-1: stamp follows serving | Fixed by the admission barrier (§5.1). |
| R2-2: upgrade serves unclassified engines | Fixed for the reported declaring-live-manifest case (§5.1). |
| R2-3: flat callers borrow door credentials | Fixed by the door’s UID restriction (§§5.4, 6.2). |
| R2-4: deployment verification fails | Fixed by watch tickets (§5.8). |
| R2-5: port-80 refusal cannot work remotely | Resolved by the narrowed contract (§5.1). |
| R3-1: previously admitted requests cross the mark | Fixed: acknowledgement waits for cancellation and completion (§5.1). |
| R3-2: flat tenant injects into a nested caller | Fixed by excluding unisolated execution while armed; historical compromise remains explicitly excluded (§6.2). |
| R3-3: grant-only routes lack watch tickets | Fixed: every deploy target receives a ticket (§5.8). |
| R4-1: foreign instances and workers remain unisolated | Fixed by the arming prerequisite and launch refusals (§6.2). |
| R4-2: path routing widens an engine grant | Fixed by exact-host engine dispatch (§5.4). |
| R4-3: watch tickets expire mid-watch | Fixed by renewal every four minutes (§5.8). |
| R5-1: platform-minted hostnames cannot classify | Fixed by execution-owner inheritance and explicit ownership (§5.1). |
| R5-2: arming rejects isolated unit-backed routes | Fixed by distinguishing backing from exec layout (§6.2). |
| R5-3: home edge lacks the probe path | Fixed by signing the watcher’s probe path (§5.8). |
| R6-1: minted row’s own grant is ignored | Fixed by aggregating grants across the execution-owner group (§5.1). |
| R6-2: static platform domains are refused | Fixed by restricting inheritance to minted instance rows (§5.1). |
| R7-1: clearing exposes a still-serving generation | Fixed for existing processes by stopping the group and proving its cgroups empty (§5.1). A subsequent-start failure follows below. |
| R7-2: TCP-backed minted rows have no owner | Fixed by recorded ownership and unique, non-empty backend matching, including TCP (§5.1). |
| R8-1: upgrade classifies a running declaring build public | Reported case fixed by scanning staged versions; the missing-manifest case remains an explicit residual (§5.1). |
| R8-2: sleeping unit-backed route cannot clear | Resolved by replacing automatic clearing with operator-controlled stop-and-clear (§5.1). |

Reviewed spec `343f0443` against locally available amadan `origin/main` at `f550afa2`. The implementation files cited below match that revision. No files changed.

1. **P1 — `--public` can expose a declaring recovery build on the next wake (§§5.1, 6.3).**

   Run a nested instance with generation rollouts enabled. Its healthy build A declares `doc_engine` and is recorded as `GoodVersion`; no group grant remains. Install non-declaring build B, which has not yet passed its first wake.

   Run `carlos route --host <host> --public`. B’s live manifest passes the check, all existing processes stop, the cgroups become empty, and the mark clears. Now send a public request. If B fails its first-wake health check, the activator starts A as its fallback and serves the request through A. The declaring engine is public again.

   Section 5.1’s assertion that everything subsequently starts from the live version is false on main. The wake planner retains `GoodVersion` as a separate staged identity and assigns it as an overlap-mode fallback ([internal/rollout/wakeplan.go:76](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/rollout/wakeplan.go:76), [internal/rollout/wakeplan.go:111](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/rollout/wakeplan.go:111)). After the failed build stops, the activator launches that fallback directly ([internal/activator/wakeplan.go:448](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/activator/wakeplan.go:448)). The edge selects the actual serving generation ([internal/edge/genproxy.go:255](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/edge/genproxy.go:255)). A failure record can also make a later wake choose A immediately, without repointing the live symlink ([internal/rollout/wakeplan.go:57](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/rollout/wakeplan.go:57), [internal/rollout/wakeplan.go:97](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/rollout/wakeplan.go:97)).

   This requires neither an incomplete stop nor a concurrent adoption. The declaring process starts **after** a successful clear, through a path outside the specified adoption barrier.

   **Suggested fix:** Make recovery and fallback activation enforce the internal mark against the build actually selected. A declaring selection must complete the admission barrier before execution, including cancelling the public request that triggered its wake. Alternatively, refuse clearing while a declaring build remains eligible for recovery, and define how the operator safely removes that eligibility. Add a test covering `--public` followed by a failed first wake and fallback to a declaring `GoodVersion`.

**Overall verdict: reject.** The new clearing operation can succeed and subsequently expose a declaring engine through normal wake recovery.