carlos / platform Public

plan: self-serve moves 2, rev 15 (Astra review 14: a durable request-expiry decision mutually exclusive with the cut; declarations completed)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev bc2c49864268c3275d0c34254486b707befc2ca0 parent 267ea4f
1 file changed, +7 −7
  • docs/superpowers/plans/2026-10-22-self-serve-moves-2-door-token-job.md +7 −7

CI failed — run details

CI log
=== gate ===
.amadan/test-gate.sh
=== launchctx (0 s)
ok  	amadan.net/carlos/platform.git/launchctx	0.020s
?   	amadan.net/carlos/platform.git/launchctx/controlname	[no test files]
?   	amadan.net/carlos/platform.git/launchctx/wireid	[no test files]
=== vet (27 s)
=== gofmt (1 s)
gofmt -l .: clean
=== rest (180 s)
?   	github.com/carlosframework/platform/cmd/changelog	[no test files]
ok  	github.com/carlosframework/platform/cmd/console	6.360s
ok  	github.com/carlosframework/platform/cmd/moveprobe	13.242s
ok  	github.com/carlosframework/platform/cmd/zddprobe	0.858s
ok  	github.com/carlosframework/platform/internal/activator	63.339s
ok  	github.com/carlosframework/platform/internal/agentsock	0.023s
ok  	github.com/carlosframework/platform/internal/alerting	0.010s
ok  	github.com/carlosframework/platform/internal/analytics	0.062s
ok  	github.com/carlosframework/platform/internal/appconfig	5.138s
ok  	github.com/carlosframework/platform/internal/apperr	0.265s
ok  	github.com/carlosframework/platform/internal/applog	0.461s
ok  	github.com/carlosframework/platform/internal/awsinv	0.009s
ok  	github.com/carlosframework/platform/internal/boxchoice	0.007s
ok  	github.com/carlosframework/platform/internal/boxid	1.072s
?   	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.024s
ok  	github.com/carlosframework/platform/internal/caps	0.045s
ok  	github.com/carlosframework/platform/internal/certwarm	0.005s
ok  	github.com/carlosframework/platform/internal/cgroup	0.890s
ok  	github.com/carlosframework/platform/internal/changelog	0.970s
ok  	github.com/carlosframework/platform/internal/claimactivation	1.713s
ok  	github.com/carlosframework/platform/internal/clamd	0.083s
?   	github.com/carlosframework/platform/internal/cliflag	[no test files]
?   	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.688s
ok  	github.com/carlosframework/platform/internal/dbdoor/dbdoortest	0.024s
ok  	github.com/carlosframework/platform/internal/dbverify	0.011s
ok  	github.com/carlosframework/platform/internal/dnsrec	0.008s
ok  	github.com/carlosframework/platform/internal/docsite	0.034s
ok  	github.com/carlosframework/platform/internal/domains	5.358s
ok  	github.com/carlosframework/platform/internal/doorkey	0.012s
ok  	github.com/carlosframework/platform/internal/economics	0.006s
ok  	github.com/carlosframework/platform/internal/edge	48.468s
?   	github.com/carlosframework/platform/internal/edgeproof	[no test files]
ok  	github.com/carlosframework/platform/internal/edgesfile	0.010s
ok  	github.com/carlosframework/platform/internal/fleetapi	0.166s
ok  	github.com/carlosframework/platform/internal/gate	1.739s
ok  	github.com/carlosframework/platform/internal/genselect	0.033s
ok  	github.com/carlosframework/platform/internal/geo	0.049s
ok  	github.com/carlosframework/platform/internal/geoip	0.068s
ok  	github.com/carlosframework/platform/internal/historyreadback	0.210s
ok  	github.com/carlosframework/platform/internal/host	137.915s
ok  	github.com/carlosframework/platform/internal/hostactors	9.112s
ok  	github.com/carlosframework/platform/internal/hostactors/awsmembership	0.006s
ok  	github.com/carlosframework/platform/internal/hostbox	5.281s
ok  	github.com/carlosframework/platform/internal/hostclaim	1.610s
ok  	github.com/carlosframework/platform/internal/hostenv	0.016s
ok  	github.com/carlosframework/platform/internal/hostevidence	0.013s
ok  	github.com/carlosframework/platform/internal/hostexec	8.754s
ok  	github.com/carlosframework/platform/internal/hostfence	0.099s
ok  	github.com/carlosframework/platform/internal/hostfiles	12.269s
ok  	github.com/carlosframework/platform/internal/hostfloor	0.019s
ok  	github.com/carlosframework/platform/internal/hostguard	1.206s
ok  	github.com/carlosframework/platform/internal/hostops	3.886s
?   	github.com/carlosframework/platform/internal/hostops/fencerelease	[no test files]
ok  	github.com/carlosframework/platform/internal/hostops/internal/fencerelease	0.014s
ok  	github.com/carlosframework/platform/internal/hostquarantine	0.015s
ok  	github.com/carlosframework/platform/internal/hostrelocate	1.393s
ok  	github.com/carlosframework/platform/internal/hostresolve	0.534s
ok  	github.com/carlosframework/platform/internal/hostwrite	0.005s
ok  	github.com/carlosframework/platform/internal/infraview	0.007s
ok  	github.com/carlosframework/platform/internal/instancectl	5.390s
ok  	github.com/carlosframework/platform/internal/instanceexec	3.033s
ok  	github.com/carlosframework/platform/internal/instancefs	0.010s
ok  	github.com/carlosframework/platform/internal/instancekey	0.023s
ok  	github.com/carlosframework/platform/internal/instanceupdates	0.022s
ok  	github.com/carlosframework/platform/internal/layout	3.552s
ok  	github.com/carlosframework/platform/internal/lbhealth	0.024s
ok  	github.com/carlosframework/platform/internal/lease	10.305s
ok  	github.com/carlosframework/platform/internal/lease/leasetest	0.862s
ok  	github.com/carlosframework/platform/internal/ledger	0.110s
ok  	github.com/carlosframework/platform/internal/mail	0.458s
ok  	github.com/carlosframework/platform/internal/maintenance	0.175s
ok  	github.com/carlosframework/platform/internal/maintenanceexec	6.100s
ok  	github.com/carlosframework/platform/internal/maintenanceguard	0.234s
ok  	github.com/carlosframework/platform/internal/metrics	0.009s
ok  	github.com/carlosframework/platform/internal/moves	28.633s
ok  	github.com/carlosframework/platform/internal/moves/archive	1.579s
ok  	github.com/carlosframework/platform/internal/objstore	0.514s
ok  	github.com/carlosframework/platform/internal/ops	0.684s
ok  	github.com/carlosframework/platform/internal/park	0.651s
ok  	github.com/carlosframework/platform/internal/plans	0.007s
ok  	github.com/carlosframework/platform/internal/privatefile	0.005s
2026/10/22 11:09:24 provision: listing apps/bab/blog/instances/: list refused — its records are unseen this pass
2026/10/22 11:09:24 provision: listing apps/bab/: listdirs refused — its records are unseen this pass
2026/10/22 11:09:24 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:24 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:24 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:24 provision: listing apps/bac/tito/instances/: list refused — its records are unseen this pass
2026/10/22 11:09:24 provision: listing apps/bac/tito/instances/: list refused — its records are unseen this pass
2026/10/22 11:09:24 provision: skipping record apps/bac/tito/instances/one.example.com.json: unreadable: read refused
2026/10/22 11:09:24 provision: listing apps/bac/tito/instances/: list refused — its records are unseen this pass
2026/10/22 11:09:24 provision: an app's records could not be listed: they are skipped
2026/10/22 11:09:24 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:24 provision: remove retired instance route shop.example: provision: claim admission unavailable
2026/10/22 11:09:24 provision: remove retired instance route shop.example: provision: claim admission unavailable
2026/10/22 11:09:25 provision: remove retired sidecar route worker.sidecar.internal: provision: claim admission unavailable
2026/10/22 11:09:25 provision: remove retired sidecar route worker.sidecar.internal: provision: claim admission unavailable
2026/10/22 11:09:25 provision: claim install acme.go.tito.io: provision: claim admission unavailable
2026/10/22 11:09:25 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:25 provision: claim install acme.go.tito.io: registry: claim row ownership changed or unknown
2026/10/22 11:09:25 provision: claim install bot.eleven.bac.sidecar.internal: provision: claim admission unavailable
2026/10/22 11:09:25 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["run"])
2026/10/22 11:09:25 provision: claim install bot.eleven.bac.sidecar.internal: registry: claim row ownership changed or unknown
2026/10/22 11:09:25 provision: refusing to mint route acme.go.tito.io (app "tito" acct "bac"): this box declares CARLOS_INBOUND=none (no-inbound) and cannot serve routed instance traffic
2026/10/22 11:09:25 provision: acme.go.tito.io: not minting this pass: the box's layout intent could not be read: no sealed config
2026/10/22 11:09:25 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:25 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:25 provision: REFUSING to mint sidecar bot.eleven.bac.sidecar.internal: bot.eleven.bac.sidecar.internal-sidecar.env is staged on this box — the legacy file co-spawn and a native sidecar row are two mechanisms for one host; remove the file to migrate this host onto sidecar records
2026/10/22 11:09:25 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["run"])
2026/10/22 11:09:25 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["run"])
2026/10/22 11:09:25 provision: refusing to mint route acme.go.tito.io (app "tito" acct "bac"): this box declares CARLOS_INBOUND=none (no-inbound) and cannot serve routed instance traffic
2026/10/22 11:09:25 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:25 provision: REFUSING to mint sidecar bot.eleven.bac.sidecar.internal: bot.eleven.bac.sidecar.internal-sidecar.env is staged on this box — the legacy file co-spawn and a native sidecar row are two mechanisms for one host; remove the file to migrate this host onto sidecar records
2026/10/22 11:09:25 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["run"])
2026/10/22 11:09:25 provision: acme.go.tito.io exists but is not the route this record describes (app "other"/"tito") — leaving it alone
2026/10/22 11:09:25 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:25 provision: claim install acme.go.tito.io: registry: claim row ownership changed or unknown
2026/10/22 11:09:25 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:25 provision: claim install acme.go.tito.io: registry: claim row ownership changed or unknown
2026/10/22 11:09:25 provision: bot.eleven.bac.sidecar.internal exists but is not a sidecar row this pass owns (kind "sidecar" provisioned false app "eleven" acct "bac") — leaving it alone
2026/10/22 11:09:25 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["run"])
2026/10/22 11:09:25 provision: claim install bot.eleven.bac.sidecar.internal: registry: claim row ownership changed or unknown
2026/10/22 11:09:25 provision: acme.go.tito.io exists but is not the route this record describes (app "other"/"tito") — leaving it alone
2026/10/22 11:09:25 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:25 provision: adopted existing route acme.go.tito.io (app "tito" acct "bac") — this record now owns its channel and environment
2026/10/22 11:09:25 provision: bot.eleven.bac.sidecar.internal exists but is not a sidecar row this pass owns (kind "sidecar" provisioned false app "eleven" acct "bac") — leaving it alone
2026/10/22 11:09:25 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:26 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: skipping record apps/bac/tito/instances/acme.go.tito.io.json: malformed: provision: invalid maintenance projection or protected fields
2026/10/22 11:09:26 provision: skipping record apps/bac/tito/instances/new.go.tito.io.json: malformed: provision: invalid maintenance projection or protected fields
2026/10/22 11:09:26 provision: not removing acme.go.tito.io: its record exists but could not be read cleanly this pass
2026/10/22 11:09:26 provision: skipping record apps/bac/tito/instances/acme.go.tito.io.json: malformed: provision: invalid maintenance projection or protected fields
2026/10/22 11:09:26 provision: skipping record apps/bac/tito/instances/new.go.tito.io.json: malformed: provision: invalid maintenance projection or protected fields
2026/10/22 11:09:26 provision: minted instance route rd.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route rf.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route rh.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route rb.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route rc.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route re.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route rg.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route ri.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route rj.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route rk.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route rl.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route ra.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route ra.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route rb.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route rc.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route rd.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: skipping record apps/bac/tito/instances/rb.go.tito.io.json: read failed: read refused
2026/10/22 11:09:26 provision: skipping record apps/bac/tito/instances/rb.go.tito.io.json: read failed: read refused
2026/10/22 11:09:26 provision: minted instance route re.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route x.appc.example (app "appc" acct "bac")
2026/10/22 11:09:26 provision: minted instance route x.appd.example (app "appd" acct "bac")
2026/10/22 11:09:26 provision: minted instance route x.appf.example (app "appf" acct "bac")
2026/10/22 11:09:26 provision: minted instance route x.appg.example (app "appg" acct "bac")
2026/10/22 11:09:26 provision: minted instance route x.appi.example (app "appi" acct "bac")
2026/10/22 11:09:26 provision: minted instance route x.appj.example (app "appj" acct "bac")
2026/10/22 11:09:26 provision: minted instance route x.appa.example (app "appa" acct "bac")
2026/10/22 11:09:26 provision: minted instance route x.appe.example (app "appe" acct "bac")
2026/10/22 11:09:26 provision: minted instance route x.apph.example (app "apph" acct "bac")
2026/10/22 11:09:26 provision: minted instance route x.appb.example (app "appb" acct "bac")
2026/10/22 11:09:26 provision: bac/tito is in the trash — not minting instance routes for it
2026/10/22 11:09:26 provision: minted instance route r0040.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0083.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0115.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0042.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0111.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0053.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0071.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0072.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0077.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0069.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0096.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0109.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0056.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0090.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0097.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0007.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0081.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0102.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0104.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0031.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0032.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0076.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0120.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0125.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0066.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0045.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0009.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0021.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0025.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0027.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0059.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0063.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0078.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0005.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0046.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0052.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0064.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0074.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0015.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0099.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0026.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0048.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0117.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0129.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0017.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0080.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0011.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0030.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0044.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0060.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0121.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0013.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0004.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0014.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0041.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0051.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0108.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0043.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0050.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0002.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0035.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0084.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0029.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0057.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0091.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0101.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0124.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:26 provision: minted instance route r0067.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0075.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0079.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0089.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0092.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0093.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0098.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0100.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0001.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0113.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0116.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0118.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0119.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0127.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0006.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0023.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0019.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0065.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0018.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0036.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0054.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0061.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0062.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0073.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0095.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0087.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0088.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0094.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0016.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0070.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0028.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0105.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0068.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0082.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0103.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0126.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0020.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0085.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0114.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0086.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0107.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0112.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0123.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0128.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0003.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0034.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0038.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0047.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0055.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0110.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0122.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0058.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0106.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0000.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0010.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0012.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0022.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0049.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0008.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0024.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0033.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0037.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:27 provision: minted instance route r0039.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: refusing to mint route acme.go.tito.io (app "tito" acct "bac"): this box declares CARLOS_INBOUND=none (no-inbound) and cannot serve routed instance traffic
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route console.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted service route ha.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted static route site.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted service route svc.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route whole.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route shared.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: converged acme.go.tito.io channel stable -> edge
2026/10/22 11:09:29 provision: converged acme.go.tito.io channel edge -> canary/rehearsal
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: skipping record apps/bac/tito/instances/acme.go.tito.io.json: empty channel
2026/10/22 11:09:29 provision: not removing acme.go.tito.io: its record exists but could not be read cleanly this pass
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: converged acme.go.tito.io environment "" -> "staging"
2026/10/22 11:09:29 provision: converged acme.go.tito.io environment "staging" -> ""
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: converged acme.go.tito.io steering "" -> "latency"
2026/10/22 11:09:29 provision: converged acme.go.tito.io steering "latency" -> ""
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: converged acme.go.tito.io hibernate false -> true
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: converged acme.go.tito.io hibernate true -> false (replication "daily" cleared: only a hibernating route's rung is read)
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: converged acme.go.tito.io status-named false -> true
2026/10/22 11:09:29 provision: converged acme.go.tito.io status-named true -> false
2026/10/22 11:09:29 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: minted service route ha.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: converged ha.go.tito.io upstreams addr "" -> "", addrs "127.0.0.1:7001,127.0.0.1:7002" -> "127.0.0.1:7001,127.0.0.1:7003" (probe "{\"path\":\"/\",\"status\":200,\"interval_ms\":2000,\"fail_after\":3,\"rise_after\":2}" -> "{\"path\":\"/\",\"status\":200,\"interval_ms\":2000,\"fail_after\":3,\"rise_after\":2}")
2026/10/22 11:09:29 provision: converged ha.go.tito.io upstreams addr "" -> "", addrs "127.0.0.1:7001,127.0.0.1:7003" -> "127.0.0.1:7003,127.0.0.1:7001" (probe "{\"path\":\"/\",\"status\":200,\"interval_ms\":2000,\"fail_after\":3,\"rise_after\":2}" -> "{\"path\":\"/\",\"status\":200,\"interval_ms\":2000,\"fail_after\":3,\"rise_after\":2}")
2026/10/22 11:09:29 provision: converged ha.go.tito.io upstreams addr "" -> "", addrs "127.0.0.1:7003,127.0.0.1:7001" -> "127.0.0.1:7003,127.0.0.1:7001" (probe "{\"path\":\"/\",\"status\":200,\"interval_ms\":2000,\"fail_after\":3,\"rise_after\":2}" -> "{\"path\":\"/healthz\",\"status\":200,\"interval_ms\":2000,\"fail_after\":3,\"rise_after\":2}")
2026/10/22 11:09:29 provision: minted service route whole.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:29 provision: converged whole.go.tito.io upstreams addr "127.0.0.1:9443" -> "", addrs "" -> "127.0.0.1:9443,127.0.0.1:9444" (probe "" -> "{\"path\":\"/\",\"status\":200,\"interval_ms\":2000,\"fail_after\":3,\"rise_after\":2}")
2026/10/22 11:09:29 provision: converged whole.go.tito.io upstreams addr "" -> "", addrs "127.0.0.1:9443,127.0.0.1:9444" -> "" (probe "{\"path\":\"/\",\"status\":200,\"interval_ms\":2000,\"fail_after\":3,\"rise_after\":2}" -> "")
2026/10/22 11:09:29 provision: whole.go.tito.io: record describes a different route SHAPE than the row (kind "instance"/"service" unit ""/"" socket "/run/carlos/whole.go.tito.io.sock"/"" db "/data/whole.go.tito.io.db"/"") — not converged in place; `carlos remove whole.go.tito.io` purges this route's capability grants (registry.Delete's contract, not a bug) before the next pass re-mints it, so treat that as a last resort, not a routine fix
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted service route whole.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: acme.go.tito.io exists but is not the route this record describes (app "other"/"tito") — leaving it alone
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: removed retired instance route acme.go.tito.io (record gone)
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: skipping accounts/bac/account.json: malformed account manifest: invalid character 'o' in literal null (expecting 'u')
2026/10/22 11:09:30 provision: removed retired instance route acme.go.tito.io (record gone)
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: manifest bac/tito: read failed: provision: manifest bac/tito: invalid character 'o' in literal null (expecting 'u')
2026/10/22 11:09:30 provision: skipping record apps/bac/tito/instances/acme.go.tito.io.json: disagrees with its own path (host="wrong-host.go.tito.io" account="bac" app="tito")
2026/10/22 11:09:30 provision: skipping record apps/bac/tito/instances/acme$evil.go.tito.io.json: host "acme$evil.go.tito.io" is not a hostname
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: skipping record apps/bac/tito/instances/acme$evil.go.tito.io.json: host "acme$evil.go.tito.io" is not a hostname
2026/10/22 11:09:30 provision: not removing acme$evil.go.tito.io: its record exists but could not be read cleanly this pass
2026/10/22 11:09:30 provision: skipping record apps/bac/tito/instances/bad-service.go.tito.io.json: invalid shape: kind service with no addr: the platform only proxies to a service, so the record must name the upstream it proxies to
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: skipping record apps/bac/tito/instances/bad-service.go.tito.io.json: invalid shape: kind service with no addr: the platform only proxies to a service, so the record must name the upstream it proxies to
2026/10/22 11:09:30 provision: not removing bad-service.go.tito.io: its record exists but could not be read cleanly this pass
2026/10/22 11:09:30 provision: skipping record apps/bac/tito/instances/no-channel.go.tito.io.json: empty channel
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: skipping record apps/bac/tito/instances/no-channel.go.tito.io.json: empty channel
2026/10/22 11:09:30 provision: not removing no-channel.go.tito.io: its record exists but could not be read cleanly this pass
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: skipping record apps/bac/tito/instances/acme.go.tito.io.json: malformed: provision: invalid maintenance projection or protected fields
2026/10/22 11:09:30 provision: not removing acme.go.tito.io: its record exists but could not be read cleanly this pass
2026/10/22 11:09:30 provision: removed retired instance route ghost.go.tito.io (record gone)
2026/10/22 11:09:30 provision: duplicate host dup.go.tito.io: keeping apps/bac/tito/instances/dup.go.tito.io.json, skipping apps/bad/tito/instances/dup.go.tito.io.json
2026/10/22 11:09:30 provision: minted instance route dup.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: bac/tito is in the trash — not minting instance routes for it
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: bac/tito is in the trash — not minting instance routes for it
2026/10/22 11:09:30 provision: removed retired instance route acme.go.tito.io (app in the trash)
2026/10/22 11:09:30 provision: minted static route site.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: bac/tito is in the trash — not minting instance routes for it
2026/10/22 11:09:30 provision: removed retired static route site.go.tito.io (app in the trash)
2026/10/22 11:09:30 provision: trash marker for bac/tito unreadable: release: malformed trash marker for bac/tito: invalid character 'n' looking for beginning of object key string — not minting for this app
2026/10/22 11:09:30 provision: bac/tito is in the trash — not minting instance routes for it
2026/10/22 11:09:30 provision: removed retired instance route acme.go.tito.io (app in the trash)
2026/10/22 11:09:30 provision: bac/tito is in the trash — not minting instance routes for it
2026/10/22 11:09:30 provision: trash marker for bac/tito unreadable: release: malformed trash marker for bac/tito: invalid character 'n' looking for beginning of object key string — not minting for this app
2026/10/22 11:09:30 provision: adopted existing route acme.go.tito.io (app "tito" acct "bac") — this record now owns its channel and environment
2026/10/22 11:09:30 provision: converged acme.go.tito.io channel stable -> edge
2026/10/22 11:09:30 provision: adopted existing route acme.go.tito.io (app "tito" acct "bac") — this record now owns its channel and environment
2026/10/22 11:09:30 provision: converged acme.go.tito.io channel canary/rehearsal -> edge
2026/10/22 11:09:30 provision: converged acme.go.tito.io environment "staging" -> ""
2026/10/22 11:09:30 provision: acme.go.tito.io exists but is not the route this record describes (app "other"/"tito") — leaving it alone
2026/10/22 11:09:30 provision: acme.go.tito.io exists but is not the route this record describes (backing "unit" (box-scoped, not expressible in a record)) — leaving it alone
2026/10/22 11:09:30 provision: acme.go.tito.io exists but is not the route this record describes (tunnel "pi-fleet" (box-scoped, not expressible in a record)) — leaving it alone
2026/10/22 11:09:30 provision: acme.go.tito.io exists but is not the route this record describes (caps "port:25" (box-scoped, not expressible in a record)) — leaving it alone
2026/10/22 11:09:30 provision: acme.go.tito.io exists but is not the route this record describes (platform (owned by the domains reconcile pass)) — leaving it alone
2026/10/22 11:09:30 provision: acme.go.tito.io exists but is not the route this record describes (canary (owned by the domains reconcile pass)) — leaving it alone
2026/10/22 11:09:30 provision: acme.go.tito.io exists but is not the route this record describes (db "/data/other.db"/"/data/acme.go.tito.io.db") — leaving it alone
2026/10/22 11:09:30 provision: adopted existing route acme.go.tito.io (app "tito" acct "bac") — this record now owns its channel and environment
2026/10/22 11:09:30 provision: removed retired instance route acme.go.tito.io (record gone)
2026/10/22 11:09:30 provision: dry-run: would mint instance route acme.go.tito.io (app "tito" acct "bac" channel "stable")
2026/10/22 11:09:30 provision: dry-run: would adopt existing route adopt.go.tito.io (app "tito" acct "bac") — this record would own its channel and environment
2026/10/22 11:09:30 provision: dry-run: would converge adopt.go.tito.io channel stable -> edge
2026/10/22 11:09:30 provision: dry-run: would converge adopt.go.tito.io environment "" -> "staging"
2026/10/22 11:09:30 provision: dry-run: would converge owned.go.tito.io channel stable -> edge
2026/10/22 11:09:30 provision: dry-run: would converge owned.go.tito.io environment "" -> "staging"
2026/10/22 11:09:30 provision: dry-run: would converge owned.go.tito.io hibernate false -> true
2026/10/22 11:09:30 provision: dry-run: would converge owned.go.tito.io seed
2026/10/22 11:09:30 provision: dry-run: would remove retired instance route gone.go.tito.io (record gone)
2026/10/22 11:09:30 provision: converged owned.go.tito.io channel stable -> edge
2026/10/22 11:09:30 provision: converged owned.go.tito.io environment "" -> "staging"
2026/10/22 11:09:30 provision: converged owned.go.tito.io hibernate false -> true
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: adopted existing route adopt.go.tito.io (app "tito" acct "bac") — this record now owns its channel and environment
2026/10/22 11:09:30 provision: converged adopt.go.tito.io channel stable -> edge
2026/10/22 11:09:30 provision: converged adopt.go.tito.io environment "" -> "staging"
2026/10/22 11:09:30 provision: removed retired instance route gone.go.tito.io (record gone)
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: adopted existing route story.carlosframework.com (app "story" acct "bad") — this record now owns its channel and environment
2026/10/22 11:09:30 provision: story.carlosframework.com exists but is not the route this record describes (kind "instance"/"static") — leaving it alone
2026/10/22 11:09:30 provision: minted static route site.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted service route pub.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted service route pubs.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted service route loop.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted service route named.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted service route priv.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted instance route unit.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted instance route exec.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted static route site.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted static route pisite.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted static route site.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: removed retired static route site.go.tito.io (record gone)
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted instance route acme-uk.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: converged acme.go.tito.io replicas "ie,uk" -> "uk"
2026/10/22 11:09:30 provision: converged acme.go.tito.io replicas "uk" -> ""
2026/10/22 11:09:30 provision: minted instance route acme-uk.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:30 provision: converged acme-uk.go.tito.io replica mark true -> false
2026/10/22 11:09:31 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:31 provision: minted instance route router.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:31 provision: acme.go.tito.io: row is on the nested layout (db "/data/instances/acme.go.tito.io/acme.go.tito.io.db" socket "/run/carlos/instances/acme.go.tito.io/app.sock"); the record's shared paths are not drift
2026/10/22 11:09:31 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:31 provision: minted instance route router.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:31 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:31 provision: minted instance route router.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:31 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:31 provision: minted instance route router.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:31 provision: router.go.tito.io: not minting this pass: the box's layout intent could not be read: store down
2026/10/22 11:09:31 provision: acme.go.tito.io: not minting this pass: the box's layout intent could not be read: store down
2026/10/22 11:09:31 provision: adopted existing route acme.go.tito.io (app "tito" acct "bac") — this record now owns its channel and environment
2026/10/22 11:09:31 provision: converged acme.go.tito.io channel stable -> edge
2026/10/22 11:09:31 provision: minted instance route acme.go.tito.io held landing by mv_acme (app "tito" acct "bac")
2026/10/22 11:09:31 provision: not removing acme.go.tito.io (record gone): participant of a running operation
2026/10/22 11:09:31 provision: removed retired instance route acme.go.tito.io (record gone)
2026/10/22 11:09:31 provision: minted instance route acme.go.tito.io held landing by mv_acme (app "tito" acct "bac")
2026/10/22 11:09:31 provision: refusing to mint held route acme.go.tito.io (app "tito" acct "bac"): this box declares CARLOS_INBOUND=none (no-inbound) and cannot serve routed instance traffic
2026/10/22 11:09:31 provision: held acme.go.tito.io landing by mv_acme (was ready)
2026/10/22 11:09:31 provision: acme.go.tito.io: held restoring by rb_other, not by mv_acme; leaving it
2026/10/22 11:09:31 provision: acme.go.tito.io: the row is not this pass's (app "other" acct ""); not holding it for mv_acme
2026/10/22 11:09:31 provision: acme.go.tito.io exists but is not the route this record describes (app "other"/"tito") — leaving it alone
2026/10/22 11:09:31 provision: dry-run: would mint instance route acme.go.tito.io held landing by mv_acme (app "tito" acct "bac" channel "stable")
2026/10/22 11:09:31 provision: acme.go.tito.io: not held landing by mv_acme: the row's hold changed under this pass; the next pass judges it afresh
2026/10/22 11:09:31 provision: held acme.go.tito.io landing by mv_acme (was ready)
2026/10/22 11:09:31 provision: minted instance route acme.example.com (app "shop" acct "bac")
2026/10/22 11:09:31 provision: minted instance route plain.example.com (app "shop" acct "bac")
2026/10/22 11:09:31 provision: skipping record apps/bac/shop/instances/garbled.shop.example.com.json: malformed: provision: invalid maintenance projection or protected fields
2026/10/22 11:09:31 provision: skipping record apps/bac/shop/instances/liar.shop.example.com.json: disagrees with its own path (host="other.shop.example.com" account="bac" app="shop")
2026/10/22 11:09:31 provision: skipping record apps/bac/shop/instances/garbled.shop.example.com.json: malformed: provision: invalid maintenance projection or protected fields
2026/10/22 11:09:31 provision: skipping record apps/bac/shop/instances/liar.shop.example.com.json: disagrees with its own path (host="other.shop.example.com" account="bac" app="shop")
2026/10/22 11:09:31 provision: skipping record apps/bac/shop/instances/garbled.shop.example.com.json: malformed: provision: invalid maintenance projection or protected fields
2026/10/22 11:09:31 provision: skipping record apps/bac/shop/instances/liar.shop.example.com.json: disagrees with its own path (host="other.shop.example.com" account="bac" app="shop")
2026/10/22 11:09:31 provision: skipping record apps/bac/shop/instances/garbled.shop.example.com.json: malformed: provision: invalid maintenance projection or protected fields
2026/10/22 11:09:31 provision: listing apps/bac/shop/instances/: list refused — its records are unseen this pass
2026/10/22 11:09:32 provision: a.shop.example.com: swapped for import sd_rxdxx4qykjx4qogzx2li6a6ibi (the original route is journaled)
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_rxdxx4qykjx4qogzx2li6a6ibi committed: its gate is cleared and its journal row dropped
2026/10/22 11:09:32 provision: a.shop.example.com: row is on the nested layout (db "/data/instances/a.shop.example.com/a.shop.example.com.db" socket "/run/carlos/instances/a.shop.example.com/app.sock"); the record's shared paths are not drift
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_7sjemdumhuf2mhbldtyr4powl4 rolled back to its original route
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_7sjemdumhuf2mhbldtyr4powl4: the host's replica is left alone: the record apps/bac/shop/instances/a.shop.example.com.json holds the host
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_7sjemdumhuf2mhbldtyr4powl4 is cleaned up and its journal row retired
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_bhdpbvpz4yeyjwergmh7e2iooy rolled back to its original route
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_bhdpbvpz4yeyjwergmh7e2iooy: the host's replica is left alone: the record apps/bac/shop/instances/a.shop.example.com.json holds the host
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_bhdpbvpz4yeyjwergmh7e2iooy is cleaned up and its journal row retired
2026/10/22 11:09:32 provision: dry-run: would redo a.shop.example.com's swap record CAS for import sd_6g6nlf4avl5yy3wfpjtwyguo2a
2026/10/22 11:09:32 provision: dry-run: would clear a.shop.example.com's import gate
2026/10/22 11:09:32 provision: dry-run: would converge a.shop.example.com seed source
2026/10/22 11:09:32 provision: a.shop.example.com: row is on the nested layout (db "/data/instances/a.shop.example.com/a.shop.example.com.db" socket "/run/carlos/instances/a.shop.example.com/app.sock"); the record's shared paths are not drift
2026/10/22 11:09:32 provision: a.shop.example.com: the import's record apps/bac/shop/instances/a.shop.example.com.json is not one this pass can use (connection reset)
2026/10/22 11:09:32 provision: a.shop.example.com: the import's record apps/bac/shop/instances/a.shop.example.com.json is not one this pass can use (provision: invalid maintenance projection or protected fields)
2026/10/22 11:09:32 provision: a.shop.example.com: the import's record apps/bac/shop/instances/a.shop.example.com.json is not one this pass can use (the record under apps/bac/shop/instances/a.shop.example.com.json is apps/bac/shop/instances/b.shop.example.com.json's)
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_3epubajtttl5ocvyyjxvq4762y cannot roll back on this box: the activator is not wired; it stays journaled and gated
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_6e24dhfipstsxzsinvg4iqotvq cannot roll back on this box: the activator is not wired; it stays journaled and gated
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_2yi3ddkgdz7yekbwu6v7n5trny is journaled, but this box cannot act on imports; its row is left alone
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_xumj6obzd6fc4ms7tgprngrddy is journaled, but this box cannot act on imports; its row is left alone
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_ircactigyjpldbhx3ni3xpzbbi is journaled, but this box cannot act on imports; its row is left alone
2026/10/22 11:09:32 provision: the import journal could not be read: registry: import journal a.shop.example.com: original row: unexpected end of JSON input (no import is acted on and no route is removed this pass)
2026/10/22 11:09:32 provision: b.shop.example.com: import sd_odvakcgkvzkgajvqatuut2limm left alone this pass: the import journal could not be read
2026/10/22 11:09:32 provision: c.shop.example.com: import sd_o6uweljxldj7dfraajm5uqjxou left alone this pass: the import journal could not be read
2026/10/22 11:09:32 provision: a.shop.example.com: import sd_5q4bppdye6xaifcxrf66eqp2ea committed: its gate is cleared and its journal row dropped
2026/10/22 11:09:32 provision: a.shop.example.com: not converging import sd_lstqa2yi7hlb53bel6qeqktsba: it is swapped but not committed, and the row on this box has no import gate
2026/10/22 11:09:32 provision: a.shop.example.com: not converging import sd_7imu6gcfhxjthws3jhz3zbxlci: it is swapped but not committed, and the row on this box has no import gate
2026/10/22 11:09:32 provision: a.shop.example.com: not converging import sd_ibug3ihvngchz2obni4agy26gu: it is placed but not committed, and the row on this box has no import gate
2026/10/22 11:09:32 provision: a.shop.example.com: not converging import sd_fjmaap6izd5a5g6qx5hcayarmi: it is placed but not committed, and the row on this box has no import gate
2026/10/22 11:09:32 provision: a.shop.example.com: row is on the nested layout (db "/data/instances/a.shop.example.com/a.shop.example.com.db" socket "/run/carlos/instances/a.shop.example.com/app.sock"); the record's shared paths are not drift
2026/10/22 11:09:33 provision: converge seed source on a.shop.example.com: constraint failed: seed_source is read-only here (1811)
2026/10/22 11:09:33 provision: a.shop.example.com: row is on the nested layout (db "/data/instances/a.shop.example.com/a.shop.example.com.db" socket "/run/carlos/instances/a.shop.example.com/app.sock"); the record's shared paths are not drift
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_jcqiljmxpkhk5mwdbvavowygji committed: its gate is cleared and its journal row dropped
2026/10/22 11:09:33 provision: a.shop.example.com: row is on the nested layout (db "/data/instances/a.shop.example.com/a.shop.example.com.db" socket "/run/carlos/instances/a.shop.example.com/app.sock"); the record's shared paths are not drift
2026/10/22 11:09:33 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:33 provision: acme.go.tito.io: row is on the nested layout (db "/data/instances/acme.go.tito.io/acme.go.tito.io.db" socket "/run/carlos/instances/acme.go.tito.io/app.sock"); the record's shared paths are not drift
2026/10/22 11:09:33 provision: acme.go.tito.io: not minting a seeded instance: this box does not mint nested (<nil>)
2026/10/22 11:09:33 provision: acme.go.tito.io: not minting a seeded instance: claim control is on for this box
2026/10/22 11:09:33 provision: acme.go.tito.io: aborted seed sd_2fteyyqijjdcvsgjypwyaqeq2m: this box cannot read seed markers, and places no seed; nothing local is removed
2026/10/22 11:09:33 provision: acme.go.tito.io: aborted seed sd_2fteyyqijjdcvsgjypwyaqeq2m rolled back (no box had swapped it)
2026/10/22 11:09:33 provision: acme.go.tito.io: not minting a seeded instance: its record does not describe a hibernating instance
2026/10/22 11:09:33 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:33 provision: removed instance route acme.go.tito.io (its seed sd_7yrnujllmczinztwxzwbq2s4m4 was aborted); the next pass rolls it back
2026/10/22 11:09:33 provision: acme.go.tito.io: aborted seed sd_7yrnujllmczinztwxzwbq2s4m4: this box cannot read seed markers, and places no seed; nothing local is removed
2026/10/22 11:09:33 provision: acme.go.tito.io: aborted seed sd_7yrnujllmczinztwxzwbq2s4m4 rolled back (no box had swapped it)
2026/10/22 11:09:33 provision: acme.go.tito.io: aborted seed sd_pcd6vxtu4ccgwfrspcxqm7evc4 has a row this pass may not remove; leaving the seed aborted
2026/10/22 11:09:33 provision: acme.go.tito.io: aborted seed sd_jfe6etlfzafotqdradfkwg7p7q rolled back (no box had swapped it)
2026/10/22 11:09:33 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:33 provision: removed instance route acme.go.tito.io (its seed sd_rlqxottxtcdlhj62p2ut6amjwi was aborted); the next pass rolls it back
2026/10/22 11:09:33 provision: acme.go.tito.io: aborted seed sd_rlqxottxtcdlhj62p2ut6amjwi has no route on this box: its local data is removed
2026/10/22 11:09:33 provision: acme.go.tito.io: aborted seed sd_rlqxottxtcdlhj62p2ut6amjwi rolled back (no box had swapped it)
2026/10/22 11:09:33 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_xljdfehrz2qkcppl5iwvr5ev6y (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_xljdfehrz2qkcppl5iwvr5ev6y rolled back to its original route
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_xljdfehrz2qkcppl5iwvr5ev6y is cleaned up and its journal row retired
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_mvtlw32f423dps5aucby32w4be (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_mvtlw32f423dps5aucby32w4be rolled back to its original route
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_mvtlw32f423dps5aucby32w4be is cleaned up and its journal row retired
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_3vujpmu5lqdxonmqyzvdlzdz7i (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_3vujpmu5lqdxonmqyzvdlzdz7i rolled back to its original route
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_3vujpmu5lqdxonmqyzvdlzdz7i: the host's replica is left alone: its record no longer names this seed
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_3vujpmu5lqdxonmqyzvdlzdz7i is cleaned up and its journal row retired
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_ho2wh6maxcgoyvjlictmsfnzpm (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_ho2wh6maxcgoyvjlictmsfnzpm rollback deferred: the host is not fenced and stopped yet (<nil>)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_ho2wh6maxcgoyvjlictmsfnzpm rolled back to its original route
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_ho2wh6maxcgoyvjlictmsfnzpm is cleaned up and its journal row retired
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_xwpg36mq3rbb2qbzyrfs2ntile (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_xwpg36mq3rbb2qbzyrfs2ntile rollback deferred: the host is not fenced and stopped yet (stop unproven)
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_6qqsnmhprthnoigvpevkccd4ri (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_6qqsnmhprthnoigvpevkccd4ri is cleaned up and its journal row retired
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_2t4la353jokfmvqfuflpaeedxe (the original route is journaled)
2026/10/22 11:09:33 provision: skipping record apps/bac/shop/instances/a.shop.example.com.json: malformed: provision: invalid maintenance projection or protected fields
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_2t4la353jokfmvqfuflpaeedxe left alone this pass: its record could not be read
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_vjtoefvyh3nwaewnlsp6uccld4 (the original route is journaled)
2026/10/22 11:09:33 provision: skipping record apps/bac/shop/instances/a.shop.example.com.json: read failed: connection reset
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_vjtoefvyh3nwaewnlsp6uccld4 left alone this pass: its record could not be read
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_ts7n475utfv2rnkmt2xpbhb7ia (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_ts7n475utfv2rnkmt2xpbhb7ia: close the import gate: constraint failed: injected (1811)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_ts7n475utfv2rnkmt2xpbhb7ia rolled back to its original route
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_ts7n475utfv2rnkmt2xpbhb7ia is cleaned up and its journal row retired
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_mjin2c43xvse4ka4p4xvjczxhm (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_mjin2c43xvse4ka4p4xvjczxhm: close the import gate: constraint failed: injected (1811)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_mjin2c43xvse4ka4p4xvjczxhm rolled back to its original route
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_mjin2c43xvse4ka4p4xvjczxhm is cleaned up and its journal row retired
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_u3jefrei7cvp4t7lk22reqpkte (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_u3jefrei7cvp4t7lk22reqpkte rollback deferred: the host is not fenced and stopped yet (injected failure at fence)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_u3jefrei7cvp4t7lk22reqpkte rolled back to its original route
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_u3jefrei7cvp4t7lk22reqpkte is cleaned up and its journal row retired
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_yrbsmldy7vppjgg76drgj75yuu (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_yrbsmldy7vppjgg76drgj75yuu rolled back to its original route
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_yrbsmldy7vppjgg76drgj75yuu is cleaned up and its journal row retired
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_o4pgdjrrqeszuygt4p4iypn3iy (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_o4pgdjrrqeszuygt4p4iypn3iy: retire its instance key: injected failure at retire-key
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_o4pgdjrrqeszuygt4p4iypn3iy rolled back to its original route
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_o4pgdjrrqeszuygt4p4iypn3iy is cleaned up and its journal row retired
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_ugqlns64gieknbn5w7houguidm (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_ugqlns64gieknbn5w7houguidm rolled back to its original route
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_ugqlns64gieknbn5w7houguidm is cleaned up and its journal row retired
2026/10/22 11:09:33 provision: a.shop.example.com: swapped for import sd_t5jyccskpo4inc6f5hiaacqjky (the original route is journaled)
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_t5jyccskpo4inc6f5hiaacqjky: remove its local data: injected failure at remove-local
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_t5jyccskpo4inc6f5hiaacqjky rolled back to its original route
2026/10/22 11:09:33 provision: a.shop.example.com: import sd_t5jyccskpo4inc6f5hiaacqjky is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_53s4pugfgpsk7xrhozk76pwkce (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_53s4pugfgpsk7xrhozk76pwkce rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_53s4pugfgpsk7xrhozk76pwkce is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_cdkmpyvrs37t23ivsljkux76la (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_cdkmpyvrs37t23ivsljkux76la: remove its local data: injected failure at remove-local-done
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_cdkmpyvrs37t23ivsljkux76la rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_cdkmpyvrs37t23ivsljkux76la is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_2ssdihqkwfbzcmekeja65cyu2i (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_2ssdihqkwfbzcmekeja65cyu2i rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_2ssdihqkwfbzcmekeja65cyu2i is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_gjkceefy7yskqdny2btgyddynq (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_gjkceefy7yskqdny2btgyddynq: restore the original route: constraint failed: injected (1811)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_gjkceefy7yskqdny2btgyddynq rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_gjkceefy7yskqdny2btgyddynq is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_y7y54he6ibtspxohscxkpt2644 (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_y7y54he6ibtspxohscxkpt2644: restore the original route: constraint failed: injected (1811)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_y7y54he6ibtspxohscxkpt2644 rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_y7y54he6ibtspxohscxkpt2644 is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_snnophat2ux4hkunuboc27hn3i (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_snnophat2ux4hkunuboc27hn3i is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_xenpqea6zbhdouxpdlc5c7zqta (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_xenpqea6zbhdouxpdlc5c7zqta rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_xenpqea6zbhdouxpdlc5c7zqta: delete its snapshot: injected failure at delete-snapshot
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_xenpqea6zbhdouxpdlc5c7zqta is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_xno4x4wphe4k73sj7uddwlirgq (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_xno4x4wphe4k73sj7uddwlirgq rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_xno4x4wphe4k73sj7uddwlirgq is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_liv344l67fay3wpmbcik6pizwe (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_liv344l67fay3wpmbcik6pizwe rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_liv344l67fay3wpmbcik6pizwe: delete the host's replica: injected failure at delete-replica
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_liv344l67fay3wpmbcik6pizwe is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_laalmtdjhkvvwwecmdhb2lywma (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_laalmtdjhkvvwwecmdhb2lywma rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_laalmtdjhkvvwwecmdhb2lywma is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_tkyns3olnyyiuyn5j5zcaonree (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_tkyns3olnyyiuyn5j5zcaonree rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_tkyns3olnyyiuyn5j5zcaonree: retire its journal row: constraint failed: injected (1811)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_tkyns3olnyyiuyn5j5zcaonree is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_uivnygswplhfkjj5ptetk4imhi (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_uivnygswplhfkjj5ptetk4imhi rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_uivnygswplhfkjj5ptetk4imhi: retire its journal row: constraint failed: injected (1811)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_uivnygswplhfkjj5ptetk4imhi is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_sk7dgil2igufezunoxfibioujm (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_sk7dgil2igufezunoxfibioujm rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_sk7dgil2igufezunoxfibioujm is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: mark import sd_sk7dgil2igufezunoxfibioujm rolled back: injected failure at cas
2026/10/22 11:09:34 provision: a.shop.example.com: aborted seed sd_sk7dgil2igufezunoxfibioujm rolled back (no box had swapped it)
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_p3fr5ep3ah7nycsopwv552ckfm (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_p3fr5ep3ah7nycsopwv552ckfm rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_p3fr5ep3ah7nycsopwv552ckfm is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: aborted seed sd_p3fr5ep3ah7nycsopwv552ckfm rolled back (no box had swapped it)
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_njdsmzrgv2ca2jwnadxsnm45lq (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_njdsmzrgv2ca2jwnadxsnm45lq rollback deferred: the host is not fenced and stopped yet (<nil>)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_njdsmzrgv2ca2jwnadxsnm45lq rollback deferred: the host is not fenced and stopped yet (<nil>)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_njdsmzrgv2ca2jwnadxsnm45lq rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_njdsmzrgv2ca2jwnadxsnm45lq is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_z5ynr5bjldzy3bmszn4xdpdhfe (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_z5ynr5bjldzy3bmszn4xdpdhfe rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_z5ynr5bjldzy3bmszn4xdpdhfe is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_zij57zyxcis5nizdkvnkpaasru (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_zij57zyxcis5nizdkvnkpaasru rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_zij57zyxcis5nizdkvnkpaasru is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: minted instance route a.shop.example.com (app "shop" acct "bac")
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_txyll47t5xc6ae5tjszwhm6mu4 (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_txyll47t5xc6ae5tjszwhm6mu4 rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_txyll47t5xc6ae5tjszwhm6mu4 is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: minted instance route a.shop.example.com (app "shop" acct "bac")
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_54i772vuifoorx4d3jn5oxowkm (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_54i772vuifoorx4d3jn5oxowkm rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_54i772vuifoorx4d3jn5oxowkm is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: minted instance route a.shop.example.com (app "shop" acct "bac")
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_ia5jwjyu5pymwou722qzct4mbq (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_ia5jwjyu5pymwou722qzct4mbq rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_ia5jwjyu5pymwou722qzct4mbq is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: minted instance route a.shop.example.com (app "other" acct "bac")
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_4h23uuxaus5xgkrj5ljmnhhplm (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_4h23uuxaus5xgkrj5ljmnhhplm rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_4h23uuxaus5xgkrj5ljmnhhplm is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: minted instance route a.shop.example.com (app "other" acct "bac")
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_fb7ol3x6eh62mkqgtk2vx77peq (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_fb7ol3x6eh62mkqgtk2vx77peq rolled back to its original route
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_fb7ol3x6eh62mkqgtk2vx77peq is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: minted instance route a.shop.example.com (app "other" acct "bac")
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_uhgzxoes435akws5l7rb6ympki (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_uhgzxoes435akws5l7rb6ympki has no route on this box: its local data is removed and no route is put back
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_uhgzxoes435akws5l7rb6ympki is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_kyzlba3atxo2emmyxerl3wlb2m (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_c2hkl332haf65lr2kai7pd7ywu (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_xps4tyjv5eurywbdbqflm3seym (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_xps4tyjv5eurywbdbqflm3seym cannot roll back on this box: the activator is not wired; it stays journaled and gated
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_dyxvkvce3dtzzwexaabyqnyama (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_dyxvkvce3dtzzwexaabyqnyama is not rolled back: the route changed under the fence, so nothing there is touched
2026/10/22 11:09:34 provision: a.shop.example.com: import "../not-a-seed" names no snapshot and no replica; only its journal row is cleaned up
2026/10/22 11:09:34 provision: a.shop.example.com: import ../not-a-seed is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_smuoyuago75s7qbr4icvpwosfm (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_nbx52f4lctcgkfn5zb3pdrusvu (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_b5wn43pgkfds7v2dlt2v7ijnr4 (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_fea24vd57mhxlxrithq43g43fi (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_fugpooifbfpn7qm3rdmv23ukga (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_fugpooifbfpn7qm3rdmv23ukga rollback deferred: the host is not fenced and stopped yet (stop evidence unreadable)
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_nmtkd6q4kjngjpwz5y4ecyd6se (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_nmtkd6q4kjngjpwz5y4ecyd6se has no route on this box: its local data is removed and no route is put back
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_nmtkd6q4kjngjpwz5y4ecyd6se is cleaned up and its journal row retired
2026/10/22 11:09:34 provision: minted instance route a.shop.example.com (app "shop" acct "bac")
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_fzwhlfw6ol22oe5pa36bhbwmty (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_fzwhlfw6ol22oe5pa36bhbwmty: remove its local data: injected failure at remove-local
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_fzwhlfw6ol22oe5pa36bhbwmty is not rolled back: the route at the host is not the import's, so nothing there is touched
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_ol4x7ijyq2cphggd4ijbvydvqi (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_ol4x7ijyq2cphggd4ijbvydvqi: a route appeared at the host, so its local database is left and the rollback waits
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_l6656aiplkxfxajs3pmrwc6ao4 (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_l6656aiplkxfxajs3pmrwc6ao4 rollback deferred: no fence generation: registry busy
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_fj2q7to75gucxw5m6srycptvwy (the original route is journaled)
2026/10/22 11:09:34 provision: a.shop.example.com: import sd_fj2q7to75gucxw5m6srycptvwy rollback deferred: no fence generation: the generation source answered 0
2026/10/22 11:09:34 provision: a.shop.example.com: swapped for import sd_f4azbyprstkigmhew7k5mhpgam (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_jwd5eq73qnjb4ybiiszzoqfp3y (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_ekgizyp75vn5qydxfyn4lbxk5q (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: import deferred: this box cannot read the instance's env file
2026/10/22 11:09:35 provision: a.shop.example.com: import deferred: the instance's env file could not be read: a symlink
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_sui62m7ilrb3wykfwuxfuaxmte (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_sui62m7ilrb3wykfwuxfuaxmte rolled back to its original route
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_sui62m7ilrb3wykfwuxfuaxmte is cleaned up and its journal row retired
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_esphjwaxauh2x5zidnf2drgitu (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_esphjwaxauh2x5zidnf2drgitu rolled back to its original route
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_esphjwaxauh2x5zidnf2drgitu is cleaned up and its journal row retired
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_udbwpmc2jxeggbxkmxuq7y4qvu (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_udbwpmc2jxeggbxkmxuq7y4qvu rolled back to its original route
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_udbwpmc2jxeggbxkmxuq7y4qvu is cleaned up and its journal row retired
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_ktqnpxljow47xkpklodp3z6lxa (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_ktqnpxljow47xkpklodp3z6lxa: retire its instance key: the env file is a symlink
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_ktqnpxljow47xkpklodp3z6lxa rolled back to its original route
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_ktqnpxljow47xkpklodp3z6lxa is cleaned up and its journal row retired
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_ztuy544mdrymed6ofmbix6ko3u (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: row is on the nested layout (db "/data/instances/a.shop.example.com/a.shop.example.com.db" socket "/run/carlos/instances/a.shop.example.com/app.sock"); the record's shared paths are not drift
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_qdot3b3g5kuvvniuy4yx5zl2fy (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_3miiydyouljfj7whrchxtgvysi refused: there is no route at a.shop.example.com to replace
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_ul7soepmypeifnhchzdcoh447e refused: the route's address is 127.0.0.1:9, not 127.0.0.1:8401
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_2tyortblfk7qdgiqhaarzr7sdi refused: the route's address is 127.0.0.1:8401,127.0.0.1:8402, not 127.0.0.1:8401
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_3pdqwaswfwappyg2bmlasaazli refused: the route's address is 127.0.0.1:9, not 127.0.0.1:8401
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_x4g7znegx6vrdbjqfcgmxr5u4u refused: the route belongs to app other
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_rtnv6b3tzmvujvrawy46wv43tu refused: the route is filed under another account
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_erv2x63pn5tr3pmf6g3qkktmsu refused: the route is filed under the operator account, and no assignment maps shop to this app
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_imcm4domzaqxkqpm32glc2h4vm refused: the route is filed under the operator account, and no assignment maps shop to this app
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_jflbrstrua5bbu6sxl4xfek3ou refused: the route is filed under the operator account, and no assignment maps shop to this app
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_frfs3wkn7jjuh6je7hmdeh2wme refused: the route is filed under the operator account, and no assignment maps shop to this app
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_4nq2ojc7fxxktxbbayi4h5cmpm refused: the route is not an address route this import can take over (socket)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_vz3327cwiph4guux6sowmv2xhq refused: the route is not an address route this import can take over (no address)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_iwjzkb5yw3m2twv7zzzz4c7qmy refused: the route is not an address route this import can take over (provisioned)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_5ybe3tflblfntxt7kqjzygvlqi refused: the route is not an address route this import can take over (kind static)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_7py5cxrvir2uyn7vt4yl6nkbje refused: the route is not an address route this import can take over (backing)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_7cef6uasrwev5fxpks3lucvqzm refused: the route is not an address route this import can take over (tunnel)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_tmioro2h7b32mbqjbewr2q6rkm refused: the route is not an address route this import can take over (caps)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_7h4ebmcjgjusdtkw6xb7pnmpse refused: the route is not an address route this import can take over (platform)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_7gqq4rofftkuf4waazggn3ee6y refused: the route is not an address route this import can take over (canary)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_qirhplqjgreppzi3npi6vnwone refused: the route is not an address route this import can take over (kind sidecar)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_wufb2qzkcblgbyg7ilcn4tk57y refused: the route is not an address route this import can take over (region)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_fnzwziqggfqwcytp7ew33slahy refused: the route is not an address route this import can take over (fleet_box)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_33gnttebprucy7itbm73xsy6uy refused: the route is not an address route this import can take over (hibernate)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_uvifkaoofotfm3pr5375mmtkyu refused: the route is not an address route this import can take over (claim_owner)
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_ijpjyh6nmytqtfno5npn23dib4 refused: this box does not run instances nested
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_e73mcvky7ih4sujmak3l7gnugm refused: this box does not run instances nested
2026/10/22 11:09:35 provision: a.shop.example.com: import sd_xu376a45gejho3jtvopmm66zpa refused: claim control is on for this box
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_bgkhs5cjyriohdzvzs4olhrmse (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_lwf4nysqotpg7w2joie2iq3h7i (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: import deferred: this box cannot read the legacy route assignments
2026/10/22 11:09:35 provision: a.shop.example.com: import deferred: the legacy route assignments could not be read: store down
2026/10/22 11:09:35 provision: a.shop.example.com: not swapping for import sd_olgwcf552ea32dm4kzo5hxgjtq: its verify hash is not a sha256
2026/10/22 11:09:35 provision: a.shop.example.com: not swapping for import sd_xjyducmqjnxjzmapvnlkpace4q: its verify hash is not a sha256
2026/10/22 11:09:35 provision: a.shop.example.com: not swapping for import sd_bzqo6d34cd62ixrsmlxhczuvvm: its verify hash is not a sha256
2026/10/22 11:09:35 provision: a.shop.example.com: not swapping for import sd_../../x: its host or seed id is malformed (seeds: not a seed id)
2026/10/22 11:09:35 provision: A.shop.example.com/..: not swapping for import sd_zugpj2fnfcfp3o6h3jh7ezuh7a: its host or seed id is malformed (seeds: not a host)
2026/10/22 11:09:35 provision: a.shop.example.com: not swapping for import sd_t6vmvnhwkiph2xngxwwnq4rhmi: its record does not describe a nested, hibernating instance
2026/10/22 11:09:35 provision: a.shop.example.com: not swapping for import sd_e3lnqxyvuotbjcp6wg3zrsc434: its record does not describe a nested, hibernating instance
2026/10/22 11:09:35 provision: a.shop.example.com: not swapping for import sd_ga4uoeqmklph5rpgqtmdc56qvm: its record does not describe a nested, hibernating instance
2026/10/22 11:09:35 provision: a.shop.example.com: not swapping for import sd_rzq72icrhwxlnlim2hwpdortte: its record does not describe a nested, hibernating instance
2026/10/22 11:09:35 provision: a.shop.example.com: import deferred: the box's layout intent could not be read: store down
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_rbaqyrqw4mk2zxf5uxgqoazili (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: import deferred: the box's nested probe did not answer: ready probe timed out
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_53tn44wu2d2fby3irllycbprme (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: swapped for import sd_5zznb3tvyqgoaaoouabnvr3h5y (the original route is journaled)
2026/10/22 11:09:35 provision: a.shop.example.com: import deferred: the route is held by operation op_1
2026/10/22 11:09:36 provision: dry-run: would consider swapping a.shop.example.com for import sd_mes4cuydk5eefuhb27nlycyqvy
2026/10/22 11:09:36 provision: a.shop.example.com: import sd_6i55ynvsb47c365gq4dcp7hbmu rolled back to its original route
2026/10/22 11:09:36 provision: a.shop.example.com: import sd_6i55ynvsb47c365gq4dcp7hbmu: the host's replica is left alone: the record apps/bac/shop/instances/a.shop.example.com.json holds the host
2026/10/22 11:09:36 provision: a.shop.example.com: import sd_6i55ynvsb47c365gq4dcp7hbmu is cleaned up and its journal row retired
2026/10/22 11:09:36 provision: a.shop.example.com: import sd_k6k7cwbldbzbbwuehqu6khoszi left alone: the import journal holds seed sd_lqxch2bv3edxp7uut7iymmz4ny at swapped
2026/10/22 11:09:36 provision: a.shop.example.com: not minting import sd_57zpxnubz5oazlpdtvo5atmvhm: it is swapped but not committed, and only its swap makes its row
2026/10/22 11:09:36 provision: a.shop.example.com: not minting import sd_bon5kb3fpebhj3zuddgknrk36q: it is placed but not committed, and only its swap makes its row
2026/10/22 11:09:36 provision: a.shop.example.com: swapped for import sd_qp46hs4hiev663fn5gpj256si4 (the original route is journaled)
2026/10/22 11:09:36 provision: a.shop.example.com: not minting import sd_qp46hs4hiev663fn5gpj256si4: it is swapped but not committed, and only its swap makes its row
2026/10/22 11:09:36 provision: a.shop.example.com: not minting import sd_qp46hs4hiev663fn5gpj256si4: it is placed but not committed, and only its swap makes its row
2026/10/22 11:09:36 provision: minted instance route a.shop.example.com (app "shop" acct "bac")
2026/10/22 11:09:36 provision: removed retired sidecar route gone.eleven.bac.sidecar.internal (record gone)
2026/10/22 11:09:36 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:36 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:36 provision: converged sidecar bot.eleven.bac.sidecar.internal args ["sidecar","run"] -> ["worker","run"]
2026/10/22 11:09:36 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:36 provision: converged sidecar bot.eleven.bac.sidecar.internal ceilings 300/3600 -> 60/120
2026/10/22 11:09:36 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:36 provision: converged sidecar bot.eleven.bac.sidecar.internal channel stable -> canary/eleven
2026/10/22 11:09:36 provision: converged sidecar bot.eleven.bac.sidecar.internal environment "other" -> "relay"
2026/10/22 11:09:36 provision: converged sidecar bot.eleven.bac.sidecar.internal hibernate true -> false
2026/10/22 11:09:36 provision: skipping sidecar record apps/bac/eleven/sidecars/bot.json: read failed: failStore: reads disabled under apps/bac/eleven/sidecars/
2026/10/22 11:09:36 provision: skipping sidecar record apps/bac/eleven/sidecars/bot.json: malformed: invalid character 'n' looking for beginning of object key string
2026/10/22 11:09:36 provision: not removing sidecar bot.eleven.bac.sidecar.internal: its record exists but could not be read cleanly this pass
2026/10/22 11:09:36 provision: skipping sidecar record apps/bac/eleven/sidecars/bot.json: empty channel
2026/10/22 11:09:36 provision: skipping sidecar record apps/bac/eleven/sidecars/held.json: empty channel
2026/10/22 11:09:36 provision: not removing sidecar held.eleven.bac.sidecar.internal: its record exists but could not be read cleanly this pass
2026/10/22 11:09:36 provision: removed retired sidecar route old.eleven.bac.sidecar.internal (record gone)
2026/10/22 11:09:36 provision: bac/eleven has sidecar records but no sidecars manifest — not minting
2026/10/22 11:09:36 provision: bac/eleven is in the trash — not minting sidecar routes for it
2026/10/22 11:09:36 provision: sidecar bot.eleven.bac.sidecar.internal is not placeable here: it asks for "no-inbound" placement and this box accepts inbound work (CARLOS_INBOUND="")
2026/10/22 11:09:36 provision: sidecar hub.relay.bac.sidecar.internal is not placeable here: it asks for "no-inbound" placement and this box accepts inbound work (CARLOS_INBOUND="")
2026/10/22 11:09:36 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:36 provision: minted sidecar route hub.relay.bac.sidecar.internal (app "relay" acct "bac" args ["relay"])
2026/10/22 11:09:36 provision: sidecar bot.eleven.bac.sidecar.internal is not placeable here: it asks for "no-inbound" placement and this box accepts inbound work (CARLOS_INBOUND="")
2026/10/22 11:09:36 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:36 provision: sidecar bot.eleven.bac.sidecar.internal is not placeable here: it asks for "no-inbound" placement and this box accepts inbound work (CARLOS_INBOUND="")
2026/10/22 11:09:36 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:36 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:36 provision: sidecar bot.eleven.bac.sidecar.internal is not placeable here: it asks for "no-inbound" placement and this box accepts inbound work (CARLOS_INBOUND="")
2026/10/22 11:09:36 provision: removed retired sidecar route bot.eleven.bac.sidecar.internal (record gone)
2026/10/22 11:09:36 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:36 provision: sidecar bot.eleven.bac.sidecar.internal is not placeable here: it asks for "no-inbound" placement and this box accepts inbound work (CARLOS_INBOUND="")
2026/10/22 11:09:36 provision: skipping sidecar record apps/bac/relay/sidecars/hub.json: read failed: failStore: reads disabled under apps/bac/relay/sidecars/
2026/10/22 11:09:36 provision: REFUSING to mint sidecar bot.eleven.bac.sidecar.internal: bot.eleven.bac.sidecar.internal-sidecar.env is staged on this box — the legacy file co-spawn and a native sidecar row are two mechanisms for one host; remove the file to migrate this host onto sidecar records
2026/10/22 11:09:36 provision: minted sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" args ["sidecar","run"])
2026/10/22 11:09:36 provision: dry-run: would mint sidecar route bot.eleven.bac.sidecar.internal (app "eleven" acct "bac" channel "stable" args ["sidecar","run"])
2026/10/22 11:09:36 provision: dry-run: would remove retired sidecar route gone.eleven.bac.sidecar.internal (record gone)
2026/10/22 11:09:36 provision: bot.eleven.bac.sidecar.internal exists but is not a sidecar row this pass owns (kind "sidecar" provisioned false app "eleven" acct "bac") — leaving it alone
2026/10/22 11:09:36 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:36 provision: converged acme.go.tito.io update settings "{\"updates\":\"manual\",\"channel\":\"stable\"}" -> ""
2026/10/22 11:09:36 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:36 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:36 provision: manifest bac/tito: read failed: provision: manifest bac/tito: unexpected end of JSON input
2026/10/22 11:09:36 provision: manifest bac/tito: read failed: provision: manifest bac/tito: unexpected end of JSON input
2026/10/22 11:09:36 provision: acme.go.tito.io: not minted this pass: the app's update policy could not be read
2026/10/22 11:09:36 provision: minted instance route acme.go.tito.io (app "tito" acct "bac")
2026/10/22 11:09:36 provision: manifest bac/tito: read failed: provision: manifest bac/tito: unexpected end of JSON input
2026/10/22 11:09:36 provision: acme.go.tito.io: not minted this pass: the app's update policy could not be read
2026/10/22 11:09:36 provision: minted instance route acme.go.tito.io held landing by mv_acme (app "tito" acct "bac")
--- FAIL: TestPlan14RootReadCensus (18.24s)
    plan14_root_reads_test.go:1261: root read census: 1 discrepancies
        changed root source envelope internal/provision
FAIL
FAIL	github.com/carlosframework/platform/internal/provision	30.067s
ok  	github.com/carlosframework/platform/internal/publicrelease	0.015s
?   	github.com/carlosframework/platform/internal/regionname	[no test files]
ok  	github.com/carlosframework/platform/internal/registry	7.527s
ok  	github.com/carlosframework/platform/internal/relay	7.328s
ok  	github.com/carlosframework/platform/internal/release	32.378s
ok  	github.com/carlosframework/platform/internal/rollout	5.283s
ok  	github.com/carlosframework/platform/internal/rolloutwords	0.004s
ok  	github.com/carlosframework/platform/internal/rootaws	0.009s
ok  	github.com/carlosframework/platform/internal/rootparticipation	0.064s
ok  	github.com/carlosframework/platform/internal/rootstate	0.028s
ok  	github.com/carlosframework/platform/internal/runs	0.604s
ok  	github.com/carlosframework/platform/internal/s3compat	0.007s
ok  	github.com/carlosframework/platform/internal/safefile	0.004s
ok  	github.com/carlosframework/platform/internal/schedule	3.735s
ok  	github.com/carlosframework/platform/internal/seeds	0.022s
ok  	github.com/carlosframework/platform/internal/sim/hostlife	25.858s
ok  	github.com/carlosframework/platform/internal/sim/litestreamfacts	4.157s
ok  	github.com/carlosframework/platform/internal/status	0.150s
ok  	github.com/carlosframework/platform/internal/steering	0.012s
ok  	github.com/carlosframework/platform/internal/stopevidence	0.483s
ok  	github.com/carlosframework/platform/internal/svcrole	0.004s
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.004s
ok  	github.com/carlosframework/platform/internal/updatewords	0.011s
ok  	github.com/carlosframework/platform/internal/usage	0.006s
ok  	github.com/carlosframework/platform/internal/version	0.004s
ok  	github.com/carlosframework/platform/internal/vet	2.023s
FAIL
=== internal_console@0 (80 s)
ok  	github.com/carlosframework/platform/internal/console	77.653s
=== internal_console@1 (44 s)
ok  	github.com/carlosframework/platform/internal/console	41.716s
=== internal_console@2 (51 s)
ok  	github.com/carlosframework/platform/internal/console	48.224s
=== internal_console@3 (45 s)
ok  	github.com/carlosframework/platform/internal/console	41.987s
=== internal_console@4 (45 s)
ok  	github.com/carlosframework/platform/internal/console	42.462s
=== internal_console@5 (43 s)
ok  	github.com/carlosframework/platform/internal/console	40.155s
=== internal_console@6 (44 s)
ok  	github.com/carlosframework/platform/internal/console	41.167s
=== internal_console@7 (51 s)
ok  	github.com/carlosframework/platform/internal/console	48.114s
=== root@0 (44 s)
ok  	github.com/carlosframework/platform	42.303s
=== root@1 (49 s)
ok  	github.com/carlosframework/platform	46.994s
=== root@2 (48 s)
ok  	github.com/carlosframework/platform	46.283s

FAILED: rest
make: *** [Makefile:19: 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-22-self-serve-moves-2-door-token-job.md b/docs/superpowers/plans/2026-10-22-self-serve-moves-2-door-token-job.md
index 474949a6c..9f471428a 100644
--- a/docs/superpowers/plans/2026-10-22-self-serve-moves-2-door-token-job.md
+++ b/docs/superpowers/plans/2026-10-22-self-serve-moves-2-door-token-job.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 14, 2026-10-22. Rev 13's review (`selfserve-plan2-review13.md`: N11, N10a closed; N10b narrowed; N12 new) is answered: the maintenance-to-idle consume requires `cut_requested_at = 0` in its predicate, so a cut that won makes a stale consume fail and the worker re-reads into the handoff (N10b); `MarkSelfServeCut` also transfers an outstanding unconfirmed `maintain` request's `request_deadline` to the cut's copy allowance in the same UPDATE, so one deadline policy governs adoption (N12). Rev 12's review (`selfserve-plan2-review12.md`: N9 closed; N10 narrowed; N11 new) is answered: **a request deadline exists only for writes whose expiry action is abort** (the pre-open writes: queue, stage, maintain, precheck, start, seal, flip, open); the post-open and clearing writes (gate 1, gate 2, finish, the abort path's abort and finish, estimate) carry `request_deadline = 0`, which `selfServeApply` never checks, so a page-and-retain phase whose evidence arrives late still clears the move (N11); abandonment rolls the next wait's deadline in its own UPDATE (`AbandonSelfServeRequest(id, nonce, nextDeadline)`) (N10a); a maintenance round's allowance starts at its issue and `ready` has **no step deadline while idle** (`next_maintenance_at` schedules the next round; `step_deadline = 0` between rounds) (N10b). Rev 11's review (`selfserve-plan2-review11.md`: N8 closed; N9 narrowed; N10 new) is answered: `selfServeApply` checks the request's deadline **before every forward-write attempt, replays included**, and an expired request leaves the loop as `errRequestExpired` for the fence-and-classify path, so no retry can open after the deadline inside one invocation (N9); a same-phase consume **rolls the next wait's deadline** in the same UPDATE (`ConsumeSelfServeRequest(id, nonce, nextStep, nextDeadline)`), issuance copies that fresh deadline into `request_deadline`, and the phase-wide limits stay on `staging_started_at` and `window_deadline` (N10). Rev 10's review (`selfserve-plan2-review10.md`: N6 closed; N8 narrowed; N9 new) is answered: **every** writer, the operator doors included, proposes its stamp as `max(now, the observed record's previous stamp + 1 ns)` and the mutation stores it verbatim, so stamps are monotonic under a backward clock and supersession by stamp is sound (N8); every request persists **its own deadline** (`request_deadline`, the issuing phase's step deadline), and an unconfirmed request whose deadline has passed while the record is at or before `offline-landed` is never replayed from **any** row phase, `open-uncertain` included: fence, classify, confirm if the write won, else void and abort (N9). Rev 9's review (`selfserve-plan2-review9.md`: 8, 10, 13, 20, N7 closed) is answered: **a committed confirmation expiry wins over a later cut** (`MarkSelfServeCut` also requires `expiry_pending = 0`; the cut door answers 409 "the move expired. prepare again"), and the persisted expiry carries its kind and deadline so execution revalidates its identity (N6); **an operator's newer staging stamp supersedes the job's outstanding wait**: when the record's stamp for the awaited field has moved past `request_proposed` without the receipt changing, the job abandons its request and issues a fresh bound round, with the crash between the two stated (N8). Rev 8's review (`selfserve-plan2-review8.md`: 21, N4 closed) is answered: reconciliation maps the record to a **phase and substep** (the first substep whose transition the record has not made), so an operator's progress never makes the job repeat a refused transition (item 10); abandonment is only for **leaving** a wait (abort, cancel, operator supersession), never for a page-and-retain expiry, with the phase table stated (item 13); the confirmation-deadline expiry commits only against `cut_requested_at = 0` and the deadline it saw, and the cut's copy expiry is a different decision (N6); the cut handoff persists which continuation it chose as a `restage` substep (`adopted` or `issue`) in the advancing transaction (N7); acceptance and discovery share one participant predicate (item 8); the superseded tag arrangement is deleted (item 20). Rev 7's review (`selfserve-plan2-review7.md`: N1, N2, N3, N5 closed) is answered: a phase with several writes has a durable **substep** (`phase_step`), advanced atomically with the consumption that ends the previous substep, and the phase function dispatches on it (item 10); confirmation is the **receipt alone** (no state predicate), phase progress is reconciliation's business (item 10); issuance refused with no outstanding request is its own result (`errRequestRefused`) (item 10); a confirmed request whose wait will never be satisfied is **abandoned** (consumed without its wait) by abort, expiry and operator supersession, and the finaliser consumes a confirmed clearing request in the transaction that records the outcome (item 13); `maintain` updates the stage identity like `stage` (N4); the cut's `MarkSelfServeCut` retires the ready deadline in the same UPDATE and ready expiry is conditional on no accepted cut (N6); return reports are **immutable per request key** (item 21); an id-less forward keeps `BoxID` membership and drops only the instance comparison (item 8); one untagged bridge file with the complete helper closure (item 20). Rev 6's review (`selfserve-plan2-review6.md`: items 1, 6, 17 closed) is answered: the request lifecycle is a complete state machine (`issued → confirmed → consumed`, or `voided`) with a **resume** path for a confirmed-unconsumed request, a standalone consume for same-phase sequences (start then seal, finish gate 1 then finish, round after round, estimate), issuance that returns the existing request so a caller of another kind or phase stops instead of interpreting it, and no-op-free receipts (a request-bearing mutation always writes its receipt) (item 10); the bound write checks **incarnation and sequence** (`provision.Expect{Incarnation, Seq}`) for the job and the operator doors (N5, item 13); every finalisation requires no outstanding request after a fence (item 13); the expiry branch classifies the fenced observation (N3); the cut is a **handoff**: the door marks `cut_requested_at` and the job turns the outstanding maintenance round into the first cut round (N4); event delivery marks `emitted` inside the transaction before delivering and the terminal event is inserted with the outcome (N1); per-box FIFO is stated (N2); the open intent is prepared before the request is issued so adoption and the persisted proposal agree, return requests carry a full identity ordered deterministically, reports name the request key, and acceptance binds the report to the reverse move's selected target (item 21); `Expect`'s real fields, `Load`'s absence distinction and one id-less rule (item 8); the fixtures move to an untagged `linux` file so today's tests keep compiling, `CopyEvent` carries its completion fields, the saved book is validated before seeding, `DiskFreeBytes` is numeric (item 20). Rev 5's review (`selfserve-plan2-review5.md`: items 2, 3, 4, 5, 7, 9, 11, 12, 14, 15, 16, 18, 19 closed) is answered: every job and operator record write is **predecessor-bound** (`provision.SetRecordMoveAt(ctx, s, acct, app, host, expectSeq, mut)`: one CAS write against the record whose `record_seq` equals the persisted expectation, no fresh-read retry), so a voided request can never land and an operator door never rebuilds a write after a reclaim fence (items 10, 13); every self-serve mutation stamps a **nonce receipt** on the record (`SelfServe.LastRequest`, or `LastMove.Request` for a clearing write), so confirmation is exact for every transition and distinct from an operator's reconciliation (item 10); confirm and advance require an unconsumed, unvoided request, so a stale worker cannot confirm a voided one (item 10); "pending" means **no confirmed request for the phase's write**, so the interval before issuance is compatible with the predecessor state (item 10); an expired uncommitted open is fenced and aborted, never replayed (N1); the stage book is reconciled against each complete successful round so deleted keys leave it (item 6); identity records are loaded by `boxid.Key(BoxID)` and `Verified` is narrowed to what `Enroll` proves (item 8); the gate's exception for an authorised malformed hostname and plan 1's outer 503 are declared (item 1); the view joins row id, move id, self-serve id and incarnation (item 17); the open record adopts an existing complete intent, return discovery and acceptance compare `InstanceID`, incarnation is re-checked at the door and in the guarded write, and `Layout` comes from the source's `stopped` report so every operator move has it (item 21); a maintenance restage in `ready` has its own kind and keeps the confirmation deadline (N2); the gate types, `StagedRequest`, failed diagnostics, the request argument to `confirmed`, and the bridge's compile rule are stated (item 20). Reviews: rev 1 (`after236/selfserve-plan2-review.md`, 20 findings), rev 2 (`selfserve-plan2-review2.md`, 21), rev 3 (`selfserve-plan2-review3.md`, 21 items), rev 4 (`selfserve-plan2-review4.md`, 21 items, 9 closed). Rev 5 is **self-contained** (nothing is "as rev N"; every schema, phase, predicate, sentence and test list is in this document) and answers rev 4's open items: the gate orders authentication, host shape and the capability check before the limiter and the no-bucket rail (item 1); operator moves keep today's admission (nil or stale metrics, no identity record) and only the self-serve path requires fresh identity; `BootID` is dropped (items 4, 8); the evidence reader takes the move and a freshness table is stated (item 5); the staged inventory is a **move-bound book** built from every copy event the mirror reports, including same-ETag and deferred copies, through a new observer hook that leaves ordinary mirroring unchanged (item 6); a participant is identified by `BoxID` **and** `InstanceID` in the resolver, in report validation and at every gate, and abort never requires the target (item 8); every request persists its **nonce, expected sequence and proposed stamp before the write**, confirmation is conditional on the record carrying that exact stamp, replay is idempotent, and consumption and the phase advance are one UPDATE predicated on the nonce (item 10); compatible sets include the predecessor state while a phase's write is pending (item 10); expiry is bound to its phase and cleared on reconciliation into another phase, with the health rule taking precedence (item 12); abandonment is conditional on the fenced observation and persisted before release, and every reclaim fences first, operator reservations included (item 13); own retries are accepted only for a complete expected selection after the whole table validates (item 14); the status view joins rows regardless of the mode (item 17); events carry a per-row sequence and are delivered inside the caller's transaction, the harness is an exported bridge **inside package host** behind the `e2e` tag with the CI step named, the Go declarations are complete, and queue ordering is stated (item 20); the open record is written **before** the open transition with the proposed open time, return requests have unique durable identities, the report path is named, acceptance is bound to the lifetime and the forward's participants, and leftovers are judged by the forward's layout (item 21).
+Rev 15, 2026-10-22. Rev 14's review (`selfserve-plan2-review14.md`: N10b closed; N12 narrowed) is answered: the request-expiry decision is **durable and conditional** (`ExpireSelfServeRequest(id, nonce, sawDeadline)`: one UPDATE predicated on the nonce, the deadline the worker saw, no consumption and no accepted cut), mutually exclusive with `MarkSelfServeCut` (which also requires `request_expired = 0`), and only the winning expiry fences, voids and aborts; `persistedRequest` carries `Deadline`; the abbreviated call sites name their full arguments. Rev 13's review (`selfserve-plan2-review13.md`: N11, N10a closed; N10b narrowed; N12 new) is answered: the maintenance-to-idle consume requires `cut_requested_at = 0` in its predicate, so a cut that won makes a stale consume fail and the worker re-reads into the handoff (N10b); `MarkSelfServeCut` also transfers an outstanding unconfirmed `maintain` request's `request_deadline` to the cut's copy allowance in the same UPDATE, so one deadline policy governs adoption (N12). Rev 12's review (`selfserve-plan2-review12.md`: N9 closed; N10 narrowed; N11 new) is answered: **a request deadline exists only for writes whose expiry action is abort** (the pre-open writes: queue, stage, maintain, precheck, start, seal, flip, open); the post-open and clearing writes (gate 1, gate 2, finish, the abort path's abort and finish, estimate) carry `request_deadline = 0`, which `selfServeApply` never checks, so a page-and-retain phase whose evidence arrives late still clears the move (N11); abandonment rolls the next wait's deadline in its own UPDATE (`AbandonSelfServeRequest(id, nonce, nextDeadline)`) (N10a); a maintenance round's allowance starts at its issue and `ready` has **no step deadline while idle** (`next_maintenance_at` schedules the next round; `step_deadline = 0` between rounds) (N10b). Rev 11's review (`selfserve-plan2-review11.md`: N8 closed; N9 narrowed; N10 new) is answered: `selfServeApply` checks the request's deadline **before every forward-write attempt, replays included**, and an expired request leaves the loop as `errRequestExpired` for the fence-and-classify path, so no retry can open after the deadline inside one invocation (N9); a same-phase consume **rolls the next wait's deadline** in the same UPDATE (`ConsumeSelfServeRequest(id, nonce, nextStep, nextDeadline)`), issuance copies that fresh deadline into `request_deadline`, and the phase-wide limits stay on `staging_started_at` and `window_deadline` (N10). Rev 10's review (`selfserve-plan2-review10.md`: N6 closed; N8 narrowed; N9 new) is answered: **every** writer, the operator doors included, proposes its stamp as `max(now, the observed record's previous stamp + 1 ns)` and the mutation stores it verbatim, so stamps are monotonic under a backward clock and supersession by stamp is sound (N8); every request persists **its own deadline** (`request_deadline`, the issuing phase's step deadline), and an unconfirmed request whose deadline has passed while the record is at or before `offline-landed` is never replayed from **any** row phase, `open-uncertain` included: fence, classify, confirm if the write won, else void and abort (N9). Rev 9's review (`selfserve-plan2-review9.md`: 8, 10, 13, 20, N7 closed) is answered: **a committed confirmation expiry wins over a later cut** (`MarkSelfServeCut` also requires `expiry_pending = 0`; the cut door answers 409 "the move expired. prepare again"), and the persisted expiry carries its kind and deadline so execution revalidates its identity (N6); **an operator's newer staging stamp supersedes the job's outstanding wait**: when the record's stamp for the awaited field has moved past `request_proposed` without the receipt changing, the job abandons its request and issues a fresh bound round, with the crash between the two stated (N8). Rev 8's review (`selfserve-plan2-review8.md`: 21, N4 closed) is answered: reconciliation maps the record to a **phase and substep** (the first substep whose transition the record has not made), so an operator's progress never makes the job repeat a refused transition (item 10); abandonment is only for **leaving** a wait (abort, cancel, operator supersession), never for a page-and-retain expiry, with the phase table stated (item 13); the confirmation-deadline expiry commits only against `cut_requested_at = 0` and the deadline it saw, and the cut's copy expiry is a different decision (N6); the cut handoff persists which continuation it chose as a `restage` substep (`adopted` or `issue`) in the advancing transaction (N7); acceptance and discovery share one participant predicate (item 8); the superseded tag arrangement is deleted (item 20). Rev 7's review (`selfserve-plan2-review7.md`: N1, N2, N3, N5 closed) is answered: a phase with several writes has a durable **substep** (`phase_step`), advanced atomically with the consumption that ends the previous substep, and the phase function dispatches on it (item 10); confirmation is the **receipt alone** (no state predicate), phase progress is reconciliation's business (item 10); issuance refused with no outstanding request is its own result (`errRequestRefused`) (item 10); a confirmed request whose wait will never be satisfied is **abandoned** (consumed without its wait) by abort, expiry and operator supersession, and the finaliser consumes a confirmed clearing request in the transaction that records the outcome (item 13); `maintain` updates the stage identity like `stage` (N4); the cut's `MarkSelfServeCut` retires the ready deadline in the same UPDATE and ready expiry is conditional on no accepted cut (N6); return reports are **immutable per request key** (item 21); an id-less forward keeps `BoxID` membership and drops only the instance comparison (item 8); one untagged bridge file with the complete helper closure (item 20). Rev 6's review (`selfserve-plan2-review6.md`: items 1, 6, 17 closed) is answered: the request lifecycle is a complete state machine (`issued → confirmed → consumed`, or `voided`) with a **resume** path for a confirmed-unconsumed request, a standalone consume for same-phase sequences (start then seal, finish gate 1 then finish, round after round, estimate), issuance that returns the existing request so a caller of another kind or phase stops instead of interpreting it, and no-op-free receipts (a request-bearing mutation always writes its receipt) (item 10); the bound write checks **incarnation and sequence** (`provision.Expect{Incarnation, Seq}`) for the job and the operator doors (N5, item 13); every finalisation requires no outstanding request after a fence (item 13); the expiry branch classifies the fenced observation (N3); the cut is a **handoff**: the door marks `cut_requested_at` and the job turns the outstanding maintenance round into the first cut round (N4); event delivery marks `emitted` inside the transaction before delivering and the terminal event is inserted with the outcome (N1); per-box FIFO is stated (N2); the open intent is prepared before the request is issued so adoption and the persisted proposal agree, return requests carry a full identity ordered deterministically, reports name the request key, and acceptance binds the report to the reverse move's selected target (item 21); `Expect`'s real fields, `Load`'s absence distinction and one id-less rule (item 8); the fixtures move to an untagged `linux` file so today's tests keep compiling, `CopyEvent` carries its completion fields, the saved book is validated before seeding, `DiskFreeBytes` is numeric (item 20). Rev 5's review (`selfserve-plan2-review5.md`: items 2, 3, 4, 5, 7, 9, 11, 12, 14, 15, 16, 18, 19 closed) is answered: every job and operator record write is **predecessor-bound** (`provision.SetRecordMoveAt(ctx, s, acct, app, host, expectSeq, mut)`: one CAS write against the record whose `record_seq` equals the persisted expectation, no fresh-read retry), so a voided request can never land and an operator door never rebuilds a write after a reclaim fence (items 10, 13); every self-serve mutation stamps a **nonce receipt** on the record (`SelfServe.LastRequest`, or `LastMove.Request` for a clearing write), so confirmation is exact for every transition and distinct from an operator's reconciliation (item 10); confirm and advance require an unconsumed, unvoided request, so a stale worker cannot confirm a voided one (item 10); "pending" means **no confirmed request for the phase's write**, so the interval before issuance is compatible with the predecessor state (item 10); an expired uncommitted open is fenced and aborted, never replayed (N1); the stage book is reconciled against each complete successful round so deleted keys leave it (item 6); identity records are loaded by `boxid.Key(BoxID)` and `Verified` is narrowed to what `Enroll` proves (item 8); the gate's exception for an authorised malformed hostname and plan 1's outer 503 are declared (item 1); the view joins row id, move id, self-serve id and incarnation (item 17); the open record adopts an existing complete intent, return discovery and acceptance compare `InstanceID`, incarnation is re-checked at the door and in the guarded write, and `Layout` comes from the source's `stopped` report so every operator move has it (item 21); a maintenance restage in `ready` has its own kind and keeps the confirmation deadline (N2); the gate types, `StagedRequest`, failed diagnostics, the request argument to `confirmed`, and the bridge's compile rule are stated (item 20). Reviews: rev 1 (`after236/selfserve-plan2-review.md`, 20 findings), rev 2 (`selfserve-plan2-review2.md`, 21), rev 3 (`selfserve-plan2-review3.md`, 21 items), rev 4 (`selfserve-plan2-review4.md`, 21 items, 9 closed). Rev 5 is **self-contained** (nothing is "as rev N"; every schema, phase, predicate, sentence and test list is in this document) and answers rev 4's open items: the gate orders authentication, host shape and the capability check before the limiter and the no-bucket rail (item 1); operator moves keep today's admission (nil or stale metrics, no identity record) and only the self-serve path requires fresh identity; `BootID` is dropped (items 4, 8); the evidence reader takes the move and a freshness table is stated (item 5); the staged inventory is a **move-bound book** built from every copy event the mirror reports, including same-ETag and deferred copies, through a new observer hook that leaves ordinary mirroring unchanged (item 6); a participant is identified by `BoxID` **and** `InstanceID` in the resolver, in report validation and at every gate, and abort never requires the target (item 8); every request persists its **nonce, expected sequence and proposed stamp before the write**, confirmation is conditional on the record carrying that exact stamp, replay is idempotent, and consumption and the phase advance are one UPDATE predicated on the nonce (item 10); compatible sets include the predecessor state while a phase's write is pending (item 10); expiry is bound to its phase and cleared on reconciliation into another phase, with the health rule taking precedence (item 12); abandonment is conditional on the fenced observation and persisted before release, and every reclaim fences first, operator reservations included (item 13); own retries are accepted only for a complete expected selection after the whole table validates (item 14); the status view joins rows regardless of the mode (item 17); events carry a per-row sequence and are delivered inside the caller's transaction, the harness is an exported bridge **inside package host** behind the `e2e` tag with the CI step named, the Go declarations are complete, and queue ordering is stated (item 20); the open record is written **before** the open transition with the proposed open time, return requests have unique durable identities, the report path is named, acceptance is bound to the lifetime and the forward's participants, and leftovers are judged by the forward's layout (item 21).
Builds on plan 1 (`2026-10-22-self-serve-moves-1-lifetimes-and-order.md`, rev 13): records carry a lifetime, `record_seq` and `move_seq`, rows carry the pair, readers and writers are judged, `fenceRecord(ctx, acct, app, host, op fenceOwner) (fenceResult, Observation, error)` exists, the console runs behind the lifetimes cutover. This plan adds everything a Tito customer's request needs up to a finished move except the holding page, the edge probe mode and cleanup (plans 3 and 4).
@@ -102,9 +102,9 @@ Builds on plan 1 (`2026-10-22-self-serve-moves-1-lifetimes-and-order.md`, rev 13
- Test: `internal/console/selfserve_store_test.go`, `internal/console/selfserve_pass_test.go`
**Interfaces:**
-- Table `self_serve_moves (id TEXT PRIMARY KEY, account TEXT, app TEXT, host TEXT, incarnation INTEGER, from_region TEXT, to_region TEXT, participants TEXT, display_name TEXT, requested_by TEXT, phase TEXT, phase_started_at INTEGER, step_deadline INTEGER, window_deadline INTEGER, expiry_pending INTEGER, expiry_phase TEXT, expiry_kind TEXT, expiry_deadline INTEGER, staging_started_at INTEGER, request_issued INTEGER, request_kind TEXT, request_phase TEXT, request_nonce TEXT, request_expect_seq INTEGER, request_proposed INTEGER, request_confirmed INTEGER, request_consumed INTEGER, request_voided INTEGER, request_abandoned INTEGER, request_expect_inc INTEGER, request_deadline INTEGER, next_maintenance_at INTEGER, cut_requested_at INTEGER, phase_step TEXT, stage_request INTEGER, precheck_request INTEGER, rounds INTEGER, estimate_seconds INTEGER, estimate_terms TEXT, reason TEXT, health_attempts INTEGER, health_consecutive_ok INTEGER, health_first_ok_at INTEGER, health_last_probe_at INTEGER, health_last_error TEXT, finish_gate TEXT, notified_seq INTEGER, event_seq INTEGER, outcome TEXT, outcome_reason TEXT, warning TEXT, abort_requested_at INTEGER, source_reopened_at INTEGER, abort_finished_at INTEGER, effects_done INTEGER, release_pending INTEGER, open_record_pending INTEGER, created_at INTEGER, updated_at INTEGER)`; `CREATE UNIQUE INDEX IF NOT EXISTS self_serve_moves_open ON self_serve_moves(account, app, host) WHERE outcome = ''`.
+- Table `self_serve_moves (id TEXT PRIMARY KEY, account TEXT, app TEXT, host TEXT, incarnation INTEGER, from_region TEXT, to_region TEXT, participants TEXT, display_name TEXT, requested_by TEXT, phase TEXT, phase_started_at INTEGER, step_deadline INTEGER, window_deadline INTEGER, expiry_pending INTEGER, expiry_phase TEXT, expiry_kind TEXT, expiry_deadline INTEGER, staging_started_at INTEGER, request_issued INTEGER, request_kind TEXT, request_phase TEXT, request_nonce TEXT, request_expect_seq INTEGER, request_proposed INTEGER, request_confirmed INTEGER, request_consumed INTEGER, request_voided INTEGER, request_abandoned INTEGER, request_expect_inc INTEGER, request_deadline INTEGER, request_expired INTEGER, next_maintenance_at INTEGER, cut_requested_at INTEGER, phase_step TEXT, stage_request INTEGER, precheck_request INTEGER, rounds INTEGER, estimate_seconds INTEGER, estimate_terms TEXT, reason TEXT, health_attempts INTEGER, health_consecutive_ok INTEGER, health_first_ok_at INTEGER, health_last_probe_at INTEGER, health_last_error TEXT, finish_gate TEXT, notified_seq INTEGER, event_seq INTEGER, outcome TEXT, outcome_reason TEXT, warning TEXT, abort_requested_at INTEGER, source_reopened_at INTEGER, abort_finished_at INTEGER, effects_done INTEGER, release_pending INTEGER, open_record_pending INTEGER, created_at INTEGER, updated_at INTEGER)`; `CREATE UNIQUE INDEX IF NOT EXISTS self_serve_moves_open ON self_serve_moves(account, app, host) WHERE outcome = ''`.
- **The request lifecycle** (one request at a time per row): `IssueSelfServeRequest(id, kind, phase string, pr persistedRequest, now time.Time) (issued bool, existing *persistedRequest, err error)` (`WHERE phase = ? AND outcome = '' AND (request_consumed <> 0 OR request_issued = 0)`: sets `request_issued = now, request_kind, request_phase, request_nonce, request_expect_inc, request_expect_seq, request_proposed, request_deadline = the issuing phase's step deadline **for a request whose expiry action is abort** (queue, stage, maintain, precheck, start, seal, flip, open) and **0 for every other kind** (gate 1, gate 2, finish, abort, the abort path's finish, estimate: their phases page and retain, and their writes must always be allowed to complete), request_confirmed = 0, request_consumed = 0, request_voided = 0`; not issued → `existing` is the outstanding request, whatever its kind and phase); `ConsumeSelfServeRequest(id, nonce, nextStep string, nextDeadline time.Time) (bool, error)` (`WHERE request_nonce = ? AND request_confirmed <> 0 AND request_consumed = 0`: `request_consumed = 1, phase_step = nextStep, step_deadline = nextDeadline` in one statement, so **each wait's deadline starts when the previous request is consumed**: a staging round's `max(10 min, 3 × est.Copy)` runs from its own issue, each finishing gate gets its own 10 min, each maintenance round its own allowance; the phase-wide limits (`now - staging_started_at > 30 min`, `WindowDeadline`) are separate columns and unaffected; `AdvanceSelfServe` sets `step_deadline` for the new phase's first wait likewise; a crash between a consume and the next issue finds the fresh deadline already persisted; the standalone consume for a same-phase sequence: the substep advances exactly when the previous request is consumed, so a crash between them cannot lose the position); `AbandonSelfServeRequest(id, nonce string, nextDeadline time.Time) (bool, error)` (`WHERE request_nonce = ? AND request_confirmed <> 0 AND request_consumed = 0`: `request_consumed = 1, request_abandoned = 1, step_deadline = nextDeadline` in one statement, so the replacement wait gets a fresh allowance and a crash between the abandon and the next issue finds it persisted; only abort, an expiry action and operator supersession call it: the request's write committed but its wait will never be satisfied, so the phase gives it up and proceeds); `ConfirmSelfServeRequest(id, nonce string, now time.Time) (bool, error)` (`WHERE request_nonce = ? AND request_consumed = 0 AND request_voided = 0 AND request_confirmed = 0`: `request_confirmed = now`; false → the caller re-reads the row: confirmed already → **resume** (success), voided or consumed → stop; for kinds `stage` **and `maintain`** also `stage_request = request_proposed`, for `precheck` also `precheck_request = request_proposed`); `VoidSelfServeRequest(id, nonce string) error` (`WHERE request_nonce = ? AND request_consumed = 0 AND request_confirmed = 0`: `request_consumed = 1, request_voided = 1`; a confirmed request is never voided; the phase function decides again); `AdvanceSelfServe(id, from, to, reason string, step, window time.Time, nonce string, now time.Time) (bool, error)`: one UPDATE with the predicate `phase = ? AND (abort_requested_at = 0 OR ? IN ('reverting','done','opened','health','finishing')) AND (? = '' OR request_nonce = ?)` that sets the phase, `phase_started_at`, the deadlines, `expiry_pending = 0, expiry_phase = ''` when `to <> expiry_phase`, and, when a nonce is given, additionally requires `request_nonce = ? AND request_confirmed <> 0 AND request_consumed = 0` and sets `request_consumed = 1` (**consumption and the advance are one statement**), and inserts the phase event in the same transaction (`event_seq = event_seq + 1`); a stale worker holding another nonce, or the same nonce after a void, cannot confirm or consume.
-- Other store methods: `AdmitSelfServeMove(m SelfServeMove) (admitted bool, open *SelfServeMove, err error)`; `SelfServeMove(id string) (*SelfServeMove, error)`; `SelfServeMoveForHost(acct, app, host string) (open, terminal *SelfServeMove, err error)` (the open row, and the newest terminal row); `OpenSelfServeMoves() ([]SelfServeMove, error)` (`outcome = '' OR release_pending = 1 OR effects_done = 0 OR open_record_pending = 1`, **ordered by `created_at, id`**: the pass steps rows in that order; **per-box FIFO**: a row in `reserving` may reserve only when no older open row (by `created_at, id`) that shares any participant `BoxID` is still in `requested` or `reserving`; otherwise it waits with `reason` "waiting for an earlier move on this box"; rows with disjoint participants never wait on each other); `MarkSelfServeCut(id string, now time.Time, copyDeadline time.Time) (bool, error)` (`WHERE phase = 'ready' AND abort_requested_at = 0 AND cut_requested_at = 0 AND expiry_pending = 0`: a confirmation expiry already committed wins, and the cut door re-reads and answers 409 "the move expired. prepare again"; sets `cut_requested_at = now`, **`window_deadline = 0`** (the confirmation deadline is retired by the cut that won), `step_deadline = copyDeadline` (the cut's copy wait) **and, when an unconsumed `maintain` request is outstanding, `request_deadline = copyDeadline`** (the adopted round gets the cut's allowance whether or not its write has committed yet) in the same UPDATE; the cut door's only write); the `ready` expiry rule applies only while `cut_requested_at = 0`; `SetSelfServeEstimate`, `RecordSelfServeHealth(id string, probeAt time.Time, ok bool, errText string) error` (`health_attempts + 1`; `consecutive_ok = CASE ok THEN consecutive_ok + 1 ELSE 0`; `first_ok_at` kept once set), `SetSelfServeFinishGate`, `SetSelfServeWarning`, `SetSelfServeNotifiedSeq(id string, seq uint64) error`, `SetSelfServeExpiry(id, phase string, kind string, sawDeadline time.Time, pending bool) (bool, error)` (`kind` is `window` or `step`; the UPDATE also records `expiry_kind = kind, expiry_deadline = sawDeadline`, and the expiry **action** later re-reads the row and runs only when `expiry_pending`, `expiry_phase`, `expiry_kind` and `expiry_deadline` still match what it is acting on (an expiry whose identity changed is dropped); the UPDATE's predicate is `phase = ? AND (window_deadline = ? for window, step_deadline = ? for step) AND (kind <> 'window' OR cut_requested_at = 0)`, so a worker whose snapshot predates a successful cut cannot record the obsolete confirmation expiry (`TestStaleExpiryLosesToTheCut`: a worker paused across the cut at T-1 resumes at T+1 and its `window` expiry is refused; the copy's `step` expiry after the cut is accepted; **expiry first**: the window expiry commits at T+ε, then the cut door → 409 expired, and the abort runs; a restart between the committed expiry and the cut → the same); `SetSelfServeExpiry` returning false → the worker re-reads the row and decides again`, `RequestSelfServeAbort(id string, phases []string, now time.Time) (bool, error)` (`WHERE phase IN (...) AND abort_requested_at = 0`), `SetSelfServeReopened`, `SetSelfServeAbortFinished`, `FinishSelfServeMove(id, outcome, reason, warning string, now time.Time) error` (`release_pending = 1`, `effects_done = 0`), `SetSelfServeEffectsDone(id string) error`, `ClearSelfServeRelease(id string) error`, `SetSelfServeOpenRecordPending(id string, pending bool) error`.
+- Other store methods: `AdmitSelfServeMove(m SelfServeMove) (admitted bool, open *SelfServeMove, err error)`; `SelfServeMove(id string) (*SelfServeMove, error)`; `SelfServeMoveForHost(acct, app, host string) (open, terminal *SelfServeMove, err error)` (the open row, and the newest terminal row); `OpenSelfServeMoves() ([]SelfServeMove, error)` (`outcome = '' OR release_pending = 1 OR effects_done = 0 OR open_record_pending = 1`, **ordered by `created_at, id`**: the pass steps rows in that order; **per-box FIFO**: a row in `reserving` may reserve only when no older open row (by `created_at, id`) that shares any participant `BoxID` is still in `requested` or `reserving`; otherwise it waits with `reason` "waiting for an earlier move on this box"; rows with disjoint participants never wait on each other); `MarkSelfServeCut(id string, now time.Time, copyDeadline time.Time) (bool, error)` (`WHERE phase = 'ready' AND abort_requested_at = 0 AND cut_requested_at = 0 AND expiry_pending = 0 AND request_expired = 0`: a confirmation expiry already committed wins, and the cut door re-reads and answers 409 "the move expired. prepare again"; sets `cut_requested_at = now`, **`window_deadline = 0`** (the confirmation deadline is retired by the cut that won), `step_deadline = copyDeadline` (the cut's copy wait) **and, when an unconsumed `maintain` request is outstanding, `request_deadline = copyDeadline`** (the adopted round gets the cut's allowance whether or not its write has committed yet) in the same UPDATE; the cut door's only write); the `ready` expiry rule applies only while `cut_requested_at = 0`; `SetSelfServeEstimate`, `RecordSelfServeHealth(id string, probeAt time.Time, ok bool, errText string) error` (`health_attempts + 1`; `consecutive_ok = CASE ok THEN consecutive_ok + 1 ELSE 0`; `first_ok_at` kept once set), `SetSelfServeFinishGate`, `SetSelfServeWarning`, `SetSelfServeNotifiedSeq(id string, seq uint64) error`, `SetSelfServeExpiry(id, phase string, kind string, sawDeadline time.Time, pending bool) (bool, error)` (`kind` is `window` or `step`; the UPDATE also records `expiry_kind = kind, expiry_deadline = sawDeadline`, and the expiry **action** later re-reads the row and runs only when `expiry_pending`, `expiry_phase`, `expiry_kind` and `expiry_deadline` still match what it is acting on (an expiry whose identity changed is dropped); the UPDATE's predicate is `phase = ? AND (window_deadline = ? for window, step_deadline = ? for step) AND (kind <> 'window' OR cut_requested_at = 0)`, so a worker whose snapshot predates a successful cut cannot record the obsolete confirmation expiry (`TestStaleExpiryLosesToTheCut`: a worker paused across the cut at T-1 resumes at T+1 and its `window` expiry is refused; the copy's `step` expiry after the cut is accepted; **expiry first**: the window expiry commits at T+ε, then the cut door → 409 expired, and the abort runs; a restart between the committed expiry and the cut → the same); `SetSelfServeExpiry` returning false → the worker re-reads the row and decides again`, `RequestSelfServeAbort(id string, phases []string, now time.Time) (bool, error)` (`WHERE phase IN (...) AND abort_requested_at = 0`), `SetSelfServeReopened`, `SetSelfServeAbortFinished`, `FinishSelfServeMove(id, outcome, reason, warning string, now time.Time) error` (`release_pending = 1`, `effects_done = 0`), `SetSelfServeEffectsDone(id string) error`, `ClearSelfServeRelease(id string) error`, `SetSelfServeOpenRecordPending(id string, pending bool) error`.
- Table `self_serve_events (id TEXT, seq INTEGER, phase TEXT, account TEXT, app TEXT, host TEXT, at INTEGER, reason TEXT, detail TEXT, emitted INTEGER, PRIMARY KEY (id, seq))`: `InsertSelfServeEventTx(tx *sql.Tx, e SelfServeEvent) error` (allocates `seq` from the row's `event_seq` in the same transaction; used by `AdvanceSelfServe` and by every refusal, fact decision, lane probe, health probe and timing); `UnemittedSelfServeEvents(limit int) ([]SelfServeEvent, error)`; `DeliverSelfServeEvent(ctx context.Context, e SelfServeEvent, deliver func(tx *sql.Tx) error) error` (one transaction: first `UPDATE self_serve_events SET emitted = 1 WHERE id = ? AND seq = ? AND emitted = 0`; zero rows → commit nothing and return (another worker delivered it); else `deliver(tx)` inserts the audit row through `auditActivityTx(tx, ...)`; a failure rolls both back). The terminal event is inserted by `FinishSelfServeMove` in the transaction that sets the outcome, so a crash between finalisation steps never allocates a second terminal event. Table `self_serve_timings (id TEXT, mark TEXT, account TEXT, app TEXT, host TEXT, at INTEGER, bytes INTEGER, PRIMARY KEY (id, mark))`.
- Phases: `requested`, `reserving`, `queued`, `reports`, `staging`, `prechecks`, `ready`, `restage`, `barrier`, `stopping`, `sealing`, `landing`, `landed`, `open-uncertain`, `opened`, `health`, `finishing`, `reverting`, `done`.
- **Compatible sets** (Task 7's reconciliation; "pending" = the row has **no confirmed request** for that phase's write, whether none was issued yet, or one is issued and unconfirmed): `offline-queued` ↔ {queued, reports, staging(pending)}; `offline-staging` ↔ {staging, prechecks, ready, restage, barrier, stopping(pending)}; `offline-stopping` ↔ {stopping, sealing(pending)}; `offline-sealing` ↔ {sealing}; `offline-sealed` ↔ {sealing, landing(pending)}; `offline-landing` ↔ {landing}; `offline-landed` ↔ {landed, open-uncertain, opened(pending)}; `offline-open` ↔ {opened, health, finishing}; `offline-finishing` ↔ {finishing}; `offline-reverting` ↔ {reverting}; cleared with `LastMove.ID == id` ↔ {done, finishing(gate-2 pending), reverting(finish pending)}; no move and no `LastMove` for the id ↔ {requested, reserving, queued(pending)}. Reconciliation moves the row **forward** to the first phase of the record's set only when the row's phase is not in that set, **entering the first substep whose transition the record has not yet made**: `offline-stopping` → `stopping/seal` (the start is done; the stopped reports are awaited, then seal); `offline-sealing` → `sealing`; `offline-sealed` → `landing/flip`; `offline-landing` → `landing/wait`; `offline-landed` → `landed/open`; `offline-open` → `opened` when the row was before it, else untouched; `offline-finishing` → `finishing/gate2` (gate 1 is done; the sources' `gone` is awaited); `offline-reverting` → `reverting/finish` (the abort is done; the reopen facts are awaited); and **within an already-compatible phase** the same mapping advances the substep when the record shows the operator made the substep's transition (`stopping/start` with `offline-stopping` → `seal`; `finishing/gate1` with `offline-finishing` → `gate2`), abandoning the superseded request first; a job request that was written for the transition the operator made is confirmed by its receipt as usual and the mapping simply agrees (`TestOperatorProgressEntersTheRightSubstep`: an operator start while the row is pre-cut → the job awaits stopped reports then seals, never re-issues start; an operator gate 1 during `health` → the job enters `gate2`).
@@ -126,7 +126,7 @@ Builds on plan 1 (`2026-10-22-self-serve-moves-1-lifetimes-and-order.md`, rev 13
- `func recordEligibility(rec *provision.Record, c moveCopy) *offlineRefusal`: `moveGate`'s checks in order (`Kind`, `Addr`/`Addrs`, fleet placement, `Pool`, `!HibernateOrDefault()`; 400s).
- `func (s *Server) offlineRecordChecks(ctx, acct, app, host string, rec *provision.Record) *offlineRefusal` (the pre-body half: the seed block, `Role`, `Replicas`, `Steering`/`Unit`, `offlineClaimEvidence`); `func (s *Server) offlineRegionChecks(ctx, acct, app, host string, rec *provision.Record, region string, stage, requireIDs bool, returnOf string) (offlineSelection, *offlineRefusal)` (the post-body half: the region, the manifest, the fleet, the home rule, `offlineSelect`, the stage rules, participant pinning, the return's evidence); `type offlineSelection struct { From, To string; Fleet offlineFleet; Source []provision.Participant; Target provision.Participant; Stage provision.StageTarget; ReturnOf string; Sentinel bool }` (`Sentinel` when any participant's `InstanceID` is empty).
- **Participant pinning.** `BoxID` and `Label` from the edges file. With `requireIDs: false` (**every operator door**): `InstanceID` from `status/boxes/<label>.json` when the report exists, is within 10 minutes and carries `Metrics.BoxID == BoxID`; otherwise `InstanceID = ""`, `Verified = false`, and the move proceeds as today (`offlineSelect` already admits a box with nil metrics); no identity record is read. With `requireIDs: true` (**the self-serve door and the job**): the status report must be present and fresh with a non-empty `InstanceID` (else "the box <label> has not reported recently"); `Verified` when `boxid.Load(ctx, s, BoxID)` (the record key is `boxid.Key(BoxID)`, never the label) finds a record and the verifier (constructed as `ClaimRootHTTP` constructs it) `Enroll`s it with `boxid.Expect{Box: BoxID, AWSRegion: the manifest's AWS region for the box's region, TofuInstanceID: the region's tofu output when the box predates region HA as the claims path supplies it, Roster: the current roster}` (the deployment account is the verifier's own field) to evidence naming that `InstanceID`; `boxid.Load` returning `os.ErrNotExist` → the unverified fallback; any other error → refuse "could not read the identity record for box <label>"; `Verified` means exactly what `Enroll` proves (a signed document of this deployment naming the instance, consistent with the roster); it does not claim reference ownership beyond the roster rule, and the plan relies on it only to detect a replaced machine; a record that exists but does not verify → refuse "box <label> has an identity record that does not verify"; no record → pinned with `Verified: false` (allowed; the status report's `InstanceID` is the identity).
-- **The self-serve bodies.** `POST .../move {"region", "display_name"?, "requested_by"?, "start_at"?}`: `selfServeGate`; `s.selfServeAdmits()` else 409 "self-serve moves are not enabled on this console"; `obs := s.observeRecord(...)` (absent or stale → 404; corrupt or unreadable → 502 "could not read the instance"); `recordEligibility`; `rec.ActiveRun.Open()` → the existing run 409; `rec.Move != nil` → 409 `offlineConflict`'s sentence; an open row → the same 409; the body; `start_at` → 400 "scheduled starts are not available yet"; `display_name` over 80 runes or with a control character → 400 "display_name must be at most 80 characters of plain text"; `offlineRecordChecks`; `offlineRegionChecks(..., stage: true, requireIDs: true, "")`; one source box → else 409 "<region> has <n> boxes. a self-serve move needs exactly one box in each region"; the source's status facts (Task 6: `Hosts[host]` with `Incarnation == rec.Incarnation`, `Known`, `CollectedAt` and `ReplicaCollectedAt` within 10 minutes and not more than 60 s in the future, else 409 "the source box has not reported recently. try again in a minute"; `OverCap` → 409 "this account's files are too large to move this way"; `Truncated` → 409 "could not measure the account's files. try again in a minute"); the lane (`Lanes` names the target bucket) → else 409 "no staging lane is configured from <from> to <to>"; the lifetime: `rec.Incarnation == 0` → `withHostname`: `migrateHostLifetimeLocked(ctx, acct.Sqid, app, host, obs.ETag)` (**bound**); `ErrCASConflict` or settling → 409 "another change to this instance is still settling. try again in a minute"; committed → `rec` is the returned record and `recordEligibility`, the run and move checks run again on it; `AdmitSelfServeMove({..., Incarnation: rec.Incarnation, Participants, Phase: requested, RequestedBy: "token:" + p.TokenID + " " + requested_by, DisplayName, EstimateSeconds, EstimateTerms, WindowDeadline: now + 24 h})`; not admitted → 409 the in-flight sentence; `bumpSerial`; 202 with the view. `GET .../move?estimate=1&region=uk`: `moveGate`; the list through the lane without writing or migrating; 200 `{"estimate_seconds", "files_bytes", "replica_bytes"}` or the refusal. `POST .../move/cut {"id"}`: `selfServeGate`; the row; `row.ID != body.id` or none → 409 "this is not the move you confirmed"; `MarkSelfServeCut(id, now)` → 202 (the **handoff**: the job's `ready` phase performs the transition, Task 7); false → re-read: `cut_requested_at` set or a cut phase → 202; abort requested or `aborted` → 409 "the move was cancelled"; else 409 "the move is not ready to cut yet. it is <phase>". The view shows `cutting` from `cut_requested_at` on. `DELETE .../move {"id"}`: `selfServeGate`; the row and id; `RequestSelfServeAbort(id, [requested, reserving, queued, reports, staging, prechecks, ready], now)` (its predicate also requires `cut_requested_at = 0`) → 202; false → re-read: abort already requested → 202; a cut phase → 409 "the move was confirmed and cannot be cancelled. it completes or returns on its own"; terminal → 409 "no move is in flight".
+- **The self-serve bodies.** `POST .../move {"region", "display_name"?, "requested_by"?, "start_at"?}`: `selfServeGate`; `s.selfServeAdmits()` else 409 "self-serve moves are not enabled on this console"; `obs := s.observeRecord(...)` (absent or stale → 404; corrupt or unreadable → 502 "could not read the instance"); `recordEligibility`; `rec.ActiveRun.Open()` → the existing run 409; `rec.Move != nil` → 409 `offlineConflict`'s sentence; an open row → the same 409; the body; `start_at` → 400 "scheduled starts are not available yet"; `display_name` over 80 runes or with a control character → 400 "display_name must be at most 80 characters of plain text"; `offlineRecordChecks`; `offlineRegionChecks(..., stage: true, requireIDs: true, "")`; one source box → else 409 "<region> has <n> boxes. a self-serve move needs exactly one box in each region"; the source's status facts (Task 6: `Hosts[host]` with `Incarnation == rec.Incarnation`, `Known`, `CollectedAt` and `ReplicaCollectedAt` within 10 minutes and not more than 60 s in the future, else 409 "the source box has not reported recently. try again in a minute"; `OverCap` → 409 "this account's files are too large to move this way"; `Truncated` → 409 "could not measure the account's files. try again in a minute"); the lane (`Lanes` names the target bucket) → else 409 "no staging lane is configured from <from> to <to>"; the lifetime: `rec.Incarnation == 0` → `withHostname`: `migrateHostLifetimeLocked(ctx, acct.Sqid, app, host, obs.ETag)` (**bound**); `ErrCASConflict` or settling → 409 "another change to this instance is still settling. try again in a minute"; committed → `rec` is the returned record and `recordEligibility`, the run and move checks run again on it; `AdmitSelfServeMove({..., Incarnation: rec.Incarnation, Participants, Phase: requested, RequestedBy: "token:" + p.TokenID + " " + requested_by, DisplayName, EstimateSeconds, EstimateTerms, WindowDeadline: now + 24 h})`; not admitted → 409 the in-flight sentence; `bumpSerial`; 202 with the view. `GET .../move?estimate=1&region=uk`: `moveGate`; the list through the lane without writing or migrating; 200 `{"estimate_seconds", "files_bytes", "replica_bytes"}` or the refusal. `POST .../move/cut {"id"}`: `selfServeGate`; the row; `row.ID != body.id` or none → 409 "this is not the move you confirmed"; `MarkSelfServeCut(id, now, now + max(5 min, 2 × est.Copy))` → 202 (the **handoff**: the job's `ready` phase performs the transition, Task 7); false → re-read: `cut_requested_at` set or a cut phase → 202; abort requested or `aborted` → 409 "the move was cancelled"; else 409 "the move is not ready to cut yet. it is <phase>". The view shows `cutting` from `cut_requested_at` on. `DELETE .../move {"id"}`: `selfServeGate`; the row and id; `RequestSelfServeAbort(id, [requested, reserving, queued, reports, staging, prechecks, ready], now)` (its predicate also requires `cut_requested_at = 0`) → 202; false → re-read: abort already requested → 202; a cut phase → 409 "the move was confirmed and cannot be cancelled. it completes or returns on its own"; terminal → 409 "no move is in flight".
- **The view** (`selfServeViewOf(rec, open, terminal, now)`, rendered whenever claims-off and Phase 1 off): (1) the record carries an offline move with `SelfServe != nil` **and** `open != nil && open.ID == rec.Move.ID && open.ID == rec.Move.SelfServe.ID && open.Incarnation == rec.Incarnation` → the open row's view (`preparing` through `ready`, `cutting` from `restage`); (2) the record carries any other move → today's legacy view, no `last`; (3) no record move and an open row with `open.Incarnation == rec.Incarnation` → `preparing`; (4) no record move and a terminal row with `terminal.Incarnation == rec.Incarnation` and `now - UpdatedAt < 7 days` → `none` with `last`; (5) otherwise today's view. `type selfServeMoveView struct { State string \`json:"state"\`; Target string \`json:"target,omitempty"\`; UpdatedAt int64 \`json:"updated_at,omitempty"\`; Kind string \`json:"kind"\`; ID string \`json:"id,omitempty"\`; EstimateSeconds int \`json:"estimate_seconds,omitempty"\`; OfflineAt int64 \`json:"offline_at,omitempty"\`; Reason string \`json:"reason,omitempty"\`; Abort *selfServeAbortView \`json:"abort,omitempty"\`; Last *selfServeLast \`json:"last,omitempty"\` }`; `type selfServeAbortView struct { RequestedAt int64 \`json:"requested_at"\`; SourceReopenedAt int64 \`json:"source_reopened_at,omitempty"\`; FinishedAt int64 \`json:"finished_at,omitempty"\` }`; `type selfServeLast struct { ID string \`json:"id"\`; Outcome string \`json:"outcome"\`; Reason string \`json:"reason,omitempty"\`; Warning string \`json:"warning,omitempty"\`; From string \`json:"from"\`; To string \`json:"to"\`; At int64 \`json:"at"\` }` (unix seconds; regions through `homeRegionOut`). Phase 1's `moveView` is untouched.
- Copy rows: "only an account owner can mint a move-capable instance token"; "self-serve moves are not enabled on this console"; "could not read the instance"; "could not read the move"; "scheduled starts are not available yet"; "display_name must be at most 80 characters of plain text"; "<region> has <n> boxes. a self-serve move needs exactly one box in each region"; "the source box has not reported recently. try again in a minute"; "the box <label> has not reported recently"; "box <label> has an identity record that does not verify"; "this account's files are too large to move this way"; "could not measure the account's files. try again in a minute"; "no staging lane is configured from <from> to <to>"; "another change to this instance is still settling. try again in a minute"; "this is not the move you confirmed"; "the move was cancelled"; "the move is not ready to cut yet. it is <phase>"; "the move was confirmed and cannot be cancelled. it completes or returns on its own"; "no move is in flight"; "the reservation does not match this move's participants".
@@ -161,9 +161,9 @@ Builds on plan 1 (`2026-10-22-self-serve-moves-1-lifetimes-and-order.md`, rev 13
- Test: `internal/e2e/selfserve/job_test.go`
**Interfaces:**
-- `type persistedRequest struct { Kind, Phase, Nonce string; ExpectInc, ExpectSeq uint64; Proposed time.Time; Confirmed, Consumed, Voided bool }`; `func (s *Server) selfServeApply(ctx context.Context, t *leaseToken, row *SelfServeMove, req request, proposed *time.Time, mut func(at time.Time, rc provision.Receipt) func(*provision.Record) error) (*provision.Record, error)` with `type request struct { Kind, Phase string }`: (1) the judged record → `pr.ExpectInc = rec.Incarnation`, `pr.ExpectSeq = rec.RecordSeq`; `pr.Proposed = *proposed` when given (the open intent) else `max(now, latest stamp on the record + 1 ns)`; `pr.Nonce = random`; `IssueSelfServeRequest(id, kind, phase, pr, now)`: not issued and `existing == nil` → `errRequestRefused` (the row left the phase or ended; the step ends); `existing.Kind != req.Kind || existing.Phase != req.Phase` → return `errRequestForeign` (this caller never interprets another request; the step ends and reconciliation decides next tick); `existing.Confirmed && !existing.Consumed` → **resume**: return the record (the caller continues its wait and the notification catch-up); otherwise `pr = *existing` and go to (3); (2) **first, when `pr.Deadline != 0`, `now < pr.Deadline`**, else return `errRequestExpired` without writing (the step's fence-and-classify path takes over); a request with `Deadline == 0` is never expired by this check (`TestLateEvidenceStillClearsTheMove`: a source's `gone` report arriving after `finishing`'s deadline → the finish is written and the reservations release; the same for `reverting`'s facts and for an already-issued uncommitted finish recovering after the deadline); then `provision.SetRecordMoveAt(ctx', s, acct, app, host, provision.Expect{Incarnation: pr.ExpectInc, Seq: pr.ExpectSeq}, mut(pr.Proposed, Receipt{pr.Nonce}))` with the lease-bounded context and the write guard: **one CAS attempt against the record at that incarnation and sequence; no fresh-read retry inside**; (3) **confirmation** from a fresh judged read, whatever (2) returned: `rec` carries the receipt (`SelfServe.LastRequest == pr.Nonce`, or `LastMove.Request == pr.Nonce` for a clearing write) → `ConfirmSelfServeRequest(id, nonce, now)` (**the receipt alone confirms**; a box that has already advanced the record past the written state (seal → sealed, flip → landed) does not change that; the `confirmed` callback is dropped and phase progress is reconciliation's business) (false → re-read: already confirmed → resume; voided → stop); else `rec.Incarnation == pr.ExpectInc && rec.RecordSeq == pr.ExpectSeq` (unchanged) → the write did not land: repeat (2), **which re-checks the deadline first** (idempotent replay of the same bound write; bounded by the lease and the deadline; `TestReplayStopsAtTheDeadlineInsideOneInvocation`: an open request whose PUT fails at T-1 s and whose confirmation read returns at T+1 s is not replayed; the step fences and classifies; the same with the PUT having committed → confirmed); else (the record advanced without the receipt: another writer, an operator) → `VoidSelfServeRequest(id, nonce)` and return `errRequestVoided`; the bound write makes this safe: a PUT transmitted against `ExpectSeq` cannot commit on a record that has moved past it; after a confirmed write: `bumpSerialErr` and, on success, `SetSelfServeNotifiedSeq(id, rec.RecordSeq)`; a failed bump leaves `notified_seq` behind and every later tick bumps again while `rec.RecordSeq != notified_seq`. A crash anywhere resumes at (3) on the next tick from the persisted request.
+- `type persistedRequest struct { Kind, Phase, Nonce string; ExpectInc, ExpectSeq uint64; Proposed, Deadline time.Time; Confirmed, Consumed, Voided, Expired bool }`; `func (s *Server) selfServeApply(ctx context.Context, t *leaseToken, row *SelfServeMove, req request, proposed *time.Time, mut func(at time.Time, rc provision.Receipt) func(*provision.Record) error) (*provision.Record, error)` with `type request struct { Kind, Phase string }`: (1) the judged record → `pr.ExpectInc = rec.Incarnation`, `pr.ExpectSeq = rec.RecordSeq`; `pr.Proposed = *proposed` when given (the open intent) else `max(now, latest stamp on the record + 1 ns)`; `pr.Nonce = random`; `IssueSelfServeRequest(id, kind, phase, pr, now)`: not issued and `existing == nil` → `errRequestRefused` (the row left the phase or ended; the step ends); `existing.Kind != req.Kind || existing.Phase != req.Phase` → return `errRequestForeign` (this caller never interprets another request; the step ends and reconciliation decides next tick); `existing.Confirmed && !existing.Consumed` → **resume**: return the record (the caller continues its wait and the notification catch-up); otherwise `pr = *existing` and go to (3); (2) **first, when `pr.Deadline != 0` and `now >= pr.Deadline`**, the expiry is **decided durably**: `ExpireSelfServeRequest(id, pr.Nonce, pr.Deadline)` (`UPDATE ... SET request_expired = 1 WHERE request_nonce = ? AND request_deadline = ? AND request_consumed = 0 AND request_expired = 0 AND cut_requested_at = 0`); true → return `errRequestExpired` without writing (the step's fence-and-classify path takes over, and only this winner may fence, void and abort); false → the row changed under this worker (a cut extended the deadline, or the request was consumed): **reload the request** and go back to (2) with the fresh `pr` (`TestStaleRequestDeadlineLosesToTheCut`: a worker paused in its confirmation read across a cut that extends the deadline → its expiry UPDATE matches nothing, it reloads and continues under the new allowance; expiry first → the cut door is refused; crashes after the decision and around the fence in both orders); otherwise a request with `Deadline == 0` is never expired by this check (`TestLateEvidenceStillClearsTheMove`: a source's `gone` report arriving after `finishing`'s deadline → the finish is written and the reservations release; the same for `reverting`'s facts and for an already-issued uncommitted finish recovering after the deadline); then `provision.SetRecordMoveAt(ctx', s, acct, app, host, provision.Expect{Incarnation: pr.ExpectInc, Seq: pr.ExpectSeq}, mut(pr.Proposed, Receipt{pr.Nonce}))` with the lease-bounded context and the write guard: **one CAS attempt against the record at that incarnation and sequence; no fresh-read retry inside**; (3) **confirmation** from a fresh judged read, whatever (2) returned: `rec` carries the receipt (`SelfServe.LastRequest == pr.Nonce`, or `LastMove.Request == pr.Nonce` for a clearing write) → `ConfirmSelfServeRequest(id, nonce, now)` (**the receipt alone confirms**; a box that has already advanced the record past the written state (seal → sealed, flip → landed) does not change that; the `confirmed` callback is dropped and phase progress is reconciliation's business) (false → re-read: already confirmed → resume; voided → stop); else `rec.Incarnation == pr.ExpectInc && rec.RecordSeq == pr.ExpectSeq` (unchanged) → the write did not land: repeat (2), **which re-checks the deadline first** (idempotent replay of the same bound write; bounded by the lease and the deadline; `TestReplayStopsAtTheDeadlineInsideOneInvocation`: an open request whose PUT fails at T-1 s and whose confirmation read returns at T+1 s is not replayed; the step fences and classifies; the same with the PUT having committed → confirmed); else (the record advanced without the receipt: another writer, an operator) → `VoidSelfServeRequest(id, nonce)` and return `errRequestVoided`; the bound write makes this safe: a PUT transmitted against `ExpectSeq` cannot commit on a record that has moved past it; after a confirmed write: `bumpSerialErr` and, on success, `SetSelfServeNotifiedSeq(id, rec.RecordSeq)`; a failed bump leaves `notified_seq` behind and every later tick bumps again while `rec.RecordSeq != notified_seq`. A crash anywhere resumes at (3) on the next tick from the persisted request.
- `type provision.Expect struct { Incarnation, Seq uint64 }`; `provision.SetRecordMoveAt(ctx, s, acct, app, host string, expect Expect, mut) (*provision.Record, error)`: reads the judged record; `rec.Incarnation != expect.Incarnation || rec.RecordSeq != expect.Seq` → `ErrCASConflict` without writing; otherwise one `WriteRecord` against the observed ETag; a CAS conflict → `ErrCASConflict` (no retry). `SetRecordMove` (today's, with its retry) is no longer used by any self-serve or operator move writer.
-- `selfServeStep`: (1) the row's deadlines: an expired `StepDeadline`, or an expired `WindowDeadline` while `cut_requested_at = 0`, → `SetSelfServeExpiry(id, phase, true)` (no action yet); (2) the judged record; (3) **reconcile forward** by the compatible sets (Task 4): an unconfirmed request → step (3) of `selfServeApply` first, **except** when the request's own `request_deadline` has passed (whatever the row's current phase: `landed`, `open-uncertain` or any other) and the record is at or before `offline-landed`: then the record is observed once; the receipt present → confirmed (the write won before the expiry, the expiry is post-write); absent → `fenceRecord` (plan 1; so the outstanding bound PUT can never land) and **the fenced observation is classified**: the receipt present in it → the write won during the fence: confirm and proceed forward (an open that committed is reconciled as opened, never aborted); absent → `VoidSelfServeRequest` and the expiry action runs (abort), **never a replay** (`TestExpiredOpenIsNeverReplayed`); then the row's phase not in the record's set → `AdvanceSelfServe` to the set's first phase (without the abort predicate for `opened`), which clears a foreign expiry; (4) the expiry action for an `expiry_pending` whose `expiry_phase == phase`: the record at or before `offline-landed` → abort; committed open → the blocked action (page); unreadable → `open-uncertain`; `health` → warning, page, `finishing`; (5) the abort step when requested and the record at or before `offline-landed`; (6) the phase function. Every wait for a report is for `Request`/`StagedRequest == request_proposed` of the **confirmed** request; **supersession by stamp**: each tick the waiting phase also reads the record's stamp for the awaited field (`StagedAt` for `stage`/`maintain`, `PrecheckAt` for `precheck`); when it is **later** than `request_proposed` while the receipt is unchanged, an operator round has superseded the job's (`OfflineRestage`/`OfflinePrecheck` from the operator doors move the stamp without a receipt), so the job `AbandonSelfServeRequest`s its request and, on the next step, issues a fresh bound round (the abandon is one UPDATE; a crash after it finds no outstanding request and issues; a crash before it repeats the comparison); the job never adopts an operator round as its own (`TestOperatorRoundSupersedesTheJobsWait`: a confirmed restage at S1, an operator stage to S2, the stager reports S2 only → the job abandons S1 and issues S3, the cut proceeds; the same in `staging/round` and `ready/round`; a crash between the abandon and the issue); the report is consumed by the `AdvanceSelfServe` that leaves the waiting phase, with the nonce, **or**, inside a phase that writes more than once (`stopping`: start then seal; `finishing`: gate 1 then gate 2; `staging`: round after round; `prechecks`: the precheck then the estimate; `ready`: each maintenance round), by `ConsumeSelfServeRequest(id, nonce)` once its wait is satisfied, immediately before the next request is issued, and **the phase function dispatches on `phase_step`**: `stopping` = `start` → `seal`; `finishing` = `gate1` → `gate2`; `prechecks` = `precheck` → `estimate`; `reverting` = `abort` → `finish`; `staging` and `ready` = `round` (repeated); a phase entered by `AdvanceSelfServe` from the **job's own** progression starts at its first substep (`phase_step` set by the advance); a phase entered by **reconciliation** starts at the substep the record dictates (below); a restart resumes the substep recorded, never the phase's first write (`TestSubstepsResumeAfterEveryCrash`: a crash after consuming start and before issuing seal re-enters at `seal`; a crash with the estimate request outstanding re-enters at `estimate` and resumes it; the same for gate 1 → gate 2 and abort → finish). **Abandonment** is for **leaving a wait**, never for retaining it: when abort is requested, when an expiry whose action is **abort** fires, or when an operator transition supersedes the phase, a confirmed request whose wait is unsatisfied is `AbandonSelfServeRequest`ed before the abort or the reconciliation step issues its own request; an expiry whose action is page-and-retain (`opened`, `finishing`, `reverting`, `open-uncertain`) or warn-and-finish (`health`) abandons nothing and the wait continues (`TestPageOnlyExpiriesKeepTheWait`: the open request confirmed, `opened` missing at the deadline, the page sent, then the target reports opened and the nonce-bearing advance succeeds). By phase: `requested`/`reserving` resolve or fence an issued queue request before finalising or releasing; `queued`/`reports` abandon a superseded wait, a queued abort clears and finalises atomically; `staging`/`prechecks`/`ready` may abandon on cancel or aborting expiry; `restage`/`barrier`/`stopping`/`sealing`/`landing`/pre-open `landed` may abandon on aborting expiry after resolving the uncertain write; `open-uncertain` abandons nothing; a confirmed clearing write is consumed with the terminal outcome (`TestAbandonedRequestsNeverStrandAbort`: a confirmed stage request whose copy never reports, then cancel → the abort request issues; a confirmed precheck whose box died, then the deadline → abort issues). **Clearing requests**: `OfflineFinish`, `OfflineAbortAt` and the abort path's finish are confirmed from `LastMove.Request`; the finaliser's `FinishSelfServeMove` consumes that confirmed request in the same transaction as the outcome, so a crash between confirmation and finalisation resumes at the finaliser, not at a re-issue.
+- `selfServeStep`: (1) the row's deadlines: an expired `StepDeadline`, or an expired `WindowDeadline` while `cut_requested_at = 0`, → `SetSelfServeExpiry(id, phase, kind, sawDeadline, true)` (`kind` `window` or `step` by which deadline passed, `sawDeadline` the value the worker read) (no action yet); (2) the judged record; (3) **reconcile forward** by the compatible sets (Task 4): an unconfirmed request → step (3) of `selfServeApply` first, **except** when the request's own `request_deadline` has passed (whatever the row's current phase: `landed`, `open-uncertain` or any other) and the record is at or before `offline-landed`: then the record is observed once; the receipt present → confirmed (the write won before the expiry, the expiry is post-write); absent → `fenceRecord` (plan 1; so the outstanding bound PUT can never land) and **the fenced observation is classified**: the receipt present in it → the write won during the fence: confirm and proceed forward (an open that committed is reconciled as opened, never aborted); absent → `VoidSelfServeRequest` and the expiry action runs (abort), **never a replay** (`TestExpiredOpenIsNeverReplayed`); then the row's phase not in the record's set → `AdvanceSelfServe` to the set's first phase (without the abort predicate for `opened`), which clears a foreign expiry; (4) the expiry action for an `expiry_pending` whose `expiry_phase == phase`: the record at or before `offline-landed` → abort; committed open → the blocked action (page); unreadable → `open-uncertain`; `health` → warning, page, `finishing`; (5) the abort step when requested and the record at or before `offline-landed`; (6) the phase function. Every wait for a report is for `Request`/`StagedRequest == request_proposed` of the **confirmed** request; **supersession by stamp**: each tick the waiting phase also reads the record's stamp for the awaited field (`StagedAt` for `stage`/`maintain`, `PrecheckAt` for `precheck`); when it is **later** than `request_proposed` while the receipt is unchanged, an operator round has superseded the job's (`OfflineRestage`/`OfflinePrecheck` from the operator doors move the stamp without a receipt), so the job `AbandonSelfServeRequest`s its request and, on the next step, issues a fresh bound round (the abandon is one UPDATE; a crash after it finds no outstanding request and issues; a crash before it repeats the comparison); the job never adopts an operator round as its own (`TestOperatorRoundSupersedesTheJobsWait`: a confirmed restage at S1, an operator stage to S2, the stager reports S2 only → the job abandons S1 and issues S3, the cut proceeds; the same in `staging/round` and `ready/round`; a crash between the abandon and the issue); the report is consumed by the `AdvanceSelfServe` that leaves the waiting phase, with the nonce, **or**, inside a phase that writes more than once (`stopping`: start then seal; `finishing`: gate 1 then gate 2; `staging`: round after round; `prechecks`: the precheck then the estimate; `ready`: each maintenance round), by `ConsumeSelfServeRequest(id, nonce)` once its wait is satisfied, immediately before the next request is issued, and **the phase function dispatches on `phase_step`**: `stopping` = `start` → `seal`; `finishing` = `gate1` → `gate2`; `prechecks` = `precheck` → `estimate`; `reverting` = `abort` → `finish`; `staging` and `ready` = `round` (repeated); a phase entered by `AdvanceSelfServe` from the **job's own** progression starts at its first substep (`phase_step` set by the advance); a phase entered by **reconciliation** starts at the substep the record dictates (below); a restart resumes the substep recorded, never the phase's first write (`TestSubstepsResumeAfterEveryCrash`: a crash after consuming start and before issuing seal re-enters at `seal`; a crash with the estimate request outstanding re-enters at `estimate` and resumes it; the same for gate 1 → gate 2 and abort → finish). **Abandonment** is for **leaving a wait**, never for retaining it: when abort is requested, when an expiry whose action is **abort** fires, or when an operator transition supersedes the phase, a confirmed request whose wait is unsatisfied is `AbandonSelfServeRequest`ed before the abort or the reconciliation step issues its own request; an expiry whose action is page-and-retain (`opened`, `finishing`, `reverting`, `open-uncertain`) or warn-and-finish (`health`) abandons nothing and the wait continues (`TestPageOnlyExpiriesKeepTheWait`: the open request confirmed, `opened` missing at the deadline, the page sent, then the target reports opened and the nonce-bearing advance succeeds). By phase: `requested`/`reserving` resolve or fence an issued queue request before finalising or releasing; `queued`/`reports` abandon a superseded wait, a queued abort clears and finalises atomically; `staging`/`prechecks`/`ready` may abandon on cancel or aborting expiry; `restage`/`barrier`/`stopping`/`sealing`/`landing`/pre-open `landed` may abandon on aborting expiry after resolving the uncertain write; `open-uncertain` abandons nothing; a confirmed clearing write is consumed with the terminal outcome (`TestAbandonedRequestsNeverStrandAbort`: a confirmed stage request whose copy never reports, then cancel → the abort request issues; a confirmed precheck whose box died, then the deadline → abort issues). **Clearing requests**: `OfflineFinish`, `OfflineAbortAt` and the abort path's finish are confirmed from `LastMove.Request`; the finaliser's `FinishSelfServeMove` consumes that confirmed request in the same transaction as the outcome, so a crash between confirmation and finalisation resumes at the finaliser, not at a re-issue.
- **Reconciliation and recovery table** (the record is the truth):
| row phase | record | action |
@@ -241,5 +241,5 @@ Builds on plan 1 (`2026-10-22-self-serve-moves-1-lifetimes-and-order.md`, rev 13
- Spec coverage: §5 (T1), §6.1 (T5), §6.2 (T7), §6.3 (T9, T5, T6), §7 admission and recovery (T7's table), §7.1 (T3), §7.2 and the three facts with the sealer's durable lift (T6, T8), §7.3 (T6, T7, T8's barrier), §7.4 without the probe mode (T8), §7.5 the no-return boundary and the operator return (T2's open record, T8), §7.7 (T5), §8 pages, log and member stream (T8, T9), §9 (T3's rollout). Deferred: §6.4 holding page and the probe headers (plan 3); §7.6 cleanup (plan 4), whose status contract the reclaim rule names (`RetirementsComplete`, a terminal state, `RootRequest == ""`, `ReleasePending == false`, `Metrics.BoxID`).
- Dependencies for plan 3: `SelfServeMove{DisplayName, OfflineAt, EstimateSeconds}`, `Participants.Target.BoxID`, `moveCfg.BoxID`, `probeTarget`; for plan 4: the status `Retirements` contract and the open record.
-- Names used across tasks: `selfServeGate`, `instanceRails(w, r, acct, noun, c)`, `moveCapable`, `Principal.Moves/TokenID`, `selfServeMode`, `selfServeAdmits`, `recordEligibility`, `offlineRecordChecks`, `offlineRegionChecks`, `offlineSelection`, `OfflineQueued`, `OfflineQueue`, `OfflineQueuedToStaging`, `OfflinePrecheck`, `OfflineSetEstimate`, `OfflineAbortAt`, `provision.SelfServeMove`, `Participant{BoxID, Label, InstanceID, Verified}`, `Participants`, `moves.OpenRecord{..., Layout}`, `OpenRecordKey`, `moves.ParticipantRole`, `moves.ParticipantStillPresent`, `moves.OfflineReservation`, `reserveBoxes`, `releaseBoxes`, `selfServeTick`, `selfServeStep`, `selfServeApply`, `request`, `persistedRequest`, `provision.Receipt`, `provision.Expect`, `ConsumeSelfServeRequest(id, nonce, nextStep, nextDeadline)`, `errRequestExpired`, `AbandonSelfServeRequest(id, nonce, nextDeadline)`, `next_maintenance_at`, `phase_step` (`adopted`/`issue` in `restage`), `participantMatches`, `SetSelfServeExpiry(id, phase, kind, sawDeadline, pending)`, `expiry_kind`/`expiry_deadline`, supersession by stamp, `errRequestRefused`, `MarkSelfServeCut`/`cut_requested_at`, `errRequestForeign`, `OfflineReport.RequestKey`, `DiskFreeBytes`, `OfflineReservation.ExpectIncarnation`, `SelfServeMove.LastRequest`, `LastMove.Request`, `provision.SetRecordMoveAt`, `OfflineReservation.ExpectSeq`, `moves.FailedDetail`, `OfflineReport.Layout`, `errRequestVoided`, `selfServeFinalise`, `leaseToken`, `provision.WithWriteGuard`, `IssueSelfServeRequest`, `ConfirmSelfServeRequest`, `VoidSelfServeRequest`, `request_voided`, `AdvanceSelfServe(..., nonce)`, `SetSelfServeExpiry`, `SetSelfServeNotifiedSeq`, `SetSelfServeOpenRecordPending`, `InsertSelfServeEventTx`, `DeliverSelfServeEvent`, `selfServeMoveView`, `selfServeAbortView`, `selfServeLast`, `moves.Fact`, `PrefixFacts`, `PrefixObject`, `StagedObject{Size, ETag, VersionID, Deferred}`, `LaneReport`, `TargetReadyReport`, `SourcePrecheck{..., Layout}`, `StrayEntry`, `StraysFact`, `ReturnLeftovers`, `ValidateOfflineReportFor`, `readOfflineEvidence(ctx, host, id, m)`, `readReturnReport`, `lease.CopyEvent`, `lease.MirrorPrefixKeepObserved`, `stageBook`, `status.HostFacts`, `BoxMetrics.Hosts/Lanes/BoxID/InstanceID`, `measureFiles`, `targetReadyDecision`, `sourcePrecheckDecision`, `probeTarget`, `estimateTerms`, `MarkSelfServeTiming`, `SelfServeEvent`, `host.E2E`/`NewE2E`, `console.TestHooks`.
+- Names used across tasks: `selfServeGate`, `instanceRails(w, r, acct, noun, c)`, `moveCapable`, `Principal.Moves/TokenID`, `selfServeMode`, `selfServeAdmits`, `recordEligibility`, `offlineRecordChecks`, `offlineRegionChecks`, `offlineSelection`, `OfflineQueued`, `OfflineQueue`, `OfflineQueuedToStaging`, `OfflinePrecheck`, `OfflineSetEstimate`, `OfflineAbortAt`, `provision.SelfServeMove`, `Participant{BoxID, Label, InstanceID, Verified}`, `Participants`, `moves.OpenRecord{..., Layout}`, `OpenRecordKey`, `moves.ParticipantRole`, `moves.ParticipantStillPresent`, `moves.OfflineReservation`, `reserveBoxes`, `releaseBoxes`, `selfServeTick`, `selfServeStep`, `selfServeApply`, `request`, `persistedRequest`, `provision.Receipt`, `provision.Expect`, `ConsumeSelfServeRequest(id, nonce, nextStep, nextDeadline)`, `errRequestExpired`, `AbandonSelfServeRequest(id, nonce, nextDeadline)`, `next_maintenance_at`, `phase_step` (`adopted`/`issue` in `restage`), `participantMatches`, `SetSelfServeExpiry(id, phase, kind, sawDeadline, pending)`, `expiry_kind`/`expiry_deadline`, `ExpireSelfServeRequest`/`request_expired`, supersession by stamp, `errRequestRefused`, `MarkSelfServeCut`/`cut_requested_at`, `errRequestForeign`, `OfflineReport.RequestKey`, `DiskFreeBytes`, `OfflineReservation.ExpectIncarnation`, `SelfServeMove.LastRequest`, `LastMove.Request`, `provision.SetRecordMoveAt`, `OfflineReservation.ExpectSeq`, `moves.FailedDetail`, `OfflineReport.Layout`, `errRequestVoided`, `selfServeFinalise`, `leaseToken`, `provision.WithWriteGuard`, `IssueSelfServeRequest`, `ConfirmSelfServeRequest`, `VoidSelfServeRequest`, `request_voided`, `AdvanceSelfServe(..., nonce)`, `SetSelfServeExpiry`, `SetSelfServeNotifiedSeq`, `SetSelfServeOpenRecordPending`, `InsertSelfServeEventTx`, `DeliverSelfServeEvent`, `selfServeMoveView`, `selfServeAbortView`, `selfServeLast`, `moves.Fact`, `PrefixFacts`, `PrefixObject`, `StagedObject{Size, ETag, VersionID, Deferred}`, `LaneReport`, `TargetReadyReport`, `SourcePrecheck{..., Layout}`, `StrayEntry`, `StraysFact`, `ReturnLeftovers`, `ValidateOfflineReportFor`, `readOfflineEvidence(ctx, host, id, m)`, `readReturnReport`, `lease.CopyEvent`, `lease.MirrorPrefixKeepObserved`, `stageBook`, `status.HostFacts`, `BoxMetrics.Hosts/Lanes/BoxID/InstanceID`, `measureFiles`, `targetReadyDecision`, `sourcePrecheckDecision`, `probeTarget`, `estimateTerms`, `MarkSelfServeTiming`, `SelfServeEvent`, `host.E2E`/`NewE2E`, `console.TestHooks`.
- Review Focus 1 to 5 are pinned by T7, T3, T8, T5, T1.