carlos / platform Public

plan: home part 2 rev 4.1, Astra round 4 P3

QueueStagingPark does not compare its region with intent.to: it
validates the scope and queues through the alias-aware
queueReplicaPark (hostclaim/move.go:598). Removed from the
exact-comparison lists; a fresh ie there is caught by the chore-region
assertion. Round 4 disposition row added (verdict READY).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev af17d34fdd69dab3d11d21572d22f9ca997e3c06 parent 9c2fbf0
1 file changed, +12 −3
  • docs/superpowers/plans/2026-10-15-moves-home-region-part2.md +12 −3

CI failed — run details

CI log
=== gate ===
cd launchctx && go vet ./... && go test ./... -count=1
ok  	amadan.net/carlos/platform.git/launchctx	0.014s
?   	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	289.773s
?   	github.com/carlosframework/platform/cmd/changelog	[no test files]
ok  	github.com/carlosframework/platform/cmd/console	4.651s
ok  	github.com/carlosframework/platform/cmd/moveprobe	94.297s
ok  	github.com/carlosframework/platform/cmd/zddprobe	0.827s
ok  	github.com/carlosframework/platform/internal/activator	249.536s
ok  	github.com/carlosframework/platform/internal/agentsock	0.035s
ok  	github.com/carlosframework/platform/internal/alerting	0.023s
ok  	github.com/carlosframework/platform/internal/analytics	0.022s
ok  	github.com/carlosframework/platform/internal/appconfig	3.641s
ok  	github.com/carlosframework/platform/internal/apperr	0.229s
ok  	github.com/carlosframework/platform/internal/applog	0.344s
ok  	github.com/carlosframework/platform/internal/awsinv	0.018s
ok  	github.com/carlosframework/platform/internal/boxchoice	0.018s
ok  	github.com/carlosframework/platform/internal/boxid	1.199s
?   	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.013s
ok  	github.com/carlosframework/platform/internal/caps	0.030s
ok  	github.com/carlosframework/platform/internal/certwarm	0.005s
ok  	github.com/carlosframework/platform/internal/cgroup	0.830s
ok  	github.com/carlosframework/platform/internal/changelog	0.651s
ok  	github.com/carlosframework/platform/internal/clamd	0.062s
?   	github.com/carlosframework/platform/internal/cliflag	[no test files]
ok  	github.com/carlosframework/platform/internal/console	390.171s
?   	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.426s
ok  	github.com/carlosframework/platform/internal/dbdoor/dbdoortest	0.010s
ok  	github.com/carlosframework/platform/internal/dbverify	0.006s
ok  	github.com/carlosframework/platform/internal/dnsrec	0.003s
ok  	github.com/carlosframework/platform/internal/docsite	0.006s
ok  	github.com/carlosframework/platform/internal/domains	3.707s
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	27.932s
?   	github.com/carlosframework/platform/internal/edgeproof	[no test files]
ok  	github.com/carlosframework/platform/internal/edgesfile	0.012s
ok  	github.com/carlosframework/platform/internal/fleetapi	0.286s
ok  	github.com/carlosframework/platform/internal/gate	2.020s
ok  	github.com/carlosframework/platform/internal/genselect	0.026s
ok  	github.com/carlosframework/platform/internal/geo	0.014s
ok  	github.com/carlosframework/platform/internal/geoip	0.060s
ok  	github.com/carlosframework/platform/internal/host	139.999s
ok  	github.com/carlosframework/platform/internal/hostactors	0.710s
ok  	github.com/carlosframework/platform/internal/hostbox	3.076s
ok  	github.com/carlosframework/platform/internal/hostclaim	1.128s
ok  	github.com/carlosframework/platform/internal/hostevidence	0.015s
ok  	github.com/carlosframework/platform/internal/hostexec	7.102s
ok  	github.com/carlosframework/platform/internal/hostfence	0.072s
ok  	github.com/carlosframework/platform/internal/hostfiles	10.796s
ok  	github.com/carlosframework/platform/internal/hostfloor	0.025s
ok  	github.com/carlosframework/platform/internal/hostguard	1.094s
ok  	github.com/carlosframework/platform/internal/hostops	2.925s
?   	github.com/carlosframework/platform/internal/hostops/fencerelease	[no test files]
ok  	github.com/carlosframework/platform/internal/hostops/internal/fencerelease	0.006s
ok  	github.com/carlosframework/platform/internal/hostquarantine	0.006s
ok  	github.com/carlosframework/platform/internal/hostrelocate	0.962s
ok  	github.com/carlosframework/platform/internal/hostresolve	0.361s
ok  	github.com/carlosframework/platform/internal/hostwrite	0.004s
ok  	github.com/carlosframework/platform/internal/infraview	0.003s
ok  	github.com/carlosframework/platform/internal/instancectl	4.214s
ok  	github.com/carlosframework/platform/internal/instanceexec	2.871s
ok  	github.com/carlosframework/platform/internal/instancefs	0.015s
ok  	github.com/carlosframework/platform/internal/instancekey	0.002s
ok  	github.com/carlosframework/platform/internal/instanceupdates	0.006s
ok  	github.com/carlosframework/platform/internal/layout	2.350s
ok  	github.com/carlosframework/platform/internal/lease	9.872s
ok  	github.com/carlosframework/platform/internal/lease/leasetest	0.006s
ok  	github.com/carlosframework/platform/internal/ledger	0.015s
ok  	github.com/carlosframework/platform/internal/mail	0.311s
ok  	github.com/carlosframework/platform/internal/maintenance	0.139s
ok  	github.com/carlosframework/platform/internal/maintenanceexec	5.635s
ok  	github.com/carlosframework/platform/internal/maintenanceguard	0.170s
ok  	github.com/carlosframework/platform/internal/metrics	0.005s
ok  	github.com/carlosframework/platform/internal/moves	22.631s
ok  	github.com/carlosframework/platform/internal/moves/archive	1.301s
ok  	github.com/carlosframework/platform/internal/objstore	0.487s
ok  	github.com/carlosframework/platform/internal/ops	0.297s
ok  	github.com/carlosframework/platform/internal/park	0.364s
ok  	github.com/carlosframework/platform/internal/privatefile	0.006s
ok  	github.com/carlosframework/platform/internal/provision	14.108s
ok  	github.com/carlosframework/platform/internal/publicrelease	0.019s
?   	github.com/carlosframework/platform/internal/regionname	[no test files]
ok  	github.com/carlosframework/platform/internal/registry	5.321s
ok  	github.com/carlosframework/platform/internal/relay	7.266s
ok  	github.com/carlosframework/platform/internal/release	21.725s
--- FAIL: TestNudgesForOneHostCollapse (5.02s)
    wakeplan_test.go:635: timed out waiting for the attempt to finish
