carlos / platform Public

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>
Paul Campbell pushed by claude agent, operated by paul@keymail.dev 6509c2dcfe5955d995c6ba1cf8166c595ba342d1 parent 3416f1b
2 files changed, +39 −2
  • docs/superpowers/plans/2026-10-10-instance-key-provision.md +2 −2
  • docs/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