code wiki / _hdl_build / nx_janitor_caps_gate.nx
nx_janitor_caps_gate.nx source
↩ module page · 56 lines · 4181 B
1// nx_janitor_caps_gate.nx -- proves the silent-truncation CAP detector (nx_cap_detect_lib) has TEETH and NO
2// false positives on its discriminators. In-memory fixtures (no /tmp): one POSITIVE that MUST flag, and four
3// NEG-CONTROLS that MUST NOT -- data-driven size, no-source, byte-buffer(no '*'), and shift-not-bound. The
4// fixtures are code-representing strings passed straight to the CORE scan (the gate does NOT strip -- the
5// sweep strips real files; here the string IS the simulated code). GREEN iff all six checks pass.
6// license_tier: ORIGINAL | genealogy_id: nishi_janitor_caps_gate_2026_07_15
7import "nx_syscalls.nx"
8import "nx_cap_detect_lib.nx"
9
10func gg(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
11func gg_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
12func gg_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)}; 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}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 }
13
14// would the SWEEP flag this buffer? (a literal cap AND an unbounded-source read)
15func gg_would_flag(buf: *u8) -> i64 {
16 let n: i64=gg_slen(buf)
17 if jc_mmap_scan(buf, n)>0 { if jc_has_src(buf, n)==1 { return 1 } }
18 return 0
19}
20// one check; prints PASS/FAIL, returns 1 if pass
21func gg_check(label: *u8, actual: i64, expect: i64) -> i64 {
22 gg(" " as *u8)
23 if actual==expect { gg("PASS " as *u8) } else { gg("FAIL " as *u8) }
24 gg(label); gg(" (got " as *u8); gg_num(actual); gg(", want " as *u8); gg_num(expect); gg(")\n" as *u8)
25 if actual==expect { return 1 }
26 return 0
27}
28
29func main(argc: i64, argv: *i64) -> i64 {
30 gg("=== nx_janitor_caps_gate: does the cap detector have teeth + no false positives? ===\n" as *u8)
31 // POSITIVE: fixed-count array + '< 128' bound + sys_read -> MUST flag, cap literal = 128
32 let f1: *u8 = "func f(fd: i64, b: *u8) { let a: *i64 = sys_mmap(8 * 128) as *i64; var i: i64 = 0; while i < 128 { let n: i64 = sys_read(fd, b, 64); a[i] = n; i = i + 1 } }" as *u8
33 // NEG data-driven: a VARIABLE after '*' -> no literal -> invisible
34 let f2: *u8 = "func f(fd: i64, b: *u8, ns: i64) { let a: *i64 = sys_mmap(8 * ns + 64) as *i64; var i: i64 = 0; while i < ns { let n: i64 = sys_read(fd, b, 64); a[i] = n; i = i + 1 } }" as *u8
35 // NEG no-source: cap present but no unbounded read (argc-bounded, provably safe)
36 let f3: *u8 = "func f(argc: i64) { let a: *i64 = sys_mmap(8 * 128) as *i64; var i: i64 = 0; while i < 128 { a[i] = i; i = i + 1 } }" as *u8
37 // NEG byte-buffer: sys_mmap(256) has no '*' -> not a fixed-count array
38 let f4: *u8 = "func f(fd: i64) { let a: *u8 = sys_mmap(256); var i: i64 = 0; while i < 256 { let n: i64 = sys_read(fd, a, 1); i = i + 1 } }" as *u8
39 // NEG shift-not-bound: '<< 128' is a shift, not a loop bound
40 let f5: *u8 = "func f(fd: i64, b: *u8) { let a: *i64 = sys_mmap(8 * 128) as *i64; var x: i64 = 1 << 128; let n: i64 = sys_read(fd, b, 64); a[0] = x }" as *u8
41
42 var pass: i64 = 0
43 var total: i64 = 0
44 total = total + 1; pass = pass + gg_check("F1 positive flags" as *u8, gg_would_flag(f1), 1)
45 total = total + 1; pass = pass + gg_check("F1 exact cap literal=128" as *u8, jc_mmap_scan(f1, gg_slen(f1)), 128)
46 total = total + 1; pass = pass + gg_check("F2 data-driven NOT flagged" as *u8, gg_would_flag(f2), 0)
47 total = total + 1; pass = pass + gg_check("F3 no-source NOT flagged" as *u8, gg_would_flag(f3), 0)
48 total = total + 1; pass = pass + gg_check("F4 byte-buffer(no *) NOT flagged" as *u8, gg_would_flag(f4), 0)
49 total = total + 1; pass = pass + gg_check("F5 shift-not-bound NOT flagged" as *u8, gg_would_flag(f5), 0)
50
51 gg("--- " as *u8); gg_num(pass); gg("/" as *u8); gg_num(total)
52 if pass==total { gg(" GREEN -- detector flags the real silent-truncation smell + rejects all four neg-controls (data-driven, no-source, byte-buffer, shift).\n" as *u8); sys_exit(0); return 0 }
53 gg(" RED -- detector logic regressed; see FAILs above.\n" as *u8)
54 sys_exit(1)
55 return 1
56}