| 1 | # Review brief: console release defences |
| 2 | |
| 3 | You are reviewing `docs/superpowers/specs/2026-10-06-console-release-defences-design.md` |
| 4 | on branch `design-console-release-defences` in the carlos/platform repo, at the |
| 5 | commit named in the prompt. Read the spec, then read the code it cites: |
| 6 | |
| 7 | - `internal/release/adopt.go`, `adoptHost`: the restart-failure rollback |
| 8 | branch, `poisoned`, `ensureStaged`, `PointLive`, `stageBlocked`, `BakeDir`, |
| 9 | `WithStartUnit`. |
| 10 | - `internal/host/agent.go`: `makeRestartRoute`, `rootRestartRoute`, |
| 11 | `systemctlTryRestartUnit`, `makeStartRoute`, the `-stage-only` verb and the |
| 12 | stage-request relay, the fast converge loop. |
| 13 | - `internal/release/release.go`: `Manifest`, `Ship`. |
| 14 | - `cli.go` (the direct-bucket ship) and `internal/console/apicli.go` (the API |
| 15 | ship door). |
| 16 | - `internal/release/bake.go`, `internal/release/signer.go`, |
| 17 | `internal/registry/registry.go` (`Route.Unit`, `Route.Health`, `Route.Addr`). |
| 18 | - `internal/host/alertsink.go`. |
| 19 | |
| 20 | ## Fixed rulings (§1): do not re-argue them |
| 21 | |
| 22 | Four defences (D1 rollback on a named unit that will not come up, D2 refuse |
| 23 | the wrong Go main package, D3 dev-proof requirement for the flagship console, |
| 24 | D4 process). No new AWS account. D1 and D2 on everywhere; D3 opt-in per |
| 25 | deployment with no per-promote bypass. Enforcement on the adopting box, not |
| 26 | the client. External uptime alerting is out of scope. The threat model is |
| 27 | mistakes, not a compromised key or bucket. |
| 28 | |
| 29 | ## What to look for |
| 30 | |
| 31 | Report mechanisms that fail to honour those rulings or that break something |
| 32 | that works today. In particular: |
| 33 | |
| 34 | 1. Interleavings between the agent's fast loop, the root stage pass, the |
| 35 | hourly root pass and the stage-request relay that defeat the refusal |
| 36 | record, the proof wait or the settle check. Examples: a relay storm, a |
| 37 | bounce loop, a refusal the agent cannot read, a proof minted for a build |
| 38 | that is no longer live. |
| 39 | 2. States in which D1 makes things worse than today, such as rolling back a |
| 40 | healthy build, leaving the unit stopped, or fighting an operator's |
| 41 | deliberate stop. |
| 42 | 3. Ways today's exact failure still gets through: CLI binary as console, |
| 43 | hand ship, promote with the root key. |
| 44 | 4. Ways D3 blocks a recovery it should allow (rollback to a previously-run |
| 45 | build, break glass) or allows a build it should block (different bytes |
| 46 | under a proven version name). |
| 47 | 5. Claims about the code that are wrong. Cite file:line. |
| 48 | 6. Placeholders, contradictions, or requirements an implementer could read |
| 49 | two ways. |
| 50 | |
| 51 | A mechanism that is named, bounded and assigned to the plan is complete at |
| 52 | spec level; do not pull plan-level detail up into the spec. |
| 53 | |
| 54 | ## Output |
| 55 | |
| 56 | Number each finding, give it a severity (P1 breaks a ruling or production, |
| 57 | P2 a real defect, P3 clarity), and cite the spec section and any code |
| 58 | file:line. End with a one-line verdict: accept, accept with fixes, or reject. |
| 59 | |