code wiki / (root) / nx_gateaddr.nx

nx_gateaddr.nx source

↩ module page · 283 lines · 13864 B

1// nx_gateaddr.nx -- CAN THIS GATE'S SUBJECT BE SUBSTITUTED BY A MUTATION HARNESS? 2// 3// NOT A DUPLICATE OF nx_gatesubj, and the distinction is the whole point: that organ answers WHICH 4// organ a gate tests (subject IDENTITY, resolved from the gate's own source). This one answers a 5// different question about the same literal -- WHETHER A HARNESS CAN SWAP THE ARTIFACT THE GATE 6// EXECUTES. A gate can name its subject perfectly and still be impossible to mutation-test. 7// 8// WHY IT EXISTS, MEASURED 2026-08-14: nx_gate_bite ran 9 valid mutants against nx_bodyfit_canon_gate 9// and killed ZERO -- verdict INCONCLUSIVE. The teeth were fine. The gate forked an ABSOLUTE DEPLOYED 10// path while the harness rebuilds each mutant into the build tree and CORRECTLY refuses to clobber the 11// live binary. PROVEN, not inferred: the deployed sha256 was byte-identical before and after the whole 12// sweep, so every mutant ran against pristine code and survived BY CONSTRUCTION. 13// -- AN END-TO-END GATE THAT PINS ITS SUBJECT TO A DEPLOYED PATH CANNOT BE MUTATION-TESTED, AND ITS 14// INCONCLUSIVE IS A PROPERTY OF ITS ADDRESSING, NOT OF ITS ASSERTIONS. 15// That is a measurement-integrity defect: the estate counts such a gate as existing and never collects 16// its verdict, which is worse than not having it, because its existence is mistaken for coverage. 17// 18// nx_gateaddr [dir] [deploy-root] 19// 20// CLASSES -- a PARTITION. The parts are printed and MUST sum to the gate count; an unreconciled 21// residual is a leak, an explained one is a decision. 22// PINNED names an absolute <deploy-root> path -> NOT substitutable; a bite here proves nothing 23// STAGED names a relative _offc/ path -> substitutable; a bite here is meaningful 24// ELFOTHER names some other .elf -> addressed a third way, REPORTED not guessed 25// INPROC names no .elf at all (imports subject) -> rebuilt with the gate, bite works 26// -- UNRECOGNISED SHAPES GET THEIR OWN BUCKET. A shape folded into a known class becomes the number 27// somebody plans against. 28// -- COMMENTS ARE STRIPPED BEFORE CLASSIFYING. A scanner that reads comments measures the 29// DOCUMENTATION, not the code -- and this very header names every pattern it hunts, so an unstripped 30// scan would classify this organ as its own worst offender. 31// -- NO SILENT CAPS: it REFUSES at capacity rather than publishing a partial count as a total. 32// exit 0 census printed | 2 usage | 3 cannot open dir | 4 no gates matched | 5 capacity exceeded 33// license_tier: ORIGINAL. No hw writes (Rule 26). 34import "nx_syscalls.nx" 35 36const GA_DIRBUF: i64 = 262144 37const GA_MAXGATE: i64 = 8192 38// dirent64: d_reclen is a u16 at byte 16, the NUL-terminated name starts at byte 19. 39const GA_RECLEN_OFF: i64 = 16 40const GA_NAME_OFF: i64 = 19 41const GA_DEFAULT_DIR: *u8 = "buildroot/runtime" 42// the estate's deployed organ root. Overridable as argv[2] so this organ is not pinned to one layout -- 43// a census hardcoded to one estate can only ever measure that estate. 44const GA_DEFAULT_DEPLOY: *u8 = "/volume1/homes/elderwesto/nishihost/" 45 46func ga_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 47func ga_puts(s: *u8) -> i64 { sys_write(1, s, ga_len(s)); return 0 } 48func ga_pn(v: i64) -> i64 { 49 var m: i64 = v 50 if m < 0 { ga_puts("-" as *u8); m = 0 - m } 51 let t: *u8 = sys_mmap(32) 52 var k: i64 = 0 53 if m == 0 { t[0] = 48 as u8; k = 1 } 54 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 55 let o: *u8 = sys_mmap(32) 56 var i: i64 = 0 57 while i < k { o[i] = t[k - 1 - i]; i = i + 1 } 58 sys_write(1, o, k) 59 return 0 60} 61func ga_ends(s: *u8, suf: *u8) -> i64 { 62 let ls: i64 = ga_len(s) 63 let lf: i64 = ga_len(suf) 64 if lf > ls { return 0 } 65 var i: i64 = 0 66 var ok: i64 = 1 67 var go: i64 = 1 68 while go == 1 { 69 if i >= lf { go = 0 } else { 70 if s[ls - lf + i] != suf[i] { ok = 0; go = 0 } else { i = i + 1 } 71 } 72 } 73 return ok 74} 75// substring presence. Separate flag, never a clobbered cursor. 76func ga_has(h: *u8, n: i64, needle: *u8) -> i64 { 77 let m: i64 = ga_len(needle) 78 if m == 0 { return 0 } 79 var j: i64 = 0 80 var hit: i64 = 0 81 while j + m <= n { 82 var k: i64 = 0 83 var ok: i64 = 1 84 var go: i64 = 1 85 while go == 1 { 86 if k >= m { go = 0 } else { 87 if h[j+k] != needle[k] { ok = 0; go = 0 } else { k = k + 1 } 88 } 89 } 90 if ok == 1 { hit = 1 } 91 j = j + 1 92 } 93 return hit 94} 95// Strip // line comments, honouring double-quoted strings so a path INSIDE a literal survives while the 96// same text in prose does not. Returns stripped length written into dst. 97func ga_strip(src: *u8, n: i64, dst: *u8) -> i64 { 98 var i: i64 = 0 99 var o: i64 = 0 100 var instr: i64 = 0 101 while i < n { 102 let c: i64 = src[i] as i64 103 if instr == 1 { 104 dst[o] = src[i]; o = o + 1 105 if c == 92 { if i + 1 < n { dst[o] = src[i+1]; o = o + 1; i = i + 1 } } else { 106 if c == 34 { instr = 0 } 107 } 108 i = i + 1 109 } else { 110 if c == 34 { instr = 1; dst[o] = src[i]; o = o + 1; i = i + 1 } else { 111 var iscm: i64 = 0 112 if c == 47 { if i + 1 < n { if (src[i+1] as i64) == 47 { iscm = 1 } } } 113 if iscm == 1 { 114 var go: i64 = 1 115 while go == 1 { 116 if i >= n { go = 0 } else { 117 if (src[i] as i64) == 10 { go = 0 } else { i = i + 1 } 118 } 119 } 120 } else { dst[o] = src[i]; o = o + 1; i = i + 1 } 121 } 122 } 123 } 124 return o 125} 126 127func main(argc: i64, argv: *i64) -> i64 { 128 var dir: *u8 = GA_DEFAULT_DIR 129 var deploy: *u8 = GA_DEFAULT_DEPLOY 130 if argc >= 2 { dir = argv[1] as *u8 } 131 if argc >= 3 { deploy = argv[2] as *u8 } 132 133 ga_puts("=== nx_gateaddr dir=" as *u8); ga_puts(dir) 134 ga_puts(" deploy_root=" as *u8); ga_puts(deploy) 135 ga_puts(" ===\n" as *u8) 136 137 let fd: i64 = sys_openat_rd(dir) 138 if fd < 0 { ga_puts("GATEADDR REFUSE: cannot open directory\n" as *u8); sys_exit(3); return 3 } 139 140 let dbuf: *u8 = sys_mmap(GA_DIRBUF) 141 let names: *i64 = sys_mmap(GA_MAXGATE*8) as *i64 142 var ngate: i64 = 0 143 var over: i64 = 0 144 145 // LOOP UNTIL getdents64 RETURNS 0. One call is a PREFIX of a large directory, not a listing. 146 var more: i64 = 1 147 while more == 1 { 148 let n: i64 = sys_getdents64(fd, dbuf, GA_DIRBUF) 149 if n <= 0 { more = 0 } else { 150 var off: i64 = 0 151 while off < n { 152 let base: i64 = dbuf as i64 153 let rec: *u8 = (base + off) as *u8 154 let reclen: i64 = (rec[GA_RECLEN_OFF] as i64) + ((rec[GA_RECLEN_OFF+1] as i64) << 8) 155 let nm: *u8 = (base + off + GA_NAME_OFF) as *u8 156 if ga_ends(nm, "_gate.nx" as *u8) == 1 { 157 if ngate < GA_MAXGATE { 158 let keep: *u8 = sys_mmap(512) 159 var q: i64 = 0 160 while nm[q] != (0 as u8) { keep[q] = nm[q]; q = q + 1 } 161 keep[q] = 0 as u8 162 names[ngate] = keep as i64 163 ngate = ngate + 1 164 } else { over = 1 } 165 } 166 if reclen <= 0 { off = n } else { off = off + reclen } 167 } 168 } 169 } 170 sys_close(fd) 171 172 if over == 1 { 173 ga_puts("GATEADDR REFUSE: gate count exceeded capacity -- a partial census published as a total is\n" as *u8) 174 ga_puts("the defect this organ exists to find. Raise GA_MAXGATE and re-run.\n" as *u8) 175 sys_exit(5) 176 return 5 177 } 178 if ngate == 0 { ga_puts("GATEADDR: no *_gate.nx matched in this directory\n" as *u8); sys_exit(4); return 4 } 179 180 var pinned: i64 = 0 181 var staged: i64 = 0 182 var elfother: i64 = 0 183 var inproc: i64 = 0 184 var unread: i64 = 0 185 // ★★ORTHOGONAL AXIS, DELIBERATELY OUTSIDE THE PARTITION. "Does this gate read an argument?" is a 186 // different question from "how does it address its subject", so it is counted and reported 187 // SEPARATELY -- folding it into the addressing partition would stop the parts summing and destroy 188 // the one check that proves the census is complete. 189 // WHY IT MATTERS, MEASURED 2026-08-14: nx_vizsla_digest_gate run BARE reported `instrument missing` 190 // and 1/14 RED; its own header says "bogus instrument argv[1] => all rows FAIL => RED". Pointing it 191 // at its subject took it to 4/14. A ROSTER THAT INVOKES EVERY GATE BARE MANUFACTURES A RED FOR EVERY 192 // GATE THAT TAKES ARGUMENTS, and in a rollup those are indistinguishable from real failures. 193 // ★UPPER BOUND, NOT A DEFECT LIST: a gate may read argv[1] and still have a SAFE DEFAULT (nx_dstate 194 // does). This names the population AT RISK, not the population broken -- the same honesty the PINNED 195 // axis carries above. 196 var argvread: i64 = 0 197 // ★★TIGHTEN THE BOUND: a gate that reads argv[1] BEHIND AN argc GUARD has a default and is SAFE to run 198 // bare (nx_dstate is exactly this); one that reads it UNGUARDED is the actual risk. Splitting them 199 // turns a loose 200-wide upper bound into a worklist somebody can act on. 200 // ⚠SIGNAL CHOICE, AND ITS IMPRECISION, STATED: the guard is detected as the literal `argc >` (which 201 // covers `argc >= n` and `argc > n`, the idiom this corpus actually uses). Matching bare `argc` would 202 // match EVERY gate, since `main(argc: i64, ...)` names it -- a signal that fires on everything 203 // discriminates nothing. A gate guarding some other way (`if argc == 1`) is counted as UNGUARDED, so 204 // this errs toward FLAGGING, never toward silence. 205 var argvguard: i64 = 0 206 let bare: *i64 = sys_mmap(GA_MAXGATE*8) as *i64 207 var nbare: i64 = 0 208 209 let path: *u8 = sys_mmap(4096) 210 let flen: *i64 = sys_mmap(16) as *i64 211 212 // ★★PINNED IS AN UPPER BOUND, NOT A DEFECT LIST. This organ detects that a gate NAMES a deployed path, 213 // which is exact -- but it CANNOT tell "pinned with no escape" from "pinned DEFAULT that argv can 214 // override". PROOF CASE, measured on my own work: nx_bodyfit_canon_gate was given an argv subject 215 // override and STILL lists here, because the deployed path remains its default. 216 // ★THE DEFINITIVE TEST IS THE OUTCOME, NOT THE SOURCE SHAPE: nx_gate_bite now reports `not_reached` 217 // when a mutant produces a byte-identical artifact, which catches every non-substitutable gate however 218 // it is addressed. THIS CENSUS IS THE CHEAP SCREEN; THAT BITE IS THE PROOF. 219 ga_puts("\n-- PINNED (names an absolute deployed path -- an UPPER BOUND on non-substitutable) --\n" as *u8) 220 ga_puts(" (a deployed path may be an OVERRIDABLE DEFAULT; nx_gate_bite's not_reached is the proof)\n" as *u8) 221 var gi: i64 = 0 222 while gi < ngate { 223 let nm: *u8 = names[gi] as *u8 224 var po: i64 = 0 225 var di: i64 = 0 226 while dir[di] != (0 as u8) { path[po] = dir[di]; po = po + 1; di = di + 1 } 227 path[po] = 47 as u8; po = po + 1 228 var ni: i64 = 0 229 while nm[ni] != (0 as u8) { path[po] = nm[ni]; po = po + 1; ni = ni + 1 } 230 path[po] = 0 as u8 231 232 let src: *u8 = sys_read_file(path, flen) 233 if (src as i64) == 0 { unread = unread + 1 } else { 234 let dst: *u8 = sys_mmap(flen[0] + 64) 235 let sn: i64 = ga_strip(src, flen[0], dst) 236 if ga_has(dst, sn, "argv[1]" as *u8) == 1 { 237 argvread = argvread + 1 238 if ga_has(dst, sn, "argc >" as *u8) == 1 { argvguard = argvguard + 1 } else { 239 if nbare < GA_MAXGATE { bare[nbare] = nm as i64; nbare = nbare + 1 } 240 } 241 } 242 let hasdep: i64 = ga_has(dst, sn, deploy) 243 let hasoffc: i64 = ga_has(dst, sn, "_offc/" as *u8) 244 let haself: i64 = ga_has(dst, sn, ".elf" as *u8) 245 if hasdep == 1 { 246 pinned = pinned + 1 247 ga_puts(" " as *u8); ga_puts(nm); ga_puts("\n" as *u8) 248 } else { 249 if hasoffc == 1 { staged = staged + 1 } else { 250 if haself == 1 { elfother = elfother + 1 } else { inproc = inproc + 1 } 251 } 252 } 253 } 254 gi = gi + 1 255 } 256 257 let sum: i64 = pinned + staged + elfother + inproc + unread 258 ga_puts("\ngates=" as *u8); ga_pn(ngate) 259 ga_puts(" PINNED=" as *u8); ga_pn(pinned) 260 ga_puts(" STAGED=" as *u8); ga_pn(staged) 261 ga_puts(" ELFOTHER=" as *u8); ga_pn(elfother) 262 ga_puts(" INPROC=" as *u8); ga_pn(inproc) 263 ga_puts(" UNREADABLE=" as *u8); ga_pn(unread) 264 ga_puts(" sum=" as *u8); ga_pn(sum) 265 if sum == ngate { ga_puts(" partition=RECONCILES\n" as *u8) } else { ga_puts(" partition=LEAK\n" as *u8) } 266 // ★THE WORKLIST, NOT JUST THE COUNT. These read argv[1] with NO argc guard, so a roster that invokes 267 // them bare gets a verdict that is an artifact of the invocation, not a property of the code. 268 ga_puts("\n-- ARGV-UNGUARDED (read argv[1] with no `argc >` guard: a BARE run is not attributable) --\n" as *u8) 269 if nbare == 0 { ga_puts(" (none)\n" as *u8) } 270 var bi: i64 = 0 271 while bi < nbare { 272 ga_puts(" " as *u8); ga_puts(bare[bi] as *u8); ga_puts("\n" as *u8) 273 bi = bi + 1 274 } 275 ga_puts("\nargv_reading=" as *u8); ga_pn(argvread) 276 ga_puts(" of " as *u8); ga_pn(ngate) 277 ga_puts(" guarded=" as *u8); ga_pn(argvguard) 278 ga_puts(" UNGUARDED=" as *u8); ga_pn(nbare) 279 ga_puts("\n (ORTHOGONAL to the partition above. GUARDED gates have a default and are safe bare;\n" as *u8) 280 ga_puts(" UNGUARDED is the population whose bare verdict cannot be attributed.)\n" as *u8) 281 sys_exit(0) 282 return 0 283}