nx_assetingest_gate.nx source
↩ module page · 269 lines · 10379 B
1// nx_assetingest_gate.nx -- THE ASSET INGEST LANE'S STANDING GATE. Runs every ingest organ's KAT
2// *and* its real-data regressions in one command, from a roster that is DATA.
3//
4// NAMING: nx_ingest_gate.nx ALREADY EXISTS and is the referee for a WRITING rung (prose scene /
5// entity extraction). "ingest" means text there and assets here. This file was almost written over
6// it; the compare-and-swap guard refused the blind write and saved the other lane's organ. Third
7// name collision of the day, after nx_bvh (bounding volume, not biovision).
8// *A NAME IS NOT A CAPABILITY -- AND A NAME YOU DID NOT CHECK IS SOMEBODY ELSE'S ORGAN.
9//
10// D001 COMPLIANT (2026-08-07): the first cut of this gate rolled its OWN verdict and /api/promote
11// refused it -- nx_gate_green could not judge it and it wrote no harness.jrnl frame, so its flake
12// and erosion would have been invisible. It was a gate that existed but was not IN THE WORKFLOW.
13// It now inherits nx_gate_verdict, the one canonical emitter.
14// *A GATE NOBODY RUNS IS A COMMENT; A GATE NOTHING CAN READ IS AN ISLAND.
15//
16// THE THIRD STATE: a roster row's fixture can be absent. Per gv_need, that is SKIP -- "I could not
17// look" is not "I looked and it is broken". A detector that cannot tell those apart teaches
18// everyone to ignore it.
19//
20// ROSTER-DRIVEN (knowledge/assetingest_gate.roster): adding a check is an APPEND, never a
21// recompile. Rows: <elf-basename> TAB <space-separated args> TAB <expected substring>.
22// The roster deliberately mixes KATs with THIRD-PARTY-DATA regressions -- a lane gated only by
23// fixtures its own author wrote is a lane grading its own homework.
24//
25// usage: nx_assetingest_gate [roster] default knowledge/assetingest_gate.roster
26// nx_assetingest_gate --kat selftest: 4 teeth, 3 of them anti-vacuity
27// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
28import "nx_gate_verdict.nx"
29import "nx_tool_run.nx"
30
31const AG_ELFDIR: *u8 = "/volume1/homes/elderwesto/nishihost/"
32const AG_ROSTER: *u8 = "knowledge/assetingest_gate.roster"
33const AG_CAP: i64 = 1048576
34const AG_MAXARG: i64 = 32
35const AG_PATHW: i64 = 512
36const AG_FLDW: i64 = 1024
37const AG_MODE: i64 = 420
38
39func ag_slen(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { i = i + 1 } return i }
40
41func ag_contains(buf: *u8, n: i64, needle: *u8) -> i64 {
42 let m: i64 = ag_slen(needle)
43 if m == 0 { return 1 }
44 if m > n { return 0 }
45 var i: i64 = 0
46 while i + m <= n {
47 var k: i64 = 0
48 var ok: i64 = 1
49 while k < m {
50 if buf[i + k] != needle[k] { ok = 0; k = m } else { k = k + 1 }
51 }
52 if ok == 1 { return 1 }
53 i = i + 1
54 }
55 return 0
56}
57
58func ag_slice(src: *u8, a: i64, b: i64, dst: *u8, cap: i64) -> i64 {
59 var n: i64 = b - a
60 if n < 0 { n = 0 }
61 if n > cap - 1 { n = cap - 1 }
62 var i: i64 = 0
63 while i < n { dst[i] = src[a + i]; i = i + 1 }
64 dst[n] = 0 as u8
65 return n
66}
67
68func ag_cat(dst: *u8, o: i64, s: *u8, cap: i64) -> i64 {
69 let n: i64 = ag_slen(s)
70 var i: i64 = 0
71 while i < n { if o + i < cap - 1 { dst[o + i] = s[i] } i = i + 1 }
72 var e: i64 = o + n
73 if e > cap - 1 { e = cap - 1 }
74 dst[e] = 0 as u8
75 return e
76}
77
78func ag_run_row(elf: *u8, args: *u8, expect: *u8) -> i64 {
79 let path: *u8 = sys_mmap(AG_PATHW)
80 var p: i64 = 0
81 let dn: i64 = ag_slen(AG_ELFDIR)
82 while p < dn { path[p] = AG_ELFDIR[p]; p = p + 1 }
83 let en: i64 = ag_slen(elf)
84 var q: i64 = 0
85 while q < en { path[p + q] = elf[q]; q = q + 1 }
86 path[p + en] = 0 as u8
87
88 let av: *i64 = sys_mmap(AG_MAXARG * 8) as *i64
89 av[0] = path as i64
90 var ac: i64 = 1
91 let an: i64 = ag_slen(args)
92 var s: i64 = 0
93 while s < an {
94 if (args[s] & 0xff) as i64 == 32 { s = s + 1 }
95 else {
96 var e: i64 = s
97 var stop: i64 = 0
98 while stop == 0 {
99 if e >= an { stop = 1 }
100 else { if (args[e] & 0xff) as i64 == 32 { stop = 1 } else { e = e + 1 } }
101 }
102 if ac < AG_MAXARG - 1 {
103 let tb: *u8 = sys_mmap(AG_FLDW)
104 ag_slice(args, s, e, tb, AG_FLDW)
105 av[ac] = tb as i64
106 ac = ac + 1
107 }
108 s = e
109 }
110 }
111 av[ac] = 0
112
113 let out: *u8 = sys_mmap(AG_CAP)
114 let olen: *i64 = sys_mmap(16) as *i64
115 olen[0] = 0
116 tr_run_capture(path, av, out, AG_CAP, olen)
117 if ag_contains(out, olen[0], expect) == 1 { return 1 }
118 return 0
119}
120
121// Walk the roster. If ctr is non-null every row becomes a gv_check; otherwise rows are only
122// counted (the KAT needs the raw outcome without polluting the outer counters).
123func ag_rows(buf: *u8, len: i64, ran: *i64, ctr: *i64) -> i64 {
124 var fails: i64 = 0
125 var n: i64 = 0
126 var i: i64 = 0
127 let elf: *u8 = sys_mmap(AG_FLDW)
128 let args: *u8 = sys_mmap(AG_FLDW)
129 let exp: *u8 = sys_mmap(AG_FLDW)
130 let lbl: *u8 = sys_mmap(AG_FLDW)
131 while i < len {
132 var e: i64 = i
133 var stop: i64 = 0
134 while stop == 0 {
135 if e >= len { stop = 1 }
136 else { if (buf[e] & 0xff) as i64 == 10 { stop = 1 } else { e = e + 1 } }
137 }
138 if e > i {
139 if (buf[i] & 0xff) as i64 != 35 {
140 var t1: i64 = 0 - 1
141 var t2: i64 = 0 - 1
142 var k: i64 = i
143 while k < e {
144 if (buf[k] & 0xff) as i64 == 9 {
145 if t1 < 0 { t1 = k } else { if t2 < 0 { t2 = k } }
146 }
147 k = k + 1
148 }
149 if t1 > 0 {
150 if t2 > 0 {
151 ag_slice(buf, i, t1, elf, AG_FLDW)
152 ag_slice(buf, t1 + 1, t2, args, AG_FLDW)
153 ag_slice(buf, t2 + 1, e, exp, AG_FLDW)
154 let ok: i64 = ag_run_row(elf, args, exp)
155 n = n + 1
156 if ok == 0 { fails = fails + 1 }
157 if (ctr as i64) != 0 {
158 var o: i64 = ag_cat(lbl, 0, elf, AG_FLDW)
159 o = ag_cat(lbl, o, " " as *u8, AG_FLDW)
160 o = ag_cat(lbl, o, args, AG_FLDW)
161 gv_check(lbl, ok, ctr)
162 }
163 }
164 }
165 }
166 }
167 i = e + 1
168 }
169 ran[0] = n
170 return fails
171}
172
173// raw evaluation used by the KAT: -1 unreadable, else failure count (ran[0] = rows executed)
174func ag_eval(rpath: *u8, ran: *i64) -> i64 {
175 let lenp: *i64 = sys_mmap(16) as *i64
176 let buf: *u8 = sys_read_file(rpath, lenp)
177 ran[0] = 0
178 if (buf as i64) == 0 { return 0 - 1 }
179 return ag_rows(buf, lenp[0], ran, 0 as *i64)
180}
181
182func ag_gate(rpath: *u8) -> i64 {
183 let ctr: *i64 = gv_ctr()
184 gv_head("nx_assetingest_gate -- asset ingest lane: format KATs + third-party-data regressions" as *u8)
185 let lenp: *i64 = sys_mmap(16) as *i64
186 let buf: *u8 = sys_read_file(rpath, lenp)
187 var present: i64 = 0
188 if (buf as i64) != 0 { present = 1 }
189 // A missing roster is a MISSING PRECONDITION, not a failure of the lane under test.
190 if gv_need(rpath, present, ctr) == 0 {
191 return gv_verdict("ASSETINGEST-GATE" as *u8, ctr, "roster absent" as *u8)
192 }
193 let ran: *i64 = sys_mmap(16) as *i64
194 ran[0] = 0
195 ag_rows(buf, lenp[0], ran, ctr)
196 // A gate that ran nothing has PROVEN nothing -- zero rows is a missing precondition too,
197 // never a silent pass.
198 var any: i64 = 0
199 if ran[0] > 0 { any = 1 }
200 gv_need("roster-has-at-least-one-row" as *u8, any, ctr)
201 return gv_verdict("ASSETINGEST-GATE" as *u8, ctr, "roster-driven; rows are data" as *u8)
202}
203
204// ===== KAT ========================================================
205func ag_put(b: *u8, o: i64, s: *u8) -> i64 {
206 let n: i64 = ag_slen(s)
207 var i: i64 = 0
208 while i < n { b[o + i] = s[i]; i = i + 1 }
209 return o + n
210}
211func ag_writef(path: *u8, b: *u8, n: i64) -> i64 {
212 let fd: i64 = sys_openat_wr(path, AG_MODE)
213 if fd < 0 { return 0 - 1 }
214 sys_write(fd, b, n)
215 sys_close(fd)
216 return n
217}
218
219func ag_kat() -> i64 {
220 let ctr: *i64 = gv_ctr()
221 gv_head("nx_assetingest_gate KAT -- proves the roster comparator can pass, fail and refuse" as *u8)
222 let b: *u8 = sys_mmap(4096)
223 let ran: *i64 = sys_mmap(16) as *i64
224
225 var o: i64 = ag_put(b, 0, "nx_fetchclean.elf\t--kat\tnx_fetchclean KAT GREEN 5/5\n" as *u8)
226 ag_writef("/tmp/ag_ok.roster" as *u8, b, o)
227 let f1: i64 = ag_eval("/tmp/ag_ok.roster" as *u8, ran)
228 var t1: i64 = 0
229 if f1 == 0 { if ran[0] == 1 { t1 = 1 } }
230 gv_check("T1 a satisfied roster row passes" as *u8, t1, ctr)
231
232 // T2 ANTI-VACUITY: the comparator must be able to go RED. If this cannot fail, every GREEN
233 // this gate ever prints is meaningless -- the check would not be checking.
234 o = ag_put(b, 0, "nx_fetchclean.elf\t--kat\tTHIS-STRING-CANNOT-APPEAR\n" as *u8)
235 ag_writef("/tmp/ag_bad.roster" as *u8, b, o)
236 let f2: i64 = ag_eval("/tmp/ag_bad.roster" as *u8, ran)
237 var t2: i64 = 0
238 if f2 == 1 { if ran[0] == 1 { t2 = 1 } }
239 gv_check("T2 ANTI-VACUITY an unsatisfiable row FAILS" as *u8, t2, ctr)
240
241 // T3 ANTI-VACUITY: a comments-only roster executes ZERO rows. Zero must stay visible as zero.
242 o = ag_put(b, 0, "# only a comment\n" as *u8)
243 ag_writef("/tmp/ag_empty.roster" as *u8, b, o)
244 let f3: i64 = ag_eval("/tmp/ag_empty.roster" as *u8, ran)
245 var t3: i64 = 0
246 if f3 == 0 { if ran[0] == 0 { t3 = 1 } }
247 gv_check("T3 ANTI-VACUITY a zero-row roster reports zero rows" as *u8, t3, ctr)
248
249 // T4 ANTI-VACUITY: an absent roster is distinguishable from an empty one.
250 let f4: i64 = ag_eval("/tmp/ag_does_not_exist.roster" as *u8, ran)
251 var t4: i64 = 0
252 if f4 == 0 - 1 { t4 = 1 }
253 gv_check("T4 ANTI-VACUITY an absent roster is -1, not 0" as *u8, t4, ctr)
254
255 return gv_verdict("ASSETINGEST-GATE-KAT" as *u8, ctr, "comparator can pass, fail and refuse" as *u8)
256}
257
258func main(argc: i64, argv: *i64) -> i64 {
259 if argc > 1 {
260 let a1: *u8 = argv[1] as *u8
261 if ag_slen(a1) == 5 { if a1[0] == (45 as u8) { let r: i64 = ag_kat(); sys_exit(r); return r } }
262 let r2: i64 = ag_gate(a1)
263 sys_exit(r2)
264 return r2
265 }
266 let r3: i64 = ag_gate(AG_ROSTER)
267 sys_exit(r3)
268 return r3
269}