| index b11ee48f2..8b0acbc56 100644 |
| --- a/docs/superpowers/plans/2026-10-16-claim-activation-dev-cohort1.md |
| +++ b/docs/superpowers/plans/2026-10-16-claim-activation-dev-cohort1.md |
| @@ -4,40 +4,44 @@ Draft, first written 2026-10-16, revised 2026-10-17 against main at 26065378. St |
| |
| ## Go package (for Paul): the v0.28.4 session |
| |
| -Prepared on 2026-10-18 for platform-1e to present. The values below were read read-only on DOCS-T1; nothing was changed on any box or bucket. The v0.28.3 package is in this file's history at `ccaea17f`, the v0.28.2 one at `72b5ab3e`. |
| - |
| -**Where things stand.** The first signing session (2026-10-18) did 5.0a (digests on for `bab`, console `7c1beb2d`), 5.1 (roster revision 5: leo in pool `cohort1`, sophie in pool `console`, `dev-console` enrolled) and 6.1 (the v0.28.2 identity published). It stopped at 6.2 on leo's v0.28.1 `carlos.prev`, and was torn down (CloudTrail clean). v0.28.3 (`50f5b268`, `install-channel --policy`) was published and rolled to dev's boxes, but its pointers carry no `release_tag`, and v0.28.3's `install-channel --policy` would have refused them (blocker 7). Paul chose option (b): `install-channel --policy` gains a required `--identity FILE` (main `f3bf1214`). v0.28.4 is built from `f3bf1214` and also carries platform-87's console invite delivery (`91a651b3`). It is not yet published or rolled. Read on 2026-10-18: leo, sophie and dennis run v0.28.3 (`.prev` v0.28.2); the dev console runs `7c1beb2d`; the roster is at revision 5 (etag `f3717d8d67f496ffd9525704c7a690b0`); no floor is published; `control/system/router/releases/` holds only `v0.28.2.json`; `apps/bab/console/releases/` has no `50f5b268` or `f3bf1214`. |
| - |
| -**v0.28.4 values** |
| -- Release: v0.28.4, built on DOCS-T1 from main `f3bf1214` (`~/.cache/release-v0.28.4/src` at `f3bf1214ab92a47ecb626400e7bd1b35cd7a112c`, main's tip). Tag commit: **TO-CONFIRM** (the forge has no v0.28.4 tag yet; it should be `f3bf1214`). |
| -- carlos `linux-arm64` (router artefact, signer CLI, box binary): **TO-CONFIRM** from v0.28.4's signed `SHA256SUMS.txt`. Local build: `736826e40d5c1de399678e8bf82bbd15c0a5123f766089d5b42d0539f2ea4b21`. |
| -- carlos `linux-amd64` (operator CLI for 5.0a): **TO-CONFIRM**. Local build: `2d53162fa28accc724a0571f8c7ff59ca36c9050201446e3f33faf4a6f608548`. |
| -- `SHA256SUMS.txt` and `SHA256SUMS.txt.sig`: **TO-CONFIRM**, sha256 of each, signature verified with the README's pinned key. The list must name `carlos_0.28.4_amd64.deb` and `carlos_0.28.4_arm64.deb` and no other `carlos_*.deb`. Any published sha256 that differs from the local build stops the release block. |
| -- Console: `~/.cache/release-v0.28.4/console-linux-arm64`, 47186082 bytes, sha256 `8d49199f433662ab183a98ce7a5ebeb18f36bc02af5689752580a596bc565e9b`. Checked without running it: `file` says stripped aarch64; `go version -m` shows `path github.com/carlosframework/platform/cmd/console` and `-ldflags="-s -w -X github.com/carlosframework/platform/internal/version.Build=v0.28.4"`, the stamp exactly once. Never rebuild it. |
| -- Console ship version `CV`: `f3bf1214` (the build's source commit; must equal the tag's commit). `apps/bab/console/releases/f3bf1214/` does not exist, so the ship is new. |
| -- Identity key: `control/system/router/releases/v0.28.4.json`, new and create-only. The v0.28.2 identity (`v0.28.2.json`, `2d22f05f`) stays as it is, unused. No v0.28.3 identity exists; none is published now, and one that ever appears is left as it is. |
| -- Floor: `{"min": 1, "min_release": "v0.28.4"}` (`floor.json`, sha256 `881acf53c6f3753c685656bba62f632ed29a2fff75be476c58df93737a6b37a9`). Expected `floor_sha256` `1a6a7e50f1081e1fdebe07026a9ad1cd0b27e9e36851176c5f510185832a4ab3`, the sha256 of the compact `{"min":1,"min_release":"v0.28.4"}` (the same rule gives v0.28.2's `3a361ab8…`). `sign-policy`'s output is the value of record. |
| +Final, 2026-10-19. Every value below was read or verified read-only on DOCS-T1 between 07:50Z and 07:55Z; nothing was changed on any box or bucket. Earlier packages are in this file's history: v0.28.3 at `ccaea17f`, v0.28.2 at `72b5ab3e`. |
| + |
| +**Where things stand.** The first signing session (2026-10-18) did 5.0a (digests on for `bab`, console `7c1beb2d`), 5.1 (roster revision 5: leo in pool `cohort1`, sophie in pool `console`, `dev-console` enrolled) and 6.1 (the v0.28.2 identity published). It stopped at 6.2 on leo's v0.28.1 `carlos.prev` and was torn down (CloudTrail clean). v0.28.3 brought `install-channel --policy` but needed a tag on the channel pointer, which `carlos system update` does not write before a floor (blocker 7). Paul chose option (b): `--identity FILE` (main `f3bf1214`). v0.28.4 carries it, with platform-87's console invite delivery (`91a651b3`), and is published and on dev's boxes (platform-1e, "v0.28.4 on dev"; verified below). The dev console is still on `7c1beb2d`, waiting for 5.0a. Nothing is open. |
| + |
| +**v0.28.4 values (all confirmed)** |
| +- Tag: `v0.28.4` on `f3bf1214ab92a47ecb626400e7bd1b35cd7a112c` (`git ls-remote --tags` on the forge: tag object `4807dd9d…`, peeled `v0.28.4^{}` = `f3bf1214…`). |
| +- `SHA256SUMS.txt`: sha256 `b2dcd93c2a24ba474f8832eed1e6ee03cb97799c1ed161b9e710f59ef4c2cd2f`, 704 bytes, ends in a newline; lists `carlos_0.28.4_amd64.deb` and `carlos_0.28.4_arm64.deb` and no other deb. `SHA256SUMS.txt.sig`: sha256 `480ecfb158371bc4ea2be963dbcda4dba8be58203ca591b6645b54ea1c71d812`, 89 bytes. Downloaded from `https://github.com/carlosframework/releases/releases/download/v0.28.4/`; `openssl pkeyutl -verify` with the README's pinned key printed "Signature Verified Successfully". Both are byte-identical to the local build's `dist/` copies, and `sha256sum -c` passed for every listed file. `publish-identity` carries both verbatim. |
| +- carlos `linux-arm64` (router artefact, signer CLI, box binary): `736826e40d5c1de399678e8bf82bbd15c0a5123f766089d5b42d0539f2ea4b21`, from the signed sums. It equals the local build, the artefact in dev's signed `stable.json` and `canary.json` (key `bootstrap/router/v0.28.4/carlos-linux-arm64`, 49217698 bytes in the bucket), and `/opt/carlos/carlos` on leo, sophie and dennis. |
| +- carlos `linux-amd64` (operator CLI for 5.0a): `2d53162fa28accc724a0571f8c7ff59ca36c9050201446e3f33faf4a6f608548`, from the signed sums, equal to the local build. |
| +- Console: `~/.cache/release-v0.28.4/console-linux-arm64`, 47186082 bytes, sha256 `8d49199f433662ab183a98ce7a5ebeb18f36bc02af5689752580a596bc565e9b`. Checked without running it: `file` says stripped aarch64; `go version -m` shows `path github.com/carlosframework/platform/cmd/console` and `-ldflags="-s -w -X github.com/carlosframework/platform/internal/version.Build=v0.28.4"`, the stamp exactly once; its sha256 is not in v0.28.4's sums (count `0`). Never rebuild it. |
| +- Console ship version `CV`: `f3bf1214`, the tag's commit. `apps/bab/console/releases/f3bf1214/` does not exist yet, so the ship is new. |
| +- Identity key: `control/system/router/releases/v0.28.4.json`, new and create-only, not yet written. The v0.28.2 identity (`v0.28.2.json`, 1076 bytes, `2d22f05f`) stays as it is, unused. No v0.28.3 identity exists; one that ever appears is left as it is. Expected identity: `version` and `release_tag` `v0.28.4`, `moves_protocol` `1`, router `bootstrap/router/v0.28.4/carlos-linux-arm64` `736826e4…4b21`, console `bootstrap/console/v0.28.4/carlos-linux-arm64` `8d49199f…5e9b`. |
| +- Floor: `{"min": 1, "min_release": "v0.28.4"}` (`floor.json`, sha256 `881acf53c6f3753c685656bba62f632ed29a2fff75be476c58df93737a6b37a9`). Expected `floor_sha256` `1a6a7e50f1081e1fdebe07026a9ad1cd0b27e9e36851176c5f510185832a4ab3`, the sha256 of the compact form (the same rule gives v0.28.2's `3a361ab8…`). `sign-policy`'s output is the value of record. No floor is published yet. |
| - Policy and identity files: `/root/claim-trial/policy.v0.28.4.json` and `/root/claim-trial/identity.v0.28.4.json`, new paths on the signer, leo and sophie, each checked absent before `box_put`. The first session's `policy.json` (`dfac87e6`) and `identity.json` (`2d22f05f`) stay staged on leo and sophie, unused. |
| -- 6.1a: `install-channel --policy /root/claim-trial/policy.v0.28.4.json --identity /root/claim-trial/identity.v0.28.4.json`. Its `-h` output, checked against the local v0.28.4 CLI, is quoted in 6.1a. The `claims` help is unchanged. |
| -- Signer: write grant on exactly `control/system/router/releases/v0.28.4.json`, no prefix; CLI carlos v0.28.4 `linux-arm64` (TO-CONFIRM above); jq 1.7.1 `4dd2d8a0…b4a5`. |
| +- 6.1a: `install-channel --policy /root/claim-trial/policy.v0.28.4.json --identity /root/claim-trial/identity.v0.28.4.json`, help as quoted in 6.1a. |
| +- Signer: write grant on exactly `control/system/router/releases/v0.28.4.json`, no prefix; CLI carlos v0.28.4 `linux-arm64` `736826e4…4b21`; jq 1.7.1 `4dd2d8a0…b4a5`. |
| - Console rollback version: `7c1beb2d`, promoted with digests on. |
| |
| +**Checks today (2026-10-19, read-only)** |
| +- Pointers, 07:53Z: `stable.json` (promoted 07:50:55Z) and `canary.json` (07:50:02Z) have `current` `{version v0.28.4, source release:v0.28.4, released_at …, artifacts.linux-arm64 {bootstrap/router/v0.28.4/carlos-linux-arm64, 736826e4…4b21}}` and no `release_tag` or `moves_protocol`: untagged, as expected. 6.1a's precondition will hold: `publish-identity` takes the router sha256 from the signed sums' `carlos-linux-arm64` line (`identityRelease`, `internal/claimactivation/artifacts.go` at `f3bf1214`), with key `bootstrap/router/v0.28.4/carlos-linux-arm64` and version `v0.28.4`, and that is `736826e4…4b21`, the sha256 and key both pointers carry. |
| +- Leo and sophie, over SSM: `carlos v0.28.4` (`736826e4`), `.prev` `carlos v0.28.3` (`6154afb4`); `applied.json` v0.28.4 (leo `stable` 07:52:09Z, sophie `canary` 07:51:03Z); edge and instance-control `active`; no `host-actor.json`, guard, edge drop-in, `channel-identity.json` or `/opt/carlos/system/console`; leo has no `CARLOS_HOST_CLAIM` or `CARLOS_SYSTEM_CHANNEL`, sophie `CARLOS_SYSTEM_CHANNEL=canary`. Staged 5.1 files unchanged, each root:root `600`, one link, in a root `700` `/root/claim-trial`: leo `release.pub` `960d03ff`, `leo-climbing-enrollment.json` `800b181f`; sophie `release.pub` `960d03ff`, `sophie-knitting-enrollment.json` `85380180`, `console-id` `cfacdf55`; both `policy.json` `dfac87e6`, `identity.json` `2d22f05f`. |
| +- Dennis, 7.1's check: `Success`, `absent /opt/carlos/system/guard/policy.json`, `absent /etc/carlos/host-actor.json`, `carlos v0.28.4`; `.prev` `carlos v0.28.3` (`6154afb4`). PASS. |
| +- P9 on sophie, 07:54Z: PASS (record under P9). It ran against the `7c1beb2d` console; the invite-delivery console arrives only with 5.0a, so P9 runs again after 5.0a and again in 6.3. |
| +- Bucket: roster revision 5 (etag `f3717d8d67f496ffd9525704c7a690b0`, unchanged since 2026-10-18 10:21:54Z); `control/moves-protocol.json` 404; `control/system/router/releases/` holds only `v0.28.2.json`; nothing under `claim-signer/`; the `bab` digests marker is in place; `x-carlos-version: 7c1beb2d`. |
| + |
| **Paul's go.** It is said to cover the merge, the release, the dev roll, and the new session from 5.1's leftovers through step 7. Paul's go on 2026-10-18 named "publish-identity and the console promote redone for v0.28.3", so 5.0a's promote-only step is approved (relayed by platform-1e; carried to v0.28.4 by the coordinator), with `7c1beb2d` as its rollback. Paul chose option (b) for the untagged pointer. platform-1e confirms with Paul before the signer is created. |
| |
| **The blocks, in order, each with its stop points** |
| -1. **Release v0.28.4** (README, "Releasing the platform"): tag `f3bf1214`, publish, verify from the public side, fill in the TO-CONFIRM values. Stop: the signature does not verify; the tag is not on `f3bf1214`; the sums list other debs; any published sha256 differs from the local build. |
| -2. **Dev roll, boxes only** (step 1's commands with `--version v0.28.4`, `stable` then `canary`; no console item). Stop: a box not `current` at v0.28.4, `refused` or `rolled-back`; instance-control not restarted (H4). Expected after: each box `carlos v0.28.4`, `.prev` `carlos v0.28.3`, and pointers without `release_tag` (expected). |
| -3. **5.0a, promote-only** (approved): ship and promote `f3bf1214` to `canary/console` with the v0.28.4 amd64 CLI. Stop: the console's sha256 is not `8d49199f…5e9b`; a pointer row `written after digests were turned on`; the header or `readlink` not `f3bf1214`. Rollback: promote `7c1beb2d`. Then P9 again: the build carries invite delivery. |
| +1. **Release v0.28.4. DONE** (verified above). Stop rule for any re-check: the signature does not verify; the tag is not on `f3bf1214`; the sums list other debs; any published sha256 differs from the local build. |
| +2. **Dev roll, boxes only. DONE** (platform-1e: 0 refusing, no panics, wakecheck 200; verified above). Stop rule for any re-check: a box not `current` at v0.28.4, `refused` or `rolled-back`; instance-control not restarted (H4). |
| +3. **5.0a, promote-only** (approved): ship and promote `f3bf1214` to `canary/console` with the v0.28.4 amd64 CLI, then re-run P9. Stop: the console's sha256 is not `8d49199f…5e9b`; a pointer row `written after digests were turned on`; the header or `readlink` not `f3bf1214`; any P9 `SET` line or console-mail role policy. Rollback: promote `7c1beb2d`. |
| 4. **Open the session** (`signing-host.md`, "Create"). platform-1e confirms with Paul first. This puts the release key on a host a second time. Stop: a checksum mismatch; `carlos version` not `carlos v0.28.4`; `claims help` not as quoted; a key file that is not root `600`. |
| 5. **5.1, resumed** ("5.1 in the second session"): the box re-check, then `refresh` only, never `initialize`. Stop: revision not 5, the listing not as recorded, or a staged file missing or changed. |
| -6. **Step 6**: 6.1 `sign-policy` and `publish-identity` (new `--out` paths) and staging under new paths; 6.1a the `-h` check, then `install-channel --policy --identity` on leo, then sophie; 6.2 `guard-arm` on leo; 6.3 P9, `install-console`, `guard-arm --console`, `console-config`, the restart, and the wait for both boxes' `floor_guard_ready`. Stop: any refusal (6.1a lists its refusals, the four `--identity` ones included); an identity value other than 6.1's expected ones; any 6.1a output other than its expected lines; a P9 `SET` line or console-mail role policy; `console.service` not `active`. |
| +6. **Step 6**: 6.1 `sign-policy` and `publish-identity` (new `--out` paths) and staging under new paths; 6.1a the `-h` check, then `install-channel --policy --identity` on leo, then sophie; 6.2 `guard-arm` on leo; 6.3 P9 (third run), `install-console`, `guard-arm --console`, `console-config`, the restart, and the wait for both boxes' `floor_guard_ready`. Stop: any refusal (6.1a lists its refusals, the `--identity` ones included); an identity value other than the expected ones above; any 6.1a output other than its expected lines; a P9 `SET` line or console-mail role policy; `console.service` not `active`. |
| 7. **Step 7**: readers first (P3), then the dennis guard check (7.1), then **`console-report` on sophie, followed IMMEDIATELY by `publish-floor` on the signer** (the console's evidence lasts only until the agent's next status tick, about 5 minutes, #312), then home, leo's key, the `jq -e` check and the console runtime. Stop: a reader below v0.28.4; an armed policy on dennis; `publish-floor` refused after one fresh `console-report`; `jq -e` not `true`. |
| 8. **Close the session**, always allowed and done at any stop: shred the key on the signer; terminate the instance; remove the exchange objects under `claim-signer/<run-id>/` by exact key; delete the role, instance profile, inline and managed policy attachments and security group. Then the CloudTrail check from DOCS-T1 ("Closing the signing session"): every `GetParameter` on `/carlos/release-key` since the session's start comes from `assumed-role/carlos-claim-signer/<instance id>`, one per key fetch; no instance tagged `purpose=claim-signer` pending or running; `NoSuchEntity` for the role. Anything else goes to #250 before any further step. |
| |
| -**TO-CONFIRM, open until platform-1e posts "v0.28.4 on dev"** |
| -1. The v0.28.4 tag's commit (expected `f3bf1214`), by `git ls-remote --tags` on the forge. |
| -2. From v0.28.4's signed `SHA256SUMS.txt`, signature verified with the README's pinned key: the `carlos-linux-arm64` and `carlos-linux-amd64` sha256 (each must equal the local build), and the sha256 of `SHA256SUMS.txt` and `.sig`. Fill them in here, in 5.0a, in 6.1's expected identity and in `claim-trial-inputs/`. |
| -3. The dev roll: leo, sophie and dennis `carlos v0.28.4`, `.prev` `carlos v0.28.3`, `current`; dennis's guard still unarmed (7.1's check); P9 re-run on sophie once 5.0a has put the invite-delivery console there. |
| +**Open:** nothing. Every TO-CONFIRM is cleared. |
| |
| Later, each with its own go and outside this package: 7a.2 (fence-writer credentials), step 8 (leo's offline window), steps 9 and 10. |
| |
| @@ -274,6 +278,10 @@ The dev root grep, at `platform-infrastructure` main `a0b3f5a`, printed nothing. |
| |
| 2026-10-18 15:48Z, after the v0.28.3 roll, run read-only once from DOCS-T1: PASS. `Success`, `checked: the running console (pid 581646), console.service Environment=, and 5 files:` the same five files as above, no `SET` and no `missing:` line, `console mail: OFF (none of the 7 names is set)`. Sophie's role policies: `carlos-dev-host-buckets`, `carlos-dev-host-metrics`, `deny-release-key-reads`. The dev root grep at `platform-infrastructure` main `a0b3f5a` printed nothing. |
| |
| +2026-10-19 07:54Z, after the v0.28.4 roll and before 5.0a, run read-only once from DOCS-T1: PASS. `Success`, `checked: the running console (pid 581646), console.service Environment=, and 5 files:` the same five files, no `SET` and no `missing:` line, `console mail: OFF (none of the 7 names is set)`. Sophie's role policies: `carlos-dev-host-buckets`, `carlos-dev-host-metrics`, `deny-release-key-reads`. The dev root grep at `platform-infrastructure` main `a0b3f5a` printed nothing. This run checked the `7c1beb2d` console, which predates invite delivery. |
| + |
| +**In the v0.28.4 session P9 runs twice more:** straight after 5.0a's promote, because the invite-delivery console (`91a651b3`) reaches sophie only with that promote; and in 6.3, before `install-console`. Neither may be skipped. |
| + |
| Re-run P9 right before step 6 (step 6.3), inside the signing session and before `install-console`, because 5.0a restarts the console on a new build and the invite delivery branch may have landed by then. |
| |
| **Note for v0.28.4 (console invite delivery).** The invite delivery branch has landed: it is on main as `91a651b3` and ships in v0.28.4, so 5.0a's promote puts it on sophie. With it, the console's own mailer can start itself when `CARLOS_MAIL_REGION` is set (that creates the mail provisioner; the From then comes from `CARLOS_CONSOLE_MAIL_FROM`, or from `CARLOS_MAIL_PLATFORM_SUFFIX`). P9's check covers both names, and `CARLOS_MAIL_PLATFORM_SUFFIX` is among the seven names it checks. platform-87 confirms sophie has none of them, and with `CARLOS_HOST_CLAIM` on the console refuses the mailer anyway (`consoleMailer` takes `hostClaim`, `cmd/console/main.go` at `f3bf1214`). The check and its pass are otherwise unchanged. |
| @@ -544,9 +552,9 @@ Digests have been on for `bab` since the first run (`pointer digests: on for bab |
| Why it is needed: `publish-identity` for v0.28.4 reads the console's sha256 only through the `canary/console` pointer's signed manifest digest for the console version, then the manifest, then the artefact, whose `version.Build` must be `v0.28.4`. Sophie's `install-console` then takes the promoted build as its `--source`. |
| |
| Values, on DOCS-T1: |
| -- `CARLOS`: the carlos v0.28.4 CLI for DOCS-T1, `carlos-linux-amd64`, sha256 `<TO-CONFIRM>` (from v0.28.4's signed sums; the local build is `2d53162fa28accc724a0571f8c7ff59ca36c9050201446e3f33faf4a6f608548`). Download it with `SHA256SUMS.txt` and `SHA256SUMS.txt.sig` from `https://github.com/carlosframework/releases/releases/download/v0.28.4/`, verify the signature as the README's "Releasing the platform" does, then `sha256sum -c --ignore-missing SHA256SUMS.txt`. |
| +- `CARLOS`: the carlos v0.28.4 CLI for DOCS-T1, `carlos-linux-amd64`, sha256 `2d53162fa28accc724a0571f8c7ff59ca36c9050201446e3f33faf4a6f608548` (signed sums, verified 2026-10-19; equal to the local build). Download it with `SHA256SUMS.txt` and `SHA256SUMS.txt.sig` from `https://github.com/carlosframework/releases/releases/download/v0.28.4/`, verify the signature as the README's "Releasing the platform" does, then `sha256sum -c --ignore-missing SHA256SUMS.txt`. |
| - `CONSOLE=~/.cache/release-v0.28.4/console-linux-arm64`: the prebuilt console, sha256 `8d49199f433662ab183a98ce7a5ebeb18f36bc02af5689752580a596bc565e9b`. Use that exact file; never rebuild it, and never run it. |
| -- `CV=f3bf1214`: the console's ship version, the short sha of v0.28.4's commit (`~/.cache/release-v0.28.4/src` is at `f3bf1214ab92a47ecb626400e7bd1b35cd7a112c`, main's tip; the tag commit is TO-CONFIRM). `apps/bab/console/releases/f3bf1214/` does not exist (read 2026-10-18), so the ship is new. If that prefix appears before item 4, stop and ask. Never make up another version. |
| +- `CV=f3bf1214`: the console's ship version, the short sha of v0.28.4's commit (the forge's `v0.28.4^{}` is `f3bf1214ab92a47ecb626400e7bd1b35cd7a112c`, checked 2026-10-19, the commit the build came from). `apps/bab/console/releases/f3bf1214/` does not exist (read 2026-10-18), so the ship is new. If that prefix appears before item 4, stop and ask. Never make up another version. |
| - `release.pub`: as in the first run. |
| |
| **1. Read-only checks, on the day.** The commands are the first run's (below); only the expected values change. |
| @@ -565,7 +573,7 @@ go version -m "$CONSOLE" | grep -o 'internal/version.Build=[^ "]*' | sort | uniq |
| grep -c "$(sha256sum "$CONSOLE" | cut -d' ' -f1)" SHA256SUMS.txt |
| ``` |
| |
| -Expected. All but the last line were read on 2026-10-18 (PASS); the last waits for v0.28.4's published sums: |
| +Expected, as read on 2026-10-18 and 2026-10-19 (PASS; the last line against v0.28.4's published, signature-verified sums): |
| |
| ``` |
| 8d49199f433662ab183a98ce7a5ebeb18f36bc02af5689752580a596bc565e9b /home/paulca/.cache/release-v0.28.4/console-linux-arm64 |
| @@ -595,7 +603,8 @@ Expected: |
| - the `readlink` from 1c shows `/opt/carlos/versions/f3bf1214/console`, and that file's sha256 on sophie is `8d49199f…5e9b`. That path is `install-console`'s `--source` in step 6.3; |
| - `"$CARLOS" channels --app console --account-id bab` shows `canary/console f3bf1214 ... yes`; |
| - `channels digests --account-id bab` (as in 1e) lists no `console canary/console` row and no `written after digests were turned on` row; |
| -- wakecheck still answers 200 through DNS. |
| +- wakecheck still answers 200 through DNS; |
| +- then re-run P9 on sophie, from DOCS-T1. The console invite delivery (`91a651b3`) reaches sophie only with this promote, so the P9 runs before it (the latest on 2026-10-19 07:54Z) checked the `7c1beb2d` console. Any `SET` line or console-mail role policy is a STOP: roll back as below and report on #250. 6.3 runs P9 once more before `install-console`. |
| |
| Rollback: leave digests on and promote `7c1beb2d` again, with the same CLI. That pointer carries digests, so sophie accepts it: |
| |
| @@ -839,7 +848,7 @@ Paul's ruling, 2026-10-18: the trusted signing host is created once, after v0.28 |
| That first session stopped at 6.2 and was closed (step 6's record). The second session, on v0.28.4, puts the release key on a host a second time. Paul's go is said to cover it, from 5.1's leftovers through step 7; platform-1e confirms with Paul before the signer is created. |
| |
| Order of work for the second session (v0.28.4), each block with its stop points: |
| -1. **Open the session.** Only once v0.28.4 (with `install-channel --identity`, the fix for the untagged pointers) is published and verified, every dev box reads `carlos v0.28.4` (`.prev` `carlos v0.28.3`) and `current`, and 5.0a for v0.28.4 has passed. platform-1e confirms with Paul, then: create the signer host and its role policy (`signing-host.md`, "Create", with write on exactly `control/system/router/releases/v0.28.4.json`), install the verified tools (carlos v0.28.4 `linux-arm64`, sha256 TO-CONFIRM from the signed sums; jq 1.7.1 `4dd2d8a0...`), then fetch the key into tmpfs (`signing-host.md`, "Getting the key there"). Record the session's start time before the key fetch, and choose a new exchange `<run-id>`. Stop points: a checksum mismatch, `carlos version` not `carlos v0.28.4`, `claims help` not as quoted below, or a key file that is not root `600`. |
| +1. **Open the session.** Only once v0.28.4 (with `install-channel --identity`, the fix for the untagged pointers) is published and verified, every dev box reads `carlos v0.28.4` (`.prev` `carlos v0.28.3`) and `current`, and 5.0a for v0.28.4 has passed. platform-1e confirms with Paul, then: create the signer host and its role policy (`signing-host.md`, "Create", with write on exactly `control/system/router/releases/v0.28.4.json`), install the verified tools (carlos v0.28.4 `linux-arm64` `736826e4...4b21`; jq 1.7.1 `4dd2d8a0...`), then fetch the key into tmpfs (`signing-host.md`, "Getting the key there"). Record the session's start time before the key fetch, and choose a new exchange `<run-id>`. Stop points: a checksum mismatch, `carlos version` not `carlos v0.28.4`, `claims help` not as quoted below, or a key file that is not root `600`. |
| 2. **5.1, resumed.** "5.1 in the second session". Stop points: revision not 5, the listing not as recorded, or a staged file missing or with another sha256. |
| 3. **Step 6.** In order: 6.1 `sign-policy` and `publish-identity` on the signer with new `--out` paths, then staging under new paths on leo and sophie; 6.1a `install-channel --policy --identity` on leo, then on sophie; 6.2 `guard-arm` on leo; 6.3 the P9 re-run from DOCS-T1, then `install-console`, `guard-arm --console`, `console-config` and the restart on sophie, then the wait until both boxes' reports carry `floor_guard_ready`. `console-report` is not in step 6 any more: it opens step 7's report-and-floor pair. Stop points: any refusal; an identity value other than step 6.1's expected values (a wrong published identity cannot be replaced); any 6.1a output other than its expected lines; any P9 `SET` line or console-mail role policy; `console.service` not `active`. |
| 4. **Step 7** (`home_region` becomes write-once). Readers re-checked first (P3, with `carlos.prev`), then the read-only check that dennis's guard is unarmed. Then `console-report` on sophie, **followed immediately by `publish-floor` on the signer**, then home, leo's key and the console runtime. Stop points: any reader below v0.28.4; an armed policy on dennis; `publish-floor` refused after one fresh `console-report`; the `jq -e` roster check not `true`; a refused report that a fresh box report does not clear. |
| @@ -1122,7 +1131,7 @@ Run the dry run on its own first and check it field by field, as the first sessi |
| |
| Expected: |
| - the dry run, then the apply, succeed, and `writes` lists one create-only put (`before_etag` empty) of `control/system/router/releases/v0.28.4.json`; |
| -- `identity_key` is that key, and `release` shows `version` and `release_tag` `v0.28.4`, `moves_protocol` `1`, `artifacts.linux-arm64` `{"key": "bootstrap/router/v0.28.4/carlos-linux-arm64", "sha256": "<TO-CONFIRM>"}` (the `carlos-linux-arm64` line of v0.28.4's `SHA256SUMS.txt`; the local build is `736826e4…4b21`), and `console_artifacts.linux-arm64` `{"key": "bootstrap/console/v0.28.4/carlos-linux-arm64", "sha256": "8d49199f433662ab183a98ce7a5ebeb18f36bc02af5689752580a596bc565e9b"}` (5.0a's prebuilt console). The payload also holds `channel stable`, `spread 0s`, `source release:v0.28.4` and `released_at` zero, on purpose (step 6's first-session record). Any other value is a STOP. The console key is a name only: nothing in step 6 reads it, and it is not in the bucket; |
| +- `identity_key` is that key, and `release` shows `version` and `release_tag` `v0.28.4`, `moves_protocol` `1`, `artifacts.linux-arm64` `{"key": "bootstrap/router/v0.28.4/carlos-linux-arm64", "sha256": "736826e40d5c1de399678e8bf82bbd15c0a5123f766089d5b42d0539f2ea4b21"}` (the `carlos-linux-arm64` line of v0.28.4's `SHA256SUMS.txt`, equal to the local build and to both dev pointers), and `console_artifacts.linux-arm64` `{"key": "bootstrap/console/v0.28.4/carlos-linux-arm64", "sha256": "8d49199f433662ab183a98ce7a5ebeb18f36bc02af5689752580a596bc565e9b"}` (5.0a's prebuilt console). The payload also holds `channel stable`, `spread 0s`, `source release:v0.28.4` and `released_at` zero, on purpose (step 6's first-session record). Any other value is a STOP. The console key is a name only: nothing in step 6 reads it, and it is not in the bucket; |
| - `identity.v0.28.4.json` is the published object's bytes as read back, the same file `aws s3 cp` of that key would give. |
| |
| The signer's role may write exactly one identity object: the key `control/system/router/releases/v0.28.4.json`, an exact key and not a prefix (`signing-host.md`, statement `WriteIdentity`). The runner also admits only that key for the phase. |
| @@ -1147,7 +1156,7 @@ Expected: `absent` twice, then `staged` four times. If a path exists, stop: neve |
| |
| From the prev-rehearsal (main `50f5b268`) and the untagged-pointer fix (main `f3bf1214`, Paul's option (b)), both in v0.28.4. Before `guard-arm`, each box to be armed runs `carlos system install-channel --policy <policy> --identity <identity>` as root, leo first, then sophie (the console box). On a box that `carlos system update` has already moved to its channel's release, it leaves `carlos` as it is and replaces `carlos.prev` (the release before, v0.28.3) with it, so `guard-arm`'s two-slot check passes. It takes the armed policy's floor as the floor, because none is published yet. It finds the release through the `--identity` file (6.1's `publish-identity` output), never through the pointer's tag: the file is checked against the published identity object and the release key, the pointer's current artefact sha256 must equal the identity's router sha256, a tag on the pointer (if any) must name this identity, and the pointer itself is left unchanged. |
| |
| -Before it, on each box: the channel pointer names v0.28.4 with the identity's `carlos-linux-arm64` sha256 (leo `stable`, sophie `canary`; P3's `carlos system status`). It carries no `release_tag` and no `moves_protocol`: that is how `carlos system update` writes it before a floor is published, and it is expected (on 2026-10-18 the v0.28.3 pointers had exactly that shape). If a pointer does carry a `release_tag`, it must be `v0.28.4`. `install-channel` reads the box's own channel; a box whose channel names another release is refused ("this box already runs ..."). |
| +Before it, on each box: the channel pointer names v0.28.4 with the identity's `carlos-linux-arm64` sha256 (leo `stable`, sophie `canary`; P3's `carlos system status`). It carries no `release_tag` and no `moves_protocol`: that is how `carlos system update` writes it before a floor is published, and it is expected (on 2026-10-18 the v0.28.3 pointers had exactly that shape). If a pointer does carry a `release_tag`, it must be `v0.28.4`. Read on 2026-10-19 07:53Z: `stable.json` and `canary.json` both name v0.28.4, artefact `bootstrap/router/v0.28.4/carlos-linux-arm64` `736826e4…4b21`, no `release_tag`, no `moves_protocol`. `publish-identity` will put the same key and sha256 (the signed sums' `carlos-linux-arm64` line) in the v0.28.4 identity, so the precondition holds. `install-channel` reads the box's own channel; a box whose channel names another release is refused ("this box already runs ..."). |
| |
| The help check first, on leo: `/opt/carlos/carlos system install-channel -h`. It prints and exits before reading anything. Expected, exactly (as printed by the local v0.28.4 build, `~/.cache/release-v0.28.4/dist/carlos-linux-amd64`, built from `f3bf1214`, on 2026-10-18): |
| |
| @@ -1329,7 +1338,7 @@ Paul's go: once for step 7. `home_region` becomes write-once as soon as claims a |
| carlos v0.28.4 |
| ``` |
| |
| - Run read-only on 2026-10-18 at about 14:45Z, before the v0.28.3 roll: `Success`, both `absent`, `carlos v0.28.2`; and at about 15:45Z, after it: both `absent`, `carlos v0.28.3`. A `present /opt/carlos/system/guard/policy.json` line is a STOP whatever its mode, and so is status `Failed` or any other output: do not start 7.2, report to platform-1e, and close the session if they say so. |
| + Run read-only on 2026-10-18 at about 14:45Z, before the v0.28.3 roll: `Success`, both `absent`, `carlos v0.28.2`; and at about 15:45Z, after it: both `absent`, `carlos v0.28.3`. On 2026-10-19 at about 07:53Z, after the v0.28.4 roll: `Success`, both `absent`, `carlos v0.28.4`: PASS. A `present /opt/carlos/system/guard/policy.json` line is a STOP whatever its mode, and so is status `Failed` or any other output: do not start 7.2, report to platform-1e, and close the session if they say so. |
| 2. **Report and floor, back to back. HARD ORDERING: `console-report` is followed IMMEDIATELY by `publish-floor`.** The console's evidence in sophie's box report lasts only until the agent's next status tick, about 5 minutes (#312). Before starting, check that both boxes' reports carry `floor_guard_ready` (6.3's check), and have the `publish-floor` command ready to send. For the widest window, start just after sophie's report's `generated_at` moves. |
| |
| On the trusted host, stage sophie's current roster and revision (`box_inspect "$SOPHIE"`). Then on sophie: |
| @@ -2253,7 +2262,7 @@ For platform-1e: |
| 3. Answered 2026-10-18: leo's object-version actions are applied for the trial; the box-records bucket policy goes with the fence-writer role in platform-infrastructure#46. |
| 4. Box identity records: `carlos system box publish-record` ships in v0.28.1, dev only (step 5.0). The v0.28.1 dev roll comes before step 5. |
| 6. Answered 2026-10-18: platform-1e builds the armed policy signing phase and the published system identity with the protected console install, in v0.28.2 (blocker 5). Built on branch `claim-step6-artifacts` (census ruled), on main 7c1beb2d, published (v0.28.2, tag on 7c1beb2d): `sign-policy`, `publish-identity` and `install-console`. Step 6 waits for it, and for 5.0a; step 5.0 did not. |
| -7. Still open in `docs/superpowers/notes/claim-trial-inputs/README.md` for the second session: the v0.28.4 release values (TO-CONFIRM until platform-1e posts "v0.28.4 on dev") and the second signer's IDs. The console enrollment token was generated in the first session and is in the roster. Namespace `platform`, sophie's pool `console`, console ID `dev-console` and operator `paul@keymail.dev` are confirmed. |
| +7. Still open in `docs/superpowers/notes/claim-trial-inputs/README.md` for the second session: the second signer's IDs (the v0.28.4 values are confirmed, 2026-10-19). The console enrollment token was generated in the first session and is in the roster. Namespace `platform`, sophie's pool `console`, console ID `dev-console` and operator `paul@keymail.dev` are confirmed. |
| 5. The console's mutation classifier lets it delete under `control/boxes/` and `control/box-volumes/`, which the new box-records bucket policy refuses: amadan carlos/platform#302. |
| 8. Answered 2026-10-18 by platform-1e: dennis's `carlos.prev` (the release before) passes P3 (P3 is about reader versions against the floor; dennis is not enrolled and is outside the census scope). Dennis never runs 6.1a. Step 7.1 checks read-only that its guard is unarmed. |
| 9. Answered 2026-10-18 (Paul, option (b)): the untagged channel pointer is met by `install-channel --policy --identity` (main `f3bf1214`, v0.28.4), not by tagging the pointer. Blocker 7. |