nx_shipcheck_gate.nx source
↩ module page · 381 lines · 13229 B
1// nx_shipcheck_gate.nx -- proves the ship-complete orphan detector's teeth. DOGFOODS the D001
2// gate base (nx_gate_verdict). Fixtures are INJECTED roots under /tmp so the gate never reads or
3// writes production surfaces; the debt filer tooth INJECTS argecho (F872 pattern) so selftest
4// never writes the production debt plane. Teeth: planted-orphan detection per class (exact
5// counts), clean-fixture NEGATIVE (all zero, GREEN), determinism (two scans byte-equal counts),
6// injectable-filer receipts, clean-fixture files NOTHING.
7// license_tier: ORIGINAL /tmp fixtures only. No hw writes (Rule 26).
8import "nx_syscalls.nx"
9import "nx_gate_verdict.nx"
10
11const GT_TAB: i64 = 9
12const GT_NL: i64 = 10
13const GT_HASH: i64 = 35
14const GT_BUF: i64 = 8192
15const GT_LOGB: i64 = 65536
16const GT_PATH: i64 = 1024
17const GT_MODE_F: i64 = 420
18const GT_MODE_D: i64 = 493
19const GT_B256: i64 = 256
20const GT_EXITRED: i64 = 3
21const GT_EXEFAIL: i64 = 127
22
23static g_elf: *u8
24static g_log: *u8
25static g_ln: i64
26static g_sp: *i64
27static g_argecho: *u8
28
29func gt_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
30
31func gt_cat(d: *u8, o: i64, s: *u8) -> i64 {
32 var i: i64 = 0
33 var p: i64 = o
34 while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 }
35 d[p] = 0 as u8
36 return p
37}
38
39func gt_tab(d: *u8, o: i64) -> i64 { d[o] = GT_TAB as u8; return o + 1 }
40func gt_nl(d: *u8, o: i64) -> i64 { d[o] = GT_NL as u8; return o + 1 }
41
42func gt_path2(d: *u8, root: *u8, rel: *u8) -> *u8 {
43 var o: i64 = gt_cat(d, 0, root)
44 d[o] = 47 as u8
45 o = o + 1
46 o = gt_cat(d, o, rel)
47 return d
48}
49
50func gt_wf(path: *u8, content: *u8) -> i64 {
51 let fd: i64 = sys_openat_wr(path, GT_MODE_F)
52 if fd < 0 { return 0 }
53 let n: i64 = gt_len(content)
54 sys_write(fd, content, n)
55 sys_close(fd)
56 return 1
57}
58
59func gt_wrel(root: *u8, rel: *u8, content: *u8) -> i64 {
60 let pb: *u8 = sys_mmap(GT_PATH)
61 let pp: *u8 = gt_path2(pb, root, rel)
62 return gt_wf(pp, content)
63}
64
65func gt_le(b: *u8, i: i64, n: i64) -> i64 {
66 var j: i64 = i
67 var d: i64 = 0
68 while d == 0 { if j >= n { d = 1 } else { if b[j] == (GT_NL as u8) { d = 1 } else { j = j + 1 } } }
69 return j
70}
71
72func gt_col(b: *u8, ls: i64, le: i64, want: i64, sp: *i64) -> i64 {
73 var c: i64 = 0
74 var s: i64 = ls
75 var j: i64 = ls
76 var fnd: i64 = 0
77 var d: i64 = 0
78 while d == 0 {
79 var hit: i64 = 0
80 if j >= le { hit = 1 } else { if b[j] == (GT_TAB as u8) { hit = 1 } }
81 if hit == 1 {
82 if c == want { sp[0] = s; sp[1] = j; fnd = 1; d = 1 } else { c = c + 1; s = j + 1; if j >= le { d = 1 } else { j = j + 1 } }
83 } else { j = j + 1 }
84 }
85 return fnd
86}
87
88func gt_span_lit(b: *u8, s: i64, e: i64, lit: *u8) -> i64 {
89 let n: i64 = gt_len(lit)
90 if e - s != n { return 0 }
91 var i: i64 = 0
92 while i < n { let bi: i64 = s + i; if b[bi] != lit[i] { return 0 } i = i + 1 }
93 return 1
94}
95
96func gt_resolve_argecho() -> i64 {
97 let buf: *u8 = sys_mmap(GT_LOGB)
98 let fd: i64 = sys_openat_rd("tool_allowlist.conf" as *u8)
99 if fd < 0 { return 0 }
100 var t: i64 = 0
101 var done: i64 = 0
102 while done == 0 {
103 let want: i64 = GT_LOGB - 8 - t
104 let r: i64 = sys_read(fd, buf + t, want)
105 if r <= 0 { done = 1 } else { t = t + r; if t >= GT_LOGB - 8 { done = 1 } }
106 }
107 sys_close(fd)
108 var i: i64 = 0
109 var fnd: i64 = 0
110 while i < t {
111 let le: i64 = gt_le(buf, i, t)
112 if fnd == 0 {
113 if gt_col(buf, i, le, 0, g_sp) == 1 {
114 if gt_span_lit(buf, g_sp[0], g_sp[1], "argecho" as *u8) == 1 {
115 if gt_col(buf, i, le, 1, g_sp) == 1 {
116 var k: i64 = 0
117 var z: i64 = g_sp[0]
118 while z < g_sp[1] { g_argecho[k] = buf[z]; k = k + 1; z = z + 1 }
119 g_argecho[k] = 0 as u8
120 fnd = 1
121 }
122 }
123 }
124 }
125 i = le + 1
126 }
127 return fnd
128}
129
130func fx_build(root: *u8, dirty: i64) -> i64 {
131 let pb: *u8 = sys_mmap(GT_PATH)
132 sys_mkdir(root, GT_MODE_D)
133 let p1: *u8 = gt_path2(pb, root, "knowledge" as *u8)
134 sys_mkdir(p1, GT_MODE_D)
135 let p2: *u8 = gt_path2(pb, root, "knowledge/status" as *u8)
136 sys_mkdir(p2, GT_MODE_D)
137 let p3: *u8 = gt_path2(pb, root, "knowledge/registry" as *u8)
138 sys_mkdir(p3, GT_MODE_D)
139 gt_wrel(root, "bin.elf" as *u8, "x" as *u8)
140 if dirty == 1 { gt_wrel(root, "x.sov.elf.new" as *u8, "y" as *u8) }
141 let ab: *u8 = sys_mmap(GT_BUF)
142 var o: i64 = 0
143 o = gt_cat(ab, o, "argecho" as *u8)
144 o = gt_tab(ab, o)
145 o = gt_cat(ab, o, g_argecho)
146 o = gt_tab(ab, o)
147 o = gt_cat(ab, o, "GREEN" as *u8)
148 o = gt_nl(ab, o)
149 o = gt_cat(ab, o, "good" as *u8)
150 o = gt_tab(ab, o)
151 o = gt_cat(ab, o, root)
152 o = gt_cat(ab, o, "/bin.elf" as *u8)
153 o = gt_tab(ab, o)
154 o = gt_cat(ab, o, "GREEN" as *u8)
155 o = gt_nl(ab, o)
156 if dirty == 1 {
157 o = gt_cat(ab, o, "staged" as *u8)
158 o = gt_tab(ab, o)
159 o = gt_cat(ab, o, root)
160 o = gt_cat(ab, o, "/x.sov.elf.new" as *u8)
161 o = gt_tab(ab, o)
162 o = gt_cat(ab, o, "GREEN" as *u8)
163 o = gt_nl(ab, o)
164 o = gt_cat(ab, o, "ghostbin" as *u8)
165 o = gt_tab(ab, o)
166 o = gt_cat(ab, o, root)
167 o = gt_cat(ab, o, "/gone.elf" as *u8)
168 o = gt_tab(ab, o)
169 o = gt_cat(ab, o, "GREEN" as *u8)
170 o = gt_nl(ab, o)
171 }
172 ab[o] = 0 as u8
173 gt_wrel(root, "tool_allowlist.conf" as *u8, ab)
174 let sb: *u8 = sys_mmap(GT_BUF)
175 var so: i64 = 0
176 so = gt_cat(sb, so, "# schema fixture" as *u8)
177 so = gt_nl(sb, so)
178 so = gt_cat(sb, so, "argecho" as *u8)
179 so = gt_tab(sb, so)
180 so = gt_cat(sb, so, "Echo" as *u8)
181 so = gt_nl(sb, so)
182 so = gt_cat(sb, so, "good" as *u8)
183 so = gt_tab(sb, so)
184 so = gt_cat(sb, so, "Good" as *u8)
185 so = gt_nl(sb, so)
186 if dirty == 1 {
187 so = gt_cat(sb, so, "stalex" as *u8)
188 so = gt_tab(sb, so)
189 so = gt_cat(sb, so, "Stale" as *u8)
190 so = gt_nl(sb, so)
191 }
192 sb[so] = 0 as u8
193 gt_wrel(root, "knowledge/tool_schemas.conf" as *u8, sb)
194 let tb: *u8 = sys_mmap(GT_BUF)
195 var to: i64 = 0
196 to = gt_cat(tb, to, "dom" as *u8)
197 to = gt_tab(tb, to)
198 to = gt_cat(tb, to, "argecho" as *u8)
199 to = gt_tab(tb, to)
200 to = gt_cat(tb, to, "own" as *u8)
201 to = gt_nl(tb, to)
202 to = gt_cat(tb, to, "dom" as *u8)
203 to = gt_tab(tb, to)
204 to = gt_cat(tb, to, "good" as *u8)
205 to = gt_tab(tb, to)
206 to = gt_cat(tb, to, "own" as *u8)
207 to = gt_nl(tb, to)
208 tb[to] = 0 as u8
209 gt_wrel(root, "knowledge/registry/atlas_catalog.tsv" as *u8, tb)
210 if dirty == 1 { gt_wrel(root, "knowledge/status/dup_source.log" as *u8, "cross-tree source-dup basenames found: 3" as *u8) } else { gt_wrel(root, "knowledge/status/dup_source.log" as *u8, "cross-tree source-dup basenames found: 0" as *u8) }
211 let wb: *u8 = sys_mmap(GT_BUF)
212 var wo: i64 = 0
213 wo = gt_cat(wb, wo, "1784600000" as *u8)
214 wo = gt_tab(wb, wo)
215 wo = gt_cat(wb, wo, "LAW" as *u8)
216 wo = gt_tab(wb, wo)
217 wo = gt_cat(wb, wo, "L003" as *u8)
218 wo = gt_tab(wb, wo)
219 wo = gt_cat(wb, wo, "unregistered" as *u8)
220 wo = gt_tab(wb, wo)
221 if dirty == 1 { wo = gt_cat(wb, wo, "7" as *u8) } else { wo = gt_cat(wb, wo, "0" as *u8) }
222 wo = gt_tab(wb, wo)
223 wo = gt_cat(wb, wo, "BREACH" as *u8)
224 wo = gt_nl(wb, wo)
225 wb[wo] = 0 as u8
226 gt_wrel(root, "knowledge/status/law_warden.jrnl" as *u8, wb)
227 gt_wrel(root, "knowledge/status/shipcheck.log" as *u8, "#" as *u8)
228 return 0
229}
230
231func gt_spawn(av: *i64) -> i64 {
232 let env: *i64 = sys_mmap(8) as *i64
233 env[0] = 0
234 let ep: *u8 = av[0] as *u8
235 let pid: i64 = sys_fork()
236 if pid == 0 { sys_execve(ep, av, env); sys_exit_group(GT_EXEFAIL) }
237 let st: *i64 = sys_mmap(16) as *i64
238 st[0] = 0
239 sys_wait4(pid, st, 0)
240 let raw: i64 = st[0]
241 let code: i64 = (raw / GT_B256) % GT_B256
242 return code
243}
244
245func gt_run(verb: *u8, root: *u8) -> i64 {
246 let av: *i64 = sys_mmap(64) as *i64
247 av[0] = g_elf as i64
248 av[1] = verb as i64
249 av[2] = root as i64
250 av[3] = 0
251 return gt_spawn(av)
252}
253
254func gt_runf(root: *u8) -> i64 {
255 let av: *i64 = sys_mmap(64) as *i64
256 av[0] = g_elf as i64
257 av[1] = "file" as *u8 as i64
258 av[2] = root as i64
259 av[3] = "argecho" as *u8 as i64
260 av[4] = 0
261 return gt_spawn(av)
262}
263
264func gt_load(root: *u8) -> i64 {
265 let pb: *u8 = sys_mmap(GT_PATH)
266 let pp: *u8 = gt_path2(pb, root, "knowledge/status/shipcheck.log" as *u8)
267 g_ln = 0
268 let fd: i64 = sys_openat_rd(pp)
269 if fd < 0 { return 0 }
270 var t: i64 = 0
271 var done: i64 = 0
272 while done == 0 {
273 let want: i64 = GT_LOGB - 8 - t
274 let r: i64 = sys_read(fd, g_log + t, want)
275 if r <= 0 { done = 1 } else { t = t + r; if t >= GT_LOGB - 8 { done = 1 } }
276 }
277 sys_close(fd)
278 g_ln = t
279 g_log[t] = 0 as u8
280 return 1
281}
282
283func gt_has(sub: *u8) -> i64 {
284 let sl: i64 = gt_len(sub)
285 let n: i64 = g_ln
286 var i: i64 = 0
287 while i + sl <= n {
288 var k: i64 = 0
289 var ok: i64 = 1
290 while k < sl { let bi: i64 = i + k; if g_log[bi] != sub[k] { ok = 0; k = sl } else { k = k + 1 } }
291 if ok == 1 { return 1 }
292 i = i + 1
293 }
294 return 0
295}
296
297func gt_findfrom(start: i64, sub: *u8) -> i64 {
298 let sl: i64 = gt_len(sub)
299 let n: i64 = g_ln
300 var i: i64 = start
301 while i + sl <= n {
302 var k: i64 = 0
303 var ok: i64 = 1
304 while k < sl { let bi: i64 = i + k; if g_log[bi] != sub[k] { ok = 0; k = sl } else { k = k + 1 } }
305 if ok == 1 { return i }
306 i = i + 1
307 }
308 return 0 - 1
309}
310
311func gt_t3eq() -> i64 {
312 let a: i64 = gt_findfrom(0, "SHIPCHECK " as *u8)
313 if a < 0 { return 0 }
314 let b: i64 = gt_findfrom(a + 1, "SHIPCHECK " as *u8)
315 if b < 0 { return 0 }
316 let fa: i64 = gt_findfrom(a, " allow=" as *u8)
317 let fb: i64 = gt_findfrom(b, " allow=" as *u8)
318 if fa < 0 { return 0 }
319 if fb < 0 { return 0 }
320 if fa >= b { return 0 }
321 let ea: i64 = gt_le(g_log, fa, g_ln)
322 let eb: i64 = gt_le(g_log, fb, g_ln)
323 if ea - fa != eb - fb { return 0 }
324 var i: i64 = 0
325 let n: i64 = ea - fa
326 while i < n { let xa: i64 = fa + i; let xb: i64 = fb + i; if g_log[xa] != g_log[xb] { return 0 } i = i + 1 }
327 return 1
328}
329
330func main(argc: i64, argv: *i64) -> i64 {
331 g_sp = sys_mmap(16) as *i64
332 g_argecho = sys_mmap(GT_PATH)
333 g_log = sys_mmap(GT_LOGB)
334 g_elf = "./nx_shipcheck.elf" as *u8
335 if argc >= 2 { g_elf = argv[1] as *u8 }
336 let ctr: *i64 = gv_ctr()
337 gv_head("nx_shipcheck gate -- ship-complete orphan detector teeth (fixture-injected, filer=argecho)" as *u8)
338 let ra: i64 = gt_resolve_argecho()
339 gv_check("T0 argecho resolved from the real allowlist" as *u8, ra, ctr)
340 fx_build("/tmp/scfa" as *u8, 1)
341 let rc1: i64 = gt_run("scan" as *u8, "/tmp/scfa" as *u8)
342 var c1: i64 = 0
343 if rc1 == GT_EXITRED { c1 = 1 }
344 gv_check("T1 orphan fixture exits RED(3)" as *u8, c1, ctr)
345 gt_load("/tmp/scfa" as *u8)
346 gv_check("T1a allow=4" as *u8, gt_has(" allow=4 " as *u8), ctr)
347 gv_check("T1b noschema=2" as *u8, gt_has(" noschema=2 " as *u8), ctr)
348 gv_check("T1c staleschema=1" as *u8, gt_has(" staleschema=1 " as *u8), ctr)
349 gv_check("T1d stagedref=1" as *u8, gt_has(" stagedref=1 " as *u8), ctr)
350 gv_check("T1e missingbin=1" as *u8, gt_has(" missingbin=1 " as *u8), ctr)
351 gv_check("T1f straynew=1" as *u8, gt_has(" straynew=1 " as *u8), ctr)
352 gv_check("T1g dupsrc=3 composed" as *u8, gt_has(" dupsrc=3 " as *u8), ctr)
353 gv_check("T1h unreg_l003=7 composed" as *u8, gt_has(" unreg_l003=7 " as *u8), ctr)
354 gv_check("T1i noatlas=2" as *u8, gt_has(" noatlas=2 " as *u8), ctr)
355 gv_check("T1j verdict=RED" as *u8, gt_has("verdict=RED" as *u8), ctr)
356 fx_build("/tmp/scfb" as *u8, 0)
357 let rc2: i64 = gt_run("scan" as *u8, "/tmp/scfb" as *u8)
358 var c2: i64 = 0
359 if rc2 == 0 { c2 = 1 }
360 gv_check("T2 clean fixture exits 0" as *u8, c2, ctr)
361 gt_load("/tmp/scfb" as *u8)
362 gv_check("T2a verdict=GREEN" as *u8, gt_has("verdict=GREEN" as *u8), ctr)
363 gv_check("T2b noschema=0" as *u8, gt_has(" noschema=0 " as *u8), ctr)
364 gv_check("T2c stagedref=0" as *u8, gt_has(" stagedref=0 " as *u8), ctr)
365 fx_build("/tmp/scfc" as *u8, 1)
366 gt_run("scan" as *u8, "/tmp/scfc" as *u8)
367 gt_run("scan" as *u8, "/tmp/scfc" as *u8)
368 gt_load("/tmp/scfc" as *u8)
369 gv_check("T3 two scans byte-equal counts" as *u8, gt_t3eq(), ctr)
370 gt_runf("/tmp/scfa" as *u8)
371 gt_load("/tmp/scfa" as *u8)
372 gv_check("T4a FILED stagedref exit=0 (argecho filer)" as *u8, gt_has("FILED class=stagedref exit=0" as *u8), ctr)
373 gv_check("T4b FILED noatlas exit=0 (argecho filer)" as *u8, gt_has("FILED class=noatlas exit=0" as *u8), ctr)
374 gt_runf("/tmp/scfb" as *u8)
375 gt_load("/tmp/scfb" as *u8)
376 var c5: i64 = 1
377 if gt_has("FILED" as *u8) == 1 { c5 = 0 }
378 gv_check("T5 clean fixture files NOTHING" as *u8, c5, ctr)
379 let rc: i64 = gv_verdict("SHIPCHECK-GATE" as *u8, ctr, "planted orphans detected exactly + clean-negative + determinism + injectable filer" as *u8)
380 return rc
381}