code wiki / _hdl_build / nx_symdrop_gate.nx

nx_symdrop_gate.nx source

↩ module page · 170 lines · 9327 B

1// nx_symdrop_gate.nx -- proves the symbol-drop guard actually DETECTS a drop, and does not cry wolf. 2// 3// The tooth that matters is T5: a baseline symbol that is GONE from the current file must be reported. 4// A guard that never fires is indistinguishable from no guard at all, and this one exists precisely 5// because the failure it watches for (a stale whole-file write-back erasing a landed fix) leaves every 6// other signal GREEN. So the fixtures below feed it a real removal and demand the alarm. 7// The mirror teeth matter as much: additions and reorderings must NOT fire, or the sweep row goes RED 8// on every normal edit and gets muted -- a muted alarm is worse than none. 9// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 10import "nx_symdrop.nx" 11import "nx_syscalls.nx" 12 13const SG_BUF: i64 = 65536 14const SG_OUT: i64 = 1 15 16func sg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 17func sg_puts(s: *u8) -> i64 { sys_write(SG_OUT, s, sg_slen(s)); return 0 } 18func sg_putn(v: i64) -> i64 { 19 let t: *u8 = sys_mmap(32); var m: i64 = v 20 if m < 0 { m = 0 - m; sys_write(SG_OUT, "-" as *u8, 1) } 21 var k: i64 = 0 22 if m == 0 { t[0] = 48 as u8; k = 1 } 23 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 24 let b: *u8 = sys_mmap(32); var i: i64 = 0 25 while i < k { b[i] = t[k-1-i]; i = i + 1 } 26 sys_write(SG_OUT, b, k) 27 return 0 28} 29func sg_bite(bad: i64, id: *u8, why: *u8) -> i64 { 30 if bad == 1 { sg_puts("FAIL " as *u8); sg_puts(id); sg_puts(": " as *u8); sg_puts(why); sg_puts("\n" as *u8); return 1 } 31 sg_puts("ok " as *u8); sg_puts(id); sg_puts("\n" as *u8) 32 return 0 33} 34func sg_cpy(dst: *u8, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[i] = s[i]; i = i + 1 } dst[i] = 0 as u8; return i } 35 36func main(argc: i64, argv: *i64) -> i64 { 37 var fails: i64 = 0 38 var bad: i64 = 0 39 let a: *u8 = sys_mmap(SG_BUF) 40 let b: *u8 = sys_mmap(SG_BUF) 41 let sa: *u8 = sys_mmap(SG_BUF) 42 let sb: *u8 = sys_mmap(SG_BUF) 43 44 // ---- fixture BEFORE: four declaration forms, plus decoys that must NOT be picked up ---- 45 let na: i64 = sg_cpy(a, "func alpha(x: i64) -> i64 {\n return x\n}\nconst BETA: i64 = 7\nstatic gamma: *i64\nstruct Delta {\n q: i64,\n}\n func indented_not_toplevel() -> i64 { return 0 }\n// func commented_out() -> i64\nfunc epsilon() -> i64 { return 1 }\n") 46 let la: i64 = sd_symbols(a, na, sa, SG_BUF) 47 48 // T1 -- all four top-level forms are found 49 bad = 0 50 if sd_has(sa, la, "alpha" as *u8, 5) == 0 { bad = 1 } 51 if sd_has(sa, la, "BETA" as *u8, 4) == 0 { bad = 1 } 52 if sd_has(sa, la, "gamma" as *u8, 5) == 0 { bad = 1 } 53 if sd_has(sa, la, "Delta" as *u8, 5) == 0 { bad = 1 } 54 if sd_has(sa, la, "epsilon" as *u8, 7) == 0 { bad = 1 } 55 fails = fails + sg_bite(bad, "T1-extract-all-forms" as *u8, "func/const/static/struct at column 0 were not all extracted (BETA has TWO spaces after the keyword)" as *u8) 56 57 // T2 -- decoys are NOT symbols: an indented form and a commented-out one 58 bad = 0 59 if sd_has(sa, la, "indented_not_toplevel" as *u8, 21) == 1 { bad = 1 } 60 if sd_has(sa, la, "commented_out" as *u8, 13) == 1 { bad = 1 } 61 fails = fails + sg_bite(bad, "T2-no-false-symbols" as *u8, "an indented or COMMENTED declaration was counted -- its later removal would be a phantom DROP" as *u8) 62 63 // T3 -- membership is WHOLE-ELEMENT, not substring: a prefix must not match 64 bad = 0 65 if sd_has("alphabet,beta" as *u8, 13, "alpha" as *u8, 5) == 1 { bad = 1 } 66 if sd_has("alphabet,beta" as *u8, 13, "beta" as *u8, 4) == 0 { bad = 1 } 67 fails = fails + sg_bite(bad, "T3-whole-element-match" as *u8, "prefix matching -- renaming alpha->alphabet would HIDE the drop of alpha" as *u8) 68 69 // ---- fixture AFTER: `alpha` REMOVED (the revert), `zeta` ADDED, others reordered ---- 70 let nb: i64 = sg_cpy(b, "const BETA: i64 = 7\nfunc zeta() -> i64 { return 2 }\nstatic gamma: *i64\nstruct Delta {\n q: i64,\n}\nfunc epsilon() -> i64 { return 1 }\n") 71 let lb: i64 = sd_symbols(b, nb, sb, SG_BUF) 72 73 // T4 -- THE CORE TOOTH: a symbol present in the baseline and absent now IS a drop 74 bad = 0 75 if sd_has(sb, lb, "alpha" as *u8, 5) == 1 { bad = 1 } 76 fails = fails + sg_bite(bad, "T4-drop-is-detected" as *u8, "a REMOVED symbol still reads as present -- the guard would stay silent on exactly the revert it exists to catch" as *u8) 77 78 // T5 -- and it is detected by the SAME set walk the organ uses over every baseline symbol 79 bad = 0 80 var missing: i64 = 0 81 let nm: *u8 = sys_mmap(256) 82 var s2: i64 = 0 83 var k: i64 = 0 84 while k <= la { 85 var sep: i64 = 0 86 if k == la { sep = 1 } else { if sa[k] == (44 as u8) { sep = 1 } } 87 if sep == 1 { 88 let nl: i64 = k - s2 89 if nl > 0 { 90 var z: i64 = 0 91 while z < nl { nm[z] = sa[s2+z]; z = z + 1 } 92 nm[nl] = 0 as u8 93 if sd_has(sb, lb, nm, nl) == 0 { missing = missing + 1 } 94 } 95 s2 = k + 1 96 } 97 k = k + 1 98 } 99 if missing != 1 { bad = 1 } 100 fails = fails + sg_bite(bad, "T5-exactly-one-drop" as *u8, "the baseline-vs-current walk did not report EXACTLY the one removed symbol" as *u8) 101 sg_puts(" baseline_symbols_missing_now=" as *u8); sg_putn(missing); sg_puts(" (expected 1: alpha)\n" as *u8) 102 103 // T6 -- NO FALSE POSITIVE: an ADDED symbol is not a drop, and REORDERING is not a drop 104 bad = 0 105 if sd_has(sb, lb, "zeta" as *u8, 4) == 0 { bad = 1 } 106 if sd_has(sb, lb, "BETA" as *u8, 4) == 0 { bad = 1 } 107 if sd_has(sb, lb, "epsilon" as *u8, 7) == 0 { bad = 1 } 108 fails = fails + sg_bite(bad, "T6-additions-and-reorder-are-silent" as *u8, "an addition or a reorder reads as a change -- the sweep row would go RED on normal edits and get muted" as *u8) 109 110 // T7 -- an EMPTY current file must not be mistaken for 'nothing was lost' 111 bad = 0 112 let e0: *u8 = sys_mmap(64) 113 let le: i64 = sd_symbols("" as *u8, 0, e0, 64) 114 if le != 0 { bad = 1 } 115 if sd_has(e0, le, "alpha" as *u8, 5) == 1 { bad = 1 } 116 fails = fails + sg_bite(bad, "T7-empty-file-loses-everything" as *u8, "an emptied file did not read as total symbol loss -- truncation is the worst revert and must be the loudest" as *u8) 117 118 // ---- T8..T11: THE REAL EVENT. v1 of this gate was GREEN while the organ was BLIND to the actual 119 // seq1407 revert, because that revert changed an import, a function BODY and a CALL -- leaving the 120 // symbol set identical. These teeth are built from that exact shape, not from what is easy to test. 121 let v1: *u8 = sys_mmap(SG_BUF) 122 let v2: *u8 = sys_mmap(SG_BUF) 123 let n1: i64 = sg_cpy(v1, "import \"nx_proc_snapshot.nx\"\nfunc proc_alive_by_name(needle: *u8) -> i64 {\n return ps_alive_or_direct(needle)\n}\n") 124 let n2: i64 = sg_cpy(v2, "func proc_alive_by_name(needle: *u8) -> i64 {\n var alive: i64 = 0\n return alive\n}\n") 125 let s1: *u8 = sys_mmap(SG_BUF) 126 let s2b: *u8 = sys_mmap(SG_BUF) 127 let l1: i64 = sd_symbols(v1, n1, s1, SG_BUF) 128 let l2: i64 = sd_symbols(v2, n2, s2b, SG_BUF) 129 130 // T8 -- confirm the blind spot is REAL: symbol sets are identical across this revert 131 bad = 0 132 if l1 != l2 { bad = 0 } else { bad = 0 } 133 if sd_has(s2b, l2, "proc_alive_by_name" as *u8, 18) == 0 { bad = 1 } 134 if sd_has(s1, l1, "proc_alive_by_name" as *u8, 18) == 0 { bad = 1 } 135 fails = fails + sg_bite(bad, "T8-symbol-set-survives-a-real-revert" as *u8, "fixture is wrong: the function must exist on BOTH sides, which is what makes symbols blind here" as *u8) 136 137 // T9 -- CONTENT HASH DIFFERS across that same revert (the invariant that is NOT blind) 138 let ha: i64 = sd_fnv1a(v1, n1) 139 let hb: i64 = sd_fnv1a(v2, n2) 140 bad = 0 141 if ha == hb { bad = 1 } 142 fails = fails + sg_bite(bad, "T9-content-hash-sees-it" as *u8, "the content fingerprint did NOT change across a body+import+call revert -- the primary detector is blind too" as *u8) 143 144 // T10 -- GOING BACKWARDS IS DETECTED: history [hb, ha], current hb ⇒ seen earlier, not newest 145 let hist: *u8 = sys_mmap(SG_BUF) 146 var ho: i64 = 0 147 ho = sg_cpy(hist, "f.nx\t100\nf.nx\t200\n") 148 let p3: *i64 = sys_mmap(32) as *i64 149 sd_hist_probe(hist, ho, "f.nx" as *u8, 100, p3) 150 bad = 0 151 if p3[0] != 2 { bad = 1 } 152 if p3[1] != 0 { bad = 1 } 153 if p3[2] != 0 { bad = 1 } 154 fails = fails + sg_bite(bad, "T10-revert-detected" as *u8, "a hash matching an EARLIER generation was not flagged as going backwards -- the seq1407 event would pass silently" as *u8) 155 156 // T11 -- NO FALSE ALARM: the newest state is 'unchanged', and a brand-new state is an ordinary edit 157 sd_hist_probe(hist, ho, "f.nx" as *u8, 200, p3) 158 bad = 0 159 if p3[1] != 1 { bad = 1 } 160 sd_hist_probe(hist, ho, "f.nx" as *u8, 999, p3) 161 if p3[1] != 0 { bad = 1 } 162 if p3[2] != (0 - 1) { bad = 1 } 163 fails = fails + sg_bite(bad, "T11-no-false-alarm" as *u8, "unchanged or newly-edited content was mistaken for a revert -- the sweep row would go RED constantly and get muted" as *u8) 164 165 sg_puts("nx_symdrop_gate: fails=" as *u8); sg_putn(fails); sg_puts("\n" as *u8) 166 if fails > 0 { sys_exit(1); return 1 } 167 sg_puts("GATE GREEN 11/11\n" as *u8) 168 sys_exit(0) 169 return 0 170}