carlos / platform Public
| Previous finding | Round 10 assessment | |---|---| | R1-1: flat tenant borrows a nested socket | Fixed by peer-cgroup authentication (§5.4). | | R1-2: aliases and path routes remain public | Fixed by checking the final upstream (§5.1). | | R1-3: new box starts public | Reported case fixed by classification before serving (§5.1). | | R1-4: revoked grants return after restart | Fixed with retained state; fresh-box replay is 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 ownership (§5.4). | | R1-7: transport and body limits | Resolved at spec level (§5.5). | | R2-1: stamp follows serving | Reported ordering fixed by the admission barrier (§5.1). | | R2-2: upgrade serves unclassified engines | Reported case fixed by startup classification and refusal of NULL (§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 when the barrier completes: 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 is 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 arming prerequisites 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 (§5.8). | | R5-1: platform-minted hostnames cannot classify | Fixed by execution-owner inheritance (§5.1). | | R5-2: arming rejects isolated unit-backed routes | Fixed by distinguishing backing from layout (§6.2). | | R5-3: home edge lacks the probe path | Fixed by signing the probe path (§5.8). | | R6-1: minted row’s own grant is ignored | Fixed by aggregating group grants (§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 by stopping the group and proving its cgroups empty (§5.1). | | R7-2: TCP-backed minted rows have no owner | Fixed by explicit ownership and unique non-empty backend matching (§5.1). | | R8-1: upgrade classifies a running declaring build public | Reported case fixed by scanning staged manifests; missing-manifest exposure remains an explicit residual (§5.1). | | R8-2: sleeping unit-backed route cannot clear | Resolved by operator-controlled stop-and-clear (§5.1). | | R9-1: recovery launches a declaring GoodVersion after clearing | First launch under 0 fixed by the launch gate (§5.1). An already-1, unfenced state remains uncovered below. |
Reviewed 267c0ee6 against locally available amadan origin/main at f550afa2. The implementation files cited below match that revision. No files changed.
1. P1 — A pending internal mark lets a later recovery launch skip the fence while I1 holds (§§5.1, 6.3).
The launch rule requires writing 1 and waiting for the fence when the group’s mark is 0. But 1 does not establish that the fence completed: the timeout rule deliberately leaves it set after an unsuccessful wait.
A concrete sequence:
- A sleeping nested instance has declaring build A as
GoodVersion, non-declaring B installed, and an overlap-mode failure record that selects A for recovery. With no grant remaining,--publicstops the group and clears its mark. - Adoption attempts declaring build C. It writes
1, but the edge’s reload fails. After 30 seconds adoption returns without repointing. The registry says1; the serving map still says0; B remains installed. - While reload remains unsuccessful, a public request passes the old map’s admission check and wakes the instance. Recovery selects A.
- A’s launch reads its declaring manifest and the already-set mark
1. The specified conditional does not require this launch to finish the outstanding fence. A starts, and the admitted public request reaches it.
These are existing execution paths. A failed alias read aborts reload before replacing the serving map (edge.go:925, edge.go:993). A blocked installed build selects GoodVersion directly (rollout/wakeplan.go:97), and the activator launches that selected build (activator/wakeplan.go:388). Once wake succeeds, the waiting request invokes its proxy (activator.go:5404), which selects the actual serving generation (genproxy.go:255).
I1 holds throughout: A runs only while the registry mark is 1. Public access nevertheless remains possible because the edge has not fenced that mark.
Suggested fix: Every declaring launch must require acknowledgement of the group’s current internal admission epoch, including when it finds 1 already set. A pending or timed-out transition must remain a launch refusal until its fence completes. Add a test that holds reload unsuccessful, times out adoption, and then requests a recovery wake; no declaring process may start.
Overall verdict: reject. I1 alone permits a declaring process behind an internal registry mark that the serving edge has not yet enforced.