carlos / platform Public

Merge pull request #334 from carlosframework/runbook-r1-three-deliveries

R1 is three deliveries, not one — the root binary carries the adoption fix and roll-console.sh never touches it.
Paul Campbell pushed by paul@keymail.dev b0da3d8679166aaaf7fb563f57ad592c0923c0f7 parent c135cccparent 1aa28f9
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`