code wiki / _hdl_build / nx_janitor_retire.nx

nx_janitor_retire.nx source

↩ module page · 55 lines · 3268 B

1// nx_janitor_retire.nx -- the RETIRE step = the actual debt count-drop (operator: "keep the debt gone"). 2// Migrating is additive (the original stays, so the auditor still counts it); RETIRING moves the already- 3// backed-up original OUT of the product zone into a fenced `_retired/` dir, so it stops counting and the 4// genuine_debt actually falls (then the ratchet locks the lower floor). SAFETY, by construction: 5// - REFUSES to retire a file whose bytes are not byte-verified in the store (never lose data). 6// - MOVES, never deletes -- the janitor has NO unlink syscall; a retire is sys_renameat (reversible). 7// - jan_unretire moves it straight back = proven reversible (never-brick #26, additive #13). 8// Pair with the auditor fencing `/_retired/` (done) so retired files are no longer product-contaminants. 9// Composes nx_janitor_scrub.jan_migrate for the verify. Sovereign. license_tier: ORIGINAL 10import "nx_janitor_scrub.nx" // jan_migrate, jan_exists 11import "nx_syscalls.nx" 12const K_MAGIC_1024: i64 = 1024 13 14// the file's bytes are byte-exact in `store_prefix`? (idempotent re-migrate+verify; the retire precondition) 15func jan_verify_in_store(src_path: *u8, store_prefix: *u8) -> i64 { 16 let totp: *i64 = sys_mmap(16) as *i64; let verp: *i64 = sys_mmap(16) as *i64 17 jan_migrate(src_path, store_prefix, totp, verp) 18 if totp[0] > 0 { if verp[0] == totp[0] { return 1 } } 19 return 0 20} 21 22// compute retdir = <dir>/_retired and dest = <dir>/_retired/<name> from a full path 23func jan_retire_dest(path: *u8, retdir: *u8, dest: *u8) -> i64 { 24 var slash: i64 = 0 - 1; var i: i64 = 0 25 while path[i] != (0 as u8) { if path[i] == (47 as u8) { slash = i } i = i + 1 } 26 var o: i64 = 0; var j: i64 = 0 27 while j <= slash { retdir[o] = path[j]; o = o + 1; j = j + 1 } // dir + trailing '/' 28 let suf: *u8 = "_retired" as *u8; var s: i64 = 0 29 while suf[s] != (0 as u8) { retdir[o] = suf[s]; o = o + 1; s = s + 1 } retdir[o] = 0 as u8 30 var d: i64 = 0; var r: i64 = 0 31 while retdir[r] != (0 as u8) { dest[d] = retdir[r]; d = d + 1; r = r + 1 } 32 dest[d] = 47 as u8; d = d + 1 33 var n: i64 = slash + 1 34 while path[n] != (0 as u8) { dest[d] = path[n]; d = d + 1; n = n + 1 } dest[d] = 0 as u8 35 return 0 36} 37 38// RETIRE: only if byte-verified in the store, MOVE (reversible, no delete) to <dir>/_retired/<name>. 39// 1 = retired | 0 = REFUSED (not verified-in-store, or the move failed) 40func jan_retire(src_path: *u8, store_prefix: *u8) -> i64 { 41 if jan_verify_in_store(src_path, store_prefix) != 1 { return 0 } // never retire unbacked-up data 42 let retdir: *u8 = sys_mmap(K_MAGIC_1024); let dest: *u8 = sys_mmap(K_MAGIC_1024) 43 jan_retire_dest(src_path, retdir, dest) 44 sys_mkdir(retdir, 493) // 0755; harmless if it already exists 45 if sys_renameat(src_path, dest) != 0 { return 0 } 46 return 1 47} 48 49// UN-RETIRE: move it straight back to the product zone (proves the retire is reversible). 1 = restored. 50func jan_unretire(src_path: *u8, store_prefix: *u8) -> i64 { 51 let retdir: *u8 = sys_mmap(K_MAGIC_1024); let dest: *u8 = sys_mmap(K_MAGIC_1024) 52 jan_retire_dest(src_path, retdir, dest) 53 if sys_renameat(dest, src_path) != 0 { return 0 } 54 return 1 55}