FAIL
FAIL	github.com/carlosframework/platform/internal/rollout	9.350s
ok  	github.com/carlosframework/platform/internal/rolloutwords	0.005s
ok  	github.com/carlosframework/platform/internal/rootaws	0.007s
ok  	github.com/carlosframework/platform/internal/rootparticipation	0.007s
ok  	github.com/carlosframework/platform/internal/rootstate	0.025s
ok  	github.com/carlosframework/platform/internal/runs	0.630s
ok  	github.com/carlosframework/platform/internal/s3compat	0.010s
ok  	github.com/carlosframework/platform/internal/safefile	0.004s
ok  	github.com/carlosframework/platform/internal/schedule	3.036s
ok  	github.com/carlosframework/platform/internal/seeds	0.012s
ok  	github.com/carlosframework/platform/internal/sim/hostlife	17.469s
ok  	github.com/carlosframework/platform/internal/sim/litestreamfacts	4.559s
ok  	github.com/carlosframework/platform/internal/status	0.067s
ok  	github.com/carlosframework/platform/internal/steering	0.009s
ok  	github.com/carlosframework/platform/internal/stopevidence	0.303s
ok  	github.com/carlosframework/platform/internal/svcrole	0.002s
ok  	github.com/carlosframework/platform/internal/telemetry	0.005s
ok  	github.com/carlosframework/platform/internal/termfence	0.004s
ok  	github.com/carlosframework/platform/internal/tunnelclient	0.007s
ok  	github.com/carlosframework/platform/internal/unixdial	0.006s
ok  	github.com/carlosframework/platform/internal/updatewords	0.004s
ok  	github.com/carlosframework/platform/internal/usage	0.015s
ok  	github.com/carlosframework/platform/internal/version	0.009s
ok  	github.com/carlosframework/platform/internal/vet	1.706s
FAIL
make: *** [Makefile:18: test] Error 1

amadan: step gate failed: exit status 2

