carlos / platform Public

provision: census overlays for self-serve moves plan 2, Task 2 (PROPOSED-self-serve-moves-2)

Root reads: offlineBegin re-pinned in place with a reviewed basis (it now
also creates the queued move), which moves the seal; the internal/console,
internal/moves and internal/provision envelopes re-pinned. The new record
fields need no @fields row: the field rule covers internal/registry only.
Record writes: SetRecordMoveAt added as a record-writer and
setrecordmoveat added to the census's exact key names, so callers of the
bound write stay counted; updateRecordSeeding, updateRecord and
SetRecordSeed re-pinned; moves.OpenRecordKey added as a key-site. The note
gains the Task 2 paragraph. Not an accepted ruling.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 7c84e4d6b5dee3661f5cae1f02bdff279d0bb49d parent 774596f
5 files changed, +48 −4
  • docs/superpowers/notes/census-proposal-self-serve-moves-2.md +2 −0
  • internal/provision/plan14_root_reads_test.go +5 −2
  • internal/provision/plan9_b8_census_test.go +4 −1
  • internal/provision/self_serve_moves2_census_test.go +31 −0
  • internal/provision/testdata/plan14-root-reads-self-serve-moves-2.tsv +6 −1

CI passed — run details

CI log
=== gate ===
.amadan/test-gate.sh
=== launchctx (1 s)
ok  	amadan.net/carlos/platform.git/launchctx	0.011s
?   	amadan.net/carlos/platform.git/launchctx/controlname	[no test files]
?   	amadan.net/carlos/platform.git/launchctx/wireid	[no test files]
=== vet (16 s)
=== gofmt (0 s)
gofmt -l .: clean
=== rest (168 s)
?   	github.com/carlosframework/platform/cmd/changelog	[no test files]
ok  	github.com/carlosframework/platform/cmd/console	3.470s
ok  	github.com/carlosframework/platform/cmd/moveprobe	11.990s
ok  	github.com/carlosframework/platform/cmd/zddprobe	0.785s
ok  	github.com/carlosframework/platform/internal/activator	61.018s
ok  	github.com/carlosframework/platform/internal/agentsock	0.038s
ok  	github.com/carlosframework/platform/internal/alerting	0.008s
ok  	github.com/carlosframework/platform/internal/analytics	0.042s
ok  	github.com/carlosframework/platform/internal/appconfig	3.108s
ok  	github.com/carlosframework/platform/internal/apperr	0.183s
ok  	github.com/carlosframework/platform/internal/applog	0.230s
ok  	github.com/carlosframework/platform/internal/awsinv	0.009s
ok  	github.com/carlosframework/platform/internal/boxchoice	0.008s
ok  	github.com/carlosframework/platform/internal/boxid	0.974s
?   	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.011s
ok  	github.com/carlosframework/platform/internal/caps	0.030s
ok  	github.com/carlosframework/platform/internal/certwarm	0.010s
ok  	github.com/carlosframework/platform/internal/cgroup	0.831s
ok  	github.com/carlosframework/platform/internal/changelog	0.568s
ok  	github.com/carlosframework/platform/internal/claimactivation	1.241s
ok  	github.com/carlosframework/platform/internal/clamd	0.080s
?   	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.118s
ok  	github.com/carlosframework/platform/internal/dbdoor/dbdoortest	0.012s
ok  	github.com/carlosframework/platform/internal/dbverify	0.007s
ok  	github.com/carlosframework/platform/internal/dnsrec	0.008s
ok  	github.com/carlosframework/platform/internal/docsite	0.023s
ok  	github.com/carlosframework/platform/internal/domains	3.112s
ok  	github.com/carlosframework/platform/internal/doorkey	0.017s
ok  	github.com/carlosframework/platform/internal/economics	0.007s
ok  	github.com/carlosframework/platform/internal/edge	45.601s
?   	github.com/carlosframework/platform/internal/edgeproof	[no test files]
ok  	github.com/carlosframework/platform/internal/edgesfile	0.011s
ok  	github.com/carlosframework/platform/internal/fleetapi	0.159s
ok  	github.com/carlosframework/platform/internal/gate	1.657s
ok  	github.com/carlosframework/platform/internal/genselect	0.025s
ok  	github.com/carlosframework/platform/internal/geo	0.020s
ok  	github.com/carlosframework/platform/internal/geoip	0.044s
ok  	github.com/carlosframework/platform/internal/historyreadback	0.245s
ok  	github.com/carlosframework/platform/internal/host	141.117s
ok  	github.com/carlosframework/platform/internal/hostactors	5.950s
ok  	github.com/carlosframework/platform/internal/hostactors/awsmembership	0.007s
ok  	github.com/carlosframework/platform/internal/hostbox	2.856s
ok  	github.com/carlosframework/platform/internal/hostclaim	0.812s
ok  	github.com/carlosframework/platform/internal/hostenv	0.005s
ok  	github.com/carlosframework/platform/internal/hostevidence	0.007s
ok  	github.com/carlosframework/platform/internal/hostexec	5.182s
ok  	github.com/carlosframework/platform/internal/hostfence	0.058s
ok  	github.com/carlosframework/platform/internal/hostfiles	10.316s
ok  	github.com/carlosframework/platform/internal/hostfloor	0.021s
ok  	github.com/carlosframework/platform/internal/hostguard	1.026s
ok  	github.com/carlosframework/platform/internal/hostops	1.958s
?   	github.com/carlosframework/platform/internal/hostops/fencerelease	[no test files]
ok  	github.com/carlosframework/platform/internal/hostops/internal/fencerelease	0.005s
ok  	github.com/carlosframework/platform/internal/hostquarantine	0.004s
ok  	github.com/carlosframework/platform/internal/hostrelocate	0.655s
ok  	github.com/carlosframework/platform/internal/hostresolve	0.173s
ok  	github.com/carlosframework/platform/internal/hostwrite	0.002s
ok  	github.com/carlosframework/platform/internal/infraview	0.009s
ok  	github.com/carlosframework/platform/internal/instancectl	5.222s
ok  	github.com/carlosframework/platform/internal/instanceexec	2.753s
ok  	github.com/carlosframework/platform/internal/instancefs	0.008s
ok  	github.com/carlosframework/platform/internal/instancekey	0.003s
ok  	github.com/carlosframework/platform/internal/instanceupdates	0.021s
ok  	github.com/carlosframework/platform/internal/layout	1.777s
ok  	github.com/carlosframework/platform/internal/lbhealth	0.004s
ok  	github.com/carlosframework/platform/internal/lease	10.084s
ok  	github.com/carlosframework/platform/internal/lease/leasetest	0.537s
ok  	github.com/carlosframework/platform/internal/ledger	0.025s
ok  	github.com/carlosframework/platform/internal/mail	0.190s
ok  	github.com/carlosframework/platform/internal/maintenance	0.085s
ok  	github.com/carlosframework/platform/internal/maintenanceexec	5.512s
ok  	github.com/carlosframework/platform/internal/maintenanceguard	0.096s
ok  	github.com/carlosframework/platform/internal/metrics	0.005s
ok  	github.com/carlosframework/platform/internal/moves	21.635s
ok  	github.com/carlosframework/platform/internal/moves/archive	0.970s
ok  	github.com/carlosframework/platform/internal/objstore	0.361s
ok  	github.com/carlosframework/platform/internal/ops	0.200s
ok  	github.com/carlosframework/platform/internal/park	0.238s
ok  	github.com/carlosframework/platform/internal/plans	0.011s
ok  	github.com/carlosframework/platform/internal/privatefile	0.011s
ok  	github.com/carlosframework/platform/internal/provision	22.075s
ok  	github.com/carlosframework/platform/internal/publicrelease	0.011s
?   	github.com/carlosframework/platform/internal/regionname	[no test files]
ok  	github.com/carlosframework/platform/internal/registry	5.828s
ok  	github.com/carlosframework/platform/internal/relay	7.239s
ok  	github.com/carlosframework/platform/internal/release	24.688s
ok  	github.com/carlosframework/platform/internal/rollout	3.778s
ok  	github.com/carlosframework/platform/internal/rolloutwords	0.007s
ok  	github.com/carlosframework/platform/internal/rootaws	0.010s
ok  	github.com/carlosframework/platform/internal/rootparticipation	0.061s
ok  	github.com/carlosframework/platform/internal/rootstate	0.031s
ok  	github.com/carlosframework/platform/internal/runs	0.597s
ok  	github.com/carlosframework/platform/internal/s3compat	0.005s
ok  	github.com/carlosframework/platform/internal/safefile	0.004s
ok  	github.com/carlosframework/platform/internal/schedule	2.674s
ok  	github.com/carlosframework/platform/internal/seeds	0.015s
ok  	github.com/carlosframework/platform/internal/sim/hostlife	9.713s
ok  	github.com/carlosframework/platform/internal/sim/litestreamfacts	4.192s
ok  	github.com/carlosframework/platform/internal/status	0.065s
ok  	github.com/carlosframework/platform/internal/steering	0.006s
ok  	github.com/carlosframework/platform/internal/stopevidence	0.970s
ok  	github.com/carlosframework/platform/internal/svcrole	0.002s
ok  	github.com/carlosframework/platform/internal/telemetry	0.004s
ok  	github.com/carlosframework/platform/internal/termfence	0.005s
ok  	github.com/carlosframework/platform/internal/tunnelclient	0.004s
ok  	github.com/carlosframework/platform/internal/unixdial	0.007s
ok  	github.com/carlosframework/platform/internal/updatewords	0.005s
ok  	github.com/carlosframework/platform/internal/usage	0.005s
ok  	github.com/carlosframework/platform/internal/version	0.002s
ok  	github.com/carlosframework/platform/internal/vet	1.672s
=== internal_console@0 (81 s)
ok  	github.com/carlosframework/platform/internal/console	79.713s
=== internal_console@1 (43 s)
ok  	github.com/carlosframework/platform/internal/console	41.243s
=== internal_console@2 (39 s)
ok  	github.com/carlosframework/platform/internal/console	37.368s
=== internal_console@3 (43 s)
ok  	github.com/carlosframework/platform/internal/console	41.537s
=== internal_console@4 (44 s)
ok  	github.com/carlosframework/platform/internal/console	42.939s
=== internal_console@5 (37 s)
ok  	github.com/carlosframework/platform/internal/console	35.940s
=== internal_console@6 (43 s)
ok  	github.com/carlosframework/platform/internal/console	42.054s
=== internal_console@7 (42 s)
ok  	github.com/carlosframework/platform/internal/console	40.427s
=== root@0 (29 s)
ok  	github.com/carlosframework/platform	28.158s
=== root@1 (44 s)
ok  	github.com/carlosframework/platform	42.384s
=== root@2 (45 s)
ok  	github.com/carlosframework/platform	43.760s
=== cross ===
--- shard 0 of 5 ---
cross-compiling darwin/arm64
--- shard 1 of 5 ---
cross-compiling darwin/amd64
--- shard 2 of 5 ---
cross-compiling linux/arm64
linux/arm64 carlos binary: 50135202 bytes (ceiling 52000000)
--- shard 3 of 5 ---
cross-compiling windows/amd64
--- shard 4 of 5 ---
cross-compiling windows/arm64
=== minio-contract ===
minio contract: arm64, minio RELEASE.2025-09-07T16-13-09Z, mc RELEASE.2025-08-13T08-35-41Z
  minio: cached, digest verified
  mc: cached, digest verified
  minio healthy on 127.0.0.1:20999
