carlos / platform Public

spec: host lifecycle claim rev 6.33 (Plan 13: home-region naming; the engine keeps the verified roster name bound to @home on the verified home placement)

Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
codex agent, operated by paul@keymail.dev pushed by claude agent, operated by paul@keymail.dev b143854602f685db201386c041ca3e99471e0e21 parent 11c01b9
1 file changed, +73 −1
  • docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md +73 −1

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	153.505s
ok  	github.com/carlosframework/platform/cmd/console	2.196s
ok  	github.com/carlosframework/platform/internal/activator	55.698s
ok  	github.com/carlosframework/platform/internal/agentsock	0.015s
ok  	github.com/carlosframework/platform/internal/analytics	0.017s
ok  	github.com/carlosframework/platform/internal/appconfig	0.945s
ok  	github.com/carlosframework/platform/internal/apperr	0.069s
ok  	github.com/carlosframework/platform/internal/applog	0.118s
ok  	github.com/carlosframework/platform/internal/awsinv	0.003s
ok  	github.com/carlosframework/platform/internal/caps	0.011s
ok  	github.com/carlosframework/platform/internal/certwarm	0.002s
ok  	github.com/carlosframework/platform/internal/cgroup	0.038s
ok  	github.com/carlosframework/platform/internal/clamd	0.054s
?   	github.com/carlosframework/platform/internal/cliflag	[no test files]
ok  	github.com/carlosframework/platform/internal/console	51.339s
?   	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	1.388s
ok  	github.com/carlosframework/platform/internal/dbdoor/dbdoortest	0.009s
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	1.077s
ok  	github.com/carlosframework/platform/internal/doorkey	0.008s
ok  	github.com/carlosframework/platform/internal/economics	0.004s
ok  	github.com/carlosframework/platform/internal/edge	23.150s
ok  	github.com/carlosframework/platform/internal/edgesfile	0.018s
ok  	github.com/carlosframework/platform/internal/fleetapi	0.092s
ok  	github.com/carlosframework/platform/internal/gate	1.656s
ok  	github.com/carlosframework/platform/internal/host	6.825s
ok  	github.com/carlosframework/platform/internal/infraview	0.018s
ok  	github.com/carlosframework/platform/internal/instancectl	0.415s
ok  	github.com/carlosframework/platform/internal/instanceexec	0.018s
ok  	github.com/carlosframework/platform/internal/instancefs	0.018s
ok  	github.com/carlosframework/platform/internal/lease	5.077s
ok  	github.com/carlosframework/platform/internal/ledger	0.018s
ok  	github.com/carlosframework/platform/internal/mail	0.053s
ok  	github.com/carlosframework/platform/internal/maintenance	0.073s
ok  	github.com/carlosframework/platform/internal/maintenanceexec	5.479s
ok  	github.com/carlosframework/platform/internal/maintenanceguard	0.046s
ok  	github.com/carlosframework/platform/internal/metrics	0.018s
ok  	github.com/carlosframework/platform/internal/objstore	0.088s
ok  	github.com/carlosframework/platform/internal/ops	0.098s
ok  	github.com/carlosframework/platform/internal/privatefile	0.017s
ok  	github.com/carlosframework/platform/internal/provision	0.860s
ok  	github.com/carlosframework/platform/internal/publicrelease	0.007s
ok  	github.com/carlosframework/platform/internal/registry	1.233s
ok  	github.com/carlosframework/platform/internal/relay	7.218s
ok  	github.com/carlosframework/platform/internal/release	3.560s
ok  	github.com/carlosframework/platform/internal/s3compat	0.005s
ok  	github.com/carlosframework/platform/internal/schedule	1.396s
ok  	github.com/carlosframework/platform/internal/status	0.025s
ok  	github.com/carlosframework/platform/internal/steering	0.006s
ok  	github.com/carlosframework/platform/internal/svcrole	0.005s
ok  	github.com/carlosframework/platform/internal/telemetry	0.004s
ok  	github.com/carlosframework/platform/internal/tunnelclient	0.004s
ok  	github.com/carlosframework/platform/internal/unixdial	0.004s
ok  	github.com/carlosframework/platform/internal/usage	0.004s
ok  	github.com/carlosframework/platform/internal/version	0.005s
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
--- 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: downloading https://github.com/minio/minio/releases/download/RELEASE.2025-09-07T16-13-09Z/minio.linux-arm64.RELEASE.2025-09-07T16-13-09Z
  minio: downloaded, digest verified
  mc: downloading https://github.com/minio/mc/releases/download/RELEASE.2025-08-13T08-35-41Z/mc.linux-arm64.RELEASE.2025-08-13T08-35-41Z
  mc: downloaded, 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
