code wiki / _hdl_build / nx_janitor_caps_gate.nx

nx_janitor_caps_gate.nx source

↩ module page · 48 lines · 4131 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// MIGRATED ONTO THE BASE CLASS 2026-09-05: the hand-rolled "--- 6/6 GREEN" line was unreadable to every rollup, 7// and the compare evidence census read this gate as GREEN at pass=0/0 -- a vacuous row, a green with no visible 8// teeth. gv_check_eq asserts AND emits actual/expected in one call so the published number and the tested number 9// cannot drift; the neg-controls are NAMED so the census can count them; the exit code carries the verdict. 10// license_tier: ORIGINAL | genealogy_id: nishi_janitor_caps_gate_2026_07_15 11import "nx_syscalls.nx" 12import "nx_gate_verdict.nx" 13import "nx_cap_detect_lib.nx" 14 15func gg_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 16 17// would the SWEEP flag this buffer? (a literal cap AND an unbounded-source read) 18func gg_would_flag(buf: *u8) -> i64 { 19 let n: i64=gg_slen(buf) 20 if jc_mmap_scan(buf, n)>0 { if jc_has_src(buf, n)==1 { return 1 } } 21 return 0 22} 23 24func main(argc: i64, argv: *i64) -> i64 { 25 let ctr: *i64 = gv_ctr() 26 gv_head("nx_janitor_caps_gate -- does the silent-truncation cap detector have teeth and no false positives?" as *u8) 27 // POSITIVE: fixed-count array + '< 128' bound + sys_read -> MUST flag, cap literal = 128 28 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 29 // NEG data-driven: a VARIABLE after '*' -> no literal -> invisible 30 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 31 // NEG no-source: cap present but no unbounded read (argc-bounded, provably safe) 32 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 33 // NEG byte-buffer: sys_mmap(256) has no '*' -> not a fixed-count array 34 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 35 // NEG shift-not-bound: '<< 128' is a shift, not a loop bound 36 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 37 38 gv_check_eq("F1 positive: a fixed-count array, a bound on the same literal and an unbounded read FLAGS" as *u8, gg_would_flag(f1), 1, ctr) 39 gv_check_eq("F1 the exact cap literal is read back from the fixture" as *u8, jc_mmap_scan(f1, gg_slen(f1)), 128, ctr) 40 gv_check_eq("neg-control-F2 data-driven size (a variable after the star) is NOT flagged" as *u8, gg_would_flag(f2), 0, ctr) 41 gv_check_eq("neg-control-F3 a cap with no unbounded source is NOT flagged" as *u8, gg_would_flag(f3), 0, ctr) 42 gv_check_eq("neg-control-F4 a byte buffer without a star is NOT flagged" as *u8, gg_would_flag(f4), 0, ctr) 43 gv_check_eq("neg-control-F5 a shift is not a bound and is NOT flagged" as *u8, gg_would_flag(f5), 0, ctr) 44 let small: *u8 = "func f(fd:i64,b:*u8){let a:*i64=sys_mmap(8 * 8) as *i64;var i:i64=0;while i < 8 {a[i]=sys_read(fd,b,1);i=i+1}}" as *u8 45 gv_check_eq("small literal count is a candidate, not presumed safe",gg_would_flag(small),1,ctr) 46 gv_check_eq("small candidate retains exact count",jc_mmap_scan(small,gg_slen(small)),8,ctr) 47 return gv_verdict("nx_janitor_caps_gate" as *u8, ctr, "Narrow lexical candidate detection; named capacities, byte buffers and data-flow safety remain unqualified" as *u8) 48}