carlos / platform Public

census: Task 3's cleaning mark in the plan 4 overlay, and S3Store.PutOnce re-pinned for the rejection ruling

doWake, ExecBackend.Acquire, serveWakeError and LockState are re-pinned in
place with reviewed bases; the now read-free readLock is reclassified as a
hint and its read frozen as fetchLock; newWriteID (crypto/rand) and
leasetest's Holder.ServeHTTP (a test double) are frozen new; the
activator, host, lease, leasetest, moves and release envelopes are
re-pinned and the seal moves. Every row awaits Paul's ruling under
PROPOSED-self-serve-moves-4.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev f3265f587f616d26e08bc7881b7a470230d548ae parent 45e0b22
4 files changed, +60 −8
  • docs/superpowers/notes/census-proposal-self-serve-moves-4.md +26 −1
  • internal/provision/plan14_root_reads_test.go +6 −2
  • internal/provision/self_serve_moves4_census_test.go +7 −1
  • internal/provision/testdata/plan14-root-reads-self-serve-moves-4.tsv +21 −4

CI failed — run details

CI log
=== gate ===
sigwho: pid 2 ppid 1 pgid 0 sid 0; child pid 3
.amadan/test-gate.sh
gate: 2026-10-24T15:42:42Z on aarch64, 32 cpus, 62124 MB available, go1.26.8 linux/arm64
gate: +0s start launchctx
gate: +0s start vet
gate: +0s start gofmt
gate: +2s start rest
gate: +13s start internal_console@0
gate: +13s start internal_console@1
gate: +13s start internal_console@2
gate: +13s start internal_console@3
gate: +13s start internal_console@4
gate: +13s start internal_console@5
gate: +13s start internal_console@6
gate: +13s start internal_console@7
gate: +13s waiting for internal_console's shards before the next split package
gate: +179s start root@0
gate: +179s start root@1
gate: +179s start root@2
gate: +179s waiting for root's shards before the next split package

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-4.md b/docs/superpowers/notes/census-proposal-self-serve-moves-4.md
index 2c626ec75..3bd16765d 100644
--- a/docs/superpowers/notes/census-proposal-self-serve-moves-4.md
+++ b/docs/superpowers/notes/census-proposal-self-serve-moves-4.md
@@ -11,9 +11,11 @@ if errs := checkRootReadLegacy(inv, seal); len(errs) != 0 {
if err = loadRootReadInventory(root+"/internal/provision/testdata/plan14-root-reads-self-serve-moves-4.tsv", &inv, true); err != nil {
t.Fatal(err)
}
-seal = "3cc0a0a022cf14a6c796599efd697d51339d60eb7de094748995151633c59075"
+seal = "840bb92c2ee7c797ccd4eb48037e0cfc28e561ae7f5f2f28458cd8d69756bf29"
```
+The seal named here is the one in force after Task 3's rows.
+
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)
@@ -52,4 +54,27 @@ The record-write census changes in two ways:
`S3Store.Put` keeps its reviewed digest. `S3Store.PutOnce` restates its body rather than sharing a helper that would move it.
+Task 2a's rejection ruling re-pins `S3Store.PutOnce` in the record-write inventory. It now answers a non-CAS 4xx as `release.ErrPutRejected`, and adds no root read.
+
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.
+
+## Task 3: the cleaning mark, its refusals, the wake's answer and the writer inventory
+
+No record envelope changes. No root read class or task is added beyond accepted legacy.
+
+Re-pinned in place, each with a reviewed basis:
+
+- `activator/activator.go:Service.doWake`: a lease refused because a cleanup holds the replica is logged and the wake refused. Its read sites are unchanged.
+- `activator/backend_exec.go:ExecBackend.Acquire`: a `HeldError` whose owner is a `cleaning:` mark maps to the cleaning refusal without reading its expiry.
+- `activator/activator.go:Service.serveWakeError` (diagnostic, `C,J4`): a cleaning-held wake is answered 503 with `Retry-After: 30`.
+- `lease/lockstate.go:LockState`: a `cleaning:` owner is held whatever its expiry, and other owners' expiries are judged on the lease's clock hook.
+
+`lease/tombstone.go:readLock` is now a wrapper over `readLockBody` and reads nothing itself. It is reclassified from accepted legacy as a read-free hint, so its frozen declaration stays classified, as `Edge.Reload` was in plan 3.
+
+Three new units are frozen as accepted legacy:
+
+- `lease/tombstone.go:fetchLock`: the lock read `readLock` used to make, with its ETag, decoded and bounded. It runs under `readLockBody` and `AcquireTTL`'s pre-read, in every process that acquires a hibernation lease.
+- `lease/cleaning.go:newWriteID`: J4 root-input, crypto/rand for a lock body's write id.
+- `lease/leasetest/hold.go:Holder.ServeHTTP`: a test double that reads each request body. Its one non-test importer is host's end-to-end bridge, which only the e2e witnesses call.
+
+Envelopes added or re-pinned: `internal/activator`, `internal/host`, `internal/lease`, `internal/lease/leasetest`, `internal/moves` and `internal/release` (the last two for Task 2a's rejection ruling). The seal moves to `840bb92c…`.
diff --git a/internal/provision/plan14_root_reads_test.go b/internal/provision/plan14_root_reads_test.go
index b97023e53..3e0c31b39 100644
--- a/internal/provision/plan14_root_reads_test.go
+++ b/internal/provision/plan14_root_reads_test.go
@@ -1426,8 +1426,12 @@ func TestPlan14RootReadCensus(t *testing.T) {
// 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"
+ // move the seal. Task 3 (the cleaning mark and its refusals) re-pins
+ // Service.doWake, ExecBackend.Acquire and LockState in place,
+ // reclassifies the now read-free readLock as a hint and freezes
+ // fetchLock, newWriteID and leasetest's Holder.ServeHTTP, which moves it
+ // again.
+ seal = "840bb92c2ee7c797ccd4eb48037e0cfc28e561ae7f5f2f28458cd8d69756bf29"
errs := append(compareRootReads(got, inv), checkRootReadLegacy(inv, seal)...)
errs = append(errs, checkRootReadDeclarations(got, inv)...)
if len(errs) > 0 {
diff --git a/internal/provision/self_serve_moves4_census_test.go b/internal/provision/self_serve_moves4_census_test.go
index ed46cd604..43f0d1f5c 100644
--- a/internal/provision/self_serve_moves4_census_test.go
+++ b/internal/provision/self_serve_moves4_census_test.go
@@ -24,6 +24,12 @@ package provision
// record key, which TestEveryTableWriteGoesThroughPutTable pins.
// - S3Store.Put is unchanged (PutOnce restates its body rather than
// sharing a helper that would move it).
+// - The rejection ruling re-pins S3Store.PutOnce in place: a non-CAS 4xx
+// (not 408, 429 or a missing bucket's 404) is wrapped as
+// release.ErrPutRejected, an answer. Its kinds are unchanged.
+//
+// Task 3 (the cleaning mark): no record write is added; lock.json is the
+// hibernation lease's object, written through the lease's own S3 client.
func plan14SelfServeMoves4WriteCensusInventory() []censusEntry {
removed := []struct{ file, unit string }{}
added := []censusEntry{
@@ -31,7 +37,7 @@ func plan14SelfServeMoves4WriteCensusInventory() []censusEntry {
{"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/release/store.go", "S3Store.PutOnce", "record-transport", "def:PutOnce", "734c81b2a8533b97c5ba18cf25d15599df3344036c9cb68c1d1a99cfc7e11812"},
{"internal/moves/tablewrite.go", "sendTableWrite", "nonrecord", "sel:PutOnce", "2a5067b7fbfa13b42e49c3723422c42e61647295d63216e05c365c862050dd4c"},
}
entries := plan14SelfServeMoves3WriteCensusInventory()
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
index 68af5109c..daf264c0d 100644
--- a/internal/provision/testdata/plan14-root-reads-self-serve-moves-4.tsv
+++ b/internal/provision/testdata/plan14-root-reads-self-serve-moves-4.tsv
@@ -2,6 +2,7 @@
# 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 1 fix round 2 (8c258e1b), rev3=PROPOSED-self-serve-moves-4: a box with no hibernate region still records its obligation and one with no versioned store never holds gone back. No frozen unit moves and the seal is unchanged; the internal/host and internal/offlinecleanup envelopes are re-pinned in place.
# 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.
+# Task 3 (the cleaning mark, its refusals, the wake's answer and the writer inventory) and Task 2a's rejection ruling, rev3=PROPOSED-self-serve-moves-4: no record envelope changes and no root read class or task is added beyond accepted-legacy. Re-pinned in place with reviewed bases: Service.doWake and ExecBackend.Acquire (a cleaning-held lease refuses the wake), Service.serveWakeError (diagnostic, the 503 with Retry-After: 30) and LockState (a cleaning: owner is held whatever its expiry). readLock is now a read-free wrapper and is reclassified as a hint so its frozen declaration stays classified; its read moved to fetchLock, frozen new. Frozen new: lease.newWriteID (J4 root-input, crypto/rand for the lock body's write id) and leasetest's Holder.ServeHTTP (a test double). Task 2a's rejection ruling (S3Store.PutOnce answers a non-CAS 4xx as release.ErrPutRejected) adds no root read. The seal moves. Envelopes added or re-pinned: internal/activator, internal/host, internal/lease, internal/lease/leasetest, 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
@@ -24,8 +25,24 @@ internal/offlinecleanup/layout_linux.go Identify legacy accepted-legacy accepted
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 9e3d57f0d449e3b793cf02e4759549565e2662f27f8d005789dab7070154a7ca
-@coverage internal/lease/leasetest d6b128f048755ffda4632f43a2d417ebe2cb8a81a4e2b296c99ac83af8132f4f
-@coverage internal/moves b5127759ebfc0b2ca957129deac0dcc3ae1255690669662215457354e146a2f8
+@legacy 85fbcdc148fff63e9afcb16a3086ff84cc720548a86b7846c846db4575ca65d5 internal/activator/activator.go Service.doWake legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): main's body (census ruling 292's legacy start mark and lease give-back; census ruling owed's pending record) with the seeded change ruled under census-ruling-seeded-instances, and census-ruling-292fix's known-not-started record of a start its pre-exec gate refused; self-serve moves 4 Task 3: a lease the backend refuses because a cleanup holds the replica (a cleaning: owner) is logged and the wake refused, answered by serveWakeError; read sites unchanged (offsets moved); no new read and no root decision registry:DBPath@1276,registry:DBPath@1292,registry:DBPath@1419,registry:DBPath@1430,registry:DBPath@22010,registry:Host@1105,registry:Host@1180,registry:Host@1258,registry:Host@1410,registry:Host@174,registry:Host@1744,registry:Host@2604,registry:Host@4579,registry:Replication@22045,registry:Seed@12149,registry:Socket@1305,registry:Socket@1321,registry:Socket@1444,registry:Socket@1455,whole:Route@10118,whole:Route@10310,whole:Route@11000,whole:Route@1203,whole:Route@12250,whole:Route@12321,whole:Route@14705,whole:Route@159,whole:Route@1639,whole:Route@1644,whole:Route@16563,whole:Route@1698,whole:Route@1704,whole:Route@17209,whole:Route@1770,whole:Route@1778,whole:Route@18516,whole:Route@18670,whole:Route@19026,whole:Route@19120,whole:Route@19804,whole:Route@20459,whole:Route@21458,whole:Route@21606,whole:Route@22119,whole:Route@22478,whole:Route@23414,whole:Route@23509,whole:Route@2494,whole:Route@3948,whole:Route@4207,whole:Route@4469,whole:Route@4474,whole:Route@4531,whole:Route@4537,whole:Route@4606,whole:Route@4614,whole:Route@5402,whole:Route@6437,whole:Route@7655,whole:Route@8536 6c97aa10a217fc5fca42b5e96d86c33a9da4025d1417db29c1b652d28a28ee11
+internal/activator/activator.go Service.doWake legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): main's body (census ruling 292's legacy start mark and lease give-back; census ruling owed's pending record) with the seeded change ruled under census-ruling-seeded-instances, and census-ruling-292fix's known-not-started record of a start its pre-exec gate refused; self-serve moves 4 Task 3: a lease the backend refuses because a cleanup holds the replica (a cleaning: owner) is logged and the wake refused, answered by serveWakeError; read sites unchanged (offsets moved); no new read and no root decision registry:DBPath@1276,registry:DBPath@1292,registry:DBPath@1419,registry:DBPath@1430,registry:DBPath@22010,registry:Host@1105,registry:Host@1180,registry:Host@1258,registry:Host@1410,registry:Host@174,registry:Host@1744,registry:Host@2604,registry:Host@4579,registry:Replication@22045,registry:Seed@12149,registry:Socket@1305,registry:Socket@1321,registry:Socket@1444,registry:Socket@1455,whole:Route@10118,whole:Route@10310,whole:Route@11000,whole:Route@1203,whole:Route@12250,whole:Route@12321,whole:Route@14705,whole:Route@159,whole:Route@1639,whole:Route@1644,whole:Route@16563,whole:Route@1698,whole:Route@1704,whole:Route@17209,whole:Route@1770,whole:Route@1778,whole:Route@18516,whole:Route@18670,whole:Route@19026,whole:Route@19120,whole:Route@19804,whole:Route@20459,whole:Route@21458,whole:Route@21606,whole:Route@22119,whole:Route@22478,whole:Route@23414,whole:Route@23509,whole:Route@2494,whole:Route@3948,whole:Route@4207,whole:Route@4469,whole:Route@4474,whole:Route@4531,whole:Route@4537,whole:Route@4606,whole:Route@4614,whole:Route@5402,whole:Route@6437,whole:Route@7655,whole:Route@8536 6c97aa10a217fc5fca42b5e96d86c33a9da4025d1417db29c1b652d28a28ee11
+internal/activator/activator.go Service.serveWakeError diagnostic C,J4 rev3=PROPOSED-self-serve-moves-4; incarnation-keyed missing-files diagnostics and indexed retry results (rev3=PROPOSED-seed); self-serve moves 4 Task 3: a wake refused because a cleanup holds the replica is answered 503 with Retry-After: 30 before the held case; read sites unchanged (offsets moved); throttles output only and grants no retry, stop or launch registry:Host@1614,registry:Host@1678 45197a316ccfb3f042a303696870f26a567b63e038c9cd52ae406e9f7bdde2df
+@legacy 284358d1103443869c67c5d3680727b995f0673f0adb546b7967eb6624229038 internal/activator/backend_exec.go ExecBackend.Acquire legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=root-route (J1); self-serve moves 4 Task 3: a lease.HeldError whose owner is a cleaning: mark maps to the cleaning refusal without reading its expiry; read sites unchanged (offsets moved) registry:Host@96,whole:Route@1074,whole:Route@399 5fcfa20b188b8d98a3f6a65432642f0b80cb4d019b5a803324a33024f16edcb7
+internal/activator/backend_exec.go ExecBackend.Acquire legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=root-route (J1); self-serve moves 4 Task 3: a lease.HeldError whose owner is a cleaning: mark maps to the cleaning refusal without reading its expiry; read sites unchanged (offsets moved) registry:Host@96,whole:Route@1074,whole:Route@399 5fcfa20b188b8d98a3f6a65432642f0b80cb4d019b5a803324a33024f16edcb7
+@legacy 2cb2011349e6d56aaf1535476122cbc3ae08858012d316adc4cfa762f504e702 internal/lease/lockstate.go LockState legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=root-input (J4); self-serve moves 4 Task 3: a cleaning: owner answers held whatever its expiry, and the expiry it reads for any other owner is judged on the lease's clock hook (leaseNow), the wall clock outside tests; the one read site (the lock object's body) unchanged file:ReadAll@613 261c40bed73f4a607bee4c40c1231e264b124113cef789913171463f487ba1d4
+internal/lease/lockstate.go LockState legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=root-input (J4); self-serve moves 4 Task 3: a cleaning: owner answers held whatever its expiry, and the expiry it reads for any other owner is judged on the lease's clock hook (leaseNow), the wall clock outside tests; the one read site (the lock object's body) unchanged file:ReadAll@613 261c40bed73f4a607bee4c40c1231e264b124113cef789913171463f487ba1d4
+internal/lease/tombstone.go readLock hint J4 rev3=PROPOSED-self-serve-moves-4;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): readLock is now a wrapper over readLockBody (fetchLock's read and decode, then the old expiry and ETag checks) returning *litestream.Lease, and reads nothing itself; its read site lives in fetchLock (frozen below); reclassified from accepted legacy as a read-free hint so its frozen declaration stays classified (as Edge.Reload under rev3=PROPOSED-self-serve-moves-3) 067121872c28c018fb23b798d67dbd11cd4e6fec3803b2d418206aca54a70fef
+@legacy 114c9f406e3baadecae8bd86f0f5ba809d63e20c0240a9301f233d1848ba8b7c internal/lease/tombstone.go fetchLock legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=root-input (J4, as readLock's read under census-ruling-moves-offline); the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos) and every other process that acquires a hibernation lease: new, self-serve moves 4 Task 3: the litestream lock object read with its ETag and decoded (bounded to lockBodyLimit), no other check; called from readLockBody (Tombstone, Reassert, LiftTombstone, the cleaning mark and unmark) and AcquireTTL's pre-read; an absent lock is answered absent, an unreadable or undecodable one is an error, never free file:ReadAll@430 1c552d7f9e4d9da710a4cf65f108771bf7e910d0a9d40a7c88570fb95deb6874
+internal/lease/tombstone.go fetchLock legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=root-input (J4, as readLock's read under census-ruling-moves-offline); the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos) and every other process that acquires a hibernation lease: new, self-serve moves 4 Task 3: the litestream lock object read with its ETag and decoded (bounded to lockBodyLimit), no other check; called from readLockBody (Tombstone, Reassert, LiftTombstone, the cleaning mark and unmark) and AcquireTTL's pre-read; an absent lock is answered absent, an unreadable or undecodable one is an error, never free file:ReadAll@430 1c552d7f9e4d9da710a4cf65f108771bf7e910d0a9d40a7c88570fb95deb6874
+@legacy d0a00fc18c46979bee9e58ffe848c10ad5ae8457a53c8c7c9b09334ddd21d56f internal/lease/cleaning.go newWriteID legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=J4 root-input: reads crypto/rand for a lock body's 16-byte write id (self-serve moves 4 Task 3), so no lock body our code writes recurs; in every process that writes the lock (the lift, the mark and the unmark, in the agent as carlos); randomness grants no root authority file:Read@57 fab5cdcd84a1e5677421eb82aa38699c8c2b0edb62796fa1a0620177bcec902e
+internal/lease/cleaning.go newWriteID legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=J4 root-input: reads crypto/rand for a lock body's 16-byte write id (self-serve moves 4 Task 3), so no lock body our code writes recurs; in every process that writes the lock (the lift, the mark and the unmark, in the agent as carlos); randomness grants no root authority file:Read@57 fab5cdcd84a1e5677421eb82aa38699c8c2b0edb62796fa1a0620177bcec902e
+@legacy 33cc42d8a7509f015c6da16f5b69360022b73210bd021cb30a8c5c137797c38a internal/lease/leasetest/hold.go Holder.ServeHTTP legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=tests only (internal/lease/leasetest; its one non-test importer is host's e2e_bridge.go, the exported end-to-end bridge that only the e2e witnesses call): new, self-serve moves 4 Task 3: the holding S3 proxy reads each request's body to record it and to hold or forward the write; a test double that grants no production root authority file:ReadAll@341 5fb506ee83ab7049992e139ce3e60de89eae88ee205fd5b74ad48c5a5dcf6423
+internal/lease/leasetest/hold.go Holder.ServeHTTP legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-4;basis=tests only (internal/lease/leasetest; its one non-test importer is host's e2e_bridge.go, the exported end-to-end bridge that only the e2e witnesses call): new, self-serve moves 4 Task 3: the holding S3 proxy reads each request's body to record it and to hold or forward the write; a test double that grants no production root authority file:ReadAll@341 5fb506ee83ab7049992e139ce3e60de89eae88ee205fd5b74ad48c5a5dcf6423
+@coverage internal/activator 0bb7d94d921626bf607ad22186bcbc658e3da06af90b22e62b4d89d376e121f3
+@coverage internal/host 7709a620e76b3161cf4fa7c8a6c80a4a612fec1aec0e48cf3ed624d41e863c75
+@coverage internal/lease 20f2e391c6f8e0d9ff7f57a374cec056c5eeefbe8191572fcd3695661a141119
+@coverage internal/lease/leasetest 726797feb98925d74aec9577cb6b1d36c5f6fa0fd32e53adc0751e01ad22305e
+@coverage internal/moves c29e4ac0264ecd9181a327c4d556439e55206dfcfadfc474bed1166263ef2f02
@coverage internal/offlinecleanup db9a962a529e985617d69ddc80ebf0dc128e6d5f229e3547613a321e63cb2778
-@coverage internal/release ea549ae64c23cd49fccba2c5e298f883f9a94cb10fff10f227b6d884b7ccd0c5
+@coverage internal/release 93341ee9413d3d1445d0c4e842cdeb6bf799d6663c317e8a4f7ba69a99bab114