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}