carlos / platform Public

provision: census re-pins for Task 5 fix round 1 (PROPOSED-self-serve-moves-2)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev c36dd63e1188abe19f17cf911c5bbd78685593ac parent adca350
3 files changed, +12 −7
  • docs/superpowers/notes/census-proposal-self-serve-moves-2.md +2 −0
  • internal/provision/plan14_root_reads_test.go +4 −2
  • internal/provision/testdata/plan14-root-reads-self-serve-moves-2.tsv +6 −5
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 a2f92c842..72b4be703 100644
--- a/docs/superpowers/notes/census-proposal-self-serve-moves-2.md
+++ b/docs/superpowers/notes/census-proposal-self-serve-moves-2.md
@@ -25,3 +25,5 @@ In the record-write inventory Task 10a adds six units of `e2e_bridge.go`, none r
Task 10a fix round 1 adds two test seams to the agent's own code and re-pins three root-read rows. `statusTick` becomes `statusTickAt` at the wall clock, so the bridge can stamp a box snapshot at its own clock. `statusTick` stays declared with no direct read. Its row is removed under a proposed H3 disposition (`census-ruling-PROPOSED-self-serve-moves-2`, as plan 1 removed `CreateAppInRegion`'s). `statusTickAt` carries the body with its read sites unchanged, frozen accepted-legacy. `E2E.status` is re-pinned in place because it now calls `statusTickAt`. The stager's new `"round-start"` call of `moveCfg.stageFault` (nil in production) adds no read or write site. The seal moves to `4cccf647…`, and the internal/host envelope is refreshed in place. In the record-write inventory `const#1` becomes `const sealPrefix`, with the same class and kinds and a new digest.
Task 5 (record eligibility, the split start validation, participant pinning, the self-serve door bodies and the view) adds no root read class or task. Six console units are new, each frozen accepted-legacy with a reviewed basis, and none reads a file; the scanner names them for sites that only look like reads. `Server.participantIdentityFor` reads the signed host roster (`hostactors.Directory.Read`: `control/host-actors.json` in the deployment bucket, verified under the release key) so a self-serve participant's identity record is checked against it; an absent roster is no entries, any other failure refuses. `Server.selfServeEstimate` reads the request's URL query. `selfServeBusy`'s one site is `rec.ActiveRun.Open()`, a method of the record already read, as `offlineBegin`'s is. `Server.estimate`, `type estimateTerms` and `var estimateDefaults` are the estimate's arithmetic and its terms: their sites are the `Open` term, a struct field named `Open` (Task 9's shape). Four units are re-pinned: `Server.handleAPIInstanceMoveStatus` (with Phase 1 off on a claims-off console the poll joins the instance's self-serve rows from the console SQLite store and answers `?estimate=1` while the switch admits; its sites are unchanged in kind) and `Server.offlineClaimEvidence` (the census-ruling-moves-offline body unchanged, its inputs passed as account, app, host and record) in new Task 5 rows; `Store.AdmitSelfServeMove` (the row also stores the estimate) and `Store.RequestSelfServeAbort` (its predicate also requires `cut_requested_at = 0`) in place in their Task 4 rows. The door's other new reads are bucket objects read with the console's deployment credentials, which the scanner names no site for: the boxes' status reports (`status/boxes/<label>.json`, through `readOfflineFleet`, now with each report's time for pinning) and the boxes' identity records (`boxid.Load`, `control/boxes/<box id>.json`, keyed by the edges file's box id and never the label). The operator doors pin an instance id from a current status report and read no identity record. The seal moves to `6f975f90…`, and the internal/console envelope is re-pinned in place. In the record-write inventory nothing is added or changed: the request door's one write is the console SQLite row (`AdmitSelfServeMove`), the cut and cancel doors' are `MarkSelfServeCut` and `RequestSelfServeAbort`, and the record's queue write is the job's (Task 7). The operator start and stage doors' record writes are unchanged (`offlineBegin`, `offlineAdvanceBound`). Paul's ruling is still outstanding.
+
+Task 5 fix round 1 adds no root read. `selfServeBusy` and `Server.selfServeEstimate` are re-pinned in place in their Task 5 rows: the record's checks (class, run, move) now come before the journal read, which moved into its own helper. Their sites are unchanged in kind, offsets moved. The seal moves to `ad120371…`, and the internal/console envelope is re-pinned in place. The other fixes of the round (operator selections reserve the sentinel outside self-serve mode, admission needs lifetimes on, the facts' order, the cancel of a returning move, and operator status views reading no identity) change no census unit's sites. The record-write inventory is unchanged.
diff --git a/internal/provision/plan14_root_reads_test.go b/internal/provision/plan14_root_reads_test.go
index b42977095..5a10c596c 100644
--- a/internal/provision/plan14_root_reads_test.go
+++ b/internal/provision/plan14_root_reads_test.go
@@ -1326,8 +1326,10 @@ func TestPlan14RootReadCensus(t *testing.T) {
// split start validation, participant pinning and the door bodies)
// adds six accepted-legacy console units that read no file and
// re-pins four (the poll door, offlineClaimEvidence and two journal
- // methods), which moves it once more.
- seal = "6f975f90eccdfb2d05fd383caf38ee5f00bbc982a12f34b2626142f8f58c3cf8"
+ // methods), which moves it once more. Its fix round 1 re-pins two of
+ // those rows in place (the record checks before the journal read),
+ // which moves it again.
+ seal = "ad1203719d20e86b2f745aa31c411afc6f4a90e579a2f8cab074598177610715"
errs := append(compareRootReads(got, inv), checkRootReadLegacy(inv, seal)...)
errs = append(errs, checkRootReadDeclarations(got, inv)...)
if len(errs) > 0 {
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 e602d4b42..e80df05ea 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
@@ -23,7 +23,7 @@ internal/console/templates/settings.html external legacy accepted-legacy accepte
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/provision 42588b9f64803b41c4463efb31e69fda0fc66573efd5d6a2d6e709682eeca385
# Task 3 (per-box reservations with a legacy projection and a sentinel, the fenced reclaim and the operator doors' bound admission), rev3=PROPOSED-self-serve-moves-2: no root read, class or task is added and no accepted-legacy unit is re-pinned, so the seal does not move. The new units (moves.ParseOfflineActive, moves.OfflineActiveBody, the console's offlinereserve.go, the doors' offlineApplyBound and offlineAdvanceBound) read no file: their reads are the bucket's control/offline-moves/active.json and the instance record through the judged readers and fenceRecord. Envelopes re-pinned in place (Task 2's rows replaced): internal/console (offlinereserve.go, the start and stage doors, the Server's two evidence fields) and internal/moves (the reservation table in offline.go).
-@coverage internal/console 13634a4f70f926d2a4040f0d66401a85438f782a6e6ef7408a27b5d47b476adc
+@coverage internal/console f862a815e0c6ce1f97eefc7101584c19b1aa4c316fc28a235c62e2fdf77b92b6
@coverage internal/moves 6a68b01ef865d9356bb19971f4cd4a61f7694769b63cee1d8234f615d5e9c8ba
# Task 4 (the journal, the events table, the console lease and the pass skeleton), rev3=PROPOSED-self-serve-moves-2: no root read, class or task is added. The console SQLite journal (selfserve_store.go) adds twenty-two units, each frozen accepted-legacy with a reviewed basis (console SQL as carlos-console, no bucket or root action), and the lease's console name adds one crypto/rand read (Server.selfServeConsoleID); serve (in place: the paging arm takes the store, the pass is started), NewServer (the row evidence and the recovery-mode scan) and Store.migrate (migrateSelfServe) are re-pinned. The seal moves. The lease and the pass read control/offline-moves/console.json and active.json from the bucket, not a file. Envelopes re-pinned in place: cmd/console, internal/console and internal/provision (WithWriteGuard in WriteRecord).
@legacy a8dd51a494ab3cd2ad371ded2850b6d78492569729527ea82cd8dd0f2b418a78 internal/console/selfserve_lease.go Server.selfServeConsoleID legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads crypto/rand once per process for the random console name the self-serve moves lease carries; randomness grants no root authority file:Read@110 3303b18ec5c77ccaf662064801f94276bfe947c31378cc1ecb8c4fe509d5d4d1
@@ -159,13 +159,14 @@ internal/console/apiinstancemove.go Server.handleAPIInstanceMoveStatus legacy ac
internal/console/apiinstancemove_offline.go Server.offlineClaimEvidence legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=root-input (J4, as main's moves units); the console (cmd/console serve under console.service, user carlos-console): the census-ruling-moves-offline body unchanged, its inputs passed as account, app, host and record (offlineRecordChecks) rather than the door; reads the host claim, the record's acquisition, a domains claim and the app's admission only to refuse a start; a failed read refuses with a 502; deny-only file:Read@427 25b39bcacda912c8e03ea7e08e96cf54ffedbc36bbcc44e046dbced9cec33200
@legacy 3e683da1dbcecefbcde3ade6601940eacbe80c746b9f290311133b3e1bad2c79 internal/console/apiinstancemove_offline.go Server.participantIdentityFor legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads the signed host roster (hostactors.Directory.Read, control/host-actors.json in the deployment bucket, verified under the release key) so a self-serve participant's identity record is checked against it; absent is no entries, any other failure refuses; no file read, no root action file:Read@478 5c91228191471a4415aa57a541861dbd20b6b2324f1d05f2610e98deba4c8e30
internal/console/apiinstancemove_offline.go Server.participantIdentityFor legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads the signed host roster (hostactors.Directory.Read, control/host-actors.json in the deployment bucket, verified under the release key) so a self-serve participant's identity record is checked against it; absent is no entries, any other failure refuses; no file read, no root action file:Read@478 5c91228191471a4415aa57a541861dbd20b6b2324f1d05f2610e98deba4c8e30
-@legacy 93dde944d11470f04e70d6da7f91e7754c696110638ac021ae3d01d2bd445573 internal/console/selfserve_door.go Server.selfServeEstimate legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the estimate of a self-serve move not yet requested: reads the request's URL query (region), the console SQLite rows and the prepare's bucket evidence, writes nothing; no file read, no root action file:Query@545 89cc1535c414f2566006b5bfa6abc336811ffa6e652f341453f80db5c98816ce
-internal/console/selfserve_door.go Server.selfServeEstimate legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the estimate of a self-serve move not yet requested: reads the request's URL query (region), the console SQLite rows and the prepare's bucket evidence, writes nothing; no file read, no root action file:Query@545 89cc1535c414f2566006b5bfa6abc336811ffa6e652f341453f80db5c98816ce
-@legacy 76c5268aa5a7316bfe99a7f66cd4903f206e5bad554a6e6f325975d7b2c00821 internal/console/selfserve_door.go selfServeBusy legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the prepare's record checks; its one site is rec.ActiveRun.Open(), a method of the record already read; no file read, no root action file:Open@165 c427659ee29d7245a254cc212a00457d0c8431c1ea0b86b2c73c8703dbdba902
-internal/console/selfserve_door.go selfServeBusy legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the prepare's record checks; its one site is rec.ActiveRun.Open(), a method of the record already read; no file read, no root action file:Open@165 c427659ee29d7245a254cc212a00457d0c8431c1ea0b86b2c73c8703dbdba902
+@legacy 87ac0e5d6b48d2440bcc8a1ff4137b7609a927b0f3f522037acaa559d0117996 internal/console/selfserve_door.go Server.selfServeEstimate legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the estimate of a self-serve move not yet requested: reads the request's URL query (region), the console SQLite rows and the prepare's bucket evidence, writes nothing; no file read, no root action; fix round 1: the record checks before the journal read (selfServeOpenRow) file:Query@354 12c7adb0d9d0682fd3ae9ec9f80884cf53899891aa4cd38ce5a0a71eff62c8b4
+internal/console/selfserve_door.go Server.selfServeEstimate legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the estimate of a self-serve move not yet requested: reads the request's URL query (region), the console SQLite rows and the prepare's bucket evidence, writes nothing; no file read, no root action; fix round 1: the record checks before the journal read (selfServeOpenRow) file:Query@354 12c7adb0d9d0682fd3ae9ec9f80884cf53899891aa4cd38ce5a0a71eff62c8b4
+@legacy 00fcfd1a948069335f118cf07dd757b90d2020fad8caef0719eb75e8d3cc261c internal/console/selfserve_door.go selfServeBusy legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the prepare's record checks; its one site is rec.ActiveRun.Open(), a method of the record already read; no file read, no root action; fix round 1: the open row is checked after it, from the journal file:Open@144 b9949bc89e1ed588d04dbd042d2a3b8a530546b85e05bf6f7fd3daf4d97a47b1
+internal/console/selfserve_door.go selfServeBusy legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the prepare's record checks; its one site is rec.ActiveRun.Open(), a method of the record already read; no file read, no root action; fix round 1: the open row is checked after it, from the journal file:Open@144 b9949bc89e1ed588d04dbd042d2a3b8a530546b85e05bf6f7fd3daf4d97a47b1
@legacy c2b468656ad27a5c0d554d7505e736deb1fe015d9b1e383240f447622f5f16a7 internal/console/selfserve_estimate.go Server.estimate legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: pure arithmetic over byte counts and the default terms; its sites are the estimate's Open term (a struct field named Open); no file read, no root action file:Open@259,file:Open@268,file:Open@356 9ce9332e764cb63574f16926dabf050a1429ceb10ff44b12c02447c08c0e5e09
internal/console/selfserve_estimate.go Server.estimate legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: pure arithmetic over byte counts and the default terms; its sites are the estimate's Open term (a struct field named Open); no file read, no root action file:Open@259,file:Open@268,file:Open@356 9ce9332e764cb63574f16926dabf050a1429ceb10ff44b12c02447c08c0e5e09
@legacy bbf40550e574bbb95012d6a817c3b71917311f71dba4061ddbad785072e61384 internal/console/selfserve_estimate.go type estimateTerms legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: a type declaration whose Open field is the open phase's duration; no file read, no root action file:Open@47 70ba8214af2db2b694d87c83750665856669faabb91359c20d6483503e69f77c
internal/console/selfserve_estimate.go type estimateTerms legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: a type declaration whose Open field is the open phase's duration; no file read, no root action file:Open@47 70ba8214af2db2b694d87c83750665856669faabb91359c20d6483503e69f77c
@legacy e7a1b4b8179de6b4d263f785208f5bad87eaa2ec4ff8eb07876e01f6034002a8 internal/console/selfserve_estimate.go var estimateDefaults legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the estimate's default terms, a literal whose Open field is the open phase's term; no file read, no root action file:Open@247,file:Open@49 e7c598c8e4a4fa1e4df207e463c6fd722f89d0955f896baa439ce328db821849
internal/console/selfserve_estimate.go var estimateDefaults legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the estimate's default terms, a literal whose Open field is the open phase's term; no file read, no root action file:Open@247,file:Open@49 e7c598c8e4a4fa1e4df207e463c6fd722f89d0955f896baa439ce328db821849
+# Task 5 fix round 1, rev3=PROPOSED-self-serve-moves-2: selfServeBusy and Server.selfServeEstimate are re-pinned in place in their Task 5 rows (the record checks come before the journal read); no root read is added. The internal/console envelope is re-pinned in place. The seal moves.