harness: Run 11 (G10 on 64a98473): disk freed, v0.28.15 build, post-b5-run8b restore (no post-8.2b existed), pre-roll check PASS, plain system update PASS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
12 files changed,
+372
−3
harness/RUNLOG.md+81 −0harness/evidence/run11/preroll.log+32 −0harness/evidence/run11/roll.log+140 −0harness/evidence/run11/window.log+0 −0harness/scenarios/cohort1/blocks/b4.sh+5 −1harness/scenarios/cohort1/blocks/g10-preroll-bucket.sh+23 −0harness/scenarios/cohort1/blocks/g10-preroll.host.sh+7 −0harness/scenarios/cohort1/blocks/g10-preroll.leo.sh+25 −0harness/scenarios/cohort1/blocks/g10-roll.host.sh+36 −0harness/scenarios/cohort1/blocks/g10-window.host.sh+21 −0harness/scenarios/cohort1/blocks/w81.box.sh+1 −1harness/scenarios/cohort1/blocks/w82b.sh+1 −1
CI cancelled — superseded by a newer push — run details
CI log
=== gate === cd launchctx && go vet ./... && go test ./... -count=1 ok amadan.net/carlos/platform.git/launchctx 0.012s ? 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 amadan: job cancelled — a newer push superseded it
diff --git a/harness/RUNLOG.md b/harness/RUNLOG.md| index 09e935d9d..1144ffb53 100644 |
| --- a/harness/RUNLOG.md |
| +++ b/harness/RUNLOG.md |
| @@ -2345,3 +2345,84 @@ wakecheck on sophie. New snapshots: `post-candidate`, `post-move-r10`. Host disk |
| G10 should check `df -h /` first. Host-only: `/root/harness/release/v0.28.8` and `/home/operator/release-v0.28.8` (this |
| run), Run 6's moved aside as `*-run6-8a313548`; sampler logs `/root/harness/r10-*`. Host TTL 2026-10-21T12:00Z. |
| DOCS-T1 scratch (`$TMPDIR/r10src` worktree, build outputs, patch, scripts) removed. |
| + |
| +# Run 11: G10 on 64a98473 (overnight 2026-10-20/21) |
| + |
| +Brief (coordinator, for the claim owner platform-1c): re-run G10 on the owner's roster-binding fix, |
| +`claim-empty-cohort-done` @ **64a98473** (CI green, census-ruling-roster-binding ruled, Astra approved), runbook |
| +`claim-dev-cohort1-runbook` @ 5860108f (corrections, the console quiesce, 8.2b's digest, B4's report wait and 202 |
| +handling, "Pre-roll emptiness check for the roster-binding fix"). Order: restore post-8.2b, pre-roll check, the tip on |
| +leo by a plain `system update`, 8.1 to 8.2b only if the snapshot needs it, step 9, B4 and G10 (sophie's console left |
| +on the v0.28.4 stand-in, D10), acceptance and a second create. Harness only. |
| + |
| +## Disk first (23:06-23:08Z): 3.2 GB -> 9.6 GB free |
| + |
| +`df -h /` 54G/59G used, 3.2G free. Deleted, each identified as stale from this RUNLOG (superseded failure or |
| +experiment states of Runs 1-7 and 9; none on the keep list post-8.2b, pre-window, post-b5*, s7, post-move-r10): |
| +- snapshots, on every container holding them (infra, leo [Run 10's], sophie, dennis, signer, leo-btrfs, |
| + leo-ext4-resume) and on `hdir/sophie-console`: `g4-fail-cc90d542`, `g4-held-8376a468`, `g4-fail-8376a468`, |
| + `g4-parent-p-refused`, `rearm-released-v0.28.7`, `post-8.1` (Run 6), `g7-fail-8a313548`, `g7-f4-census`, |
| + `post-8.1-465c3a08`, `g7-fail-465c3a08`, `post-8.1-465c3a08-c8`, `g7-fail-465c3a08-c8`, `g7-fail-465c3a08-ext4`, |
| + `resume-complete-ext4`, `e-refused-0285`, `pre-move-r9`; |
| +- old release copies: `/root/harness/release/v0.28.9`, `v0.28.10`, `v0.28.14` (the unused debug build), |
| + `v0.28.8-run6-8a313548`, and `/home/operator/release-v0.28.9`, `-v0.28.10`, `-v0.28.14`, `-v0.28.8-run6-8a313548`; |
| +- then `fstrim` on the btrfs pool (loop image `discard=async`): 20.4 GiB trimmed. Free after: 9.6 GB (84%). |
| +Kept: every other snapshot, including `post-8.1-run8`, `g10-stuck-run8`/`post-window` (Run 8's G10 evidence) and |
| +`item6-plain-update-fail`; `/root/harness/carlos-debug` (09:07Z, not identified, left). |
| + |
| +## The build: harness v0.28.15 = 64a98473 |
| + |
| +`git worktree add --detach $TMPDIR/g10src 64a98473` + the harness patch (`git diff 6b905c11^ 6b905c11 -- internal`, |
| +sha256 `b2f1ad8f...`, the same seven files), `-tags harness`, `GOFLAGS=-buildvcs=false`, `CGO_ENABLED=0`, linux/arm64, |
| +`-X .../internal/version.Build=v0.28.15`, for `.` and `./cmd/console`. Tests ok: `./internal/s3compat |
| +./internal/publicrelease ./internal/rootaws ./internal/hostfloor`; `-tags harness ./internal/s3compat ./internal/publicrelease`. |
| + |
| +| stamp | plays | carlos sha256 | console sha256 | bucket prefix | |
| +|---|---|---|---|---| |
| +| **v0.28.15** | the fix release (64a98473) | `3cdbf32b3d49a670aa66666f30c73e247e23652d5cc41d7d099ce8ec7f1cc51e` | `8b6c9b7b4932697c1ec8309d3aa8713a29894b015a75e23c94a9ce1001bc6032` | `artefacts/v0.28.15-64a98473/` | |
| + |
| +Why v0.28.15: v0.28.12 to v0.28.14 were used in Run 8's lineage (v0.28.14 the unpublished debug build); v0.28.15 is |
| +the first tag used nowhere and newer than leo's v0.28.12. CV `64a98473`. |
| + |
| +## Step 1: restore, then the pre-roll emptiness check: PASS (23:11-23:12Z) |
| + |
| +**There is no `post-8.2b` snapshot.** Run 8 took none between 8.2b (12:29Z) and B4's stalled create; the next |
| +snapshot after 8.2b is `g10-stuck-run8`, which holds the stuck create and fails the check by design (the runbook says |
| +so). The latest pre-G10 snapshot after 8.2b does not exist, so I restored **`post-b5-run8b`**, Run 8's clean base |
| +(leo ext4 on v0.28.12 = e2c006d2, armed, B1/B2(list)/B5 done, roster rev 15, pre-window), and the window (8.1 to 8.2b) |
| +runs again on the tip. This is also dev's real order (the fix rolls at G4, before the window), and it means |
| +journal-migrate's census is the fixed code's. `post-8.1-run8` was not used: its units are masked mid-window, so a |
| +plain `system update` cannot reach leo there (the runbook's 8.2 note: a fix reaches a masked leo only by hand). |
| +Swap: `leo-swap.sh leo-ext4-r10 203.0.113.127 leo-ext4-run8b` (Run 10's leo kept stopped as `leo-ext4-r10`, with |
| +`pre-0285`, `post-0285`, `post-candidate`, `post-move-r10`), then `snapshot.sh restore post-b5-run8b` (23:11:05-18Z). |
| + |
| +The runbook's two blocks verbatim (`blocks/g10-preroll.leo.sh`, `g10-preroll-bucket.sh`, driver `g10-preroll.host.sh`; |
| +harness names; `evidence/run11/preroll.log`): every line `0`, `leo: all empty`; `host-claim-files 0`, |
| +`evidence-objects-for-leo 0`, `serving-evidence-objects-for-leo 0`, `roster-holds 0`, `roster-activations 0`, |
| +`bucket and roster: all empty`. Context: `/var/lib/carlos-claims` and `/var/lib/carlos-release/private/restarts` |
| +absent, leo `carlos v0.28.12`, roster rev 15, no backfill plan. (Note: the `tools present` line did not print: the |
| +harness leo has neither `sqlite3` nor `jq` (python3 only); harmless here because every database and file is absent, so no line needed them.) |
| + |
| +## Step 2: the tip on leo by a PLAIN `carlos system update`: PASS, no re-arm (23:13-23:24Z) |
| + |
| +`blocks/g10-roll.host.sh v0.28.15 v0.28.15-64a98473 3cdbf32b... 8b6c9b7b... 64a98473` (`evidence/run11/roll.log`). |
| +- **C2 first**: `release-window.sh` signed and verified the sums (`SHA256SUMS.txt` `4a20a04d...`, `Signature Verified |
| + Successfully`), operator CLI `carlos v0.28.15`, console `64a98473` shipped and promoted to `canary/console` |
| + 23:13:26Z (was `e2c006d2`). |
| +- **Signing session** `cohort1-20261020T231326Z` (signer `carlos v0.28.15`, jq-1.7, swap 0, `/run` tmpfs, key |
| + `root 600 1 45`, 23:13:45Z); `publish-identity` v0.28.15 with CV `64a98473`: one create-only write of |
| + `control/system/router/releases/v0.28.15.json` (`before_etag ""`, `db345e78...`; router `3cdbf32b...`, console |
| + `8b6c9b7b...`); identity file = published object; REV 15. |
| +- **Promote stable 23:14:00Z** (`carlos system update --channel stable --version v0.28.15 ... --yes`, rc 0; "2 box(es) |
| + will roll over 5m": kathleen-juggling and noor-marquetry on v0.28.12); roster 15 -> 16 with activation |
| + `9efeb80ff44e8804c91f4d55c95e1157`. Canary (sophie) not promoted. |
| +- dennis 23:14:57-23:15:15Z, leo **23:18:32-23:18:52Z** `carlos-system-update.service` (root apply), both |
| + `result.json` `"outcome": "applied"` v0.28.15 stable, `applied.json` v0.28.15. |
| +- Leo after: `carlos v0.28.15` / `.prev v0.28.12`; path active; guard identities `v0.28.5 .7 .8 .12 .15`; edge pid |
| + 591 exe `3cdbf32b...` = the release, NRestarts 0; no `/root/carlos-*`. Report 23:24:40Z: release v0.28.15, |
| + binary `3cdbf32b`, `activation_complete true`. Roster rev **17**, `activations []`, `holds []` (23:23:41Z). |
| + `system status`: leo and dennis `v0.28.15 current`, sophie `canary v0.28.5 current`. |
| +- Sophie's console untouched: pid 353 exe `b2b431f3...` (the v0.28.4 stand-in, D10), router v0.28.5. |
| + |
| +So from a v0.28.5-equivalent parent (v0.28.12 carries 8376a468 and 8a313548) the fix release rolls onto an armed leo |
| +by the plain update; the ruled re-arm was not needed. |
diff --git a/harness/evidence/run11/preroll.log b/harness/evidence/run11/preroll.log| new file mode 100644 |
| index 000000000..9875ab0de |
| --- /dev/null |
| +++ b/harness/evidence/run11/preroll.log |
| @@ -0,0 +1,32 @@ |
| +[hssm] i-06a1ec144aa5226fb fd771dbf-fcac-4583-9e5e-0e0b512b10b7 Success exit=0 |
| +== block 1 on leo 23:11:59.164Z |
| +launches 0 |
| +stop_inventory 0 |
| +journal_inventory_versions 0 |
| +journal_requests 0 |
| +authority/fences 0 |
| +authority/serving-parks 0 |
| +retire/serving 0 |
| +retire/cold 0 |
| +retire/retired 0 |
| +retire 0 |
| +unit-bindings 0 |
| +unit-materializations 0 |
| +restarts 0 |
| +migration-items 0 |
| +leo: all empty |
| +(context: ls: cannot access '/var/lib/carlos-claims': No such file or directory; ls: cannot access '/var/lib/carlos-release/private/restarts': No such file or directory; carlos carlos v0.28.12) |
| +[block 1 exit=0] |
| +== block 2 bucket 23:11:59.302Z |
| +host-claim-files 0 # information only; the lines below decide |
| +evidence-objects-for-leo 0 |
| +serving-evidence-objects-for-leo 0 |
| +staged |
| + |
| +staged |
| + |
| +roster-holds 0 |
| +roster-activations 0 |
| +bucket and roster: all empty |
| +(context: roster rev 15; control/hosts-backfill.json absent) |
| +[block 2 exit=0] |
diff --git a/harness/evidence/run11/roll.log b/harness/evidence/run11/roll.log| new file mode 100644 |
| index 000000000..85a637e92 |
| --- /dev/null |
| +++ b/harness/evidence/run11/roll.log |
| @@ -0,0 +1,140 @@ |
| +[hssm] i-06a1ec144aa5226fb 0ccf2e18-6745-415b-ae45-ede6bd0b446f Success exit=0 |
| +== signing session (C2 order) 23:13:22.537Z |
| +== release-window v0.28.15 (23:13:22.540Z) |
| +== release v0.28.15 |
| +3cdbf32b3d49a670aa66666f30c73e247e23652d5cc41d7d099ce8ec7f1cc51e carlos-linux-arm64 |
| +f9cdffad5c10a7f352646147a4937860c08f4b017e5594f3ed4e4cb37aa42d54 carlos_0.28.15_amd64.deb |
| +85c7dcbc65565d6825674128af05b86d830b5f5ba94439796b822ce02bde181a carlos_0.28.15_arm64.deb |
| +4a20a04d21b8d44a226abe3174ea4b659fae26cc28bf2c69b1723f4a50d056e6 SHA256SUMS.txt |
| +967cf0889002cfdc9294137cd683a3991b9fc2e5db1d326e56bc99546a108b34 SHA256SUMS.txt.sig |
| +8b6c9b7b4932697c1ec8309d3aa8713a29894b015a75e23c94a9ce1001bc6032 console-linux-arm64 |
| +verify sums: Signature Verified Successfully |
| +operator CLI: carlos v0.28.15 |
| +harness info: harness build: yes endpoint: http://203.0.113.10:9000 sums key: mAnSlX23... sha256:85f6f13cb78c |
| +== 1a/1e |
| +CHANNEL VERSION PROMOTED TAG DIGESTS |
| +canary/console e2c006d2 2026-10-20T12:16:52Z yes |
| +pointer digests: on for bab since 2026-10-20T01:12:47Z |
| +every channel's pointer carries digests: CARLOS_REQUIRE_POINTER_DIGEST can be turned on |
| +== 2 |
| +8b6c9b7b4932697c1ec8309d3aa8713a29894b015a75e23c94a9ce1001bc6032 /home/operator/release-v0.28.15/console-linux-arm64 |
| +0 |
| +== 4 |
| +shipped console 64a98473 (1 artifacts) |
| +promoted console 64a98473 -> canary/console |
| +CHANNEL VERSION PROMOTED TAG DIGESTS |
| +canary/console 64a98473 2026-10-20T23:13:26Z yes |
| +== session open (23:13:26.555Z) |
| +run-id cohort1-20261020T231326Z |
| +2026-10-20 23:13:27 267 SHA256SUMS.txt |
| +2026-10-20 23:13:28 89 SHA256SUMS.txt.sig |
| +2026-10-20 23:13:29 49873058 carlos-linux-arm64 |
| +2026-10-20 23:13:33 203 console.json |
| +2026-10-20 23:13:30 37 floor.json |
| +2026-10-20 23:13:31 244 leo.json |
| +2026-10-20 23:13:31 191 regions.json |
| +2026-10-20 23:13:27 45 release.pub |
| +2026-10-20 23:13:34 1795 signer-helpers.sh |
| +2026-10-20 23:13:32 240 sophie.json |
| +Success /usr/local/bin/carlos: OK |
| +carlos v0.28.15 |
| +jq-1.7 |
| +/usr/bin/jq |
| +SHA256SUMS.txt: OK |
| +SHA256SUMS.txt.sig: OK |
| +helpers.sh: OK |
| +release.pub: OK |
| +swap devices: 0 |
| +/run: tmpfs |
| +session-start 2026-10-20T23:13:45Z |
| +root 600 1 45 |
| + 2026/10/20 23:13:37 ALERT: root AWS file, profile, endpoint and trust-store environment overrides ignored |
| + |
| +== publish-identity v0.28.15, console 64a98473 (23:13:48.764Z) |
| +Success "writes": [ |
| + "key": "control/system/router/releases/v0.28.15.json", |
| + "before_etag": "", |
| + "key": "bootstrap/console/v0.28.15/carlos-linux-arm64", |
| + "key": "bootstrap/router/v0.28.15/carlos-linux-arm64", |
| + "key": "bootstrap/console/v0.28.15/carlos-linux-arm64", |
| + "key": "bootstrap/router/v0.28.15/carlos-linux-arm64", |
| +publish-identity writes: [{"key":"control/system/router/releases/v0.28.15.json","before_etag":"","sha256":"db345e78e7a6cbaa15e773ea74d730ebc042185e35367299431a899976752970","payload":{"schema":1,"component":"router","channel":"stable","current":{"console_artifacts":{"linux-arm64":{"key":"bootstrap/console/v0.28.15/carlos-linux-arm64","sha256":"8b6c9b7b4932697c1ec8309d3aa8713a29894b015a75e23c94a9ce1001bc6032"}},"release_tag":"v0.28.15","moves_protocol":1,"version":"v0.28.15","artifacts":{"linux-arm64":{"key":"bootstrap/router/v0.28.15/carlos-linux-arm64","sha256":"3cdbf32b3d49a670aa66666f30c73e247e23652d5cc41d7d099ce8ec7f1cc51e"}},"source":"release:v0.28.15","released_at":"0001-01-01T00:00:00Z"},"spread":"0s","promoted_at":"2026-10-20T23:13:50Z"}}] |
| +{ |
| + "identity_key": "control/system/router/releases/v0.28.15.json", |
| + "release": { |
| + "console_artifacts": { |
| + "linux-arm64": { |
| + "key": "bootstrap/console/v0.28.15/carlos-linux-arm64", |
| + "sha256": "8b6c9b7b4932697c1ec8309d3aa8713a29894b015a75e23c94a9ce1001bc6032" |
| + } |
| + }, |
| + "release_tag": "v0.28.15", |
| + "moves_protocol": 1, |
| + "version": "v0.28.15", |
| + "artifacts": { |
| + "linux-arm64": { |
| + "key": "bootstrap/router/v0.28.15/carlos-linux-arm64", |
| + "sha256": "3cdbf32b3d49a670aa66666f30c73e247e23652d5cc41d7d099ce8ec7f1cc51e" |
| + } |
| + }, |
| + "source": "release:v0.28.15", |
| + "released_at": "0001-01-01T00:00:00Z" |
| + } |
| +} |
| +db345e78e7a6cbaa |
| +REV=15 |
| + |
| +identity file = published object |
| +identity router 3cdbf32b3d49a670aa66666f30c73e247e23652d5cc41d7d099ce8ec7f1cc51e console 8b6c9b7b4932697c1ec8309d3aa8713a29894b015a75e23c94a9ce1001bc6032 |
| +== done (23:13:57.156Z) |
| +REV after identity: {"rev":15,"activations":[],"holds":[]} |
| +box reports fresh at 23:13:59 |
| +roster before: {"rev":15,"activations":[],"holds":[]} |
| +canary v0.28.5 promoted 2026-10-20T01:22:57Z spread 5m0s file |
| +stable v0.28.12 promoted 2026-10-20T12:22:46Z spread 5m0s file |
| + |
| +ada-letterpress linux-arm64 canary v0.28.5 current |
| +kathleen-juggling linux-arm64 stable v0.28.12 current |
| +noor-marquetry linux-arm64 stable v0.28.12 current |
| +-- leo before |
| + carlos carlos v0.28.12 / prev carlos v0.28.8; path active |
| + identities: v0.28.12.json v0.28.5.json v0.28.7.json v0.28.8.json |
| + edge pid 232 exe sha 28923e4117924b4b NRestarts=0 ExecMainStartTimestamp=Tue 2026-10-20 23:11:14 UTC ActiveState=active |
| +-- dennis before |
| + carlos carlos v0.28.12 / prev carlos v0.28.8; path active |
| + |
| + edge pid 217 exe sha 28923e4117924b4b NRestarts=0 ExecMainStartTimestamp=Tue 2026-10-20 23:11:14 UTC ActiveState=active |
| +== promote stable v0.28.15 (23:14:00.260Z), plain system update, no step on any box |
| +promote v0.28.15 to router/stable — 2 box(es) will roll over 5m: |
| + kathleen-juggling (linux-arm64, running v0.28.12) |
| + noor-marquetry (linux-arm64, running v0.28.12) |
| +warning: v0.28.15 has not been on canary; promoting straight to stable |
| + using uploaded v0.28.15 for linux-arm64 |
| + mirrored bootstrap/router/v0.28.15/carlos-linux-arm64 |
| + pointed router/stable at v0.28.15 (spread 5m0s) |
| + serial bumped: boxes on stable start their spread |
| +promoted boxes on stable roll themselves; watch with: carlos system status --channel stable |
| +rc=0 roster: {"rev":16,"activations":["9efeb80ff44e8804c91f4d55c95e1157"],"holds":[]} |
| +== status 23:19:36.955Z |
| +canary v0.28.5 promoted 2026-10-20T01:22:57Z spread 5m0s file |
| +stable v0.28.15 promoted 2026-10-20T23:14:00Z spread 5m0s file |
| + |
| +ada-letterpress linux-arm64 canary v0.28.5 current |
| +kathleen-juggling linux-arm64 stable v0.28.15 current |
| +noor-marquetry linux-arm64 stable v0.28.15 current |
| +-- leo after |
| + carlos carlos v0.28.15 / prev carlos v0.28.12; path active |
| + identities: v0.28.12.json v0.28.15.json v0.28.5.json v0.28.7.json v0.28.8.json |
| + edge pid 591 exe sha 3cdbf32b3d49a670 NRestarts=0 ExecMainStartTimestamp=Tue 2026-10-20 23:18:35 UTC ActiveState=active |
| + journal: 2026-10-20T23:18:32.735979+00:00 leo systemd[1]: Starting carlos-system-update.service - carlos platform self-update (root apply)... |
| + journal: 2026-10-20T23:18:52.278672+00:00 leo systemd[1]: Finished carlos-system-update.service - carlos platform self-update (root apply). |
| +-- dennis after |
| + carlos carlos v0.28.15 / prev carlos v0.28.12; path active |
| + |
| + edge pid 521 exe sha 3cdbf32b3d49a670 NRestarts=0 ExecMainStartTimestamp=Tue 2026-10-20 23:14:58 UTC ActiveState=active |
| + journal: 2026-10-20T23:14:57.531608+00:00 dennis systemd[1]: Starting carlos-system-update.service - carlos platform self-update (root apply)... |
| + journal: 2026-10-20T23:15:15.607325+00:00 dennis systemd[1]: Finished carlos-system-update.service - carlos platform self-update (root apply). |
| +23:23:41 roster {"rev":17,"activations":[],"holds":[]} |
| +roster end: {"rev":17,"activations":[],"holds":[]} |
| +{"generated_at":"2026-10-20T23:24:40.391637156Z","release":"v0.28.15","binary":"3cdbf32b3d49a670","activation_complete":true,"host_claim_enabled":null} |
| +sophie console pid 353 exe sha b2b431f3b2fb4600; router carlos v0.28.5 |
diff --git a/harness/evidence/run11/window.log b/harness/evidence/run11/window.log| new file mode 100644 |
| index 000000000..e69de29bb |
diff --git a/harness/scenarios/cohort1/blocks/b4.sh b/harness/scenarios/cohort1/blocks/b4.sh| index d7aa5201f..60f1eba80 100755 |
| --- a/harness/scenarios/cohort1/blocks/b4.sh |
| +++ b/harness/scenarios/cohort1/blocks/b4.sh |
| @@ -15,7 +15,11 @@ box_inspect "$SOPHIE" >/dev/null; echo "rev $(cat box-rev)" |
| B=$(aws s3api head-object --bucket harness-deployment --key status/consoles/dev-console.json --query LastModified --output text); echo "dev-console.json before: $B" |
| echo "== 2 resume block on sophie $(date -u +%FT%T.%3NZ)" |
| ../ssm.sh eu-west-1 "$SOPHIE" "$(cat ../blocks/b4-resume.sophie.sh)" |
| -for i in $(seq 1 40); do A=$(aws s3api head-object --bucket harness-deployment --key status/consoles/dev-console.json --query LastModified --output text); [ "$A" != "$B" ] && break; sleep 3; done |
| +echo "== 3a the console's report must postdate the restart (runbook 5860108f, 3a) $(date -u +%FT%TZ)" |
| +RESTART=$(incus_restart=$(~/cohort1/ssm.sh eu-west-1 "$SOPHIE" 'systemctl show console.service -p ActiveEnterTimestamp --value' | sed -n 's/^Success[[:space:]]*//p' | head -1); date -u -d "$incus_restart" +%s) |
| +echo "console restart at $(date -u -d @$RESTART +%FT%TZ)" |
| +until [ "$(date -u -d "$(aws --region eu-west-1 s3api head-object --bucket harness-deployment --key status/consoles/dev-console.json --query LastModified --output text)" +%s)" -gt "$RESTART" ]; do sleep 20; done |
| +A=$(aws s3api head-object --bucket harness-deployment --key status/consoles/dev-console.json --query LastModified --output text) |
| echo "dev-console.json moved: $A ($(date -u +%FT%TZ))" |
| aws s3 cp --quiet s3://harness-deployment/status/consoles/dev-console.json - | jq -c '{generated_at, host_claim_enabled: (.metrics.host_claim_enabled // .host_claim_enabled), release: (.metrics.release // .release)}' || true |
| echo "== 3 $(date -u +%FT%TZ)" |
diff --git a/harness/scenarios/cohort1/blocks/g10-preroll-bucket.sh b/harness/scenarios/cohort1/blocks/g10-preroll-bucket.sh| new file mode 100644 |
| index 000000000..ebfeb9885 |
| --- /dev/null |
| +++ b/harness/scenarios/cohort1/blocks/g10-preroll-bucket.sh |
| @@ -0,0 +1,23 @@ |
| +#!/bin/bash |
| +# Run 11: the runbook's pre-roll emptiness check, block 2 (the bucket), from the operator shell. HARNESS: profile kass -> |
| +# harness, bucket carlos-dev-640012953448 -> harness-deployment, leo-climbing -> kathleen-juggling, SOPHIE from box-helpers. |
| +. ~/cohort1/box-helpers.sh |
| +mkdir -p ~/cohort1/out && cd ~/cohort1/out |
| +export AWS_PROFILE=harness |
| +B=harness-deployment |
| +R=eu-west-1 |
| +LEOBOX=kathleen-juggling |
| +TOTAL=0 |
| +cnt() { case "$2" in ''|*[!0-9]*) echo "$1 UNREADABLE"; TOTAL=$((TOTAL + 1000000)) ;; *) echo "$1 $2"; TOTAL=$((TOTAL + $2)) ;; esac; } |
| +set -o pipefail |
| +HOSTS=$(aws s3 ls "s3://$B/control/hosts/" | awk '$1 != "PRE" && $4 ~ /\.json$/ {print $4}') |
| +echo "host-claim-files $(printf '%s\n' "$HOSTS" | grep -c . || true) # information only; the lines below decide" |
| +for f in $HOSTS; do cnt "claim-names-leo $f" "$(aws s3 cp "s3://$B/control/hosts/$f" - | jq --arg b "$LEOBOX" '[.holder.writer_box?, .op.exec?, (.op.participants[]?), (.holder.admissions[]?.box?)] | map(select(. == $b)) | length')"; done |
| +KEYS=$(aws s3 ls --recursive "s3://$B/control/hosts/" | awk '{print $4}') |
| +cnt evidence-objects-for-leo "$(printf '%s\n' "$KEYS" | grep -cE "^control/hosts/[^/]+/evidence/[^/]+/$LEOBOX/" || true)" |
| +cnt serving-evidence-objects-for-leo "$(printf '%s\n' "$KEYS" | grep -cE "^control/hosts/[^/]+/serving-evidence/(.*/)?$LEOBOX/" || true)" # any depth (op/box/ too; platform-1c) |
| +box_inspect "$SOPHIE" |
| +cnt roster-holds "$(jq '.roster.holds // {} | length' box-inspect.json)" |
| +cnt roster-activations "$(jq '.roster.activations // {} | length' box-inspect.json)" |
| +test "$TOTAL" -eq 0 && echo "bucket and roster: all empty" |
| +echo "(context: roster rev $(jq .roster.revision box-inspect.json); control/hosts-backfill.json $(aws s3 ls s3://$B/control/hosts-backfill.json >/dev/null 2>&1 && echo present || echo absent))" |
diff --git a/harness/scenarios/cohort1/blocks/g10-preroll.host.sh b/harness/scenarios/cohort1/blocks/g10-preroll.host.sh| new file mode 100644 |
| index 000000000..74dc80a00 |
| --- /dev/null |
| +++ b/harness/scenarios/cohort1/blocks/g10-preroll.host.sh |
| @@ -0,0 +1,7 @@ |
| +#!/bin/bash |
| +# Run 11 step 1: the pre-roll emptiness check on harness leo (block 1) and the bucket (block 2), read-only. |
| +set -uo pipefail |
| +echo "== block 1 on leo $(date -u +%T.%3NZ)" |
| +incus exec leo -- bash < /home/operator/cohort1/blocks/g10-preroll.leo.sh; echo "[block 1 exit=$?]" |
| +echo "== block 2 bucket $(date -u +%T.%3NZ)" |
| +runuser -l operator -c "bash ~/cohort1/blocks/g10-preroll-bucket.sh" 2>&1 | grep -v ALERT; echo "[block 2 exit=${PIPESTATUS[0]}]" |
diff --git a/harness/scenarios/cohort1/blocks/g10-preroll.leo.sh b/harness/scenarios/cohort1/blocks/g10-preroll.leo.sh| new file mode 100644 |
| index 000000000..a487b87c5 |
| --- /dev/null |
| +++ b/harness/scenarios/cohort1/blocks/g10-preroll.leo.sh |
| @@ -0,0 +1,25 @@ |
| +# Run 11: the runbook's "Pre-roll emptiness check for the roster-binding fix", block 1 (leo, as root), verbatim |
| +# (runbook claim-dev-cohort1-runbook @ 5860108f). |
| +C=/var/lib/carlos-claims |
| +J=$C/journals.db |
| +TOTAL=0 |
| +cnt() { case "$2" in ''|*[!0-9]*) echo "$1 UNREADABLE"; TOTAL=$((TOTAL + 1000000)) ;; *) echo "$1 $2"; TOTAL=$((TOTAL + $2)) ;; esac; } |
| +dbn() { if [ ! -e "$J" ]; then echo 0; elif [ "$(sqlite3 -readonly "$J" "select count(*) from sqlite_schema where type='table' and name='$1'")" = 0 ]; then echo 0; else sqlite3 -readonly "$J" "select count(*) from $1"; fi; } |
| +dirn() { if [ -d "$1" ]; then find "$1" -mindepth 1 ! -name '*.lock' | wc -l; else echo 0; fi; } |
| +command -v sqlite3 jq > /dev/null && echo "tools present" |
| +cnt launches "$(dbn launches)" |
| +cnt stop_inventory "$(dbn stop_inventory)" |
| +cnt journal_inventory_versions "$(dbn journal_inventory_versions)" |
| +cnt journal_requests "$(dbn journal_requests)" |
| +cnt authority/fences "$(dirn $C/authority/fences)" |
| +cnt authority/serving-parks "$(dirn $C/authority/serving-parks)" |
| +cnt retire/serving "$(dirn $C/retire/serving)" |
| +cnt retire/cold "$(dirn $C/retire/cold)" |
| +cnt retire/retired "$(dirn $C/retire/retired)" |
| +cnt retire "$(dirn $C/retire)" |
| +cnt unit-bindings "$(dirn $C/unit-bindings)" |
| +cnt unit-materializations "$(dirn $C/unit-materializations)" |
| +cnt restarts "$(dirn /var/lib/carlos-release/private/restarts)" |
| +cnt migration-items "$(if [ -e $C/authority/migration/migration.json ]; then jq '.Snapshot.Items | length' $C/authority/migration/migration.json; else echo 0; fi)" |
| +test "$TOTAL" -eq 0 && echo "leo: all empty" |
| +echo "(context: $(ls -d $C 2>&1); $(ls -d /var/lib/carlos-release/private/restarts 2>&1); carlos $(/opt/carlos/carlos version 2>/dev/null | tail -1))" |
diff --git a/harness/scenarios/cohort1/blocks/g10-roll.host.sh b/harness/scenarios/cohort1/blocks/g10-roll.host.sh| new file mode 100644 |
| index 000000000..95fd5c2a1 |
| --- /dev/null |
| +++ b/harness/scenarios/cohort1/blocks/g10-roll.host.sh |
| @@ -0,0 +1,36 @@ |
| +#!/bin/bash |
| +# Run 11 step 2: the tip onto leo by a PLAIN `carlos system update` (stable: leo and dennis), no box step. |
| +# C2: release-window.sh ships and promotes the release console to canary/console first, then the |
| +# signing session's publish-identity (r9-release.host.sh). Sophie (canary router, console = the |
| +# v0.28.4 stand-in per D10) is not promoted. g10-roll.host.sh <TAG> <ART> <carlos sha> <console sha> <CV> |
| +set -uo pipefail |
| +TAG=$1 ART=$2 CS=$3 COS=$4 CV=$5 |
| +C=http://127.0.0.1:8090 |
| +insp() { runuser -l operator -c 'carlos system claims inspect --bucket harness-deployment --aws-region eu-west-1 --public-key "$(cat ~/release.pub)" 2>/dev/null | jq -c "{rev: .roster.revision, activations: (.roster.activations // {} | keys), holds: (.roster.holds // {} | keys)}"'; } |
| +st() { runuser -l operator -c "carlos system status --console $C" 2>&1 | grep -v ALERT; } |
| +box() { incus exec $1 -- bash -c 'echo " carlos $(/opt/carlos/carlos version | tail -1) / prev $(/opt/carlos/carlos.prev version 2>&1 | tail -1); path $(systemctl is-active carlos-system-update.path)" |
| + cat /opt/carlos/system/router/result.json 2>/dev/null | jq -c "{outcome, version, channel, promoted_at, reason}" 2>/dev/null | sed "s/^/ result: /" |
| + cat /opt/carlos/system/router/applied.json 2>/dev/null | jq -c . 2>/dev/null | cut -c1-200 | sed "s/^/ applied: /" |
| + ls /opt/carlos/system/guard/identities 2>/dev/null | tr "\n" " " | sed "s/^/ identities: /"; echo |
| + P=$(systemctl show -p MainPID --value carlos-edge.service); echo " edge pid $P exe sha $(sha256sum < /proc/$P/exe | cut -c1-16) $(systemctl show carlos-edge -p NRestarts -p ActiveState -p ExecMainStartTimestamp | tr "\n" " ")" |
| + ls /root/carlos-* 2>/dev/null |
| + journalctl -u carlos-system-update.service --since "-25min" --no-pager -o short-iso-precise | grep -E "Starting|Finished|refus|guard|apply|error|fail" | tail -8 | sed "s/^/ journal: /"'; } |
| +echo "== signing session (C2 order) $(date -u +%T.%3NZ)" |
| +bash /home/operator/cohort1/blocks/r9-release.host.sh $TAG $ART $CS $COS $CV 2>&1 | grep -vE '^help\| ' |
| +echo "REV after identity: $(insp)" |
| +T0=$(date -u +%s) |
| +fresh() { runuser -l operator -c 'for b in ada-letterpress kathleen-juggling noor-marquetry; do date -u -d "$(aws s3api head-object --bucket harness-deployment --key status/boxes/$b.json --query LastModified --output text)" +%s; done' | sort -n | head -1; } |
| +for i in $(seq 1 60); do [ "$(fresh)" -gt "$((T0-300))" ] && break; sleep 10; done; echo "box reports fresh at $(date -u +%T)" |
| +echo "roster before: $(insp)"; st |
| +for b in leo dennis; do echo "-- $b before"; box $b; done |
| +echo "== promote stable $TAG ($(date -u +%T.%3NZ)), plain system update, no step on any box" |
| +runuser -l operator -c "carlos system update --console $C --channel stable --version $TAG --file ~/release-$TAG/carlos-linux-arm64 --platform linux-arm64 --yes" 2>&1 | grep -v ALERT |
| +echo "rc=${PIPESTATUS[0]} roster: $(insp)" |
| +for i in $(seq 1 60); do s=$(st); [ "$(echo "$s" | grep -cE "$TAG *current")" -ge 2 ] && break; sleep 15; done |
| +echo "== status $(date -u +%T.%3NZ)"; echo "$s" |
| +for b in leo dennis; do echo "-- $b after"; box $b; done |
| +for i in $(seq 1 40); do a=$(insp); case "$a" in *'"activations":[]'*) echo "$(date -u +%T) roster $a"; break;; esac; sleep 15; done |
| +echo "roster end: $(insp)" |
| +T1=$(date -u +%s); for i in $(seq 1 50); do t=$(runuser -l operator -c 'date -u -d "$(aws s3api head-object --bucket harness-deployment --key status/boxes/kathleen-juggling.json --query LastModified --output text)" +%s'); [ "$t" -gt "$T1" ] && break; sleep 10; done |
| +runuser -l operator -c 'aws s3 cp --quiet s3://harness-deployment/status/boxes/kathleen-juggling.json - | jq -c "{generated_at, release: .metrics.release, binary: .metrics.binary_sha256[0:16], activation_complete: .metrics.activation_complete, host_claim_enabled: .metrics.host_claim_enabled}"' |
| +incus exec sophie -- bash -c 'p=$(systemctl show -p MainPID --value console.service); echo "sophie console pid $p exe sha $(sha256sum < /proc/$p/exe | cut -c1-16); router $(/opt/carlos/carlos version | tail -1)"' |
diff --git a/harness/scenarios/cohort1/blocks/g10-window.host.sh b/harness/scenarios/cohort1/blocks/g10-window.host.sh| new file mode 100644 |
| index 000000000..6331d7cba |
| --- /dev/null |
| +++ b/harness/scenarios/cohort1/blocks/g10-window.host.sh |
| @@ -0,0 +1,21 @@ |
| +#!/bin/bash |
| +# Run 11 step 3: the window on the tip, 8.1 to 8.2b, snapshot post-8.2b, then 8.4, step 9 and G9's checks. |
| +# Stops at the first block that does not reach its DONE/END line. g10-window.host.sh <WINDOW_ID> [from] |
| +set -uo pipefail |
| +WID=$1; FROM=${2:-81} |
| +D=/home/operator/cohort1/blocks |
| +step() { local name=$1 marker=$2; shift 2; echo "######## $name $(date -u +%T.%3NZ)"; out=$("$@" 2>&1); echo "$out" | grep -v '^help| '; echo "$out" | grep -q "$marker" || { echo "STOP: $name did not reach '$marker'"; exit 1; }; } |
| +op() { runuser -l operator -c "$*"; } |
| +if [ "$FROM" = 81 ]; then |
| +step 8.1 "8.1 DONE" bash $D/run-leo.sh $WID w81.box.sh |
| +step 8.1b "8.1b END" op "bash ~/cohort1/blocks/w81b.sh $WID" |
| +step 8.2 "8.2 DONE" bash $D/run-leo.sh $WID --env w82.box.sh |
| +step 8.2b "8.2b END" op "bash ~/cohort1/blocks/w82b.sh $WID" |
| +echo "######## snapshot post-8.2b $(date -u +%T.%3NZ)"; bash /root/harness/snapshot.sh create post-8.2b 2>&1 | tail -8 |
| +for c in leo sophie; do incus exec $c -- systemctl --failed --no-legend --plain; done |
| +fi |
| +step 8.4 "8.4 DONE" bash $D/run-leo.sh $WID --env w84.box.sh |
| +step 9 "9 DONE" bash $D/run-leo.sh $WID --env w9.box.sh |
| +echo "######## G9 checks $(date -u +%T.%3NZ)"; op "bash ~/cohort1/blocks/g9-check.sh" |
| +incus exec leo -- journalctl -u carlos-edge.service --since -10min --no-pager | grep -E 'claims|claim|authority|binding|ErrTyped|changed' | tail -15 |
| +echo "WINDOW END $(date -u +%T.%3NZ)" |
diff --git a/harness/scenarios/cohort1/blocks/w81.box.sh b/harness/scenarios/cohort1/blocks/w81.box.sh| index d2880b636..60b9bd639 100755 |
| --- a/harness/scenarios/cohort1/blocks/w81.box.sh |
| +++ b/harness/scenarios/cohort1/blocks/w81.box.sh |
| @@ -53,5 +53,5 @@ for unit in "${UNITS[@]}"; do |
| done |
| systemctl daemon-reload |
| systemctl show "${UNITS[@]}" -p Id -p LoadState -p ActiveState |
| -pub /opt/carlos/carlos system claims install-control --dry-run |
| +# (C7, runbook 5860108f: 8.1's closing install-control --dry-run is deleted) |
| echo "8.1 DONE $(date -u +%T)" |
diff --git a/harness/scenarios/cohort1/blocks/w82b.sh b/harness/scenarios/cohort1/blocks/w82b.sh| index 036296da1..2d045fcd1 100755 |
| --- a/harness/scenarios/cohort1/blocks/w82b.sh |
| +++ b/harness/scenarios/cohort1/blocks/w82b.sh |
| @@ -34,7 +34,7 @@ jq -e '(.backfill.reports | keys) == [\"kathleen-juggling\"]' backfill-done.json |
| jq -e '(.writes | length) == 1' backfill-done.json |
| jq -e '.writes[0].key == \"control/hosts-backfill.json\"' backfill-done.json |
| jq -e '(.writes[0].before_etag | length) > 0' backfill-done.json |
| -# Digest over the census object's raw bytes as stored. PENDING: confirmed in harness <run-id>. |
| +# Digest over the census object's raw bytes as stored: CONFIRMED in harness run cohort1-20261020T121705Z (sha256.Sum256 of the Store.Get body, internal/hostops/backfill_publish.go:219, 233-234). |
| LEO_CENSUS_SHA=\$(aws --region \"\$R\" s3 cp \"s3://\$B/control/host-census/\$BACKFILL_ID/kathleen-juggling.json\" - | sha256sum | cut -d' ' -f1) |
| test -n \"\$LEO_CENSUS_SHA\" |
| echo \"LEO_CENSUS_SHA=\$LEO_CENSUS_SHA reports=\$(jq -c .backfill.reports backfill-done.json)\" |