code wiki / (root) / nx_forge_req_gate.nx

nx_forge_req_gate.nx source

↩ module page · 288 lines · 9670 B

1// nx_forge_req_gate.nx -- FORGE requirements dossier gate (the adversary/critic tooth). 2// Walks knowledge/forge/forge_requirements_v1.txt: every REQ| row must carry EV= paths that 3// exist NON-EMPTY on disk (evidence fork, census doctrine) and a non-empty ADV= adversary test. 4// NEG-CONTROL: knowledge/forge/forge_req_negctl.txt holds a planted row whose EV file is absent; 5// verdict GREEN only if every real row PASSES and the planted row FAILS (liar-kill: a 6// rubber-stamp checker cannot go GREEN). CR-tolerant by field order (ADV last, EV mid-row). 7// license_tier: ORIGINAL expect_exit: 0 8import "nx_syscalls.nx" 9import "nx_lib_std.nx" 10import "nx_gate_verdict.nx" 11import "nx_artifact_root.nx" 12 13func rq_read(path: *u8, buf: *u8, cap: i64) -> i64 { 14 let fd: i64 = sys_openat_rd(path) 15 if fd < 0 { 16 let neg: i64 = 0 - 1 17 return neg 18 } 19 var total: i64 = 0 20 var going: i64 = 1 21 while going == 1 { 22 let lim: i64 = cap - 1 23 let room: i64 = lim - total 24 if room <= 0 { going = 0 } 25 if going == 1 { 26 let p: *u8 = buf + total 27 let n: i64 = sys_read(fd, p, room) 28 if n <= 0 { going = 0 } 29 if n > 0 { total = total + n } 30 } 31 } 32 sys_close(fd) 33 buf[total] = 0 as u8 34 return total 35} 36 37// HOST-BOUND FIX 2026-08-02 (debt 1785689846, recipe proven on nx_sclass_dispatch_gate): EV rows name 38// artifacts by CONVENTION (`runtime/nx_forge.nx`), and that convention differs per host -- on the NAS the 39// same source lives at `buildroot/runtime/nx_forge.nx`. Opening the literal made every row read EV-MISS 40// off-laptop, i.e. the gate graded the MACHINE, not the dossier. ar_resolve walks the host's roots table 41// (nx_artifact_root -- the 9-of-9-UNGROUNDED law) and tries the raw path FIRST, so dev behaviour is 42// unchanged and a genuine absence still reports the path the caller actually asked for. 43func rq_ev_ok(path: *u8, scratch: *u8) -> i64 { 44 let rp: *u8 = sys_mmap(4096) 45 ar_resolve(path, rp) 46 let fd: i64 = sys_openat_rd(rp) 47 if fd < 0 { return 0 } 48 let n: i64 = sys_read(fd, scratch, 4) 49 sys_close(fd) 50 if n > 0 { return 1 } 51 return 0 52} 53 54// find "|EV=" inside [ls,le); return index just after '=', or -1 55func rq_find_ev(buf: *u8, ls: i64, le: i64) -> i64 { 56 var i: i64 = ls 57 let stop: i64 = le - 3 58 while i < stop { 59 let c0: i64 = buf[i] as i64 60 if c0 == 124 { 61 let i1: i64 = i + 1 62 let c1: i64 = buf[i1] as i64 63 if c1 == 69 { 64 let i2: i64 = i + 2 65 let c2: i64 = buf[i2] as i64 66 if c2 == 86 { 67 let i3: i64 = i + 3 68 let c3: i64 = buf[i3] as i64 69 if c3 == 61 { 70 let r: i64 = i + 4 71 return r 72 } 73 } 74 } 75 } 76 i = i + 1 77 } 78 let neg: i64 = 0 - 1 79 return neg 80} 81 82// find "|ADV=" inside [ls,le); return index just after '=', or -1 83func rq_find_adv(buf: *u8, ls: i64, le: i64) -> i64 { 84 var i: i64 = ls 85 let stop: i64 = le - 4 86 while i < stop { 87 let c0: i64 = buf[i] as i64 88 if c0 == 124 { 89 let i1: i64 = i + 1 90 let c1: i64 = buf[i1] as i64 91 if c1 == 65 { 92 let i2: i64 = i + 2 93 let c2: i64 = buf[i2] as i64 94 if c2 == 68 { 95 let i3: i64 = i + 3 96 let c3: i64 = buf[i3] as i64 97 if c3 == 86 { 98 let i4: i64 = i + 4 99 let c4: i64 = buf[i4] as i64 100 if c4 == 61 { 101 let r: i64 = i + 5 102 return r 103 } 104 } 105 } 106 } 107 } 108 i = i + 1 109 } 110 let neg: i64 = 0 - 1 111 return neg 112} 113 114// validate one REQ row [ls,le); mode 0 = must pass, mode 1 = negctl must fail. 115// returns 1 if the row is BAD for its mode, else 0. 116func rq_row(buf: *u8, ls: i64, le: i64, mode: i64, pbuf: *u8, scratch: *u8) -> i64 { 117 std_puts("ROW " as *u8) 118 let idoff: i64 = ls + 4 119 var idend: i64 = idoff 120 var s: i64 = 1 121 while s == 1 { 122 if idend >= le { s = 0 } 123 if s == 1 { 124 let c: i64 = buf[idend] as i64 125 if c == 124 { s = 0 } 126 if c != 124 { idend = idend + 1 } 127 } 128 } 129 let idp: *u8 = buf + idoff 130 let idl: i64 = idend - idoff 131 sys_write(1, idp, idl) 132 var rowok: i64 = 1 133 let evs: i64 = rq_find_ev(buf, ls, le) 134 if evs < 0 { rowok = 0 } 135 if evs >= 0 { 136 var j: i64 = evs 137 var npaths: i64 = 0 138 var going: i64 = 1 139 while going == 1 { 140 var k: i64 = j 141 var t: i64 = 1 142 while t == 1 { 143 if k >= le { t = 0 } 144 if t == 1 { 145 let c: i64 = buf[k] as i64 146 if c == 44 { t = 0 } 147 if c == 124 { t = 0 } 148 if c != 44 { if c != 124 { k = k + 1 } } 149 } 150 } 151 let tl: i64 = k - j 152 if tl > 0 { 153 if tl < 4000 { 154 let srcp: *u8 = buf + j 155 std_memcpy(pbuf, srcp, tl) 156 pbuf[tl] = 0 as u8 157 let ok: i64 = rq_ev_ok(pbuf, scratch) 158 npaths = npaths + 1 159 if ok == 0 { 160 rowok = 0 161 std_puts(" EV-MISS:" as *u8) 162 std_puts(pbuf) 163 } 164 } 165 } 166 if k >= le { going = 0 } 167 if k < le { 168 let c2: i64 = buf[k] as i64 169 if c2 == 124 { going = 0 } 170 if c2 == 44 { j = k + 1 } 171 } 172 } 173 if npaths == 0 { rowok = 0 } 174 } 175 let ads: i64 = rq_find_adv(buf, ls, le) 176 if ads < 0 { rowok = 0 } 177 if ads >= 0 { 178 if ads >= le { rowok = 0 } 179 if ads < le { 180 let c: i64 = buf[ads] as i64 181 if c == 124 { rowok = 0 } 182 if c == 13 { rowok = 0 } 183 if c == 10 { rowok = 0 } 184 } 185 } 186 if mode == 0 { 187 if rowok == 1 { 188 std_putln(" PASS" as *u8) 189 return 0 190 } 191 std_putln(" FAIL" as *u8) 192 return 1 193 } 194 if rowok == 1 { 195 std_putln(" NEGCTL-NOT-CAUGHT" as *u8) 196 return 1 197 } 198 std_putln(" NEGCTL-CAUGHT" as *u8) 199 return 0 200} 201 202// walk all lines; validate REQ rows; return count of BAD rows for the mode. nrows via nout[0]. 203func rq_walk(buf: *u8, len: i64, mode: i64, pbuf: *u8, scratch: *u8, nout: *i64) -> i64 { 204 var bad: i64 = 0 205 var nrows: i64 = 0 206 var i: i64 = 0 207 while i < len { 208 var e: i64 = i 209 var scan: i64 = 1 210 while scan == 1 { 211 if e >= len { scan = 0 } 212 if scan == 1 { 213 let c: i64 = buf[e] as i64 214 if c == 10 { scan = 0 } 215 if c != 10 { e = e + 1 } 216 } 217 } 218 let ll: i64 = e - i 219 var isreq: i64 = 0 220 if ll > 4 { 221 let c0: i64 = buf[i] as i64 222 if c0 == 82 { 223 let i1: i64 = i + 1 224 let c1: i64 = buf[i1] as i64 225 if c1 == 69 { 226 let i2: i64 = i + 2 227 let c2: i64 = buf[i2] as i64 228 if c2 == 81 { 229 let i3: i64 = i + 3 230 let c3: i64 = buf[i3] as i64 231 if c3 == 124 { isreq = 1 } 232 } 233 } 234 } 235 } 236 if isreq == 1 { 237 nrows = nrows + 1 238 let r: i64 = rq_row(buf, i, e, mode, pbuf, scratch) 239 bad = bad + r 240 } 241 i = e + 1 242 } 243 nout[0] = nrows 244 return bad 245} 246 247func main(argc: i64, argv: *i64) -> i64 { 248 let buf: *u8 = sys_mmap(262144) as *u8 249 let nbuf: *u8 = sys_mmap(65536) as *u8 250 let pbuf: *u8 = sys_mmap(4096) as *u8 251 let scratch: *u8 = sys_mmap(64) as *u8 252 let cnt: *i64 = sys_mmap(64) as *i64 253 let n: i64 = rq_read("knowledge/forge/forge_requirements_v1.txt" as *u8, buf, 262144) 254 if n <= 0 { 255 std_putln("FORGE-REQ-GATE verdict=RED no-dossier" as *u8) 256 sys_exit(1) 257 return 1 258 } 259 let bad: i64 = rq_walk(buf, n, 0, pbuf, scratch, cnt) 260 let nrows: i64 = cnt[0] 261 let n2: i64 = rq_read("knowledge/forge/forge_req_negctl.txt" as *u8, nbuf, 65536) 262 var nbad: i64 = 1 263 var nneg: i64 = 0 264 if n2 > 0 { 265 nbad = rq_walk(nbuf, n2, 1, pbuf, scratch, cnt) 266 nneg = cnt[0] 267 } 268 if nneg == 0 { nbad = 1 } 269 std_puts("FORGE-REQ-GATE rows=" as *u8) 270 std_pdec(nrows) 271 std_puts(" rows-bad=" as *u8) 272 std_pdec(bad) 273 std_puts(" negctl-rows=" as *u8) 274 std_pdec(nneg) 275 std_puts(" negctl-bad=" as *u8) 276 std_pdec(nbad) 277 var allok: i64 = 0 278 if nrows > 0 { if bad == 0 { if nbad == 0 { allok = 1 } } } 279 if allok == 1 { std_putln(" verdict=GREEN" as *u8) } else { std_putln(" verdict=RED" as *u8) } 280 let ctr: *i64 = gv_ctr() 281 var t1: i64 = 0 282 if nrows > 0 { if bad == 0 { t1 = 1 } } 283 gv_check("T1 every REQ row carries EV= paths NON-EMPTY on disk (evidence fork)" as *u8, t1, ctr) 284 var t2: i64 = 0 285 if nneg > 0 { if nbad == 0 { t2 = 1 } } 286 gv_check("T2 LIAR-KILL: the planted absent-evidence row is CAUGHT (a rubber stamp cannot go green)" as *u8, t2, ctr) 287 return gv_verdict("FORGE-REQ-GATE" as *u8, ctr, "requirements dossier evidence-forked on disk with the planted negative control caught" as *u8) 288}