minio contract: PASS
diff --git a/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md b/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md
index a862b6f5b..cce7e8ec3 100644
--- a/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md
+++ b/docs/superpowers/specs/2026-10-02-host-lifecycle-claim-design.md
@@ -1,10 +1,12 @@
# The host lifecycle claim
+**Rev 6.33 (2026-10-12):** binds home placements to claim engine regions, preserves existing roster-name evidence, and completes the home move enrollment and loss boundaries. Claim Plan 13 supplies the implementation.
+
**Rev 6.32 (2026-10-10):** completes the claim interfaces for moves M2, M3, M5, M6, M7, M9, M12 and M21. Claim Plan 12 supplies loss-bound Group D admission, recovery predecessor evidence, atomic fenced-target release and restore retirement, held-lease parks, local park authority and retained retirement-location evidence.
**Rev 6.31 (2026-10-09):** records the accepted region HA contracts in amadan #236: `AutomaticLoss` in claim-level `evidence_refs`, the stop-only `relocation-release` obligation, and immutable signed `enrolled_at`. Section 6.2a binds moves' push, landing-install and rollback-return parks by name and region; R6 refuses automatic empty failover after any writer session. Claim Plan 11 supplies the integration.
-Design, 2026-10-10, **rev 6.32**. Joint rounds 6 and 7 judged the claim ready for primitive planning. Rev
+Design, 2026-10-12, **rev 6.33**. Joint rounds 6 and 7 judged the claim ready for primitive planning. Rev
6.5 added the R6-4 rule. Rev 6.6 added writer epochs (R7-1, amadan #225).
Rev 6.7 answered the moves session's notes on §6.4a. Rev 6.8 rewrote §6.4a
around writer sessions, for joint round 8. Rev 6.10 answers joint round 10
@@ -1123,6 +1125,76 @@ The regional adapter shall:
5. Execute Plan 4’s exact-version park.
6. Acknowledge with the chore’s own operation ID, updating `quiet_after` in the same CAS.
+### Home placement and retained claim names (rev 6.33)
+
+A home placement is still `""` in an instance record and in moves From/To.
+At the placement-to-engine boundary, `park.PlacementRegion` maps it to
+`park.HomeRegion` (`"@home"`). Empty engine regions still mean unset and
+remain refused by Validate, parkQueueGuard, AdmitWriter, PublishGeneration
+and every Cover*Predecessors entry. Invalid placement codes, including
+`"@home"` supplied as a code, refuse. A named placement called `home` is
+independent of the home token.
+
+The claim engine of an enrolled home box retains its signed roster name
+(for example `ie`), passed through PlacementRegion. This avoids changing
+existing admission tuples, stop receipts, retirement manifests and signed
+loss evidence. On a box whose configured CARLOS_REGION is the empty home
+placement, its verified roster name binds the single alias between that
+name and `@home`. A named placement must agree with the roster and gains
+no alias. Membership, enrollment, cloud identity, bucket and request limit
+checks precede use of the alias and remain fresh at every effect.
+
+The regional worker acknowledges obligations under either home spelling,
+including queued work without bucket residue. It keeps the obligation's
+original owner, region, evidence and retirement identity. Live-generation
+selection treats the two names as the same region, so an old named
+admission can never become disposable merely because a new view names
+`@home`. Read-only holder projections may normalize those names for
+selection; they must never be persisted or used to rewrite signed evidence.
+Quiet checks use the later bound under the two names. Other regions retain
+exact matching. Existing claims need no conversion and no stored rewrite.
+
+The console and BeginClaimMove share HomePlacementCode for roster/record
+comparisons. The console passes its deployment home name to BeginClaimMove;
+the start CAS retains that name as `op.intent.home_region`, beside the
+existing enrolled source and target bindings. It persists the target as
+an engine region, while the moves record and door keep placement codes.
+The record write compares its target through PlacementRegion.
+
+A move loss persists SourceRegion through PlacementRegion, so a home source
+is `@home`, never unset. SourceRegion and TargetRegion are engine values in
+the loss intent, admission policy, write-source tuples and park requests.
+They are not placement codes: do not pass them to a moves door, record
+writer or placement resolver. The loss/rollback record is written from the
+original record's From/To codes. Admission policy recognizes the operation's
+bound home alias without altering the signed loss or granting coverage.
+
+The changes remain behind CARLOS_HOST_CLAIM and preserve flag-off behavior.
+They add no root file effects, SQLite opens, AWS client construction or new
+production activation. Existing launch, moves and files-provider gates
+remain required. Roll out the alias-aware readers and quiet checks on all
+home workers before allowing home moves; earlier readers cannot service
+`@home` chores safely. The home name must remain stable across that rollout.
+
+The operation's verified home binding also projects remote admission history
+for a named worker's park view. It does not confer home ownership on that
+worker. Every moves engine retains the local binding supplied by MoveParks;
+observation reads retain the operation binding for mixed-name live chains.
+
+For an unnamed console home, legacy database admission names are recognized
+only from the configured home bucket's HibernateRegion fallback. Admission
+contents cannot establish an alias. Named placements and an explicit home
+name do not use that fallback. An unresolved console region still refuses
+startup. Signed stop receipts keep their roster region and exact bytes; only
+the comparison with the operation target uses the bound alias.
+
+Before a flip, recovery compares record placement codes through the shared
+rule and returns the source's roster identity to the claim conversion. Both
+recovery entry points keep the decision's Region, Move.From, Move.To and the
+record Region as placement codes, including an omitted empty Region field.
+The roster, enrollment, signature, fence, record sequence and admission checks
+remain intact. No empty claim or engine identity is accepted.
+
Regional ownership remains `region:<r>`. Any eligible enrolled worker with access to that region may perform the chore under the aggregate leases. Local chores remain bound to the original machine enrollment.
Receipt publication uses the existing trusted box-writer boundary. A console-generated receipt cannot substitute for another machine’s evidence. Missing transport authority leaves work unsupported; it does not justify broader IAM.