| 1 | | Round 1 finding | Round 2 disposition | |
| 2 | |---|---| |
| 3 | | R1-1: flat tenant borrows a nested socket | **Fixed for the reported direct connection:** §5.4 authenticates the peer’s cgroup. The separate door-credential attack below remains. | |
| 4 | | R1-2: aliases and path routes remain public | **Fixed:** §5.1 checks the final resolved route, including login re-resolution. | |
| 5 | | R1-3: new box starts public | **Partly fixed:** §§5.1 and 6.3 remove the bucket-mirror dependency, but the stamping and migration mechanisms still leave public-access windows, detailed below. | |
| 6 | | R1-4: revoked grants return after restart | **Fixed for retained local state:** §5.3 persists the record and revision floor. Fresh/rebuilt boxes have an explicitly stated replay exception. | |
| 7 | | R1-5: door exceptions fail across routing | **Resolved:** §§5.1 and 5.4 remove the owner exception and define the door-to-engine transition. | |
| 8 | | R1-6: socket lifecycle conflicts with generations | **Fixed:** §5.4 assigns ownership to an instance-level manager and covers pre-seed creation and environment delivery. | |
| 9 | | R1-7: transport and body limits | **Resolved at spec level:** §§5.4–5.5 specify a separate transport, whole-call deadline, upgrade refusal and streamed-body abort. | |
| 10 | |
| 11 | Reviewed spec `8cf7cc8f` against locally available `origin/main` at `f54aa2fc`. The implementation files cited below match that revision. |
| 12 | |
| 13 | 1. **P1 — The prescribed registry stamp does not precede serving the new release (§§5.1, 6.3).** |
| 14 | |
| 15 | Start with a public route, then adopt a release declaring `doc_engine`. Following the specified mechanism—writing `internal` alongside the recorded version—allows the new process to serve before the mark is written. Even after that write, requests can use the edge’s previous route snapshot. |
| 16 | |
| 17 | Adoption repoints the live symlink at [internal/release/adopt.go:1751](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/release/adopt.go:1751), invokes the restart at [adopt.go:1831](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/release/adopt.go:1831), and only afterward records the version at [adopt.go:2051](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/release/adopt.go:2051). The edge serves an in-memory route map, replaced by `Reload`, with registry changes detected on a two-second poll; reload failures retain the previous map ([edge.go:993](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/edge/edge.go:993), [edge.go:2298](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/edge/edge.go:2298)). |
| 18 | |
| 19 | **Suggested fix:** Define a serving barrier: public admission must close, and the serving edge must observe that closure, before repointing or starting the engine release. Keep the refusal through failed adoption and rollback until the running release and classification agree. An atomic registry update alone does not provide this ordering. |
| 20 | |
| 21 | 2. **P1 — Upgrade migration explicitly serves unclassified declared engines (§§5.1, 7).** |
| 22 | |
| 23 | Have an existing release that declares `doc_engine` without holding the grant. Upgrade its edge before the first capability pass. Its new column defaults to zero, and the temporary check considers only the grant, so public requests still reach it. This happens even with a readable staged manifest until the pass runs. A missing manifest extends the exposure. |
| 24 | |
| 25 | The capability pass runs in the root adoption path ([internal/host/agent.go:4782](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/host/agent.go:4782)); its timer deliberately starts after the edge ([carlos-adopt.timer:7](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/host/units/carlos-adopt.timer:7)). Missing staged manifests produce a leave-alone result ([caps_pass.go:106](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/host/caps_pass.go:106)). The grant controls resource and sandbox settings, not HTTP admission ([internal/caps/render.go:189](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/caps/render.go:189)). An engine’s inability to run Chromium does not prove that its HTTP endpoints cannot answer, and G1 covers every declaring release. |
| 26 | |
| 27 | **Suggested fix:** Complete classification before exposing existing routes on the upgraded edge. Preserve an explicit “unclassified” state and refuse public dispatch for it when the manifest cannot be read. Do not infer public safety from expected renderer failure. |
| 28 | |
| 29 | 3. **P1 — Flat callers can borrow another app’s door credential (§§5.4, 6.1–6.2).** |
| 30 | |
| 31 | Put flat apps A and B on one box. Grant B an engine and supply B’s door key through its ordinary configuration. A reads B’s key and sends `Host: <engine-name>` through the shared door. The door authenticates B’s token; §5.4 converts that into B’s engine identity. Both engine-grant checks pass. The new cgroup check never runs on this path. |
| 32 | |
| 33 | Flat children execute under the edge’s `carlos` identity ([carlos-edge.service:28](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/host/units/carlos-edge.service:28), [backend_exec.go:2236](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/activator/backend_exec.go:2236)). Their environment files share the data directory ([paths.go:35](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/activator/paths.go:35)); the existing layout code explicitly identifies same-UID cross-tenant filesystem access ([preflight.go:181](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/layout/preflight.go:181)). Door authentication derives identity entirely from the bearer token ([door.go:103](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/edge/door.go:103)). |
| 34 | |
| 35 | **Suggested fix:** Require an enforceable isolation prerequisite for engine-authorized door credentials. Flat callers sharing `carlos` with mutually untrusted processes cannot satisfy the stated no-borrowing guarantee. Restrict that deployment shape or provide separate credential and process isolation. |
| 36 | |
| 37 | 4. **P2 — Internal engines cannot complete normal deployment verification (§§5.1, 5.4, 7).** |
| 38 | |
| 39 | Deploy a healthy engine after its home box upgrades. Adoption succeeds, but `carlos deploy` polls its public HTTPS URL. The request has no engine identity, so the new refusal prevents verification indefinitely. Granting the engine to itself does not help a CLI running off-box. |
| 40 | |
| 41 | Deployment verification uses a public origin ([deploy.go:1426](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/deploy.go:1426)) and an ordinary `client.Get` for both header and build-probe verification ([deploy.go:1536](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/deploy.go:1536)). Success requires a matching build over a 2xx response ([deploy.go:1563](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/deploy.go:1563), [deploy.go:1588](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/deploy.go:1588)). |
| 42 | |
| 43 | **Suggested fix:** Assign an authenticated API-backed verification path for internal engines and wire it into deployment watching. It must verify the running service without requiring an on-box socket or reopening a public endpoint. |
| 44 | |
| 45 | 5. **P2 — Non-home boxes cannot implement the promised port-80 refusal (§§5.1, 6.3, 8).** |
| 46 | |
| 47 | Home an internal engine on box A, then send an HTTP request for it to upgraded box B. Section 5.1 says B learns nothing new. Its existing handler therefore sees a remotely routable hostname and returns an HTTPS redirect, contrary to the specified no-redirect behavior. |
| 48 | |
| 49 | The port-80 handler checks the remote home map and redirects without contacting the home box ([edge.go:2262](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/edge/edge.go:2262), [edge.go:2284](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/edge/edge.go:2284)). Also, using `unknownHost` for the local refusal can itself redirect when a fallback URL is configured ([edge.go:2205](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/design-fleet-internal-engines/internal/edge/edge.go:2205)). |
| 50 | |
| 51 | **Suggested fix:** Define a non-redirecting refusal explicitly. Either provide non-home HTTP listeners with the classification needed to apply it, or scope the no-redirect contract to home boxes and document the remote redirect followed by HTTPS refusal. |
| 52 | |
| 53 | **Overall verdict: reject.** The revised design closes several round 1 paths, but public admission still lacks safe activation ordering, and flat door callers do not satisfy the identity anti-goal. |