Added `local` successfully.
Bucket created successfully `local/contract-bucket`.
Bucket created successfully `local/denied-bucket`.
Created policy `contract-only` successfully.
Added user `scopeduser` successfully.
Attached Policies: [contract-only]
To User: scopeduser
  buckets and scoped user ready
=== RUN   TestDeliveredContractMinio
=== RUN   TestDeliveredContractMinio/put
=== RUN   TestDeliveredContractMinio/get_round-trips_the_body
=== RUN   TestDeliveredContractMinio/list_shows_the_key
=== RUN   TestDeliveredContractMinio/head_and_list_agree_on_the_version
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/not_by_PutObjectTagging
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/and_not_by_x-amz-tagging_on_upload
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CreateMultipartUpload
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CopyObject_with_a_REPLACE_tagging_directive
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/but_multipart_itself_is_allowed
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_copy_itself_is_allowed
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/a_POST-policy_forged_tag_with_a_matching_version_is_still_not_a_verdict
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_an_ordinary_tagged-with-something-else_upload_is_allowed
=== RUN   TestDeliveredContractMinio/delete_removes_it
=== RUN   TestDeliveredContractMinio/cross-bucket_denial
--- PASS: TestDeliveredContractMinio (0.02s)
    --- PASS: TestDeliveredContractMinio/put (0.00s)
    --- PASS: TestDeliveredContractMinio/get_round-trips_the_body (0.00s)
    --- PASS: TestDeliveredContractMinio/list_shows_the_key (0.00s)
    --- PASS: TestDeliveredContractMinio/head_and_list_agree_on_the_version (0.00s)
    --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/not_by_PutObjectTagging (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/and_not_by_x-amz-tagging_on_upload (0.00s)
    --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route (0.01s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CreateMultipartUpload (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CopyObject_with_a_REPLACE_tagging_directive (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/but_multipart_itself_is_allowed (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_copy_itself_is_allowed (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/a_POST-policy_forged_tag_with_a_matching_version_is_still_not_a_verdict (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_an_ordinary_tagged-with-something-else_upload_is_allowed (0.00s)
    --- PASS: TestDeliveredContractMinio/delete_removes_it (0.00s)
    --- PASS: TestDeliveredContractMinio/cross-bucket_denial (0.00s)
PASS
ok  	github.com/carlosframework/platform/internal/objstore	0.021s
=== RUN   TestT4StorageProbeMinio
2026/10/23 07:23:02 moves: T4: STORE: list: operation error S3: ListObjectsV2, https response error StatusCode: 403, RequestID: 18E117B29EAC8F18, HostID: 7c420053e0fbcd7f41653fdd92ffa2802c903d05303b1aa15adc2e8bb65d183f, api error SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method.
--- PASS: TestT4StorageProbeMinio (0.01s)
PASS
ok  	github.com/carlosframework/platform/internal/host	0.020s
minio contract: PASS
diff --git a/docs/superpowers/notes/census-proposal-self-serve-moves-2.md b/docs/superpowers/notes/census-proposal-self-serve-moves-2.md
index 89d0373ee..fbf681fca 100644
--- a/docs/superpowers/notes/census-proposal-self-serve-moves-2.md
+++ b/docs/superpowers/notes/census-proposal-self-serve-moves-2.md
@@ -5,3 +5,5 @@ Status: proposed, marked PROPOSED-self-serve-moves-2. Not an accepted ruling; th
The root-read overlay is `internal/provision/testdata/plan14-root-reads-self-serve-moves-2.tsv`, loaded after the self-serve-moves-1 overlay and before `compareRootReads`, with the preceding seal verified first. The record-write overlay is `plan14SelfServeMoves2WriteCensusInventory` in `internal/provision/self_serve_moves2_census_test.go`, built over plan 1's inventory; `TestPlan9B8RecordWriteCensus` takes it. Later tasks of the plan extend both.
Task 1 (the move-capable token and the self-serve gate) changes no record envelope and adds no root read, class or task. Eight accepted-legacy units are re-pinned in place, each with `rev3=PROPOSED-self-serve-moves-2` and a reviewed one-line basis, and take new frozen fingerprints, so the seal moves. Five are console SQL running as `carlos-console`: `migrateCLIAuth` adds the `cli_tokens` column `moves INTEGER NOT NULL DEFAULT 0` through the idempotent ALTER list; `claimRawNewAppToken` writes it (true only from the owner-only mint door); `CLITokens` and `ServicePrincipals` list it; `CLIPrincipal` reads it (honoured for kind=app rows only) and returns the stored `token_hash` as `Principal.TokenID`. The tokens page template (`settings.html`) marks a move-capable app token and reads nothing of its own. `serve` reads `CARLOS_SELF_SERVE_MOVES` into `Config.SelfServeMoves`, an environment string, beside plan 1's workers. `Server.handleAPIInstanceMoveRequest` keeps its census-ruling-region-ha-2a body; with Phase 1 off it now sends self-serve mode to `selfServeMoveRequest` (the self-serve gate, binding SQL only, no bucket or record read; its Task 1 body answers the family's 404) and every other request to the legacy body. Its read sites are unchanged and their offsets moved. The cmd/console, internal/console and internal/console/templates envelopes are re-pinned. In the record-write inventory the same door stays a record-writer (`key:SetRecordMove,lit:instances`) and takes a new digest; no record write is added, moved or made raw. The cut and abort doors' dispatch is not a census unit. A green census checks these proposed rows against the code; Paul's ruling is still outstanding.
+
+Task 2 (the queued state, the receipts, the caller's stamps, the bound write and the open record) adds no root read, class or task. In the root-read overlay one accepted-legacy unit is re-pinned in place under `rev3=PROPOSED-self-serve-moves-2` with a reviewed basis and takes a new frozen fingerprint, so the seal moves: `offlineBegin`, the shared body of `OfflineStart` and `OfflineStage`, now also creates the self-serve move in `offline-queued` for `OfflineQueue` (queued_at, staged_at and precheck_at at the caller's stamp, move.seq set to the record's move_seq, no advance) and records `return_of`. Its one site is still `rec.ActiveRun.Open()`, a method, and its offset moved. The other new transitions, `ProposeStamp`, `Receipt`, `SetRecordMoveAt` and `moves.OpenRecordKey` read no file. The internal/console envelope is re-pinned (Task 1's row replaced in place), and internal/moves and internal/provision are pinned in this overlay. The plan asks for `@fields` rows for the new record fields (`self_serve`, `participants`, `queued_at`, `precheck_at`, `return_of`, `last_move.request`); the census's field rule derives its list from the `internal/registry` structs only, so these provision record fields change no `@fields` row, and none is added. In the record-write inventory `SetRecordMoveAt` is added as a record-writer (`key:SetRecordMoveAt`): SetRecordMove bound to an observed incarnation and record_seq, one attempt through `updateRecordSeeding` and so `WriteRecord`. `setrecordmoveat` joins the census's exact key names, so a writer that moves from `SetRecordMove` to the bound write stays a typed writer in the census rather than leaving it. `updateRecordSeeding` is re-pinned (the expect parameter: nil from every other caller; with it, a read of another incarnation or record_seq is refused before the mutation and the retry loop is skipped), and `updateRecord` and `SetRecordSeed` are re-pinned for passing nil. `moves/offline.go:OpenRecordKey` is a new key-site: `control/offline-moves/<host>/<id>/open.json`, beside the seal and never an instance record; nothing writes it until Task 8. The offline transitions are mutations for the record writers and write nothing themselves. Paul's ruling is still outstanding.
diff --git a/internal/provision/plan14_root_reads_test.go b/internal/provision/plan14_root_reads_test.go
index 0064cf111..519318a56 100644
--- a/internal/provision/plan14_root_reads_test.go
+++ b/internal/provision/plan14_root_reads_test.go
@@ -1305,8 +1305,11 @@ func TestPlan14RootReadCensus(t *testing.T) {
// Task 1 (the move-capable token and the self-serve gate) re-pins eight
// accepted-legacy units (the cli_tokens moves column, its writer and
// readers, the tokens page, serve and the request door's dispatch),
- // which moves the seal.
- seal = "993491db8d9259f16ceea696eb94c823dac50cf24309854c66354f4a828e5665"
+ // which moves the seal. Task 2 (the queued state, the receipts, the
+ // caller's stamps, the bound write and the open record) re-pins
+ // offlineBegin, which now also creates the queued move, and moves it
+ // again.
+ seal = "aaa55ce2c1f834171f5d1ee2be96b00445acbd08dfe570bd941f50355a2ac20a"
errs := append(compareRootReads(got, inv), checkRootReadLegacy(inv, seal)...)
errs = append(errs, checkRootReadDeclarations(got, inv)...)
if len(errs) > 0 {
diff --git a/internal/provision/plan9_b8_census_test.go b/internal/provision/plan9_b8_census_test.go
index 3a63fe6c7..02f093061 100644
--- a/internal/provision/plan9_b8_census_test.go
+++ b/internal/provision/plan9_b8_census_test.go
@@ -51,9 +51,12 @@ var censusMethods = map[string]bool{
// Lower-cased identifier suffixes / exact names that mark a record-key or
// typed-record-writer touchpoint. Keep these names aligned with the APIs above.
+// setrecordmoveat (self-serve moves plan 2 Task 2) is SetRecordMove bound to
+// an observed record; without it a writer moving to the bound write would
+// leave the census.
var (
censusKeySuffixes = []string{"recordkey", "recordsprefix", "sidecarsprefix", "sidecarkey", "sidecarmanifestkey", "writerecord", "sequencedrecord"}
- censusKeyExact = map[string]bool{"createrecord": true, "updaterecord": true, "setrecordregion": true, "setrecordmove": true, "setrecordrun": true, "setrecordseed": true, "createsidecarrecord": true, "claimrawupdaterecord": true}
+ censusKeyExact = map[string]bool{"createrecord": true, "updaterecord": true, "setrecordregion": true, "setrecordmove": true, "setrecordmoveat": true, "setrecordrun": true, "setrecordseed": true, "createsidecarrecord": true, "claimrawupdaterecord": true}
censusLitWords = []string{"instances", "sidecars"}
)
diff --git a/internal/provision/self_serve_moves2_census_test.go b/internal/provision/self_serve_moves2_census_test.go
index 500ceed6e..1fb8df263 100644
--- a/internal/provision/self_serve_moves2_census_test.go
+++ b/internal/provision/self_serve_moves2_census_test.go
@@ -14,12 +14,43 @@ package provision
// with Phase 1 off it now sends self-serve mode to selfServeMoveRequest,
// whose gate reads no record and whose Task 1 body writes nothing, and
// every other request to the legacy body, whose writes are unchanged.
+//
+// Task 2 (the queued state, the receipts, the caller's stamps, the bound
+// write and the open record): one record writer is added, three are
+// re-pinned and one key site is added; none is raw.
+// - provision.go:SetRecordMoveAt is added, a record-writer
+// (key:SetRecordMoveAt): SetRecordMove bound to an observed incarnation
+// and record_seq, through updateRecordSeeding and so WriteRecord, one
+// attempt. setrecordmoveat joins censusKeyExact so its callers stay
+// typed writers in the census.
+// - provision.go:updateRecordSeeding is re-pinned: it gains the expect
+// parameter (nil from every caller but SetRecordMoveAt), which refuses
+// a read of another incarnation or record_seq with ErrCASConflict before
+// the mutation and skips the retry loop; the read and the WriteRecord
+// are unchanged.
+// - provision.go:updateRecord and seed.go:SetRecordSeed are re-pinned:
+// each passes nil for expect, nothing else changed.
+// - moves/offline.go:OpenRecordKey is added, a key-site (the key matches
+// the census's recordkey suffix): control/offline-moves/<host>/<id>/
+// open.json, an object beside the seal and never an instance record;
+// nothing writes it in this task (Task 8 does, create-only).
+// - The offline transitions (offline_move.go) are muts for SetRecordMove
+// and SetRecordMoveAt and write nothing themselves, so they are not
+// census units.
func plan14SelfServeMoves2WriteCensusInventory() []censusEntry {
removed := []struct{ file, unit string }{
{"internal/console/apiinstancemove.go", "Server.handleAPIInstanceMoveRequest"},
+ {"internal/provision/provision.go", "updateRecord"},
+ {"internal/provision/provision.go", "updateRecordSeeding"},
+ {"internal/provision/seed.go", "SetRecordSeed"},
}
added := []censusEntry{
{"internal/console/apiinstancemove.go", "Server.handleAPIInstanceMoveRequest", "record-writer", "key:SetRecordMove,lit:instances", "6be4b2d5ed59e3e42c47589039daba2cdb4081db45e0258d8889ef8477290591"},
+ {"internal/provision/provision.go", "updateRecord", "record-writer", "key:updateRecord", "c02b077b70a5d064bc4a602974fd11b8729365b22353aae31e04978d94f7e122"},
+ {"internal/provision/provision.go", "updateRecordSeeding", "record-writer", "key:RecordKey,key:WriteRecord", "6c67de6c105824040c297fe23838b9c4de80bdbfce065b1ce80ef46f4f422be0"},
+ {"internal/provision/seed.go", "SetRecordSeed", "record-writer", "key:SetRecordSeed", "b9b7e479f5217f26356e31e1568e1d1aa0f31c8d0f719633e7f2b15f25119d60"},
+ {"internal/provision/provision.go", "SetRecordMoveAt", "record-writer", "key:SetRecordMoveAt", "f44d62d5180d20e67d5459e7578f23fd5ac852d3f8097d14921cd63e33dc7140"},
+ {"internal/moves/offline.go", "OpenRecordKey", "key-site", "key:OpenRecordKey", "ebb4f0dcd050b5d183b642829423ba71740bf6d86427af2cba64475d54276be9"},
}
entries := plan14SelfServeMoves1WriteCensusInventory()
for _, r := range removed {
diff --git a/internal/provision/testdata/plan14-root-reads-self-serve-moves-2.tsv b/internal/provision/testdata/plan14-root-reads-self-serve-moves-2.tsv
index b6146a39a..0024cdb6d 100644
--- a/internal/provision/testdata/plan14-root-reads-self-serve-moves-2.tsv
+++ b/internal/provision/testdata/plan14-root-reads-self-serve-moves-2.tsv
@@ -17,5 +17,10 @@ internal/console/svcprincipal.go Store.ServicePrincipals legacy accepted-legacy
@legacy 058a42b1f720a95b9590b30f143ba9892bb169f1c43a386caabdf1fca6b32829 internal/console/templates/settings.html external legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the tokens page template marks a move-capable app token beside its app; it renders the rows its handler read and reads nothing of its own file:external@0 4e903910a7001a43e9f206a7d43cdf9d1fbf1e0af331f6b08f194b21681e05e4
internal/console/templates/settings.html external legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the tokens page template marks a move-capable app token beside its app; it renders the rows its handler read and reads nothing of its own file:external@0 4e903910a7001a43e9f206a7d43cdf9d1fbf1e0af331f6b08f194b21681e05e4
@coverage cmd/console b5a2b44792eeca719204eed8f55cf3c8d91f67e17532727f7adedda313470b37
-@coverage internal/console 661b25c54e6c811451ff88511266c61f6dbaee5fe3cd7e9f29282b52b1a8f58c
@coverage internal/console/templates d3e4b3b103e9a9966a8c91e6683c241b2e53ce55a24f6511c53266586b7f1c5d
+# Task 2 (the queued state, the receipts, the caller's stamps, the bound write and the open record), rev3=PROPOSED-self-serve-moves-2: no root read, class or task is added. offlineBegin (the shared body of OfflineStart, OfflineStage and now OfflineQueue) is re-pinned in place with a reviewed basis and takes a new frozen fingerprint, which moves the seal; its one site moved. The other new transitions, ProposeStamp, Receipt, SetRecordMoveAt and moves.OpenRecordKey read no file. Envelopes re-pinned: internal/console (the operator doors propose their stamps, the queued state in the verb and the view, the abort door's OfflineAbortAt; Task 1's row replaced in place), internal/moves (OpenRecord, OpenRecordKey) and internal/provision (the record fields, the transitions, the bound write). The new record fields need no @fields row: the census's field rule covers internal/registry structs only.
+@legacy 94b21acdfb6eb3f8ee0a3dd937605e18edd852766f1091d7d664e4bc566f4ad2 internal/provision/offline_move.go offlineBegin legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=root-input (J4, as OfflineStart); the console (cmd/console serve under console.service, user carlos-console): self-serve moves 1 Task 7's body (OfflineStart's, the state a parameter; a direct start advances move_seq and stamps move.seq, refusing ErrLifetimeExhausted at MaxInt64 before any write), and it now also creates the self-serve move in offline-queued for OfflineQueue (queued_at, staged_at and precheck_at at the caller's stamp, move.seq set to the record's move_seq, no advance) and records return_of; a stage and a queue hold nothing; its one site is still rec.ActiveRun.Open(), a method on the record's run state (RunState.Open), not a file read; self-serve moves 2 Task 2 file:Open@208 0a9b432ddf2f39a977c0651e377258b35c1d05635e9979583eeac6253d6c0ec8
+internal/provision/offline_move.go offlineBegin legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=root-input (J4, as OfflineStart); the console (cmd/console serve under console.service, user carlos-console): self-serve moves 1 Task 7's body (OfflineStart's, the state a parameter; a direct start advances move_seq and stamps move.seq, refusing ErrLifetimeExhausted at MaxInt64 before any write), and it now also creates the self-serve move in offline-queued for OfflineQueue (queued_at, staged_at and precheck_at at the caller's stamp, move.seq set to the record's move_seq, no advance) and records return_of; a stage and a queue hold nothing; its one site is still rec.ActiveRun.Open(), a method on the record's run state (RunState.Open), not a file read; self-serve moves 2 Task 2 file:Open@208 0a9b432ddf2f39a977c0651e377258b35c1d05635e9979583eeac6253d6c0ec8
+@coverage internal/console 29ae289dc256408f6debca9150987ba5ce7a2e80a0bbf5fc3064ead950d16bd1
+@coverage internal/moves 51465341e311dc007d75ed4f68474fe4cec05d51c6ec07ee5c64653936faa410
+@coverage internal/provision 0d327a4972f0a10304fcda5e5ba1ee1612f6e49801554290d88021d75d6d912e