Instance key provision: Astra round 7 (ready to build) unedited, plus its two P3 corrections in the plan
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 files changed,
+39
−2
docs/superpowers/plans/2026-10-10-instance-key-provision.md+2 −2docs/superpowers/plans/CODEX-PLAN-INSTANCE-KEY-R7.md+37 −0
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 319.633s
? github.com/carlosframework/platform/cmd/changelog [no test files]
ok github.com/carlosframework/platform/cmd/console 3.281s
ok github.com/carlosframework/platform/internal/activator 133.296s
ok github.com/carlosframework/platform/internal/agentsock 0.018s
ok github.com/carlosframework/platform/internal/alerting 0.005s
ok github.com/carlosframework/platform/internal/analytics 0.035s
ok github.com/carlosframework/platform/internal/appconfig 2.169s
ok github.com/carlosframework/platform/internal/apperr 0.107s
ok github.com/carlosframework/platform/internal/applog 0.164s
ok github.com/carlosframework/platform/internal/awsinv 0.004s
ok github.com/carlosframework/platform/internal/boxchoice 0.005s
ok github.com/carlosframework/platform/internal/boxid 0.931s
? 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.009s
ok github.com/carlosframework/platform/internal/caps 0.012s
ok github.com/carlosframework/platform/internal/certwarm 0.004s
ok github.com/carlosframework/platform/internal/cgroup 0.195s
ok github.com/carlosframework/platform/internal/changelog 0.279s
ok github.com/carlosframework/platform/internal/clamd 0.057s
? github.com/carlosframework/platform/internal/cliflag [no test files]
ok github.com/carlosframework/platform/internal/console 318.488s
? 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 5.602s
ok github.com/carlosframework/platform/internal/dbdoor/dbdoortest 0.012s
ok github.com/carlosframework/platform/internal/dbverify 0.005s
ok github.com/carlosframework/platform/internal/dnsrec 0.009s
ok github.com/carlosframework/platform/internal/docsite 0.005s
ok github.com/carlosframework/platform/internal/domains 1.973s
ok github.com/carlosframework/platform/internal/doorkey 0.007s
ok github.com/carlosframework/platform/internal/economics 0.006s
ok github.com/carlosframework/platform/internal/edge 25.817s
? github.com/carlosframework/platform/internal/edgeproof [no test files]
ok github.com/carlosframework/platform/internal/edgesfile 0.009s
ok github.com/carlosframework/platform/internal/fleetapi 0.139s
ok github.com/carlosframework/platform/internal/gate 1.658s
ok github.com/carlosframework/platform/internal/genselect 0.020s
ok github.com/carlosframework/platform/internal/geo 0.024s
ok github.com/carlosframework/platform/internal/geoip 0.044s
ok github.com/carlosframework/platform/internal/host 44.708s
ok github.com/carlosframework/platform/internal/hostactors 0.370s
ok github.com/carlosframework/platform/internal/hostbox 1.210s
ok github.com/carlosframework/platform/internal/hostclaim 0.228s
ok github.com/carlosframework/platform/internal/hostevidence 0.006s
ok github.com/carlosframework/platform/internal/hostexec 0.307s
ok github.com/carlosframework/platform/internal/hostfence 0.041s
ok github.com/carlosframework/platform/internal/hostfiles 4.097s
ok github.com/carlosframework/platform/internal/hostfloor 0.009s
ok github.com/carlosframework/platform/internal/hostguard 0.136s
ok github.com/carlosframework/platform/internal/hostops 1.323s
ok github.com/carlosframework/platform/internal/hostquarantine 0.003s
ok github.com/carlosframework/platform/internal/hostresolve 0.126s
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 1.703s
ok github.com/carlosframework/platform/internal/instanceexec 2.695s
ok github.com/carlosframework/platform/internal/instancefs 0.005s
ok github.com/carlosframework/platform/internal/instancekey 0.002s
ok github.com/carlosframework/platform/internal/layout 1.328s
ok github.com/carlosframework/platform/internal/lease 9.433s
ok github.com/carlosframework/platform/internal/lease/leasetest 0.007s
ok github.com/carlosframework/platform/internal/ledger 0.012s
ok github.com/carlosframework/platform/internal/mail 0.180s
ok github.com/carlosframework/platform/internal/maintenance 0.076s
ok github.com/carlosframework/platform/internal/maintenanceexec 5.535s
ok github.com/carlosframework/platform/internal/maintenanceguard 0.084s
ok github.com/carlosframework/platform/internal/metrics 0.006s
ok github.com/carlosframework/platform/internal/moves 21.020s
ok github.com/carlosframework/platform/internal/moves/archive 0.751s
ok github.com/carlosframework/platform/internal/objstore 0.162s
ok github.com/carlosframework/platform/internal/ops 0.149s
ok github.com/carlosframework/platform/internal/park 0.188s
ok github.com/carlosframework/platform/internal/privatefile 0.003s
ok github.com/carlosframework/platform/internal/provision 3.054s
ok github.com/carlosframework/platform/internal/publicrelease 0.007s
ok github.com/carlosframework/platform/internal/registry 3.523s
ok github.com/carlosframework/platform/internal/relay 7.214s
ok github.com/carlosframework/platform/internal/release 18.421s
ok github.com/carlosframework/platform/internal/rollout 1.492s
ok github.com/carlosframework/platform/internal/rootaws 0.006s
ok github.com/carlosframework/platform/internal/s3compat 0.005s
ok github.com/carlosframework/platform/internal/safefile 0.003s
ok github.com/carlosframework/platform/internal/schedule 2.200s
ok github.com/carlosframework/platform/internal/sim/hostlife 2.566s
ok github.com/carlosframework/platform/internal/sim/litestreamfacts 4.191s
ok github.com/carlosframework/platform/internal/status 0.041s
ok github.com/carlosframework/platform/internal/steering 0.006s
ok github.com/carlosframework/platform/internal/stopevidence 0.122s
ok github.com/carlosframework/platform/internal/svcrole 0.002s
ok github.com/carlosframework/platform/internal/telemetry 0.004s
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.003s
ok github.com/carlosframework/platform/internal/updatewords 0.002s
ok github.com/carlosframework/platform/internal/usage 0.004s
ok github.com/carlosframework/platform/internal/version 0.002s
ok github.com/carlosframework/platform/internal/vet 1.547s
=== 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
--- 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.024s
=== RUN TestT4StorageProbeMinio
2026/10/11 13:53:16 moves: T4: STORE: list: operation error S3: ListObjectsV2, https response error StatusCode: 403, RequestID: 18DD7E072C41686A, 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.01s)
PASS
ok github.com/carlosframework/platform/internal/host 0.016s
minio contract: PASS
diff --git a/docs/superpowers/plans/2026-10-10-instance-key-provision.md b/docs/superpowers/plans/2026-10-10-instance-key-provision.md| index bb0845aa9..2c23aba7e 100644 |
| --- a/docs/superpowers/plans/2026-10-10-instance-key-provision.md |
| +++ b/docs/superpowers/plans/2026-10-10-instance-key-provision.md |
| @@ -324,7 +324,7 @@ Source (c) and `ConfiguredInstanceKey` are gone: a configured key is covered by |
| - **How it is written.** The pre-roll check writes it whole, to a temporary file renamed into place, so a reader sees the old list or the new one, never part of one. The agent writes nothing to it. |
| - **How it is read.** `replicaHomeKeys` reads the file at every call and keeps no copy. A removed entry stops verifying at the very next replica launch, and a replacement verifies from the next launch on, with no agent restart (which would restart every instance on the box). An absent file verifies nothing. An unreadable or malformed one verifies nothing and is logged without its text. |
| -*Cost if wrong:* one read of a small file per replica launch. A list half-written by hand, without the rename, can be read mid-write; it then fails to parse and refuses every replica on the box until it is whole, which is safe. |
| +*Cost if wrong:* one read of a small file per replica launch. A list written by hand without the rename can be read mid-write. A cut inside an entry fails to parse and refuses every keyed replica until the file is whole. A cut after a complete entry still parses, so the entries before the cut keep verifying and those after it are refused until the file is whole. Both outcomes refuse rather than admit a wrong key, and the prescribed write-then-rename avoids either (Astra round 7, P3). |
| ## Obligations on other plans |
| @@ -1274,7 +1274,7 @@ func TestEmptyOwnInstanceKeyShadowsNothing(t *testing.T) { |
| t.Fatalf("empty own key: CARLOS_INSTANCE_KEY is the configured key: %v; shadowed %v, want [MINE]", env["CARLOS_INSTANCE_KEY"] == "cfg", shadowed) |
| } |
| write(".env", "CARLOS_INSTANCE_KEY=own\nMINE=1\n") |
| - if env, shadowed, err = b.LaunchEnvironment(rt); err != nil || env["CARLOS_INSTANCE_KEY"] != "own" || len(shadowed) != 2 { |
| + if env, shadowed, err = b.LaunchEnvironment(rt); err != nil || env["CARLOS_INSTANCE_KEY"] != "own" || strings.Join(shadowed, ",") != "CARLOS_INSTANCE_KEY,MINE" { |
| t.Fatalf("non-empty own key: CARLOS_INSTANCE_KEY is the own key: %v; shadowed %v; err %v", env["CARLOS_INSTANCE_KEY"] == "own", shadowed, err) |
| } |
| } |
diff --git a/docs/superpowers/plans/CODEX-PLAN-INSTANCE-KEY-R7.md b/docs/superpowers/plans/CODEX-PLAN-INSTANCE-KEY-R7.md| new file mode 100644 |
| index 000000000..24bd1cd2f |
| --- /dev/null |
| +++ b/docs/superpowers/plans/CODEX-PLAN-INSTANCE-KEY-R7.md |
| @@ -0,0 +1,37 @@ |
| +Reviewed HEAD `3416f1b8`. No P1 or P2 findings. |
| + |
| +1. **P3 — Partial writes do not necessarily fail parsing.** [Plan:327](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/instance-key-provision/docs/superpowers/plans/2026-10-10-instance-key-provision.md:327) |
| + A truncated list ending after a complete entry still parses and verifies retained entries. Correct the claim that every partial write refuses every replica. The prescribed temporary-file-and-rename procedure avoids this problem. |
| + |
| +2. **P3 — One Task 1 test differs from HEAD.** [Plan:1277](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/instance-key-provision/docs/superpowers/plans/2026-10-10-instance-key-provision.md:1277) |
| + The plan checks only `len(shadowed) != 2`; the committed test checks exactly `CARLOS_INSTANCE_KEY,MINE`. Copy the stronger assertion. Task 1’s production snippets and `instancekey` package tests otherwise match. |
| + |
| +Both round 6 findings are closed at the plan level: the gate receives provenance from the launch’s own environment read, and digest-list changes reach subsequent lookups without restarting the agent. |
| + |
| +The file reader fails closed on missing, unreadable or malformed input. With the specified permissions, tenants cannot write the list. Isolated tenants cannot read `/etc/carlos`; legacy flat children can read it through their inherited `carlos` group, consistent with their existing unisolated access. |
| + |
| +The canonical adoption parser fits the planned writers and consumers; I found no dependency on its former permissiveness. |
| + |
| +Static review only: `go test ./internal/instancekey -count=1` could not start because the sandbox forbids creating Go’s work directory. No files changed. |
| + |
| +**Verdict: ready to build.** The two P3 corrections are nonblocking. |
| + |
| +--- |
| + |
| +**FIRST PROMPT:** |
| +Review the instance-key provision plan at HEAD using brief 7. |
| + |
| +**WHAT:** |
| +Check round 6 closure, file safety and Task 1 consistency. |
| + |
| +**STATUS:** |
| +Review complete: two P3 notes; ready to build. |
| + |
| +**NEEDED:** |
| +Nothing for this review. |
| + |
| +**RECOMMENDED:** |
| +Correct the two minor discrepancies during implementation. |
| + |
| +**SESSION:** |
| +Safe to close. No processes left running; handoff not saved because the workspace is read-only. |
| \ No newline at end of file |