code wiki / _hdl_build / nx_clobber_guard_gate.nx

nx_clobber_guard_gate.nx source

↩ module page · 79 lines · 4074 B

1// nx_clobber_guard_gate.nx -- gate for the acl F744 guard. Fixture-based + DETERMINISTIC, with a 2// negative control (the scale-law/liar-kill discipline): captures the guard's stdout via tr_run_capture 3// (same proven idiom as nx_drift_watch) and substring-matches the verdict -- avoids exit-status decode. 4// T1 identical surfaces -> verdict=CONVERGED (positive) 5// T2 different surfaces -> verdict=DIVERGED (NEGATIVE CONTROL: a real clobber must be caught) 6// T3 absent surface -> verdict=ABSENT (fail-closed on a missing copy) 7// Runs _offc/nx_clobber_guard.elf (staged before this gate). license_tier: ORIGINAL expect_exit: 0 8import "nx_tool_run.nx" 9import "nx_gate_verdict.nx" 10 11func g_w(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } 12func g_wn(fd: i64, v: i64) -> i64 { var m: i64 = v; if m < 0 { g_w(fd, "-" as *u8); m = 0 - m } let t: *u8 = sys_mmap(28); 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 o: *u8 = sys_mmap(28); var i: i64 = 0; while i < k { o[i] = t[k - 1 - i]; i = i + 1 } sys_write(fd, o, k); return 0 } 13func g_wf(path: *u8, s: *u8) -> i64 { 14 let fd: i64 = sys_openat_wr(path, 0x1a4) 15 if fd < 0 { return 0 - 1 } 16 var n: i64 = 0 17 while s[n] != (0 as u8) { n = n + 1 } 18 sys_write(fd, s, n) 19 sys_close(fd) 20 return 0 21} 22// substring search: 1 if pat occurs in buf[0..n), else 0. 23func g_has(buf: *u8, n: i64, pat: *u8) -> i64 { 24 var pl: i64 = 0 25 while pat[pl] != (0 as u8) { pl = pl + 1 } 26 if pl == 0 { return 0 } 27 var i: i64 = 0 28 while i + pl <= n { 29 var k: i64 = 0 30 var m: i64 = 1 31 while k < pl { if buf[i + k] != pat[k] { m = 0; k = pl } else { k = k + 1 } } 32 if m == 1 { return 1 } 33 i = i + 1 34 } 35 return 0 36} 37// run the guard cmp A B, capture stdout into out[0..ol[0]). 38func g_run(pa: *u8, pb: *u8, out: *u8, ocap: i64, ol: *i64) -> i64 { 39 let av: *i64 = sys_mmap(64) as *i64 40 av[0] = "_offc/nx_clobber_guard.elf" as i64 41 av[1] = "cmp" as i64 42 av[2] = pa as i64 43 av[3] = pb as i64 44 av[4] = 0 45 return tr_run_capture("_offc/nx_clobber_guard.elf" as *u8, av, out, ocap, ol) 46} 47func main() -> i64 { 48 g_wf("/tmp/cg_a" as *u8, "hello world alpha line one\nline two\n" as *u8) 49 g_wf("/tmp/cg_b" as *u8, "hello world alpha line one\nline two\n" as *u8) 50 g_wf("/tmp/cg_c" as *u8, "hello world BRAVO totally different content\n" as *u8) 51 let ocap: i64 = 4096 52 let out: *u8 = sys_mmap(ocap) 53 let ol: *i64 = sys_mmap(16) as *i64 54 var pass: i64 = 0 55 var tot: i64 = 0 56 57 tot = tot + 1 58 g_run("/tmp/cg_a" as *u8, "/tmp/cg_b" as *u8, out, ocap, ol) 59 if g_has(out, ol[0], "verdict=CONVERGED" as *u8) == 1 { pass = pass + 1; g_w(1, "T1 identical->CONVERGED PASS\n" as *u8) } else { g_w(1, "T1 FAIL\n" as *u8) } 60 61 tot = tot + 1 62 g_run("/tmp/cg_a" as *u8, "/tmp/cg_c" as *u8, out, ocap, ol) 63 if g_has(out, ol[0], "verdict=DIVERGED" as *u8) == 1 { pass = pass + 1; g_w(1, "T2 different->DIVERGED PASS (neg-control)\n" as *u8) } else { g_w(1, "T2 FAIL\n" as *u8) } 64 65 tot = tot + 1 66 g_run("/tmp/cg_a" as *u8, "/tmp/cg_MISSING_XYZ" as *u8, out, ocap, ol) 67 if g_has(out, ol[0], "verdict=ABSENT" as *u8) == 1 { pass = pass + 1; g_w(1, "T3 absent->ABSENT PASS\n" as *u8) } else { g_w(1, "T3 FAIL\n" as *u8) } 68 69 g_w(1, "CLOBBER-GUARD-GATE pass=" as *u8); g_wn(1, pass); g_w(1, "/" as *u8); g_wn(1, tot) 70 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 71 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 72 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 73 let ctr__dry: *i64 = gv_ctr() 74 ctr__dry[0] = pass 75 ctr__dry[1] = tot 76 let rc__dry: i64 = gv_verdict("CLOBBER-GUARD-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 77 sys_exit(rc__dry) 78 return rc__dry 79}