code wiki / (root) / nx_contentdiff.nx

nx_contentdiff.nx source

↩ module page · 161 lines · 5806 B

1// nx_contentdiff.nx -- THE PROMOTE RULER. Answers one question: does the candidate binary still contain 2// everything the LIVE binary contains? 3// 4// WHY (debts 1785452162, 1785526315, 1785526809): the ecosystem has ~703 deployed organs awaiting a 5// rebuild, and the gate guarding that queue was BYTE SIZE. Size is uninformative IN BOTH DIRECTIONS, 6// proven twice by measurement: 7// SHRINK is not regression -- 16 live organs had LARGER .prev files, yet the smaller live binaries 8// were string SUPERSETS (lost_from_live=0). Restoring the bigger ones would have BEEN the regression. 9// GROWTH is not improvement -- nx_law_warden rebuilt GREW 161951 -> 186696 bytes while losing three 10// whole detectors (laws_measured 11 -> 8, enforced_permil 1000 -> 727). 11// A gate keyed on bytes is therefore wrong about half the time and cannot tell you which half. 12// 13// THE RULER: printable content. Every printable run of >= CD_MINLEN bytes in the LIVE binary must still 14// be findable somewhere in the candidate. Anything missing is capability the rebuild would DESTROY. 15// Searching the candidate's RAW BYTES (not a re-extracted string set) is deliberate and stricter: a 16// string that survived but got tokenized differently still counts as present, so a MISS is a real miss. 17// 18// FAIL-CLOSED: unreadable input is RED, never "clean". Verdict GREEN iff lost_from_live == 0. 19// NOT DEDUPED, and it says so in the output: runs are counted as encountered, so the counts are 20// occurrence counts and lost>0 is the signal -- declaring that beats a silent, prettier number. 21// 22// nx_contentdiff <live-elf> <candidate-elf> 23// 24// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 25import "nx_syscalls.nx" 26import "nx_gate_verdict.nx" 27 28const CD_CAP: i64 = 4194304 29const CD_MINLEN: i64 = 6 30const CD_PRINT_LO: i64 = 32 31const CD_PRINT_HI: i64 = 126 32const CD_SHOW: i64 = 8 33const CD_WORD: i64 = 8 34const CD_SLOTS: i64 = 8 35const CD_S_RUNS: i64 = 0 36const CD_S_LOST: i64 = 1 37const CD_S_SHOWN: i64 = 2 38 39func cd_slurp(path: *u8, buf: *u8, cap: i64) -> i64 { 40 let fd: i64 = sys_openat_rd(path) 41 if fd < 0 { return 0 - 1 } 42 var tot: i64 = 0 43 var go: i64 = 1 44 while go == 1 { 45 let r: i64 = sys_read(fd, ((buf as i64) + tot) as *u8, cap - tot) 46 if r <= 0 { go = 0 } else { tot = tot + r } 47 if tot >= cap { go = 0 } 48 } 49 sys_close(fd) 50 return tot 51} 52 53func cd_is_print(c: i64) -> i64 { 54 if c < CD_PRINT_LO { return 0 } 55 if c > CD_PRINT_HI { return 0 } 56 return 1 57} 58 59// is hay[0..hn) containing needle bytes hay2[s..s+len)? 60func cd_contains(hay: *u8, hn: i64, ndl: *u8, ns: i64, nl: i64) -> i64 { 61 if nl <= 0 { return 1 } 62 if nl > hn { return 0 } 63 var i: i64 = 0 64 while i + nl <= hn { 65 var k: i64 = 0 66 var ok: i64 = 1 67 while k < nl { 68 if hay[i+k] != ndl[ns+k] { ok = 0; k = nl } else { k = k + 1 } 69 } 70 if ok == 1 { return 1 } 71 i = i + 1 72 } 73 return 0 74} 75 76func main(argc: i64, argv: *i64) -> i64 { 77 if argc < 3 { 78 gv_puts("usage: nx_contentdiff <live-elf> <candidate-elf>\n" as *u8) 79 sys_exit(2) 80 return 2 81 } 82 let livep: *u8 = argv[1] as *u8 83 let candp: *u8 = argv[2] as *u8 84 85 let a: *u8 = sys_mmap(CD_CAP) 86 let b: *u8 = sys_mmap(CD_CAP) 87 let an: i64 = cd_slurp(livep, a, CD_CAP) 88 let bn: i64 = cd_slurp(candp, b, CD_CAP) 89 90 gv_puts("=== NX-CONTENTDIFF live=" as *u8) 91 gv_puts(livep) 92 gv_puts(" candidate=" as *u8) 93 gv_puts(candp) 94 gv_puts(" ===\n" as *u8) 95 96 if an <= 0 { 97 gv_puts("verdict=RED rule=live-unreadable\n" as *u8) 98 sys_exit(1) 99 return 1 100 } 101 if bn <= 0 { 102 gv_puts("verdict=RED rule=candidate-unreadable\n" as *u8) 103 sys_exit(1) 104 return 1 105 } 106 107 let st: *i64 = sys_mmap(CD_SLOTS * CD_WORD) as *i64 108 var z: i64 = 0 109 while z < CD_SLOTS { st[z] = 0; z = z + 1 } 110 111 var i: i64 = 0 112 while i < an { 113 if cd_is_print(a[i] as i64) == 1 { 114 // walk to the end of this printable run. Flag-terminated: a sentinel assignment would 115 // lose the real index, which is what the first draft of this loop got wrong. 116 var end: i64 = i 117 var scanning: i64 = 1 118 while scanning == 1 { 119 if end >= an { scanning = 0 } else { 120 if cd_is_print(a[end] as i64) == 1 { end = end + 1 } else { scanning = 0 } 121 } 122 } 123 let rl: i64 = end - i 124 if rl >= CD_MINLEN { 125 st[CD_S_RUNS] = st[CD_S_RUNS] + 1 126 if cd_contains(b, bn, a, i, rl) == 0 { 127 st[CD_S_LOST] = st[CD_S_LOST] + 1 128 if st[CD_S_SHOWN] < CD_SHOW { 129 st[CD_S_SHOWN] = st[CD_S_SHOWN] + 1 130 gv_puts(" LOST: " as *u8) 131 sys_write(1, ((a as i64) + i) as *u8, rl) 132 gv_puts("\n" as *u8) 133 } 134 } 135 } 136 i = end 137 } else { 138 i = i + 1 139 } 140 } 141 142 gv_puts("\nlive_bytes=" as *u8) 143 gv_num(an) 144 gv_puts(" candidate_bytes=" as *u8) 145 gv_num(bn) 146 gv_puts("\nruns_scanned=" as *u8) 147 gv_num(st[CD_S_RUNS]) 148 gv_puts(" lost_from_live=" as *u8) 149 gv_num(st[CD_S_LOST]) 150 gv_puts(" minlen=" as *u8) 151 gv_num(CD_MINLEN) 152 gv_puts("\ndeduped=0 (occurrence counts, declared not hidden)\n\n" as *u8) 153 154 let ctr: *i64 = gv_ctr() 155 gv_check("C1 live binary readable", an > 0, ctr) 156 gv_check("C2 candidate binary readable", bn > 0, ctr) 157 gv_check("C3 no printable content lost from live", st[CD_S_LOST] == 0, ctr) 158 let rc: i64 = gv_verdict("CONTENTDIFF", ctr, "candidate retains every printable run the live binary has") 159 sys_exit(rc) 160 return rc 161}