carlos / platform Public

provision: census for Task 9 fix round 1: moveTimings frozen in place of MoveTimings's unruled rows, estimateRules and SetSelfServeReason re-pinned, the console envelope and the seal

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 4997a30dffaf6940e32d864792c021aacd91af94 parent 9e6e600
3 files changed, +14 −9
  • 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 +8 −7

CI failed — run details

CI log
=== gate ===
.amadan/test-gate.sh

amadan: step gate failed: signal: terminated

amadan: job failed at step gate — its output is above, not at the tail of this log
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 655e9df15..a9f77e2ab 100644
--- a/docs/superpowers/notes/census-proposal-self-serve-moves-2.md
+++ b/docs/superpowers/notes/census-proposal-self-serve-moves-2.md
@@ -41,3 +41,5 @@ Also on Task 8's branch: `targetDataPaths` names the raw nested directory throug
Task 8 fix round 1 adds no root read, class or task and no record write. The operator return's discovery is now the return index: the return door writes `control/offline-moves/@returns/<region>/<host>/<forward id>.json` (`offlineReturnIndex`, nonrecord, create-only, moved to the newest request if-match), and a box lists only its own region's index once a minute (one LIST per region per box, whatever the number of hosts), reads an indexed forward's open record once (`readOpen`, a key-site; a record it may not answer for cached as a negative), writes its report (`writeReturnReport`, nonrecord, renamed from `answerReturn`'s write) and deletes the index entry if-match; `scanReturns`'s listing of every host's move prefixes is gone. `FinishSelfServeMove`'s statement moved to `finishSelfServeMove` (shared with `YieldSelfServeMove`, the move an operator took over), so its row is removed under a proposed H3 disposition and `finishSelfServeMove` is frozen accepted-legacy; `probeTarget` is re-pinned in place (one transport per target address); the console, host and moves envelopes are re-pinned in place and the seal moves to `7351b869…`. Open records of aborted moves (written before an open that never committed) are left in the bucket: their cleanup is plan 4's.
Task 9 (the estimate, the timings and the events) adds no root read, class or task, and no record write. In the root-read overlay twelve accepted-legacy units are added under `rev3=PROPOSED-self-serve-moves-2`, each frozen with a one-line basis, and none reads a file: the timing marks and `move_timings` (`ssMarkTx`, `Store.MarkSelfServeTiming`, `Store.SelfServeTimings`, `Store.InsertMoveTiming`, `Store.MoveTimings`), the estimate's medians (`Server.estimateRules`, whose sites are the `Open` term, a struct field), the events (`ssRowEventTx`, `Store.SelfServeEvents` and the dead-letter `Store.selfServeEventDeliveryFailed`), `Store.RecordSelfServeHealth` and `Store.SetSelfServeReason` (now transactions with their events, where they used `setSelfServe` before) and the operator status door `Server.handleAPIInstanceOfflineStatus` (its site is the request URL's `Query`, the `?log=1` switch). `Server.estimate`, `Store.AbortSelfServe`, `Store.AdvanceSelfServeToStep`, `Store.ConsumeSelfServeRequest` and `Store.migrateSelfServe` are re-pinned in place with their bases extended (the medians; the events and marks in the change's own transaction; the events' `attempts` column, added idempotently). The internal/console envelope is re-pinned in place, and the seal moves to `16987f09…`. In the record-write inventory nothing changes: the marks, `move_timings`, the events and their delivery are console SQLite only, and the one new bucket access is a read (the advance into landed reads the move's reports through `readOfflineEvidence`, a key-site, for the seal's sizes). `claimWriterReasons` already names `self_serve_events` and `self_serve_timings` as the claims-off pass's writers; `move_timings` is `NonApp` in the store gate and its one writer, the finaliser's timings effect, runs only in that pass, so `TestClaimConsoleMutationInvariant` reaches no new writer.
+
+Task 9 fix round 1 adds no root read, class or task and no record write. `Store.MoveTimings`'s query moved to `Store.moveTimings`, which it shares with the estimate's window (`moveTimingWindow`: the rated rows of at least 1 MiB, or the rows under that floor, which measure a term's fixed part), so `MoveTimings`'s Task 9 rows, never ruled on, are withdrawn and `moveTimings` is frozen accepted-legacy in their place. `Server.estimateRules` (a rate measured past the term's fixed part) and `Store.SetSelfServeReason` (its event stamped with the tick's clock) are re-pinned in place; the internal/console envelope is re-pinned in place and the seal moves to `532a916e…`.
diff --git a/internal/provision/plan14_root_reads_test.go b/internal/provision/plan14_root_reads_test.go
index 553fe7f0d..10139b85e 100644
--- a/internal/provision/plan14_root_reads_test.go
+++ b/internal/provision/plan14_root_reads_test.go
@@ -1356,8 +1356,10 @@ func TestPlan14RootReadCensus(t *testing.T) {
// operator status door's ?log=1 query), none a file, and re-pins
// estimate, AbortSelfServe, AdvanceSelfServeToStep,
// ConsumeSelfServeRequest and migrateSelfServe in place, which moves it
- // once more.
- seal = "16987f099bede699b0fdfb25d967f9d4a48e91e9a391a6b430cbd8202afddd16"
+ // once more. Its fix round 1 withdraws MoveTimings's unruled rows (its
+ // query moved to moveTimings, frozen in their place) and re-pins
+ // estimateRules and SetSelfServeReason in place, which moves it again.
+ seal = "532a916ebc21d41287812993943bed488b7dfcc2250570000aedb82cc48919f6"
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 51b5b1760..6ac8d781d 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 d018e5699137db933be2142f7526d0d1d10b08170525886bd9c424cde5578b55
# 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 ae4a1f3937058bf14cf053946321af10ef42abe6bc0d081c230011a4f8522475
+@coverage internal/console 31e3cb7931b2d2797538080f3d20d18262cefa9a58e804c3d235e429b1d8c9f0
@coverage internal/moves 6a61fc2680d29b8998a383c7c65756f78a06ac312279148bdde752546686cd8d
# 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
@@ -209,14 +209,12 @@ internal/console/selfserve_store.go Store.finishSelfServeMove legacy accepted-le
# Task 9 (the estimate, the timings and the events), rev3=PROPOSED-self-serve-moves-2: no root read, class or task is added and no record write. Twelve accepted-legacy units are added, each console SQLite or a URL query, none a file: the timing marks and move_timings (ssMarkTx, MarkSelfServeTiming, SelfServeTimings, InsertMoveTiming, MoveTimings), the estimate's medians (estimateRules, whose sites are the Open term), the events (ssRowEventTx, SelfServeEvents, the dead-letter selfServeEventDeliveryFailed), RecordSelfServeHealth and SetSelfServeReason (now transactions with their events) and the operator status door (its ?log=1 query). Server.estimate, Store.AbortSelfServe, Store.AdvanceSelfServeToStep, Store.ConsumeSelfServeRequest and Store.migrateSelfServe are re-pinned in place. The seal moves. The internal/console envelope is re-pinned in place.
@legacy 990c2a58e7657184add84d7aa4ba65124f5e45b13e68d06918e9a07de08c4b67 internal/console/apiinstancemove_offline.go Server.handleAPIInstanceOfflineStatus legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the operator offline status door; its site is the request URL's Query (the ?log=1 switch for the move's events, self-serve moves 2 Task 9), not a file; it reads the record through offlineGate and the console SQLite journal; no root action file:Query@213 2341180d34b7c3be07f910ab719c9ec40254de662d414c7ba4a4a7feb59b0b40
internal/console/apiinstancemove_offline.go Server.handleAPIInstanceOfflineStatus legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the operator offline status door; its site is the request URL's Query (the ?log=1 switch for the move's events, self-serve moves 2 Task 9), not a file; it reads the record through offlineGate and the console SQLite journal; no root action file:Query@213 2341180d34b7c3be07f910ab719c9ec40254de662d414c7ba4a4a7feb59b0b40
-@legacy 610946fe48a8f52616660f3906324e42c79fef3a50b8a8720321d0ec3f7ca657 internal/console/selfserve_estimate.go Server.estimateRules legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the estimate's terms refined from the region pair's move_timings medians in the console SQLite; its sites are the Open term (a struct field named Open), not a file; no root action file:Open@1175,file:Open@74 8d9cb059e2e641c9d313e08034839663488651b18b1d99dd091be50bb2b980f6
-internal/console/selfserve_estimate.go Server.estimateRules legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the estimate's terms refined from the region pair's move_timings medians in the console SQLite; its sites are the Open term (a struct field named Open), not a file; no root action file:Open@1175,file:Open@74 8d9cb059e2e641c9d313e08034839663488651b18b1d99dd091be50bb2b980f6
+@legacy 8d6e27c7315d7d62d2ce12c20a69d6fbfb8c01d4b318210194bdf39e21d6a836 internal/console/selfserve_estimate.go Server.estimateRules legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the estimate's terms refined from the region pair's move_timings medians in the console SQLite; its sites are the Open term (a struct field named Open), not a file; no root action; fix round 1: every term's fixed part from the rows under 1 MiB, a rate term's rate from the rows of at least 1 MiB measured past that fixed part (moveTimingWindow) file:Open@1257,file:Open@74 e32e6fdff0fef5b31e40266b7d6ed451f41e8bcf73efb778c848bbe3f152673e
+internal/console/selfserve_estimate.go Server.estimateRules legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: the estimate's terms refined from the region pair's move_timings medians in the console SQLite; its sites are the Open term (a struct field named Open), not a file; no root action; fix round 1: every term's fixed part from the rows under 1 MiB, a rate term's rate from the rows of at least 1 MiB measured past that fixed part (moveTimingWindow) file:Open@1257,file:Open@74 e32e6fdff0fef5b31e40266b7d6ed451f41e8bcf73efb778c848bbe3f152673e
@legacy 66f14cd5f12b609aa5a53aa4e9c9ca2a6f8de2deb410b7f4841e4145192b6c4e internal/console/selfserve_estimate.go Store.InsertMoveTiming legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: one INSERT ... ON CONFLICT DO NOTHING of a finished move's phase timing into the console SQLite move_timings; no bucket or root action file:Exec@208 cab08b1af56d4130e2c83e77d7324558c1e336edf3aefdc0455fad80d242f886
internal/console/selfserve_estimate.go Store.InsertMoveTiming legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: one INSERT ... ON CONFLICT DO NOTHING of a finished move's phase timing into the console SQLite move_timings; no bucket or root action file:Exec@208 cab08b1af56d4130e2c83e77d7324558c1e336edf3aefdc0455fad80d242f886
@legacy 0a99bf6b173528019e217c62566e3e9b7e0f9a0f695c962fa8425ff89977d87d internal/console/selfserve_estimate.go Store.MarkSelfServeTiming legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: one console SQLite transaction that checks the self-serve row exists and inserts its timing mark insert-only (ssMarkTx); no bucket or root action file:QueryRow@210 d67ab8a6b3d3144a9ea18be9d37c7053635cb8f01c2c52368193445ad0ab92db
internal/console/selfserve_estimate.go Store.MarkSelfServeTiming legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: one console SQLite transaction that checks the self-serve row exists and inserts its timing mark insert-only (ssMarkTx); no bucket or root action file:QueryRow@210 d67ab8a6b3d3144a9ea18be9d37c7053635cb8f01c2c52368193445ad0ab92db
-@legacy 5eca6c14c25b5477a782de5cb2de4142b99a2af0e02729d710b144900040848e internal/console/selfserve_estimate.go Store.MoveTimings legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads the region pair's newest move_timings rows of one phase from the console SQLite for the estimate's medians; no bucket or root action file:Query@117 2e8cfbae053573fcf997e8d05d06ef3b2a3c200e19dda7278dbb5d24a8e902ec
-internal/console/selfserve_estimate.go Store.MoveTimings legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads the region pair's newest move_timings rows of one phase from the console SQLite for the estimate's medians; no bucket or root action file:Query@117 2e8cfbae053573fcf997e8d05d06ef3b2a3c200e19dda7278dbb5d24a8e902ec
@legacy a7e744a590f3b1b2c98b2f3b295af0174401e4ceff23c352e789db74b97ba4be internal/console/selfserve_estimate.go Store.SelfServeTimings legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads one self-serve row's timing marks from the console SQLite; no bucket or root action file:Query@91 994cc662ff52770f6f54dbc1d89aa51dfb726e68174a797da9ad85d03aed6868
internal/console/selfserve_estimate.go Store.SelfServeTimings legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads one self-serve row's timing marks from the console SQLite; no bucket or root action file:Query@91 994cc662ff52770f6f54dbc1d89aa51dfb726e68174a797da9ad85d03aed6868
@legacy f24b99944010633cde8a38a952c9314c189649f432f65c8beb6c06fd23449d49 internal/console/selfserve_estimate.go ssMarkTx legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: inserts a timing mark into self_serve_timings insert-only (ON CONFLICT DO NOTHING) and, only when inserted, its timing event, inside the caller's console SQLite transaction; no bucket or root action file:Exec@114 437d4b8e5753538ece597200a6966104357062eb38c76fea2fabd371ba685882
@@ -229,5 +227,8 @@ internal/console/selfserve_events.go Store.selfServeEventDeliveryFailed legacy a
internal/console/selfserve_events.go ssRowEventTx legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads the self-serve row's phase inside the caller's console SQLite transaction to name a non-phase event; no bucket or root action file:QueryRow@145 0178919c9abe7899ec610cec24880fbe7e8f93b7483f3de4a2d0b534ead8688b
@legacy d25280e2618dba815899677401dcfe262c5f70fe4a4e1d9602a0685f0e17ae14 internal/console/selfserve_store.go Store.RecordSelfServeHealth legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: counts one health probe on a self-serve row and inserts its health:probe event in one console SQLite transaction (it used setSelfServe before self-serve moves 2 Task 9); no bucket or root action file:Exec@303 920990b6764563c6ee59d29d2df3c865663481fd4c18992af001d66ca5938b42
internal/console/selfserve_store.go Store.RecordSelfServeHealth legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: counts one health probe on a self-serve row and inserts its health:probe event in one console SQLite transaction (it used setSelfServe before self-serve moves 2 Task 9); no bucket or root action file:Exec@303 920990b6764563c6ee59d29d2df3c865663481fd4c18992af001d66ca5938b42
-@legacy 67af16969da64c16d52ccf335bf04c93b29bed42fb4cd0d75e3f1a8b35358aac internal/console/selfserve_store.go Store.SetSelfServeReason legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads a self-serve row's reason and sets the new one, inserting a waiting event only when it changed, in one console SQLite transaction (it used setSelfServe before self-serve moves 2 Task 9); no bucket or root action file:Exec@398,file:QueryRow@168 2140c1c8be9cd230d807b93778faf146f025b5a1b2a533c935e6ddf9f55eda5b
-internal/console/selfserve_store.go Store.SetSelfServeReason legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads a self-serve row's reason and sets the new one, inserting a waiting event only when it changed, in one console SQLite transaction (it used setSelfServe before self-serve moves 2 Task 9); no bucket or root action file:Exec@398,file:QueryRow@168 2140c1c8be9cd230d807b93778faf146f025b5a1b2a533c935e6ddf9f55eda5b
+@legacy 51232553f83142a5924adb4595ef9640aafbdbd45b2d19bf676f7b5173a3e9b8 internal/console/selfserve_store.go Store.SetSelfServeReason legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads a self-serve row's reason and sets the new one, inserting a waiting event only when it changed, in one console SQLite transaction (it used setSelfServe before self-serve moves 2 Task 9); no bucket or root action; fix round 1: the waiting event is stamped with the caller's tick clock file:Exec@413,file:QueryRow@183 075dc66bb1564ba52f06f858728e7c66eeba015ff0a4fe9f06df1accf67fbe5b
+internal/console/selfserve_store.go Store.SetSelfServeReason legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads a self-serve row's reason and sets the new one, inserting a waiting event only when it changed, in one console SQLite transaction (it used setSelfServe before self-serve moves 2 Task 9); no bucket or root action; fix round 1: the waiting event is stamped with the caller's tick clock file:Exec@413,file:QueryRow@183 075dc66bb1564ba52f06f858728e7c66eeba015ff0a4fe9f06df1accf67fbe5b
+# Task 9 fix round 1, rev3=PROPOSED-self-serve-moves-2: Store.MoveTimings's query moved to moveTimings (shared with the estimate's moveTimingWindow), so MoveTimings's Task 9 rows, never ruled on, are withdrawn and moveTimings is frozen accepted-legacy; Server.estimateRules (the rate measured past the fixed part) and Store.SetSelfServeReason (the event at the tick's clock) are re-pinned in place; the internal/console envelope is re-pinned in place.
+@legacy a1db4c994658cab78fcca3beaf136fb95c0947c9917243d5aab839b83b1205a4 internal/console/selfserve_estimate.go Store.moveTimings legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads the region pair's newest move_timings rows of one phase under a fixed condition (all rows, the rated rows or the rows under the rate floor) from the console SQLite, for MoveTimings and the estimate's window; no bucket or root action file:Query@107 a3d3e331cce891a1d9ef679ad09651bf50e5f6a303dfae40c5964654829f24c3
+internal/console/selfserve_estimate.go Store.moveTimings legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-2;basis=console.service user carlos-console, J4 root-input: reads the region pair's newest move_timings rows of one phase under a fixed condition (all rows, the rated rows or the rows under the rate floor) from the console SQLite, for MoveTimings and the estimate's window; no bucket or root action file:Query@107 a3d3e331cce891a1d9ef679ad09651bf50e5f6a303dfae40c5964654829f24c3