carlos / platform Public

docs: cohort-1 runbook: final v0.28.3 go package, one STOP open

v0.28.3 is on dev (platform-1e). Verified read-only and filled in:
- tag v0.28.3 on 50f5b268 (forge ls-remote);
- SHA256SUMS.txt 0a0e5e92 / .sig 38cd1cf7, signature verified with the
  pinned key; linux-arm64 6154afb4, linux-amd64 82a60203, both equal to
  the local build; console 3660b44c not in the sums;
- leo and sophie v0.28.3 / .prev v0.28.2, 5.1 staging unchanged;
  dennis v0.28.3, guard unarmed (7.1 PASS); P9 on sophie PASS 15:48Z.

TO-CONFIRM 1 to 3 cleared; Go package final: values, eight blocks with
stop points, teardown and CloudTrail.

Open STOP: dev's v0.28.3 stable/canary pointers carry no release_tag
(the console tags only once a floor is published), and install-channel
--policy refuses without one. platform-1e rules before the signer opens.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev ccaea17fbab6c54ac27b0b853d32c19b02992a6e parent 1b77291
4 files changed, +56 −50
  • docs/superpowers/notes/claim-trial-inputs/README.md +6 −5
  • docs/superpowers/notes/claim-trial-inputs/identity.template.json +2 −2
  • docs/superpowers/notes/claim-trial-inputs/signing-host.md +2 −2
  • docs/superpowers/plans/2026-10-16-claim-activation-dev-cohort1.md +46 −41

CI passed — run details

