plan: R1 is three deliveries, not one
Found after the branch merged, while setting up the roll. roll-console.sh builds ./cmd/console for the box and a NATIVE carlos used only to drive ship/promote locally (its lines 52-53). It never touches the box's root /opt/carlos/carlos binary — and §4b's restart recovery lives in internal/release/adopt.go and internal/host/agent.go, which ARE that root binary. So R1 as written delivered the console half and silently left the adoption fix on the shelf. The consequence is specific rather than tidy: R5's first carlos deploy -app console would run against the OLD adoption pass, so a failed deploy would recover through the exact defect §4b exists to fix. Also names update-platform-binary.sh as the one tenant-visible step in the runbook, since it restarts carlos-edge, and says to do one box at a time and prove the edge is serving a real tenant before moving on.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+25
−7
docs/superpowers/plans/2026-08-23-console-as-an-app.md+25 −7
diff --git a/docs/superpowers/plans/2026-08-23-console-as-an-app.md b/docs/superpowers/plans/2026-08-23-console-as-an-app.md| index 7661f6014..37318863a 100644 |
| --- a/docs/superpowers/plans/2026-08-23-console-as-an-app.md |
| +++ b/docs/superpowers/plans/2026-08-23-console-as-an-app.md |
| @@ -1890,13 +1890,31 @@ Flagship's readings are in the spec's appendix. **Tito's are not, and it is depl |
| ### R1 — Deliver the code by the legacy path, one last time |
| -``` |
| -roll-console.sh <clean-checkout-at-merge-sha> both |
| -``` |
| - |
| -Tasks 1–10 are console code; they reach the boxes only this way. **Without this, R5 runs against a console that predates its own probe and cannot succeed.** Also cut a CLI release carrying the new watch, or use a locally built `carlos` for R5–R6. |
| - |
| -Verify: `/proc/<pid>/exe` names the merge sha on both boxes, and `curl -s https://<origin>/healthz` returns `ok <sha>` — the first proof Task 5 is live. |
| +**THREE deliveries, not one.** Corrected 2026-08-28, after the branch merged and |
| +setting up the roll exposed the gap: `roll-console.sh` builds `./cmd/console` for |
| +the box and a *native* `carlos` used only to drive ship/promote locally (its lines |
| +52–53). **It never touches the box's root `/opt/carlos/carlos` binary.** |
| + |
| +| Delivery | Carries | How | |
| +|---|---|---| |
| +| console | the control-plane flag and its refusal doors, #79, the claim flags, `/healthz`, the ship-door checks, the probe echo | `roll-console.sh <clean-checkout> <box>` | |
| +| **root binary** | **§4b's restart recovery and its flap bound** — they live in `internal/release/adopt.go` and `internal/host/agent.go` | build `linux/arm64` with the version ldflag, upload to `s3://<deployment-bucket>/bootstrap/carlos`, then `update-platform-binary.sh <profile> <instance> <bucket> <sha256>` | |
| +| CLI | the build-probe watch, the dirty-tree guard | a release, or a locally built `carlos` for R5–R6 | |
| + |
| +Skipping the root-binary delivery is not cosmetic. R5's first |
| +`carlos deploy -app console` would run against the OLD adoption pass — so if that |
| +deploy failed, the recovery path would be the exact defect §4b exists to fix: the |
| +rollback leaving the console down and the next pass stamping over it. Deliver all |
| +three before R5. |
| + |
| +`update-platform-binary.sh` **restarts `carlos-edge`**, the front door for every |
| +tenant on the box — the one tenant-visible step in this runbook. Do one box at a |
| +time and verify the edge is serving a real tenant route before moving on. |
| + |
| +Verify: `/proc/<pid>/exe` names the sha for the console; `carlos version` on the box |
| +names it for the root binary; `systemctl is-active carlos-edge carlos-adopt.timer`; |
| +a real tenant hostname still answers 200; and `curl -s https://<origin>/healthz` |
| +returns `ok <sha>` — the first proof Task 5 is live. |
| ### R2 — pinfra: `Type=notify` on `console.service` |