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}