CI log
=== gate ===
cd launchctx && go vet ./... && go test ./... -count=1
ok  	amadan.net/carlos/platform.git/launchctx	0.011s
?   	amadan.net/carlos/platform.git/launchctx/controlname	[no test files]
?   	amadan.net/carlos/platform.git/launchctx/wireid	[no test files]
go vet ./...
gofmt -l .: clean
go test ./... -count=1 -timeout 30m
ok  	github.com/carlosframework/platform	294.636s
?   	github.com/carlosframework/platform/cmd/changelog	[no test files]
ok  	github.com/carlosframework/platform/cmd/console	2.972s
ok  	github.com/carlosframework/platform/cmd/moveprobe	93.161s
ok  	github.com/carlosframework/platform/cmd/zddprobe	0.699s
ok  	github.com/carlosframework/platform/internal/activator	252.581s
ok  	github.com/carlosframework/platform/internal/agentsock	0.016s
ok  	github.com/carlosframework/platform/internal/alerting	0.004s
ok  	github.com/carlosframework/platform/internal/analytics	0.019s
ok  	github.com/carlosframework/platform/internal/appconfig	2.449s
ok  	github.com/carlosframework/platform/internal/apperr	0.077s
ok  	github.com/carlosframework/platform/internal/applog	0.127s
ok  	github.com/carlosframework/platform/internal/awsinv	0.004s
ok  	github.com/carlosframework/platform/internal/boxchoice	0.004s
ok  	github.com/carlosframework/platform/internal/boxid	0.840s
?   	github.com/carlosframework/platform/internal/boxid/boxidtest	[no test files]
?   	github.com/carlosframework/platform/internal/boxid/internal/signtest	[no test files]
ok  	github.com/carlosframework/platform/internal/boxvolumes	0.008s
ok  	github.com/carlosframework/platform/internal/caps	0.013s
ok  	github.com/carlosframework/platform/internal/certwarm	0.003s
ok  	github.com/carlosframework/platform/internal/cgroup	0.692s
ok  	github.com/carlosframework/platform/internal/changelog	0.305s
ok  	github.com/carlosframework/platform/internal/claimactivation	0.027s
ok  	github.com/carlosframework/platform/internal/clamd	0.055s
?   	github.com/carlosframework/platform/internal/cliflag	[no test files]
ok  	github.com/carlosframework/platform/internal/console	401.378s
?   	github.com/carlosframework/platform/internal/controlname	[no test files]
?   	github.com/carlosframework/platform/internal/controlsock	[no test files]
ok  	github.com/carlosframework/platform/internal/dbdoor	6.115s
ok  	github.com/carlosframework/platform/internal/dbdoor/dbdoortest	0.008s
ok  	github.com/carlosframework/platform/internal/dbverify	0.004s
ok  	github.com/carlosframework/platform/internal/dnsrec	0.002s
ok  	github.com/carlosframework/platform/internal/docsite	0.004s
ok  	github.com/carlosframework/platform/internal/domains	2.410s
ok  	github.com/carlosframework/platform/internal/doorkey	0.006s
ok  	github.com/carlosframework/platform/internal/economics	0.003s
ok  	github.com/carlosframework/platform/internal/edge	44.722s
?   	github.com/carlosframework/platform/internal/edgeproof	[no test files]
ok  	github.com/carlosframework/platform/internal/edgesfile	0.008s
ok  	github.com/carlosframework/platform/internal/fleetapi	0.131s
ok  	github.com/carlosframework/platform/internal/gate	1.656s
ok  	github.com/carlosframework/platform/internal/genselect	0.014s
ok  	github.com/carlosframework/platform/internal/geo	0.018s
ok  	github.com/carlosframework/platform/internal/geoip	0.029s
ok  	github.com/carlosframework/platform/internal/historyreadback	0.153s
ok  	github.com/carlosframework/platform/internal/host	173.006s
ok  	github.com/carlosframework/platform/internal/hostactors	0.485s
ok  	github.com/carlosframework/platform/internal/hostbox	2.667s
ok  	github.com/carlosframework/platform/internal/hostclaim	0.561s
ok  	github.com/carlosframework/platform/internal/hostevidence	0.005s
ok  	github.com/carlosframework/platform/internal/hostexec	4.678s
ok  	github.com/carlosframework/platform/internal/hostfence	0.040s
ok  	github.com/carlosframework/platform/internal/hostfiles	10.365s
ok  	github.com/carlosframework/platform/internal/hostfloor	0.012s
ok  	github.com/carlosframework/platform/internal/hostguard	1.036s
ok  	github.com/carlosframework/platform/internal/hostops	1.598s
?   	github.com/carlosframework/platform/internal/hostops/fencerelease	[no test files]
ok  	github.com/carlosframework/platform/internal/hostops/internal/fencerelease	0.002s
ok  	github.com/carlosframework/platform/internal/hostquarantine	0.002s
ok  	github.com/carlosframework/platform/internal/hostrelocate	0.451s
ok  	github.com/carlosframework/platform/internal/hostresolve	0.144s
ok  	github.com/carlosframework/platform/internal/hostwrite	0.005s
ok  	github.com/carlosframework/platform/internal/infraview	0.002s
ok  	github.com/carlosframework/platform/internal/instancectl	5.206s
ok  	github.com/carlosframework/platform/internal/instanceexec	2.708s
ok  	github.com/carlosframework/platform/internal/instancefs	0.005s
ok  	github.com/carlosframework/platform/internal/instancekey	0.002s
ok  	github.com/carlosframework/platform/internal/instanceupdates	0.009s
ok  	github.com/carlosframework/platform/internal/layout	1.525s
ok  	github.com/carlosframework/platform/internal/lbhealth	0.002s
ok  	github.com/carlosframework/platform/internal/lease	9.784s
ok  	github.com/carlosframework/platform/internal/lease/leasetest	0.006s
ok  	github.com/carlosframework/platform/internal/ledger	0.017s
ok  	github.com/carlosframework/platform/internal/mail	0.180s
ok  	github.com/carlosframework/platform/internal/maintenance	0.085s
ok  	github.com/carlosframework/platform/internal/maintenanceexec	5.475s
ok  	github.com/carlosframework/platform/internal/maintenanceguard	0.072s
ok  	github.com/carlosframework/platform/internal/metrics	0.005s
ok  	github.com/carlosframework/platform/internal/moves	20.875s
ok  	github.com/carlosframework/platform/internal/moves/archive	0.773s
ok  	github.com/carlosframework/platform/internal/objstore	0.178s
ok  	github.com/carlosframework/platform/internal/ops	0.172s
ok  	github.com/carlosframework/platform/internal/park	0.196s
ok  	github.com/carlosframework/platform/internal/privatefile	0.005s
ok  	github.com/carlosframework/platform/internal/provision	17.275s
ok  	github.com/carlosframework/platform/internal/publicrelease	0.006s
?   	github.com/carlosframework/platform/internal/regionname	[no test files]
ok  	github.com/carlosframework/platform/internal/registry	5.392s
ok  	github.com/carlosframework/platform/internal/relay	7.224s
ok  	github.com/carlosframework/platform/internal/release	21.766s
ok  	github.com/carlosframework/platform/internal/rollout	3.606s
ok  	github.com/carlosframework/platform/internal/rolloutwords	0.007s
ok  	github.com/carlosframework/platform/internal/rootaws	0.006s
ok  	github.com/carlosframework/platform/internal/rootparticipation	0.059s
ok  	github.com/carlosframework/platform/internal/rootstate	0.026s
ok  	github.com/carlosframework/platform/internal/runs	0.564s
ok  	github.com/carlosframework/platform/internal/s3compat	0.004s
ok  	github.com/carlosframework/platform/internal/safefile	0.004s
ok  	github.com/carlosframework/platform/internal/schedule	2.467s
ok  	github.com/carlosframework/platform/internal/seeds	0.011s
ok  	github.com/carlosframework/platform/internal/sim/hostlife	8.359s
ok  	github.com/carlosframework/platform/internal/sim/litestreamfacts	3.826s
ok  	github.com/carlosframework/platform/internal/status	0.037s
ok  	github.com/carlosframework/platform/internal/steering	0.005s
ok  	github.com/carlosframework/platform/internal/stopevidence	0.205s
ok  	github.com/carlosframework/platform/internal/svcrole	0.002s
ok  	github.com/carlosframework/platform/internal/telemetry	0.003s
ok  	github.com/carlosframework/platform/internal/termfence	0.004s
ok  	github.com/carlosframework/platform/internal/tunnelclient	0.004s
ok  	github.com/carlosframework/platform/internal/unixdial	0.002s
ok  	github.com/carlosframework/platform/internal/updatewords	0.004s
ok  	github.com/carlosframework/platform/internal/usage	0.004s
ok  	github.com/carlosframework/platform/internal/version	0.001s
ok  	github.com/carlosframework/platform/internal/vet	1.535s
=== cross ===
--- shard 0 of 5 ---
cross-compiling darwin/arm64
--- shard 1 of 5 ---
cross-compiling darwin/amd64
--- shard 2 of 5 ---
cross-compiling linux/arm64
linux/arm64 carlos binary: 48824482 bytes (ceiling 52000000)
--- shard 3 of 5 ---
cross-compiling windows/amd64
--- shard 4 of 5 ---
cross-compiling windows/arm64
=== minio-contract ===
minio contract: arm64, minio RELEASE.2025-09-07T16-13-09Z, mc RELEASE.2025-08-13T08-35-41Z
  minio: cached, digest verified
  mc: cached, digest verified
  minio healthy on 127.0.0.1:20999
Added `local` successfully.
Bucket created successfully `local/contract-bucket`.
Bucket created successfully `local/denied-bucket`.
Created policy `contract-only` successfully.
Added user `scopeduser` successfully.
Attached Policies: [contract-only]
To User: scopeduser
  buckets and scoped user ready
