| 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 |