code wiki / _hdl_build / nx_debt_plane_check.nx

nx_debt_plane_check.nx source

↩ module page · 62 lines · 3455 B

1// nx_debt_plane_check.nx -- READ-ONLY damage report for the debt- plane. 2// 3// WHY THIS EXISTS AS A SEPARATE, ARGLESS ORGAN: nx_plane_repair takes a <prefix> argument, /api/gate_run is 4// argless (seq1384), and a newly-registered MCP tool is unreachable until a reconnect (seq1349). So the one 5// number an operator needs before deciding whether to accept permanent loss -- HOW MANY ROWS -- could not be 6// obtained on the NAS at all. This closes that: no arguments, no writes, no confirm, nothing to get wrong. 7// 8// ★IT CANNOT REPAIR. It shares the loader with nx_plane_repair but has no write path whatsoever, so running 9// it can never accept the loss by accident. Accepting permanent loss stays an explicit operator act with an 10// explicit confirm, on a tool that records a receipt. This one only tells you the size of the decision. 11// 12// usage: nx_debt_plane_check (CWD = the store root) 13// exit 0 = plane healthy · 1 = LOSSY (declared > reachable) · 2 = read truncated, numbers untrustworthy 14// license_tier: ORIGINAL expect_exit: 0 15import "nx_syscalls.nx" 16import "nx_store_seed_lib.nx" 17 18const DC_CAP: i64 = 33554432 19 20func w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 21func wn(v: i64) -> i64 { let t: *u8=sys_mmap(28); var m: i64=v; var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let b: *u8=sys_mmap(28); var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 22 23func main() -> i64 { 24 let prefix: *u8 = "knowledge/store/debt-\x00" as *u8 25 let buf: *u8 = sys_mmap(DC_CAP) 26 let f: *i64 = sys_mmap(64) as *i64 27 let n: i64 = sts_load_honest(prefix, buf, DC_CAP, f) 28 var inbuf: i64 = 0 29 var i: i64 = 0 30 while i < n { if buf[i] == (10 as u8) { inbuf = inbuf + 1 } i = i + 1 } 31 32 w("=== nx_debt_plane_check -- read-only damage report for the debt ledger ===\n") 33 w(" declared_qn="); wn(f[0]) 34 w(" reachable="); wn(f[1]) 35 w(" rows_in_buffer="); wn(inbuf) 36 w(" beyond_qn="); wn(f[2]) 37 w(" bytes="); wn(n); w("\n") 38 39 // The same lethal check nx_plane_repair makes: a cap-bounded emit drops rows the counter still counted, 40 // so if these disagree every other number here is untrustworthy and no decision should be made on them. 41 if inbuf != f[1] { 42 w(" READ-TRUNCATED: found "); wn(f[1]); w(" rows but only "); wn(inbuf) 43 w(" reached the buffer -- these numbers are NOT trustworthy, raise DC_CAP.\n") 44 w("VERDICT: verdict=RED (measurement itself is truncated)\n") 45 sys_exit(2); return 2 46 } 47 if f[2] > 0 { 48 w(" ROWS-BEYOND-QN: "); wn(f[2]); w(" rows are reachable PAST the declared count (an older seeding\n") 49 w(" generation). That is a DIFFERENT defect from loss and needs a generation diff, not a reconcile.\n") 50 } 51 if f[0] > f[1] { 52 let lost: i64 = f[0] - f[1] 53 w(" LOSSY: "); wn(lost); w(" row(s) declared but UNREACHABLE. Writes to this plane are refused until\n") 54 w(" reconciled. Those rows are NOT recoverable -- their keys are absent from every segment.\n") 55 w(" TO REPAIR (operator act, records a receipt): nx_plane_repair knowledge/store/debt- confirm=yes\n") 56 w("VERDICT: verdict=RED (ledger write-blocked, "); wn(lost); w(" rows lost)\n") 57 sys_exit(1); return 1 58 } 59 w("VERDICT: verdict=GREEN (debt ledger self-consistent, writes accepted)\n") 60 sys_exit(0) 61 return 0 62}