carlos / platform Public

census: the plan 4 overlay, PROPOSED-self-serve-moves-4: Task 1's gone evidence and Task 2a's table frozen accepted-legacy, and PutOnce a record-write census method

The root-read overlay plan14-root-reads-self-serve-moves-4.tsv takes
Task 1's sixteen discrepancies (offlineSourceGone re-pinned; the retired
file's scan, move-aside, stub and temp writer and offlinecleanup's
Identify, RootOnlyChain, RootOnlyDir and fstatat frozen with reviewed
bases; five envelopes) and Task 2a's newEpoch (crypto/rand), loaded after
plan 3's seal with a new seal. plan14SelfServeMoves4WriteCensusInventory
wraps plan 3's, classifies release.PutOnce and its implementations as
record transports and moves.sendTableWrite as nonrecord, and
TestPlan9B8RecordWriteCensus takes it. The note starts with the loader
block. Every row awaits Paul's ruling.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 3ff5cd55e8b4772a08b620a6de4aa594d00f3ab5 parent 8c258e1
5 files changed, +157 −1
  • docs/superpowers/notes/census-proposal-self-serve-moves-4.md +53 −0
  • internal/provision/plan14_root_reads_test.go +17 −0
  • internal/provision/plan9_b8_census_test.go +5 −1
  • internal/provision/self_serve_moves4_census_test.go +52 −0
  • internal/provision/testdata/plan14-root-reads-self-serve-moves-4.tsv +30 −0
