code wiki / (root) / nx_shelltool_gate.nx

nx_shelltool_gate.nx source

↩ module page · 186 lines · 12098 B

1// nx_shelltool_gate.nx -- liar-killed GATE for the MCP-ready shell-tool CLI. Forks the REAL built 2// elf against a /tmp fixture tree and captures stdout via a pipe, proving grep/glob/find each return 3// the RIGHT hits and NOT the wrong ones (the neg-controls: a non-matching file must NOT appear, an 4// ext filter must EXCLUDE, a glob must reject a non-match). Composes nx_grep so the canonical match 5// is exercised end-to-end through the invocable surface. usage: nx_shelltool_gate [elf] Exit 0 on 11/11. 6// SEQ1292 teeth (2026-07-30): the scan budget BITES (tiny max_bytes -> BUDGET-EXCEEDED partial) and is 7// ABSENT at defaults (the non-vacuous control pair). ⚠the gate's CWD is part of its contract: it writes 8// shelltool_budget.conf in CWD (scratch dirs only, per the exec-gate clobber law). 9// license_tier: ORIGINAL expect_exit: 0 10import "nx_syscalls.nx" 11import "nx_crashresume_census_core.nx" 12 13const G_OUTCAP: i64 = 65536 // captured-stdout buffer 14const G_TOTAL: i64 = 16 // 11 base + 1 anti-vacuity precondition + 4 out= teeth 15// ELF RESOLUTION + ANTI-VACUITY (2026-07-31, id 1785516061): this gate used to hardcode ONE /tmp elf 16// path. On every NAS run that path is absent, the fork exec'd nothing, every capture came back EMPTY -- 17// and the NEGATIVE controls PASSED VACUOUSLY, because "b.txt must be ABSENT" is trivially true when the 18// tool never ran. Observed live: pass=1/11 where the single PASS was a neg-control on a missing binary. 19// A gate built ONLY of neg-controls would have reported GREEN with no binary at all. Fixed two ways: 20// the elf is RESOLVED from a candidate list and PRINTED, and a hard precondition tooth must fire first. 21func g_exists(p: *u8) -> i64 { let fd: i64 = sys_openat_rd(p); if fd < 0 { return 0 } sys_close(fd); return 1 } 22func g_slurp(p: *u8, buf: *u8, cap: i64) -> i64 { 23 let fd: i64 = sys_openat_rd(p) 24 if fd < 0 { return 0 } 25 var tot: i64 = 0 26 var r: i64 = sys_read(fd, buf, cap - 1) 27 while r > 0 { tot = tot + r; if tot >= cap - 1 { r = 0 } else { r = sys_read(fd, (buf as i64 + tot) as *u8, cap - 1 - tot) } } 28 sys_close(fd) 29 buf[tot] = 0 as u8 30 return tot 31} 32 33func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 34func g_putn(v: i64) -> i64 { nxi_out(v); return 0 } 35func g_bool(name: *u8, got: i64, want: i64, passp: *i64) -> i64 { 36 g_puts("T " as *u8); g_puts(name); g_puts(" got=" as *u8); g_putn(got) 37 if got == want { g_puts(" PASS\n" as *u8); passp[0] = passp[0] + 1 } else { g_puts(" FAIL\n" as *u8) } 38 return 0 39} 40func g_write(path: *u8, s: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 420); if fd < 0 { return 0 - 1 } sys_write(fd, s, ccz_slen(s)); sys_close(fd); return 0 } 41func g_has(hay: *u8, hn: i64, needle: *u8) -> i64 { 42 let nl: i64 = ccz_slen(needle) 43 if nl == 0 { return 0 } 44 var i: i64 = 0 45 while i + nl <= hn { var k: i64 = 0; var ok: i64 = 1; while k < nl { if hay[i+k] != needle[k] { ok = 0; k = nl } k = k + 1 } if ok == 1 { return 1 } i = i + 1 } 46 return 0 47} 48// fork elf with argv[1..3], capture stdout into out (cap), return byte count. 49func g_run(elf: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, out: *u8, cap: i64) -> i64 { 50 // pipe2 fills TWO int32 fds packed into pb[0] (low=read, high=write) -- NOT two i64 slots. 51 let pb: *i64 = sys_mmap(16) as *i64 52 sys_pipe2(pb, 0) 53 let rfd: i64 = pb[0] & 0xFFFFFFFF 54 let wfd: i64 = (pb[0] >> 32) & 0xFFFFFFFF 55 let pid: i64 = sys_fork() 56 if pid == 0 { 57 sys_dup3(wfd, 1, 0) 58 sys_close(rfd); sys_close(wfd) 59 let av: *i64 = sys_mmap(64) as *i64 60 av[0] = elf as i64; av[1] = a1 as i64; av[2] = a2 as i64; av[3] = a3 as i64 61 var ac: i64 = 4 62 if a4 as i64 != 0 { av[4] = a4 as i64; ac = 5 } 63 av[ac] = 0 64 sys_execve(elf, av, 0 as *i64) 65 sys_exit(127) 66 } 67 sys_close(wfd) 68 var tot: i64 = 0 69 var n: i64 = sys_read(rfd, out, cap - 1) 70 while n > 0 { tot = tot + n; if tot >= cap - 1 { n = 0 } else { n = sys_read(rfd, (out as i64 + tot) as *u8, cap - 1 - tot) } } 71 sys_close(rfd) 72 let st: *i64 = sys_mmap(16) as *i64 73 sys_wait4(pid, st, 0) 74 out[tot] = 0 as u8 75 return tot 76} 77 78func main(argc: i64, argv: *i64) -> i64 { 79 var elf: *u8 = 0 as *u8 80 if argc >= 2 { if g_exists(argv[1] as *u8) == 1 { elf = argv[1] as *u8 } } 81 // .new FIRST so a freshly STAGED build is proven BEFORE it is promoted -- test-before-ship, structural 82 if (elf as i64) == 0 { if g_exists("buildroot/_build/nx_shelltool.sov.elf.new" as *u8) == 1 { elf = "buildroot/_build/nx_shelltool.sov.elf.new" as *u8 } } 83 if (elf as i64) == 0 { if g_exists("buildroot/_build/nx_shelltool.sov.elf" as *u8) == 1 { elf = "buildroot/_build/nx_shelltool.sov.elf" as *u8 } } 84 if (elf as i64) == 0 { if g_exists("_build/nx_shelltool.sov.elf" as *u8) == 1 { elf = "_build/nx_shelltool.sov.elf" as *u8 } } 85 if (elf as i64) == 0 { if g_exists("/tmp/nx_shelltool.sov.elf" as *u8) == 1 { elf = "/tmp/nx_shelltool.sov.elf" as *u8 } } 86 let pass: *i64 = sys_mmap(16) as *i64 87 pass[0] = 0 88 if (elf as i64) == 0 { 89 g_puts("SHELLTOOL-GATE ERROR: no nx_shelltool elf resolved (tried argv[1], buildroot/_build/*.sov.elf.new, buildroot/_build/*.sov.elf, _build/*.sov.elf, /tmp/*.sov.elf)\n" as *u8) 90 g_puts("SHELLTOOL-GATE pass=0/" as *u8); g_putn(G_TOTAL); g_puts(" verdict=RED\n" as *u8) 91 return 1 92 } 93 g_puts("elf=" as *u8); g_puts(elf); g_puts("\n" as *u8) 94 95 // pin known-large budgets FIRST so a stale conf from a prior run can never RED the base teeth 96 g_write("shelltool_budget.conf" as *u8, "max_bytes=536870912 deadline_ms=20000 max_files=200000\n" as *u8) 97 98 // fixture tree /tmp/stg/{a.nx, b.txt, sub/c.nx} 99 sys_mkdir("/tmp/stg" as *u8, 0x1ed) 100 sys_mkdir("/tmp/stg/sub" as *u8, 0x1ed) 101 g_write("/tmp/stg/a.nx" as *u8, "hello NEEDLE world\nsecond line\n" as *u8) 102 g_write("/tmp/stg/b.txt" as *u8, "NEEDLE in a txt file\n" as *u8) 103 g_write("/tmp/stg/sub/c.nx" as *u8, "no match here\nNEEDLE deep\n" as *u8) 104 105 let out: *u8 = sys_mmap(G_OUTCAP) 106 var n: i64 = 0 107 108 // T0 ANTI-VACUITY PRECONDITION: prove the binary actually RAN and produced OUR envelope before any 109 // negative control is allowed to count. Without this, an absent binary makes every neg-control PASS 110 // (measured live 2026-07-31: pass=1/11, the lone PASS being a neg-control on a binary that never ran). 111 n = g_run(elf, "grep" as *u8, "NEEDLE" as *u8, "/tmp/stg" as *u8, 0 as *u8, out, G_OUTCAP) 112 g_bool("precond-tool-executes" as *u8, g_has(out, n, "-- matches=" as *u8), 1, pass) 113 114 // grep NEEDLE across .nx only -> a.nx:1 and sub/c.nx:2 present, b.txt (a .txt) ABSENT (ext filter) 115 n = g_run(elf, "grep" as *u8, "NEEDLE" as *u8, "/tmp/stg" as *u8, ".nx" as *u8, out, G_OUTCAP) 116 g_bool("grep-hit-a.nx" as *u8, g_has(out, n, "/tmp/stg/a.nx:1:" as *u8), 1, pass) 117 g_bool("grep-recurses-sub" as *u8, g_has(out, n, "/tmp/stg/sub/c.nx:2:" as *u8), 1, pass) 118 g_bool("negctl-ext-filter-excludes-txt" as *u8, g_has(out, n, "b.txt" as *u8), 0, pass) 119 120 // grep with NO ext -> b.txt now included 121 n = g_run(elf, "grep" as *u8, "NEEDLE" as *u8, "/tmp/stg" as *u8, 0 as *u8, out, G_OUTCAP) 122 g_bool("grep-no-ext-includes-txt" as *u8, g_has(out, n, "/tmp/stg/b.txt:1:" as *u8), 1, pass) 123 124 // glob *.nx -> a.nx + c.nx present, b.txt ABSENT (neg-control) 125 n = g_run(elf, "glob" as *u8, "*.nx" as *u8, "/tmp/stg" as *u8, 0 as *u8, out, G_OUTCAP) 126 var okglob: i64 = 0 127 if g_has(out, n, "/tmp/stg/a.nx" as *u8) == 1 { if g_has(out, n, "/tmp/stg/sub/c.nx" as *u8) == 1 { if g_has(out, n, "b.txt" as *u8) == 0 { okglob = 1 } } } 128 g_bool("glob-star-nx-only" as *u8, okglob, 1, pass) 129 130 // find substr "c." -> sub/c.nx present, a.nx ABSENT 131 n = g_run(elf, "find" as *u8, "c." as *u8, "/tmp/stg" as *u8, 0 as *u8, out, G_OUTCAP) 132 var okfind: i64 = 0 133 if g_has(out, n, "/tmp/stg/sub/c.nx" as *u8) == 1 { if g_has(out, n, "/tmp/stg/a.nx" as *u8) == 0 { okfind = 1 } } 134 g_bool("find-name-substr" as *u8, okfind, 1, pass) 135 136 // --- out= teeth (id 1785516061): the MCP stdout capture truncates at 160KiB with NO marker, so a 137 // large scan arrived CLIPPED MID-LINE with its honesty trailer deleted. out= diverts RESULTS to a 138 // file so stdout carries ONLY the envelope -- coverage bounded by the corpus, never by a payload cap. 139 n = g_run(elf, "find" as *u8, "c." as *u8, "/tmp/stg" as *u8, "out=stg_res.out" as *u8, out, G_OUTCAP) 140 var okdiv: i64 = 0 141 if g_has(out, n, "out_bytes=" as *u8) == 1 { if g_has(out, n, "stdout_bounded=1" as *u8) == 1 { if g_has(out, n, "/tmp/stg/sub/c.nx" as *u8) == 0 { okdiv = 1 } } } 142 g_bool("out-diverts-results-envelope-only-on-stdout" as *u8, okdiv, 1, pass) 143 144 // and the diverted results must actually BE in the file -- a diversion that loses data is worse 145 // than the truncation it replaces, so this tooth is the paired positive control for the one above. 146 let fbuf: *u8 = sys_mmap(G_OUTCAP) 147 let fn: i64 = g_slurp("stg_res.out" as *u8, fbuf, G_OUTCAP) 148 g_bool("out-file-actually-contains-the-results" as *u8, g_has(fbuf, fn, "/tmp/stg/sub/c.nx" as *u8), 1, pass) 149 150 // NEG-CONTROL: a non-.out target is REFUSED, so a scan can never clobber source/registry/binary 151 n = g_run(elf, "find" as *u8, "c." as *u8, "/tmp/stg" as *u8, "out=stg_res.txt" as *u8, out, G_OUTCAP) 152 g_bool("negctl-out-refuses-non-dot-out-suffix" as *u8, g_has(out, n, "out= refused" as *u8), 1, pass) 153 154 // NEG-CONTROL: parent traversal is REFUSED 155 n = g_run(elf, "find" as *u8, "c." as *u8, "/tmp/stg" as *u8, "out=../escape.out" as *u8, out, G_OUTCAP) 156 g_bool("negctl-out-refuses-parent-traversal" as *u8, g_has(out, n, "out= refused" as *u8), 1, pass) 157 158 // HONESTY (07-17): a hit run carries the count trailer (matches>0 explicit) 159 n = g_run(elf, "grep" as *u8, "NEEDLE" as *u8, "/tmp/stg" as *u8, 0 as *u8, out, G_OUTCAP) 160 g_bool("summary-trailer-hits" as *u8, g_has(out, n, "-- matches=3" as *u8), 1, pass) 161 // HONESTY: zero matches is EXPLICIT (matches=0), never a silent empty 162 n = g_run(elf, "grep" as *u8, "NOSUCHTOKENZZZ" as *u8, "/tmp/stg" as *u8, 0 as *u8, out, G_OUTCAP) 163 g_bool("summary-zero-explicit" as *u8, g_has(out, n, "-- matches=0" as *u8), 1, pass) 164 // HONESTY neg-control: a FILE (not dir) as <dir> errors LOUD on stdout (the old silent-empty bug) 165 n = g_run(elf, "grep" as *u8, "NEEDLE" as *u8, "/tmp/stg/a.nx" as *u8, 0 as *u8, out, G_OUTCAP) 166 g_bool("baddir-loud-error" as *u8, g_has(out, n, "NX-SHELLTOOL ERROR" as *u8), 1, pass) 167 168 // SEQ1292 BUDGET TOOTH: tiny max_bytes (40 < fixture total 76) -> the scan STOPS, reports 169 // BUDGET-EXCEEDED + partial=1, and the summary still carries honest partial counts 170 g_write("shelltool_budget.conf" as *u8, "max_bytes=40 deadline_ms=20000 max_files=200000\n" as *u8) 171 n = g_run(elf, "grep" as *u8, "NEEDLE" as *u8, "/tmp/stg" as *u8, 0 as *u8, out, G_OUTCAP) 172 g_bool("budget-bytes-bites-partial" as *u8, g_has(out, n, "NX-SHELLTOOL BUDGET-EXCEEDED partial=1" as *u8), 1, pass) 173 // NON-VACUITY CONTROL: at default budgets the SAME run is clean (no exceed line, full matches=3) 174 g_write("shelltool_budget.conf" as *u8, "max_bytes=536870912 deadline_ms=20000 max_files=200000\n" as *u8) 175 n = g_run(elf, "grep" as *u8, "NEEDLE" as *u8, "/tmp/stg" as *u8, 0 as *u8, out, G_OUTCAP) 176 var okctl: i64 = 0 177 if g_has(out, n, "NX-SHELLTOOL BUDGET-EXCEEDED" as *u8) == 0 { if g_has(out, n, "-- matches=3" as *u8) == 1 { okctl = 1 } } 178 g_bool("budget-default-clean-full" as *u8, okctl, 1, pass) 179 180 // the denominator is DERIVED from G_TOTAL, never a literal: the hardcoded "/11" here survived the 181 // count going to 16 and printed "pass=16/11", a gate lying about its own scope in its verdict line. 182 g_puts("SHELLTOOL-GATE pass=" as *u8); g_putn(pass[0]); g_puts("/" as *u8); g_putn(G_TOTAL); g_puts(" verdict=" as *u8) 183 if pass[0] == G_TOTAL { g_puts("GREEN\n" as *u8); return 0 } 184 g_puts("RED\n" as *u8) 185 return 1 186}