=== RUN   TestDeliveredContractMinio
=== RUN   TestDeliveredContractMinio/put
=== RUN   TestDeliveredContractMinio/get_round-trips_the_body
=== RUN   TestDeliveredContractMinio/list_shows_the_key
=== RUN   TestDeliveredContractMinio/head_and_list_agree_on_the_version
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/not_by_PutObjectTagging
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/and_not_by_x-amz-tagging_on_upload
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CreateMultipartUpload
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CopyObject_with_a_REPLACE_tagging_directive
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/but_multipart_itself_is_allowed
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_copy_itself_is_allowed
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/a_POST-policy_forged_tag_with_a_matching_version_is_still_not_a_verdict
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_an_ordinary_tagged-with-something-else_upload_is_allowed
=== RUN   TestDeliveredContractMinio/delete_removes_it
=== RUN   TestDeliveredContractMinio/cross-bucket_denial
--- PASS: TestDeliveredContractMinio (0.02s)
    --- PASS: TestDeliveredContractMinio/put (0.00s)
    --- PASS: TestDeliveredContractMinio/get_round-trips_the_body (0.00s)
    --- PASS: TestDeliveredContractMinio/list_shows_the_key (0.00s)
    --- PASS: TestDeliveredContractMinio/head_and_list_agree_on_the_version (0.00s)
    --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/not_by_PutObjectTagging (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/and_not_by_x-amz-tagging_on_upload (0.00s)
    --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route (0.01s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CreateMultipartUpload (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CopyObject_with_a_REPLACE_tagging_directive (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/but_multipart_itself_is_allowed (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_copy_itself_is_allowed (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/a_POST-policy_forged_tag_with_a_matching_version_is_still_not_a_verdict (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_an_ordinary_tagged-with-something-else_upload_is_allowed (0.00s)
    --- PASS: TestDeliveredContractMinio/delete_removes_it (0.00s)
    --- PASS: TestDeliveredContractMinio/cross-bucket_denial (0.00s)
PASS
ok  	github.com/carlosframework/platform/internal/objstore	0.022s
=== RUN   TestT4StorageProbeMinio
2026/10/18 16:01:12 moves: T4: STORE: list: operation error S3: ListObjectsV2, https response error StatusCode: 403, RequestID: 18DFAB1277E00F02, HostID: 7c420053e0fbcd7f41653fdd92ffa2802c903d05303b1aa15adc2e8bb65d183f, api error SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method.
--- PASS: TestT4StorageProbeMinio (0.00s)
PASS
ok  	github.com/carlosframework/platform/internal/host	0.020s
minio contract: PASS
diff --git a/docs/superpowers/notes/claim-trial-inputs/README.md b/docs/superpowers/notes/claim-trial-inputs/README.md
index 3a7908aad..e246e0277 100644
--- a/docs/superpowers/notes/claim-trial-inputs/README.md
+++ b/docs/superpowers/notes/claim-trial-inputs/README.md
@@ -14,18 +14,19 @@ The first session (2026-10-18) did 5.0a, 5.1 and 6.1 on v0.28.2, then stopped at
| Input | Value | Status |
|---|---|---|
-| Release | v0.28.3, built on DOCS-T1 from main `50f5b268` | built; not published on 2026-10-18 (latest is v0.28.2, no v0.28.3 tag on the forge) |
-| Router `carlos-linux-arm64` sha256 | from v0.28.3's signed `SHA256SUMS.txt`; the local build is `6154afb458a35183e470f5480ea08c09817400e6e67465530477e5204af2def0` | TO-CONFIRM (published?) |
-| CLI `carlos-linux-amd64` sha256 | from the same sums; local build `82a60203b1790771b5f3da16bc5d342327131ed30a1aae59a520f42d253369b2` | TO-CONFIRM (published?) |
-| `SHA256SUMS.txt` and `.sig` | v0.28.3's own, naming `carlos_0.28.3_amd64.deb` and `carlos_0.28.3_arm64.deb` and no other deb; carried verbatim by `publish-identity` | TO-CONFIRM (published?) |
+| Release | v0.28.3, tag on main `50f5b268` (forge `v0.28.3^{}`) | published; on leo, sophie and dennis (`.prev` v0.28.2), confirmed read-only 2026-10-18 |
+| Router `carlos-linux-arm64` sha256 | `6154afb458a35183e470f5480ea08c09817400e6e67465530477e5204af2def0`, from v0.28.3's signed `SHA256SUMS.txt`, equal to the local build and to dev's `stable.json` and `canary.json` | confirmed 2026-10-18 |
+| CLI `carlos-linux-amd64` sha256 | `82a60203b1790771b5f3da16bc5d342327131ed30a1aae59a520f42d253369b2`, from the same sums, equal to the local build | confirmed 2026-10-18 |
+| `SHA256SUMS.txt` and `.sig` | `SHA256SUMS.txt` 704 bytes, sha256 `0a0e5e9287b5f9560c26b20771d8106b12d77668cc40e5d9c0786f35ca3b1038`, naming `carlos_0.28.3_amd64.deb` and `carlos_0.28.3_arm64.deb` and no other deb; `.sig` 89 bytes, sha256 `38cd1cf78075cd8284b9df803ae9d43776ee135413ae3a4641d1cbd29abfa476`; signature verified with the README's pinned key; carried verbatim by `publish-identity` | confirmed 2026-10-18 |
| Console build | `~/.cache/release-v0.28.3/console-linux-arm64`, 47055010 bytes, sha256 `3660b44c13080f0e9ead5f70754a11ec267d70eaab2a89e88ce256ab3437ec74`; stripped aarch64, `cmd/console`, `-ldflags="-s -w -X github.com/carlosframework/platform/internal/version.Build=v0.28.3"` once (checked with `file` and `go version -m`, never run). Never rebuild it | confirmed (built, not shipped) |
-| Console ship version | `50f5b268`, the short sha of v0.28.3's commit; `apps/bab/console/releases/50f5b268/` absent | TO-CONFIRM: the tag lands on `50f5b268` |
+| Console ship version | `50f5b268`, the short sha of v0.28.3's commit; `apps/bab/console/releases/50f5b268/` absent | confirmed 2026-10-18 |
| Pointer digests for `bab` | on since 2026-10-18T10:11:25Z (first 5.0a); not changed again | confirmed |
| Floor | `{"min": 1, "min_release": "v0.28.3"}`; expected `floor_sha256` `07d2b63e711af4d97fad48713096447ce3c81ff92db0e956a98543478484aa09` (sha256 of the compact form) | confirmed; `sign-policy`'s output is the value of record |
| Identity | `control/system/router/releases/v0.28.3.json`, new and create-only. The v0.28.2 identity (`v0.28.2.json`, `2d22f05f`) stays as it is, unused | to publish in 6.1 |
| `policy` and `identity` files | `/root/claim-trial/policy.v0.28.3.json` and `/root/claim-trial/identity.v0.28.3.json` on the signer, leo and sophie, new paths. The first session's `policy.json` (`dfac87e6`) and `identity.json` (`2d22f05f`) stay staged on both boxes, unused | to make in 6.1 |
| Signer write grant | exactly `control/system/router/releases/v0.28.3.json`, no prefix (`signing-host.md`) | to create, after platform-1e confirms with Paul |
| Roster | revision 5, etag `f3717d8d67f496ffd9525704c7a690b0`, resumed with `refresh`, never re-initialized | confirmed read-only 2026-10-18 14:30Z |
+| Channel pointers | dev's `stable.json` and `canary.json` name v0.28.3 with no `release_tag`, which `install-channel --policy` needs (runbook Go package, "Open") | STOP, open: platform-1e rules before the session |
## Files
diff --git a/docs/superpowers/notes/claim-trial-inputs/identity.template.json b/docs/superpowers/notes/claim-trial-inputs/identity.template.json
index 16601be75..d3aacc24d 100644
--- a/docs/superpowers/notes/claim-trial-inputs/identity.template.json
+++ b/docs/superpowers/notes/claim-trial-inputs/identity.template.json
@@ -10,7 +10,7 @@
"artifacts": {
"linux-arm64": {
"key": "bootstrap/router/v0.28.3/carlos-linux-arm64",
- "sha256": "TO-CONFIRM (published?): the carlos-linux-arm64 line of v0.28.3's signed SHA256SUMS.txt; the local build is 6154afb458a35183e470f5480ea08c09817400e6e67465530477e5204af2def0"
+ "sha256": "6154afb458a35183e470f5480ea08c09817400e6e67465530477e5204af2def0"
}
},
"console_artifacts": {
@@ -23,5 +23,5 @@
},
"spread": "0s"
},
- "note": "Shape only, for the second session: v0.28.3, built from main 50f5b268, not yet published on 2026-10-18. The real file is the root-signed identity ({payload, sig}) that the claims run phase publish-identity publishes create-only at control/system/router/releases/v0.28.3.json and writes byte-exact to --out (/root/claim-trial/identity.v0.28.3.json). The v0.28.2 identity at control/system/router/releases/v0.28.2.json stays as it is, unused. The channel is always stable and is read by nothing that checks an identity. No sha256 is typed: publish-identity reads both. The values shown are the expected ones (2026-10-18): the router from v0.28.3's signed SHA256SUMS.txt, the console from the prebuilt file runbook 5.0a ships"
+ "note": "Shape only, for the second session: v0.28.3, tag on 50f5b268, published and verified 2026-10-18 (SHA256SUMS.txt 0a0e5e92, signature verified). The real file is the root-signed identity ({payload, sig}) that the claims run phase publish-identity publishes create-only at control/system/router/releases/v0.28.3.json and writes byte-exact to --out (/root/claim-trial/identity.v0.28.3.json). The v0.28.2 identity at control/system/router/releases/v0.28.2.json stays as it is, unused. The channel is always stable and is read by nothing that checks an identity. No sha256 is typed: publish-identity reads both. The values shown are the expected ones (2026-10-18): the router from v0.28.3's signed SHA256SUMS.txt, the console from the prebuilt file runbook 5.0a ships"
}
diff --git a/docs/superpowers/notes/claim-trial-inputs/signing-host.md b/docs/superpowers/notes/claim-trial-inputs/signing-host.md
index 415efdc18..2c175fa26 100644
--- a/docs/superpowers/notes/claim-trial-inputs/signing-host.md
+++ b/docs/superpowers/notes/claim-trial-inputs/signing-host.md
@@ -101,7 +101,7 @@ The key goes from the SSM response straight into a `0600` file on tmpfs (`/run`)
Known values (2026-10-18):
- carlos v0.28.1 `carlos-linux-arm64`: `2ae174da29b1d10fdcb009172ba830db5460b62e838bcecc7d9e17535f35adea`. It comes from the published release's `SHA256SUMS.txt`, whose signature verified with the README's pinned key (`openssl pkeyutl -verify`: "Signature Verified Successfully"). It is the same binary leo and sophie run.
- jq 1.7.1 `jq-linux-arm64`: `4dd2d8a0661df0b22f1bb9a1f9830f06b6f3b8f7d91211a1ef5d7c4f06a8b4a5` (1709616 bytes). It was computed on DOCS-T1 from the file downloaded from `github.com/jqlang/jq/releases/download/jq-1.7.1/`, and matches that release's `sha256sum.txt`.
-- carlos v0.28.3 `carlos-linux-arm64` (the second session's CLI): **TO-CONFIRM (published?)**, from v0.28.3's signed `SHA256SUMS.txt`, verified the same way. The local build (`~/.cache/release-v0.28.3/dist/carlos-linux-arm64`, from main `50f5b268`) hashes to `6154afb458a35183e470f5480ea08c09817400e6e67465530477e5204af2def0`; that is what to expect, not the value of record. Fill it in below before the session.
+- carlos v0.28.3 `carlos-linux-arm64` (the second session's CLI): `6154afb458a35183e470f5480ea08c09817400e6e67465530477e5204af2def0`, from v0.28.3's `SHA256SUMS.txt` (sha256 `0a0e5e9287b5f9560c26b20771d8106b12d77668cc40e5d9c0786f35ca3b1038`; `.sig` `38cd1cf78075cd8284b9df803ae9d43776ee135413ae3a4641d1cbd29abfa476`), whose signature verified with the README's pinned key on 2026-10-18. It equals the local build and is the binary leo, sophie and dennis run.
- carlos v0.28.2 `carlos-linux-arm64` (the first session's CLI): `7141e037d61b0d95ae554252af1bb9155653a9954ad0dcaffb35c7047850f492`, from v0.28.2's `SHA256SUMS.txt` (sha256 `9c29b3d305c464cf981afffa0bc51f1654015883c02717477f38357709d46db2`), whose signature verified with the README's pinned key on 2026-10-18 ("Signature Verified Successfully", `sha256sum -c` OK). It is the binary leo, sophie and dennis run.
On DOCS-T1, before launching:
@@ -114,7 +114,7 @@ On the signer, as root:
```bash
aws s3 cp s3://carlos-dev-640012953448/claim-signer/<run-id>/carlos-linux-arm64 /usr/local/bin/carlos
aws s3 cp s3://carlos-dev-640012953448/claim-signer/<run-id>/jq-linux-arm64 /usr/local/bin/jq
-printf '%s %s\n' <v0.28.3 carlos-linux-arm64 sha256, TO-CONFIRM> /usr/local/bin/carlos \
+printf '%s %s\n' 6154afb458a35183e470f5480ea08c09817400e6e67465530477e5204af2def0 /usr/local/bin/carlos \
4dd2d8a0661df0b22f1bb9a1f9830f06b6f3b8f7d91211a1ef5d7c4f06a8b4a5 /usr/local/bin/jq | sha256sum -c
chmod 0755 /usr/local/bin/carlos /usr/local/bin/jq
/usr/local/bin/carlos version
diff --git a/docs/superpowers/plans/2026-10-16-claim-activation-dev-cohort1.md b/docs/superpowers/plans/2026-10-16-claim-activation-dev-cohort1.md
index bd95228aa..2029cdc3d 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,41 +4,44 @@ Draft, first written 2026-10-16, revised 2026-10-17 against main at 26065378. St
## Go package (for Paul): the v0.28.3 session
-Prepared on 2026-10-18 for platform-1e to present. The values and state below were read read-only at about 14:30Z; nothing was changed on any box or bucket. The first session's package (v0.28.2) is in this file's history 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, because `guard-arm` checks both `/opt/carlos/carlos` and `carlos.prev` against the identity and leo's `.prev` was v0.28.1, and the session was torn down (CloudTrail clean). The fix, `carlos system install-channel --policy <policy.json>`, is on main as `50f5b268`. It takes `sign-policy`'s armed policy as its floor before any floor is published, and on a box already at the channel's release it replaces `carlos.prev` with that release. The root-runner rehearsal ran all of steps 6 and 7 with it and passed. v0.28.3 is built from `50f5b268` on DOCS-T1 and is not yet published. Read today: dev's router pointers still name v0.28.2; leo and sophie run `carlos v0.28.2` with `.prev` `carlos v0.28.1`; the console runs `7c1beb2d`; the roster is at revision 5 (etag `f3717d8d67f496ffd9525704c7a690b0`); no floor is published (`control/moves-protocol.json` 404); `control/system/router/releases/v0.28.3.json` does not exist.
-
-**v0.28.3 values**
-- Release: v0.28.3, built from main `50f5b268` (`~/.cache/release-v0.28.3/src` at `50f5b26845fb0a23109078654ec5d59b3723d9c4`). Not published: `gh release list -R carlosframework/releases` shows v0.28.2 as the latest, and the forge has no v0.28.3 tag.
-- carlos `linux-arm64` (the router artefact and the signer's CLI) sha256: **TO-CONFIRM (published?)**, from v0.28.3's signed `SHA256SUMS.txt`. The local build `dist/carlos-linux-arm64` hashes to `6154afb458a35183e470f5480ea08c09817400e6e67465530477e5204af2def0` (49217698 bytes). That is what to expect, not the value of record.
-- carlos `linux-amd64` (the operator CLI for 5.0a) sha256: **TO-CONFIRM (published?)**. Local build: `82a60203b1790771b5f3da16bc5d342327131ed30a1aae59a520f42d253369b2`.
-- `SHA256SUMS.txt` and `SHA256SUMS.txt.sig`: **TO-CONFIRM (published?)**. The list must name `carlos_0.28.3_amd64.deb` and `carlos_0.28.3_arm64.deb` and no other `carlos_*.deb`. `publish-identity` carries both files verbatim.
-- Console: `~/.cache/release-v0.28.3/console-linux-arm64`, 47055010 bytes, sha256 `3660b44c13080f0e9ead5f70754a11ec267d70eaab2a89e88ce256ab3437ec74`. 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.3"`, the stamp exactly once. Never rebuild it.
-- Console ship version `CV`: `50f5b268`, the short sha of v0.28.3's commit. platform-1e says the v0.28.3 tag lands on `50f5b268`; **TO-CONFIRM** against the published tag. `apps/bab/console/releases/50f5b268/` does not exist yet, so the ship is new.
-- Identity key: `control/system/router/releases/v0.28.3.json`, a new create-only key. The v0.28.2 identity stays at `control/system/router/releases/v0.28.2.json` (1076 bytes, `2d22f05f`) exactly as it is: permanent, unused, never deleted or rewritten.
-- Floor: `{"min": 1, "min_release": "v0.28.3"}` (`floor.json`, sha256 `c7063389c0bd78a7cd7b400cf6a548cf527320fd562dd6c26ded1a0ecc0f303f`). Expected `floor_sha256` `07d2b63e711af4d97fad48713096447ce3c81ff92db0e956a98543478484aa09`, the sha256 of the compact form `{"min":1,"min_release":"v0.28.3"}` (the same rule gives v0.28.2's `3a361ab8…`). `sign-policy`'s own output is the value of record.
-- Policy and identity files: new bytes, new paths. On the signer and on both boxes: `/root/claim-trial/policy.v0.28.3.json` and `/root/claim-trial/identity.v0.28.3.json`. The v0.28.2 files (`policy.json` `dfac87e6`, `identity.json` `2d22f05f`) stay staged on leo and sophie, unused.
-- Signer: write grant on exactly `control/system/router/releases/v0.28.3.json`, no prefix; CLI carlos v0.28.3 `linux-arm64` (TO-CONFIRM above); jq 1.7.1 `4dd2d8a0…b4a5` (unchanged).
+Final, 2026-10-18. Every value below was read or verified read-only on DOCS-T1 between 15:30Z and 15:50Z; nothing was changed on any box or bucket. The first session's package (v0.28.2) is in this file's history 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, because `guard-arm` checks both `/opt/carlos/carlos` and `carlos.prev` against the identity and leo's `.prev` was v0.28.1, and the session was torn down (CloudTrail clean). The fix, `carlos system install-channel --policy <policy.json>`, is on main as `50f5b268` and is in v0.28.3, now published and rolled to dev's boxes (platform-1e, "v0.28.3 on dev", verified below). The dev console is still on `7c1beb2d`, waiting for 5.0a. The roster is at revision 5 (etag `f3717d8d67f496ffd9525704c7a690b0`), no floor is published (`control/moves-protocol.json` 404), `control/system/router/releases/v0.28.3.json` does not exist, and nothing is under `claim-signer/`.
+
+**One STOP is open: the channel pointers carry no release tag** (found 15:40Z, read-only; details under "Open" below). As the code stands, step 6.1a refuses on both boxes. Do not open the session until platform-1e rules on it.
+
+**v0.28.3 values (all confirmed)**
+- Tag: `v0.28.3` on `50f5b26845fb0a23109078654ec5d59b3723d9c4`. `git ls-remote --tags` on the platform forge: tag object `0f2955fa…`, peeled `v0.28.3^{}` = `50f5b268…`. The releases repo has its own `v0.28.3` tag (`9b84ff9f…`), a commit in that repo.
+- `SHA256SUMS.txt`: sha256 `0a0e5e9287b5f9560c26b20771d8106b12d77668cc40e5d9c0786f35ca3b1038`, 704 bytes, ends in a newline; it lists `carlos_0.28.3_amd64.deb` and `carlos_0.28.3_arm64.deb` and no other deb. `SHA256SUMS.txt.sig`: sha256 `38cd1cf78075cd8284b9df803ae9d43776ee135413ae3a4641d1cbd29abfa476`, 89 bytes. Both downloaded from `https://github.com/carlosframework/releases/releases/download/v0.28.3/`; `openssl pkeyutl -verify` with the README's pinned key printed "Signature Verified Successfully". `publish-identity` carries both files verbatim.
+- carlos `linux-arm64` (the router artefact, the signer's CLI and the box binary): `6154afb458a35183e470f5480ea08c09817400e6e67465530477e5204af2def0`, from the signed sums. It equals the local build, the `artifacts.linux-arm64` of dev's signed `stable.json` and `canary.json` (key `bootstrap/router/v0.28.3/carlos-linux-arm64`), and `/opt/carlos/carlos` on leo, sophie and dennis.
+- carlos `linux-amd64` (the operator CLI for 5.0a): `82a60203b1790771b5f3da16bc5d342327131ed30a1aae59a520f42d253369b2`, from the signed sums, equal to the local build. `sha256sum -c --ignore-missing` against the local `dist/` passed for every listed file.
+- Console: `~/.cache/release-v0.28.3/console-linux-arm64`, 47055010 bytes, sha256 `3660b44c13080f0e9ead5f70754a11ec267d70eaab2a89e88ce256ab3437ec74`. 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.3"`, the stamp exactly once; its sha256 is not in v0.28.3's sums (count `0`). Never rebuild it.
+- Console ship version `CV`: `50f5b268`, the tag's commit. `apps/bab/console/releases/50f5b268/` does not exist yet, so the ship is new.
+- Identity key: `control/system/router/releases/v0.28.3.json`, a new create-only key. The v0.28.2 identity stays at `control/system/router/releases/v0.28.2.json` (1076 bytes, `2d22f05f`) exactly as it is: permanent, unused, never deleted or rewritten. Expected identity: `version` and `release_tag` `v0.28.3`, `moves_protocol` `1`, router `bootstrap/router/v0.28.3/carlos-linux-arm64` `6154afb4…def0`, console `bootstrap/console/v0.28.3/carlos-linux-arm64` `3660b44c…ec74`.
+- Floor: `{"min": 1, "min_release": "v0.28.3"}` (`floor.json`, sha256 `c7063389c0bd78a7cd7b400cf6a548cf527320fd562dd6c26ded1a0ecc0f303f`). Expected `floor_sha256` `07d2b63e711af4d97fad48713096447ce3c81ff92db0e956a98543478484aa09`, the sha256 of the compact form (the same rule gives v0.28.2's `3a361ab8…`). `sign-policy`'s output is the value of record.
+- Policy and identity files: new bytes, new paths, `/root/claim-trial/policy.v0.28.3.json` and `/root/claim-trial/identity.v0.28.3.json` on the signer, leo and sophie. The first session's `policy.json` (`dfac87e6`) and `identity.json` (`2d22f05f`) stay staged on leo and sophie, unused.
+- Signer: write grant on exactly `control/system/router/releases/v0.28.3.json`, no prefix; CLI carlos v0.28.3 `linux-arm64` `6154afb4…def0`; jq 1.7.1 `4dd2d8a0…b4a5`.
- Console rollback version: `7c1beb2d`, promoted with digests on.
-**The session, in order, each block with its stop points.** Paul's go 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, with `7c1beb2d` as its rollback (relayed by platform-1e). platform-1e confirms with Paul before the signer is created.
-1. **Release v0.28.3** (README, "Releasing the platform"): tag `50f5b268`, publish, verify from the public side, then fill in every TO-CONFIRM value above. Stop: the signature does not verify; the tag is not on `50f5b268`; the sums list other debs; any published sha256 differs from the local build's value recorded above (`carlos-linux-arm64` `6154afb4…def0`, `carlos-linux-amd64` `82a60203…69b2`).
-2. **Dev roll, boxes only** (step 1's commands with `--version v0.28.3`, `stable` then `canary`; no console item). Stop: any box not `current` at v0.28.3, `refused` or `rolled-back`; `carlos-instance-control` not restarted (H4). Expected after: each box `carlos v0.28.3`, `.prev` `carlos v0.28.2`.
-3. **5.0a, promote-only** (approved: Paul's go of 2026-10-18 names the console promote redone for v0.28.3): ship and promote the v0.28.3 console to `canary/console`. Digests are already on. Stop: the console's sha256 is not `3660b44c…ec74`; a pointer row `written after digests were turned on`; the header or `readlink` not `50f5b268`.
-4. **Open the session** (`signing-host.md`, "Create", with the v0.28.3 key and CLI). This puts the release key on a host a second time. Stop: a checksum mismatch; `carlos version` not `carlos v0.28.3`; a key file that is not root `600`.
-5. **5.1, resumed** ("5.1 in the second session"): `refresh` only, never `initialize`. Stop: revision not 5, or the listing or a staged file differs.
-6. **Step 6**: 6.1 `sign-policy` and `publish-identity` (new `--out` paths), staging under new paths; **6.1a `install-channel --policy` 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, any identity value other than 6.1's expected ones, any line from 6.1a other than the expected ones.
-7. **Step 7**: readers first (P3, now 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** (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.3; an armed policy on dennis; `jq -e` not `true`; `publish-floor` refused twice.
-8. **Close the session**: shred the key, terminate the signer, remove the exchange objects, delete the role, profile and security group, then the CloudTrail check ("Closing the signing session"). Always allowed, and done at any stop.
-
-**TO-CONFIRM before the session.** Items 1 to 3 stay open until platform-1e posts "v0.28.3 on dev" with the published `SHA256SUMS.txt` values and the roll results.
-1. Is v0.28.3 published? Then, from its signed `SHA256SUMS.txt` (signature verified with the README's pinned key): the `carlos-linux-arm64` and `carlos-linux-amd64` sha256 values, and the sha256 of `SHA256SUMS.txt` and `.sig`. Fill them in here, in 6.1's expected identity, and in `claim-trial-inputs/`. Any published sha256 that differs from the local build's value stops the release block.
-2. The v0.28.3 tag is on `50f5b268` (platform-1e: it lands there), so `CV` is `50f5b268`. If the published tag is anywhere else, stop and ask: the prebuilt console's source and the ship version would not match.
-3. The dev roll: every box `carlos v0.28.3`, `.prev` `carlos v0.28.2`, `current`.
-
-**Answered by platform-1e, 2026-10-18**
-- **5.0a's console promote is approved.** Paul's go on 2026-10-18 named "publish-identity and the console promote redone for v0.28.3". The rollback is `7c1beb2d`.
-- **Dennis's `carlos.prev` is out of scope.** P3 is about each roster reader's version being at least the floor, not about `.prev`. Dennis is not enrolled and is outside the census scope (region `uk`, pools not `cohort1`; `internal/hostactors/census.go:100` on main `50f5b268`). Never run `install-channel` on dennis: it would destroy its rollback copy for no benefit. Instead, step 7 checks read-only, before the report-and-floor pair, that dennis's guard is unarmed, so the published floor does not bind dennis's recovery. An armed policy on dennis is a STOP.
+**State read today (read-only, over SSM)**
+- Leo and sophie: `carlos v0.28.3` (`6154afb4`), `.prev` `carlos v0.28.2` (`7141e037`); `applied.json` names v0.28.3 (leo `stable`, sophie `canary`); edge and instance-control active since the roll (leo 15:44:47Z, sophie 15:43:57Z); no `host-actor.json`, guard, `channel-identity.json` or `/opt/carlos/system/console`. Staged from 5.1, unchanged: 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 (the 7.1 check): `Success`, `absent /opt/carlos/system/guard/policy.json`, `absent /etc/carlos/host-actor.json`, `carlos v0.28.3`; `.prev` `carlos v0.28.2` (`7141e037`). PASS.
+- P9 on sophie, 15:48Z: PASS (record under P9).
+
+**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, with `7c1beb2d` as its rollback (relayed by platform-1e). platform-1e confirms with Paul before the signer is created.
+
+**The blocks, in order, each with its stop points**
+1. **Release v0.28.3. DONE** (platform-1e; verified above). Its stop rule stands for any re-check: the signature does not verify; the tag is not on `50f5b268`; 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; box state verified above). Stop rule for any re-check: a box not `current` at v0.28.3, `refused` or `rolled-back`; instance-control not restarted (H4).
+3. **5.0a, promote-only** (approved): ship and promote `50f5b268` to `canary/console` with the v0.28.3 amd64 CLI. Stop: the console's sha256 is not `3660b44c…ec74`; a pointer row `written after digests were turned on`; the header or `readlink` not `50f5b268`. Rollback: promote `7c1beb2d`.
+4. **Open the session** (`signing-host.md`, "Create"). Not before the open STOP below is ruled on. 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.3`; `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 `install-channel --policy` 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; 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.3; 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.
+
+**Open**
+1. **STOP: the channel pointers carry no `release_tag`, so 6.1a refuses as the code stands.** Dev's signed `control/system/router/stable.json` and `canary.json` (written 15:43Z and 15:44Z by the v0.28.3 roll) have `current` `{version v0.28.3, source release:v0.28.3, released_at …}` and the arm64 artefact, but no `release_tag` and no `moves_protocol`. On main `50f5b268`, `install-channel` (`checkFloor`, `internal/host/installchannel.go`) takes the identity key from the pointer's `release_tag`; with none it refuses: "the stable channel names v0.28.3 with no release tag, so nothing was installed" (`canary` on sophie). The console's promote path adds `release_tag` only once a floor is published (`reserveHostUpdate` in `internal/console/hostactivation.go` returns before tagging in legacy mode), and here the floor comes last, in step 7. The rehearsal did not meet this: its witness promoted with `release.PromoteSystem` and `ReleaseTag: "v1.0.0"` set directly (`activation_console_rootrunner_linux_test.go:294`). The delta's precondition, "each box's channel pointer must name vX.Y.Z with tag vX.Y.Z", is not met on dev. platform-1e rules on the remedy before the signer is created. Until then, block 4 does not start; 5.0a (block 3) is unaffected and may run.
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.
@@ -273,6 +276,8 @@ 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-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.
+
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.
## Blockers
@@ -540,9 +545,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.3 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.3`. Sophie's `install-console` then takes the promoted build as its `--source`.
Values, on DOCS-T1:
-- `CARLOS`: the carlos v0.28.3 CLI for DOCS-T1, `carlos-linux-amd64`, sha256 **TO-CONFIRM (published?)**. Download it with `SHA256SUMS.txt` and `SHA256SUMS.txt.sig` from `https://github.com/carlosframework/releases/releases/download/v0.28.3/`, verify the signature as the README's "Releasing the platform" does, then `sha256sum -c --ignore-missing SHA256SUMS.txt`.
+- `CARLOS`: the carlos v0.28.3 CLI for DOCS-T1, `carlos-linux-amd64`, sha256 `82a60203b1790771b5f3da16bc5d342327131ed30a1aae59a520f42d253369b2` (signed sums, verified 2026-10-18). Download it with `SHA256SUMS.txt` and `SHA256SUMS.txt.sig` from `https://github.com/carlosframework/releases/releases/download/v0.28.3/`, verify the signature as the README's "Releasing the platform" does, then `sha256sum -c --ignore-missing SHA256SUMS.txt`.
- `CONSOLE=~/.cache/release-v0.28.3/console-linux-arm64`: the prebuilt console, sha256 `3660b44c13080f0e9ead5f70754a11ec267d70eaab2a89e88ce256ab3437ec74`. Use that exact file; never rebuild it, and never run it.
-- `CV=50f5b268`: the console's ship version, the short sha of v0.28.3's commit (**TO-CONFIRM:** the tag is on `50f5b268`). `apps/bab/console/releases/50f5b268/` does not exist (read 2026-10-18 14:30Z), so the ship is new. If that prefix appears before item 4, stop and ask. Never make up another version.
+- `CV=50f5b268`: the console's ship version, the short sha of v0.28.3's commit (the forge's `v0.28.3^{}` is `50f5b268`, checked 2026-10-18). `apps/bab/console/releases/50f5b268/` does not exist (read 2026-10-18 14:30Z), 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.
@@ -561,7 +566,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; the last waits for the published sums:
+Expected, as read on 2026-10-18 (PASS; the last line against v0.28.3's published, signature-verified sums):
```
3660b44c13080f0e9ead5f70754a11ec267d70eaab2a89e88ce256ab3437ec74 /home/paulca/.cache/release-v0.28.3/console-linux-arm64
@@ -835,7 +840,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.3, 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.3), each block with its stop points:
-1. **Open the session.** Only once v0.28.3 is published and verified, every dev box reads `carlos v0.28.3` (`.prev` `carlos v0.28.2`) and `current`, and 5.0a for v0.28.3 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.3.json`), install the verified tools (carlos v0.28.3 `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.3`, `claims help` not as quoted below, or a key file that is not root `600`.
+1. **Open the session.** Only once the open STOP in the Go package (no `release_tag` on the channel pointers) is ruled on, v0.28.3 is published and verified (done), every dev box reads `carlos v0.28.3` (`.prev` `carlos v0.28.2`) and `current`, and 5.0a for v0.28.3 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.3.json`), install the verified tools (carlos v0.28.3 `linux-arm64` `6154afb4...def0`; 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.3`, `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` 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.3; 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.
@@ -1106,7 +1111,7 @@ Expected: the dry run, then the apply, succeed; `writes` is empty, because the p
| `identity.sha256sums_sig` | the exact text of `SHA256SUMS.txt.sig` | the same release, same path with `.sig` |
| `identity.console.account` | `bab` | the console app's account, checked in 5.0a 1a (a STOP if it differs) |
| `identity.console.channel` | `canary/console` | the channel 5.0a promoted to, checked in 5.0a 1a (a STOP if it differs) |
-| `identity.console.version` | `50f5b268` (TO-CONFIRM: the v0.28.3 tag's commit) | the console's ship version from 5.0a for v0.28.3 |
+| `identity.console.version` | `50f5b268` (the v0.28.3 tag's commit) | the console's ship version from 5.0a for v0.28.3 |
| `identity.console.app` | `console` | the console app |
| `identity.release_tag` | `v0.28.3` | the release tag |
| `identity.moves_protocol` | `1` | `moves.ProtocolVersion` on main, the floor's `min` |
@@ -1126,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.3.json`;
-- `identity_key` is that key, and `release` shows `version` and `release_tag` `v0.28.3`, `moves_protocol` `1`, `artifacts.linux-arm64` `{"key": "bootstrap/router/v0.28.3/carlos-linux-arm64", "sha256": "<TO-CONFIRM (published?)>"}` (the `carlos-linux-arm64` line of v0.28.3's `SHA256SUMS.txt`; the local build is `6154afb4…def0`), and `console_artifacts.linux-arm64` `{"key": "bootstrap/console/v0.28.3/carlos-linux-arm64", "sha256": "3660b44c13080f0e9ead5f70754a11ec267d70eaab2a89e88ce256ab3437ec74"}` (5.0a's prebuilt console). The payload also holds `channel stable`, `spread 0s`, `source release:v0.28.3` 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.3`, `moves_protocol` `1`, `artifacts.linux-arm64` `{"key": "bootstrap/router/v0.28.3/carlos-linux-arm64", "sha256": "6154afb458a35183e470f5480ea08c09817400e6e67465530477e5204af2def0"}` (the `carlos-linux-arm64` line of v0.28.3's `SHA256SUMS.txt`, equal to the local build), and `console_artifacts.linux-arm64` `{"key": "bootstrap/console/v0.28.3/carlos-linux-arm64", "sha256": "3660b44c13080f0e9ead5f70754a11ec267d70eaab2a89e88ce256ab3437ec74"}` (5.0a's prebuilt console). The payload also holds `channel stable`, `spread 0s`, `source release:v0.28.3` 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.3.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.3.json`, an exact key and not a prefix (`signing-host.md`, statement `WriteIdentity`). The runner also admits only that key for the phase.
@@ -1151,7 +1156,7 @@ Expected: `absent` twice, then `staged` four times. If a path exists, stop: neve
New for v0.28.3, from the prev-rehearsal (main `50f5b268`). Before `guard-arm`, each box to be armed runs `carlos system install-channel --policy` 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.2) 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.
-Before it, on each box: the channel pointer names v0.28.3, tag v0.28.3, with the identity's `carlos-linux-arm64` sha256 (leo `stable`, sophie `canary`; P3's `carlos system status`). `install-channel` reads the box's own channel, and a box whose channel names another release is refused ("this box already runs ...").
+Before it, on each box: the channel pointer names v0.28.3, tag v0.28.3, with the identity's `carlos-linux-arm64` sha256 (leo `stable`, sophie `canary`; P3's `carlos system status`). `install-channel` reads the box's own channel, and a box whose channel names another release is refused ("this box already runs ..."). **Not met on dev on 2026-10-18:** the v0.28.3 pointers carry no `release_tag`, so this step would refuse with "the <channel> channel names v0.28.3 with no release tag, so nothing was installed". That is the open STOP in the Go package; platform-1e rules on it before the session opens.
On leo, as root, then the same block on sophie:
@@ -2238,6 +2243,6 @@ 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.3 release values (TO-CONFIRM until it is published) 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.3 values are confirmed, 2026-10-18). 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` at v0.28.2 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.