diff --git a/docs/superpowers/notes/census-proposal-self-serve-moves-4.md b/docs/superpowers/notes/census-proposal-self-serve-moves-4.md
new file mode 100644
index 000000000..5d6c661a2
--- /dev/null
+++ b/docs/superpowers/notes/census-proposal-self-serve-moves-4.md
@@ -0,0 +1,53 @@
+# Self-serve moves plan 4: census proposal
+
+Status: proposed, marked PROPOSED-self-serve-moves-4. Not an accepted ruling; the census rulings on this plan are Paul's to make.
+
+The root-read overlay is `internal/provision/testdata/plan14-root-reads-self-serve-moves-4.tsv`. It is loaded in `TestPlan14RootReadCensus` (`internal/provision/plan14_root_reads_test.go`) after every existing overlay block and before `compareRootReads`, with the preceding seal (plan 3's, `96ef4caf…`) verified first:
+
+```go
+if errs := checkRootReadLegacy(inv, seal); len(errs) != 0 {
+ t.Fatal(errs)
+}
+if err = loadRootReadInventory(root+"/internal/provision/testdata/plan14-root-reads-self-serve-moves-4.tsv", &inv, true); err != nil {
+ t.Fatal(err)
+}
+seal = "3cc0a0a022cf14a6c796599efd697d51339d60eb7de094748995151633c59075"
+```
+
+The record-write overlay is `plan14SelfServeMoves4WriteCensusInventory` in `internal/provision/self_serve_moves4_census_test.go`, built over plan 3's inventory; `TestPlan9B8RecordWriteCensus` takes it. Every later task of the plan re-pins or adds its rows in both, so no push carries a red census.
+
+## Task 1: the obligation and its evidence at gone (with its fix round 1)
+
+No record envelope changes. No root read class or task is added beyond accepted legacy.
+
+`internal/host/movesoffline.go:movesWorker.offlineSourceGone` (accepted legacy since census-ruling-moves-offline) is re-pinned in place. On the sealing source box, once the row is gone, it records the cleanup obligation (`recordRetired`) before the gone report, and an error there writes no gone report this pass. Its read site is unchanged.
+
+Eight new units are frozen as accepted legacy. All run in the agent (`carlos-edge.service`, user `carlos`) or have no production caller yet:
+
+- `movescleanup_retired.go:scanRetired`: the corrupt scan of the move's own `retired.json`, under the agent's own data directory. It makes an Lstat of the file and of `retired.json.corrupt-1`, and a ReadFile only when the Lstat shows a regular file, so no link is followed to read.
+- `movescleanup_retired.go:moveAsideCorrupt`: Lstat, a create-only `os.Link` to the first free `.corrupt-<n>`, `os.Remove` of the original and a directory fsync. It reads no content.
+- `movescleanup_retired.go:writeCorruptStub`: an Lstat of `.corrupt-1` for its mtime, then a create-only write of the stub.
+- `movescleanup_retired.go:writeSyncedTemp`: `os.CreateTemp` in the obligation's own directory. It creates a file and reads nothing.
+- `offlinecleanup/layout_linux.go:Identify`: an Lstat and, for a symlink, a Readlink of the link itself. Nothing is followed or opened.
+- `offlinecleanup/layout_linux.go:RootOnlyChain`: an Lstat of each directory in the chain, none followed.
+- `offlinecleanup/layout_linux.go:RootOnlyDir`: an fstat of a directory the caller already opened. No production caller until Task 6c.
+- `offlinecleanup/fstatat_linux_amd64.go:fstatat` and `fstatat_linux_arm64.go:fstatat`: the raw fstatat behind `RootOwned`, which passes `AT_SYMLINK_NOFOLLOW`. No production caller until Task 6b.
+
+`Identify`, `RootOnlyChain`, `RootOnlyDir` and the two `fstatat` units will be called by root's adopt pass from Tasks 6b and 6c. Those tasks re-pin each row with root's process as its basis; the bases written now name only the agent.
+
+Envelopes added or re-pinned: `internal/host`, `internal/lease/leasetest` and `internal/offlinecleanup`.
+
+## Task 2a: the table's kinds, epoch and rev, and its single-attempt writes
+
+One new unit is frozen as accepted legacy: `internal/moves/reserve.go:newEpoch`, J4 root-input. It reads crypto/rand for the reservation table's 16-byte epoch, as the console's other random ids do. It runs in the console and, armed, in the agent. Root reads the table only through `moves.PeekActive`, which never reaches it. The table's readers, its release and its writes read no file.
+
+Envelopes re-pinned: `internal/moves` and `internal/release`. The seal moves.
+
+The record-write census changes in two ways:
+
+- **A proposed census rule: `PutOnce` is a write method.** `release.PutOnce` is a new write primitive beside `Put`. Without this rule a record written through it would not be seen, so `censusMethods` gains `PutOnce`. This is a change to the census itself, not only a row, and is the ruling this task asks for.
+- Six units are classified. `type SingleAttemptPutter` is a reference, as `type Store` and `type PutStreamer` are. `PutOnce`, `S3Store.PutOnce`, `DirStore.PutOnce` and `prefixStore.PutOnce` are record transports that carry whatever key their caller names, as `Put`'s implementations are. `moves.sendTableWrite`, their one caller, is nonrecord: it writes only `control/offline-moves/active.json`, which `TestEveryTableWriteGoesThroughPutTable` pins.
+
+`S3Store.Put` keeps its reviewed digest. `S3Store.PutOnce` restates its body rather than sharing a helper that would move it.
+
+The console's `Server.reserveBoxes` and `Server.releaseBoxes` stay nonrecord `sel:Put` rows until Task 2b rewrites them over `moves.PutTable`. That task removes or re-pins those rows.
diff --git a/internal/provision/plan14_root_reads_test.go b/internal/provision/plan14_root_reads_test.go
index d5855f9ed..b97023e53 100644
--- a/internal/provision/plan14_root_reads_test.go
+++ b/internal/provision/plan14_root_reads_test.go
@@ -1411,6 +1411,23 @@ func TestPlan14RootReadCensus(t *testing.T) {
// the now read-free Reload as a hint, and drops watchTick's and the
// removed refreshHoldRows' freezes, which moves it again.
seal = "96ef4cafa75370223a0a6d48fe1ffe8ad583e7cd5e5ef4cb5f73859acbc308f9"
+ // Self-serve moves plan 4 (cleanup): verify the preceding seal first. All
+ // rows await a human ruling under rev3=PROPOSED-self-serve-moves-4.
+ if errs := checkRootReadLegacy(inv, seal); len(errs) != 0 {
+ t.Fatal(errs)
+ }
+ if err = loadRootReadInventory(root+"/internal/provision/testdata/plan14-root-reads-self-serve-moves-4.tsv", &inv, true); err != nil {
+ t.Fatal(err)
+ }
+ // Task 1 (the obligation and its evidence at gone) re-pins
+ // offlineSourceGone in place (it records retired.json on the sealing
+ // source box before the gone report) and freezes eight new units: the
+ // retired file's scan, move-aside, stub and temp writer in
+ // movescleanup_retired.go, and offlinecleanup's Identify, RootOnlyChain,
+ // RootOnlyDir and the two fstatat files. Task 2a (the table's kinds,
+ // epoch and rev) freezes moves.newEpoch (crypto/rand). Together they
+ // move the seal.
+ seal = "3cc0a0a022cf14a6c796599efd697d51339d60eb7de094748995151633c59075"
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 c1e45ae28..36471369b 100644
--- a/internal/provision/plan9_b8_census_test.go
+++ b/internal/provision/plan9_b8_census_test.go
@@ -42,11 +42,15 @@ import (
type censusEntry struct{ File, Unit, Class, Kinds, Digest string }
+// PutOnce (self-serve moves plan 4 Task 2a, PROPOSED-self-serve-moves-4) is
+// release.Store's single-attempt Put: a write primitive like Put, so a
+// record written through it cannot leave the census.
var censusMethods = map[string]bool{
"Put": true, "PutFrom": true, "PutIfAbsent": true, "CopyVersion": true,
"PutObjectFrom": true, "PutReplace": true,
"PutIfAbsentVersioned": true, "PutIfAbsentVersionedAt": true,
"CopyVersioned": true, "CopyVersionedAt": true,
+ "PutOnce": true,
}
// Lower-cased identifier suffixes / exact names that mark a record-key or
@@ -369,7 +373,7 @@ func TestPlan9B8RecordWriteCensus(t *testing.T) {
if len(got) < 100 {
t.Fatalf("census found only %d units under %s; the walk is broken", len(got), root)
}
- inventory := plan14SelfServeMoves3WriteCensusInventory()
+ inventory := plan14SelfServeMoves4WriteCensusInventory()
problems := append(censusDiff(inventory, got), censusPolicy(inventory)...)
if len(problems) > 0 {
t.Fatalf("record-write census rejected %d site(s); update the explicit inventory only after reviewing the source:\n %s", len(problems), strings.Join(problems, "\n "))
diff --git a/internal/provision/self_serve_moves4_census_test.go b/internal/provision/self_serve_moves4_census_test.go
new file mode 100644
index 000000000..ed46cd604
--- /dev/null
+++ b/internal/provision/self_serve_moves4_census_test.go
@@ -0,0 +1,52 @@
+package provision
+
+// plan14SelfServeMoves4WriteCensusInventory is the record-write inventory for
+// the self-serve moves plan 4 (cleanup), built over plan 3's inventory
+// without editing it. Marked PROPOSED-self-serve-moves-4
+// (docs/superpowers/notes/census-proposal-self-serve-moves-4.md); not an
+// accepted ruling. Later tasks of the plan extend this function.
+//
+// Task 1 (the obligation at gone): no record write is added, moved or made
+// raw. retired.json is a local file under the box's data directory, and the
+// gone report's bucket write is putOfflineReport's, unchanged.
+//
+// Task 2a (the table's kinds, epoch and rev, and its single-attempt writes):
+// - release.PutOnce is a new write primitive beside Put, so censusMethods
+// gains PutOnce (a record written through it cannot leave the census).
+// Its units are transports that carry whatever key their caller names,
+// as Put's are: the dispatcher PutOnce, S3Store.PutOnce (Put's body sent
+// as one attempt, through a per-call NopRetryer), DirStore.PutOnce (Put),
+// prefixStore.PutOnce (rebases the key and forwards) and the interface
+// SingleAttemptPutter (a reference, as type Store and type PutStreamer
+// are).
+// - moves.sendTableWrite is the one caller: it writes only
+// moves.OfflineActiveKey (control/offline-moves/active.json), never a
+// record key, which TestEveryTableWriteGoesThroughPutTable pins.
+// - S3Store.Put is unchanged (PutOnce restates its body rather than
+// sharing a helper that would move it).
+func plan14SelfServeMoves4WriteCensusInventory() []censusEntry {
+ removed := []struct{ file, unit string }{}
+ added := []censusEntry{
+ {"internal/release/store.go", "type SingleAttemptPutter", "reference", "id:PutOnce", "4a2685f4f883cc19b845f5410952b3b689e814b0887bcce983f405da89191a3e"},
+ {"internal/release/store.go", "PutOnce", "record-transport", "def:PutOnce,sel:PutOnce", "19e681f034ce499d6d1d2382400a5f2c416af13775c1a6c24b81ab79356decc6"},
+ {"internal/release/store.go", "prefixStore.PutOnce", "record-transport", "def:PutOnce,id:PutOnce", "bff65b4c0c2b00171fe9806232288d22cdd19ceece4cde2bef25e2d7c5512929"},
+ {"internal/release/store.go", "DirStore.PutOnce", "record-transport", "def:PutOnce,sel:Put", "daca0996246008c50ee4b45ac8778557e42c42afc6a85e523ab8d5c026ba1cd7"},
+ {"internal/release/store.go", "S3Store.PutOnce", "record-transport", "def:PutOnce", "d45f4878ae80425122d3dc60ad23e80d5aa3da3e671f39a49a2dcc928415215c"},
+ {"internal/moves/tablewrite.go", "sendTableWrite", "nonrecord", "sel:PutOnce", "2a5067b7fbfa13b42e49c3723422c42e61647295d63216e05c365c862050dd4c"},
+ }
+ entries := plan14SelfServeMoves3WriteCensusInventory()
+ for _, r := range removed {
+ found := false
+ for i, entry := range entries {
+ if entry.File == r.file && entry.Unit == r.unit {
+ entries = append(entries[:i], entries[i+1:]...)
+ found = true
+ break
+ }
+ }
+ if !found {
+ panic("self-serve moves 4 removal of an unlisted unit " + r.file + ":" + r.unit)
+ }
+ }
+ return append(entries, added...)
+}
diff --git a/internal/provision/testdata/plan14-root-reads-self-serve-moves-4.tsv b/internal/provision/testdata/plan14-root-reads-self-serve-moves-4.tsv
new file mode 100644
index 000000000..e390d329d
--- /dev/null
+++ b/internal/provision/testdata/plan14-root-reads-self-serve-moves-4.tsv
@@ -0,0 +1,30 @@
+# Census overlay self-serve-moves-4, marked rev3=PROPOSED-self-serve-moves-4 (not an accepted ruling; docs/superpowers/notes/census-proposal-self-serve-moves-4.md). Loaded after the self-serve-moves-3 overlay.
+# Task 1 (the obligation and its evidence at gone) with its fix round 1, rev3=PROPOSED-self-serve-moves-4: no record envelope changes and no root read class or task is added beyond accepted-legacy. movesWorker.offlineSourceGone (accepted legacy since census-ruling-moves-offline) records the cleanup obligation on the sealing source box before its gone report and is re-pinned in place (read site unchanged, offsets moved). Four new units of internal/host/movescleanup_retired.go (scanRetired, moveAsideCorrupt, writeCorruptStub, writeSyncedTemp) and four of internal/offlinecleanup (Identify, RootOnlyChain, RootOnlyDir, and fstatat in its amd64 and arm64 files) are frozen accepted-legacy with reviewed bases: the agent as carlos in its own data directory, Lstat, Readlink, fstat and fstatat metadata reads that never follow a link, one ReadFile of a regular file the agent wrote, and two units with no production caller until Tasks 6b and 6c, which re-pin them with root's process. Envelopes added or re-pinned: internal/host, internal/lease/leasetest, internal/offlinecleanup.
+# Task 2a (the table's kinds, epoch and rev, and its single-attempt writes), rev3=PROPOSED-self-serve-moves-4: moves.newEpoch is new and frozen accepted-legacy (J4 root-input, crypto/rand for the table's epoch, as the console's other random ids); the table's readers, release and writes read no file. release gains SingleAttemptPutter and PutOnce (S3Store, DirStore, prefixStore), which read nothing. The record-write census gains PutOnce as a write method (plan14SelfServeMoves4WriteCensusInventory). The seal moves. Envelopes re-pinned: internal/moves, internal/release.
+@legacy 74fb3b90400ab84ce62dbd77469e292595d9ad5f463f71f6553d0a090c515383 internal/host/movescleanup_retired.go moveAsideCorrupt legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: moves a damaged retired.json aside create-only: an Lstat of the file, os.Link to the first free retired.json.corrupt-<n> (a name already holding the same inode, by Lstat and os.SameFile, counts as the target, which covers a crash after the link), os.Remove of the original and a directory fsync; reads no content; a link refused for permission is errRetiredUnmovable (fix round 1); scanRetired's only file:Lstat@514,file:Lstat@65 3125aba7d2f7910dbe8fd4624ebd44dc71d4a8c5574cb2d268f777b1c191188a
+internal/host/movescleanup_retired.go moveAsideCorrupt legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: moves a damaged retired.json aside create-only: an Lstat of the file, os.Link to the first free retired.json.corrupt-<n> (a name already holding the same inode, by Lstat and os.SameFile, counts as the target, which covers a crash after the link), os.Remove of the original and a directory fsync; reads no content; a link refused for permission is errRetiredUnmovable (fix round 1); scanRetired's only file:Lstat@514,file:Lstat@65 3125aba7d2f7910dbe8fd4624ebd44dc71d4a8c5574cb2d268f777b1c191188a
+@legacy a0509323f7af3ad73b961e8b8f2447494ba49e2250cf231709a67e41372a4c4c internal/host/movescleanup_retired.go scanRetired legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: the corrupt scan of this move's own obligation file, moves.RetiredFile (<data>/.offline-moves/<host>/<op>/retired.json, under the agent's own data directory, which it creates and owns): an Lstat of retired.json and of retired.json.corrupt-1, and a ReadFile of retired.json only when its Lstat shows a regular file (no link is followed to read); a body that is neither a valid Retired nor a valid stub of this obligation is moved aside (moveAsideCorrupt) and a stub written (writeCorruptStub); reached only from recordRetired at gone; never run by root file:Lstat@158,file:Lstat@80,file:ReadFile@491 740947f051de79c814b5a3f4a959c334933b0880471d17a83935ba6cc14ee907
+internal/host/movescleanup_retired.go scanRetired legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: the corrupt scan of this move's own obligation file, moves.RetiredFile (<data>/.offline-moves/<host>/<op>/retired.json, under the agent's own data directory, which it creates and owns): an Lstat of retired.json and of retired.json.corrupt-1, and a ReadFile of retired.json only when its Lstat shows a regular file (no link is followed to read); a body that is neither a valid Retired nor a valid stub of this obligation is moved aside (moveAsideCorrupt) and a stub written (writeCorruptStub); reached only from recordRetired at gone; never run by root file:Lstat@158,file:Lstat@80,file:ReadFile@491 740947f051de79c814b5a3f4a959c334933b0880471d17a83935ba6cc14ee907
+@legacy 950bdef85b1823e35676563c684f191ed951ee6348e1a4f2a4edc49391786baa internal/host/movescleanup_retired.go writeCorruptStub legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: an Lstat of retired.json.corrupt-1 for its mtime (the stub's found_at), then a create-only write of the stub at retired.json (createFile); reads no content file:Lstat@104 c3e53cc1711dcdafbdbc3488a04eb29b42760ac5e10c4192c956cce8c051c4cf
+internal/host/movescleanup_retired.go writeCorruptStub legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: an Lstat of retired.json.corrupt-1 for its mtime (the stub's found_at), then a create-only write of the stub at retired.json (createFile); reads no content file:Lstat@104 c3e53cc1711dcdafbdbc3488a04eb29b42760ac5e10c4192c956cce8c051c4cf
+@legacy fd306dd518ac5210075f623fdad88eacfac9d111993f81f8e364bb911b61a931 internal/host/movescleanup_retired.go writeSyncedTemp legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: os.CreateTemp of a .retired-*.tmp in the obligation's own directory, written and fsynced, for createRetired's link and writeRetired's rename; creates a file and reads nothing file:CreateTemp@75 7af3a1e071604c3aa879221d2220f6192f26aae880b013b0ade182d5be0b1bcc
+internal/host/movescleanup_retired.go writeSyncedTemp legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: os.CreateTemp of a .retired-*.tmp in the obligation's own directory, written and fsynced, for createRetired's link and writeRetired's rename; creates a file and reads nothing file:CreateTemp@75 7af3a1e071604c3aa879221d2220f6192f26aae880b013b0ade182d5be0b1bcc
+@legacy e58cc52c2b72ca9a090d247c9f02ae8fbe0e6d3d741954d4a41a9e1988cd6f7d internal/host/movesoffline.go movesWorker.offlineSourceGone legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=root-route (J1, as main's moves units); the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, reads the row at offline-finishing and reports gone once reconcile has removed it; lifts this move's own fence; self-serve moves 2 Task 6: writes its report through putOfflineReport, which stamps the box's identity (box id, instance id); self-serve moves 4 Task 1: on the sealing source box (cfg.offlineRoles), once the row is gone, records the cleanup obligation first (recordRetired: retired.json under the agent's own data directory, the local reads it makes frozen in their own units below), and a recordRetired error writes no gone report this pass; read sites unchanged whole:Route@236 1a9ab9301d52273da1facccfd8c6f4e02a42ba68a5e23126e576688df66f82fb
+internal/host/movesoffline.go movesWorker.offlineSourceGone legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=root-route (J1, as main's moves units); the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, reads the row at offline-finishing and reports gone once reconcile has removed it; lifts this move's own fence; self-serve moves 2 Task 6: writes its report through putOfflineReport, which stamps the box's identity (box id, instance id); self-serve moves 4 Task 1: on the sealing source box (cfg.offlineRoles), once the row is gone, records the cleanup obligation first (recordRetired: retired.json under the agent's own data directory, the local reads it makes frozen in their own units below), and a recordRetired error writes no gone report this pass; read sites unchanged whole:Route@236 1a9ab9301d52273da1facccfd8c6f4e02a42ba68a5e23126e576688df66f82fb
+@legacy 10a98e287f47b7a5ac99463b8f0ac2d8d647768b160a13f9bedab7372d9cbd0b internal/moves/reserve.go newEpoch legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=J4 root-input: reads crypto/rand for the reservation table's 16-byte epoch (self-serve moves 4 Task 2a), minted when the table is created and when a body without one (a console before plan 4 wrote it) is next written; runs in the console (cmd/console serve under console.service, user carlos-console) and, armed, in the agent (carlos-edge.service, user carlos); root's reads of the table are moves.PeekActive, which never reaches it; randomness grants no root authority file:Read@55 a8d1666dc52203b179a2787590321d7362d03b62731b13110ba9b017c6cf89b5
+internal/moves/reserve.go newEpoch legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=J4 root-input: reads crypto/rand for the reservation table's 16-byte epoch (self-serve moves 4 Task 2a), minted when the table is created and when a body without one (a console before plan 4 wrote it) is next written; runs in the console (cmd/console serve under console.service, user carlos-console) and, armed, in the agent (carlos-edge.service, user carlos); root's reads of the table are moves.PeekActive, which never reaches it; randomness grants no root authority file:Read@55 a8d1666dc52203b179a2787590321d7362d03b62731b13110ba9b017c6cf89b5
+@legacy e943c2ffd5d6b1ab95e408b535b755a129ba39dc0d978fe8e7b93d197701f1f7 internal/offlinecleanup/fstatat_linux_amd64.go fstatat legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=no production caller yet: RootOwned's metadata read (self-serve moves 4 Task 1), which nothing calls before Task 6b: the raw SYS_NEWFSTATAT under an opened directory with the caller's flags (RootOwned passes AT_SYMLINK_NOFOLLOW, so a link is judged, never followed); reads metadata only; Task 6b re-pins this row with the root adopt pass's process file:Syscall6@164 abd305c50f40b255be7d1a031e790299c3a82470865b1fe835d76991e3471047
+internal/offlinecleanup/fstatat_linux_amd64.go fstatat legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=no production caller yet: RootOwned's metadata read (self-serve moves 4 Task 1), which nothing calls before Task 6b: the raw SYS_NEWFSTATAT under an opened directory with the caller's flags (RootOwned passes AT_SYMLINK_NOFOLLOW, so a link is judged, never followed); reads metadata only; Task 6b re-pins this row with the root adopt pass's process file:Syscall6@164 abd305c50f40b255be7d1a031e790299c3a82470865b1fe835d76991e3471047
+@legacy 946214218c085c0dda7c87e581b50635c9383e5408a69ac5767a3309d54495f9 internal/offlinecleanup/fstatat_linux_arm64.go fstatat legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=no production caller yet: RootOwned's metadata read (self-serve moves 4 Task 1), which nothing calls before Task 6b: syscall.Fstatat under an opened directory with the caller's flags (RootOwned passes AT_SYMLINK_NOFOLLOW, so a link is judged, never followed); reads metadata only; Task 6b re-pins this row with the root adopt pass's process file:Fstatat@84 b2a577320150878480e9e46a3d141f524ed9cb037497271b75f0989bbca557aa
+internal/offlinecleanup/fstatat_linux_arm64.go fstatat legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=no production caller yet: RootOwned's metadata read (self-serve moves 4 Task 1), which nothing calls before Task 6b: syscall.Fstatat under an opened directory with the caller's flags (RootOwned passes AT_SYMLINK_NOFOLLOW, so a link is judged, never followed); reads metadata only; Task 6b re-pins this row with the root adopt pass's process file:Fstatat@84 b2a577320150878480e9e46a3d141f524ed9cb037497271b75f0989bbca557aa
+@legacy 081c6fed624bca1328d0f0e7119a54bde26717588f16dd18420c32990e9be0fe internal/offlinecleanup/layout_linux.go Identify legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: the gone evidence's identity of one local path (the live link, the programs file): an Lstat and, for a symlink, a Readlink of the link itself; nothing is followed or opened; another file type is ErrUnexpectedType, which the caller keeps the path for (fix round 1); called from recordRetired's localInventory; a root caller (Tasks 6b and 6c) re-pins this row with its process file:Lstat@69,file:Readlink@492 3b2fe5962a96fc50661efb700e0b79240d940200710502ec53dad2479fa3f6d7
+internal/offlinecleanup/layout_linux.go Identify legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: the gone evidence's identity of one local path (the live link, the programs file): an Lstat and, for a symlink, a Readlink of the link itself; nothing is followed or opened; another file type is ErrUnexpectedType, which the caller keeps the path for (fix round 1); called from recordRetired's localInventory; a root caller (Tasks 6b and 6c) re-pins this row with its process file:Lstat@69,file:Readlink@492 3b2fe5962a96fc50661efb700e0b79240d940200710502ec53dad2479fa3f6d7
+@legacy 46ab7982cf7458d2e9c9214a39687e3b447ee1052ad23b949d5c5ecd2a46e778 internal/offlinecleanup/layout_linux.go RootOnlyChain legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: judges a directory chain root-only: an Lstat of each directory from / (or from an e2e trust base, SetTrustForE2E) down to dir, none followed, each a directory owned by uid 0 and writable by no one else; reads no content; called from recordRetired's localInventory through moveCfg.rootOnlyChain; Tasks 6b and 6c's root checks re-pin this row with their process file:Lstat@375 95eb4ec59b23f2497e06e55b0fa73c942f414c485f03d015a9405beb555e15c1
+internal/offlinecleanup/layout_linux.go RootOnlyChain legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, self-serve moves 4 Task 1: judges a directory chain root-only: an Lstat of each directory from / (or from an e2e trust base, SetTrustForE2E) down to dir, none followed, each a directory owned by uid 0 and writable by no one else; reads no content; called from recordRetired's localInventory through moveCfg.rootOnlyChain; Tasks 6b and 6c's root checks re-pin this row with their process file:Lstat@375 95eb4ec59b23f2497e06e55b0fa73c942f414c485f03d015a9405beb555e15c1
+@legacy 036ee28f00d6dbe7cdc060fe710b3d77ded995f815fd4685178a8ac7c381a409 internal/offlinecleanup/layout_linux.go RootOnlyDir legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=no production caller yet: self-serve moves 4 Task 1 declares it for Task 6c's root step: an fstat (File.Stat) of a directory the caller already opened, judged owned by uid 0 and writable by no one else; reads no content; Task 6c re-pins this row with the root adopt pass's process when it calls it file:Stat@62 5be2487694449a4d06ea5f73bfd1c7c4e5247624e8d59fe02fc304481775159a
+internal/offlinecleanup/layout_linux.go RootOnlyDir legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=no production caller yet: self-serve moves 4 Task 1 declares it for Task 6c's root step: an fstat (File.Stat) of a directory the caller already opened, judged owned by uid 0 and writable by no one else; reads no content; Task 6c re-pins this row with the root adopt pass's process when it calls it file:Stat@62 5be2487694449a4d06ea5f73bfd1c7c4e5247624e8d59fe02fc304481775159a
+@coverage internal/host 7f2b551f39aeb3e76f45e574fea3cc621a7832d77ff648b7d1fb6585695eb6c1
+@coverage internal/lease/leasetest d6b128f048755ffda4632f43a2d417ebe2cb8a81a4e2b296c99ac83af8132f4f
+@coverage internal/moves b5127759ebfc0b2ca957129deac0dcc3ae1255690669662215457354e146a2f8
+@coverage internal/offlinecleanup f3b6902a49c5cd9d7b8567d0e81b3806e9d853524554fcf1981113b519d3202a
+@coverage internal/release ea549ae64c23cd49fccba2c5e298f883f9a94cb10fff10f227b6d884b7ccd0c5