amadan: job failed at step gate — its output is above, not at the tail of this log
diff --git a/docs/superpowers/plans/2026-10-15-moves-home-region-part2.md b/docs/superpowers/plans/2026-10-15-moves-home-region-part2.md
index 3200b643e..93396721e 100644
--- a/docs/superpowers/plans/2026-10-15-moves-home-region-part2.md
+++ b/docs/superpowers/plans/2026-10-15-moves-home-region-part2.md
@@ -2,7 +2,7 @@
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
-Rev 4, 2026-10-15. Paul approved starting part 2 on 2026-10-15. Written against `main` at a5003aba. Tracking thread: amadan #236. Revs 1 to 3 (be29ccd0, c139b80b, bdbfe3fd) were reviewed by Astra, each NOT READY; the dispositions of all three rounds are at the end.
+Rev 4.1, 2026-10-15. Paul approved starting part 2 on 2026-10-15. Written against `main` at a5003aba. Tracking thread: amadan #236. Revs 1 to 3 (be29ccd0, c139b80b, bdbfe3fd) were reviewed by Astra, each NOT READY; rev 4 (9c2fbf01) was judged READY with one P3, fixed here. The dispositions of all four rounds are at the end. Next: Paul's rulings (R1 to R7).
**Goal:** Let a Phase 1 move name the home region as its target, under host claims, with the same guarantees a move between two named regions has. That means the commit, a clean or dirty rollback, a pre-flip revert, abort, declare-lost, and the parks in home after the commit. Today the door refuses every such move (MV-N21: "moves to the home region are not supported yet. the home publishes no staging lane").
@@ -72,7 +72,7 @@ Everything else (the staging lane, the lease key, Touch, Commit, Revert, the rol
## Review Focus
1. **One region, two names (Plan 13's dedupe rule).** Two separate properties, each with its own witness:
- - **Supplied arguments are `@home`.** The claim compares `op.intent.to` exactly in `Abort`, `Revert`, `TargetReleased`, `QueueStagingPark`, the loss and fence paths, and in `requireRetiredRegion` (`internal/hostclaim/move.go:549`). If a moves call site passed the roster name `ie` instead, most of these refuse (fail closed), but `requireRetiredRegion`'s `region != to` would read `ie` as "not the target" at `landing/committed` and allow a whole-location park in the live home region. The park view still protects the live generation (`movesAuthoritative` answers `@home`, compared through `SameRegion`), so that is defence in depth. The staging lease is the other place: a key spelled with the roster name would split the lane's lease from the source's `@home` key and let two writers stage at once.
+ - **Supplied arguments are `@home`.** The claim compares `op.intent.to` exactly in `Abort`, `Revert`, `TargetReleased`, the loss and fence paths, and in `requireRetiredRegion` (`internal/hostclaim/move.go:549`). `QueueStagingPark` does not compare it: it validates the scope and queues through the alias-aware `queueReplicaPark` (`move.go:598`), so a wrong spelling there shows as a new chore's region, not a refusal. If a moves call site passed the roster name `ie` instead, most of these refuse (fail closed), but `requireRetiredRegion`'s `region != to` would read `ie` as "not the target" at `landing/committed` and allow a whole-location park in the live home region. The park view still protects the live generation (`movesAuthoritative` answers `@home`, compared through `SameRegion`), so that is defence in depth. The staging lease is the other place: a key spelled with the roster name would split the lane's lease from the source's `@home` key and let two writers stage at once.
- **Retained state keeps its spelling.** `touched`, `quiet_after`, earlier chores and admissions may already name home as `ie`. A replay must neither add a second chore for the same work under `@home` nor rewrite the `ie` one, and Touch must not write when `ie` is already there. Witnesses seed both spellings.
2. **T3's home rule.** A home target must set no `CARLOS_REGION`; a named target must still set its own, different from the source's. A target in home that does set one is a box that is not the home box, and T3 must fail it (`region-present`), not wave it through (Task 1).
3. **Production owners, not fakes.** The landing, the restarted probe, the C8 files publication, the source's recovery after a rollback and the pre-flip revert must run through `movesProbeOwners`, `movesRecoveryOwners` and the claim runtime, with the home box's engine region `ie` and the op's `to` `@home`. A witness that admits through a fake probe with a literal region proves nothing here (Tasks 2 to 4).
@@ -185,7 +185,8 @@ Fixture work only. No production code changes, and every existing test passes un
- a chore queued with `ie` is a new obligation whose `Region` or `Owner` names `ie` (alias-aware replay absorbs a call only when an equivalent chore already exists, and none does);
- a Touch with `ie` adds `ie` to `touched`;
- a staging lease keyed with `ie` shows in the fake lease's recorded keys;
- - an exact comparison against `intent.to` (`Abort`, `Revert`, `TargetReleased`, `QueueStagingPark`, `ReleaseFencedTarget`, `ReleaseLostTarget`) refuses, and the witness fails.
+ - an exact comparison against `intent.to` (`Abort`, `Revert`, `TargetReleased`, `ReleaseFencedTarget`, `ReleaseLostTarget`) refuses, and the witness fails;
+ - `QueueStagingPark` does not compare with `intent.to`: it validates the scope (`parkQueueGuard`, the lane's location) and calls the alias-aware `queueReplicaPark` (`internal/hostclaim/move.go:598`). A fresh `ie` there would queue a new lane chore named `ie`, which the chore-region assertion below catches.
After each witness the test asserts that every obligation created for the target side has `Region == "@home"` and `Owner == "region:@home"`, that `touched` gained only `@home` and the target box, and that the lease keys are `control/staging-leases/@home/<host>` for the home lane. A second call with the wrong spelling after a correct first one would be absorbed, but by construction it neither duplicates nor rewrites (that is the retained-state rule below), so it is harmless. The one harmful absorbed case, `requireRetiredRegion` allowing a location park, would create a **new** obligation and is therefore visible.
- **`TestMovesHomeRegionCallSiteInventory` (static, a pin, not a proof)** in `home_region_args_test.go` at the repository root. It lists every production call site that hands the claim a region on a move's path, and compares the list with a golden inventory in the test. Each inventory row is `{file, enclosing function, callee or composite type and field, argument expression text, witness}`.
@@ -415,3 +416,11 @@ Verdict NOT READY: the spelling, interception and generation items addressed; fo
| 2 | P2 the static check missed `ReleaseFencedTarget` and `ReleaseLostTarget`, whose regions arrive through `FencedTargetRelease` (`move_fence_release.go:130`) and `LostTargetRelease` (`move_loss_owner.go:732`) and are compared exactly with `intent.to` | Both factories, both composite literals' `TargetRegion` and `SourceRegion` fields, and the helpers that build them (`moveLossRelease`, `claimLossIntent`, `recordLossIntent`) are in the inventory. `LostTargetRelease.TargetRegion` is a named exception for retained, signed intent, with `TestMoveIntoHomeDeclareLost` as its witness. New `TestMoveIntoHomeFencedTargetRelease` witnesses the fenced path. A changed `FencedTargetRelease` literal is a failing fixture. |
| 3 | P2 `plan13Placement` cannot prove provenance: `to := c.Op.Intent["home_region"]; park.PlacementRegion(to)` passed while supplying `ie` | The static provenance check is withdrawn. Sound provenance needs dataflow across functions, parameters, signed-intent fields and closures; a heuristic gives false assurance. Replaced by `TestHomeTargetFreshStateShowsOnlyTheHomeToken`, a runtime proof from clean claim state, where every harmful wrong spelling is observable (a new obligation, a `touched` entry, a lease key, or an exact refusal), plus `TestMovesHomeRegionCallSiteInventory`, a golden inventory of every site with its runtime witness that classifies nothing by shape. The reviewer's counterexample is a failing fixture (unknown site, or changed expression at a known one). No heuristic classifier is used anywhere as proof. |
| 4 | P2 R2(a)'s confirmation: move status (`apiinstancemove.go:325`) runs neither selection nor the floor check, and S-1 only wakes the app | Step 4 keeps the evidence checks and names S-2, the move request, as the door's confirmation; both of its possible refusals precede any claim read or write, so a failed confirmation starts nothing. |
+
+## Review round 4 (Astra, on 9c2fbf01): dispositions (rev 4.1)
+
+Verdict READY: all four round-3 items addressed, and the runtime-witness trade judged sound. One P3, fixed.
+
+| # | finding | rev 4.1 |
+|---|---|---|
+| 1 | P3 `QueueStagingPark` was listed among the transitions that compare their region exactly with `intent.to`; it does not (`move.go:598` validates the scope and calls the alias-aware `queueReplicaPark`) | Removed from the exact-comparison lists in Review Focus 1 and in `TestHomeTargetFreshStateShowsOnlyTheHomeToken`'s description. Both now say a fresh `ie` there queues a new lane chore named `ie`, which the chore-region assertion catches. |