code wiki / (root) / nx_nxeconform_gate.nx

nx_nxeconform_gate.nx source

↩ module page · 672 lines · 33664 B

1// nx_nxeconform_gate.nx -- NXE FORMAT CONFORMANCE (constitution A2: NXE, NOT ELF). 2// 3// THE DEFECT THIS EXISTS TO MAKE UNSHIPPABLE (measured 2026-08-15, full population, 23,181 files): 4// NXE had forked into THREE on-disk layouts across TWO magics -- NXE1@80 (the prototype the rule-15 DRY 5// extraction left behind), NXE1@96 (the live lane, and F103a's own witness for C01/C02/C11), and 6// NXE0@64 with a WRAPPING SUM for the kernel image. Nobody was counting, because no instrument counted. 7// * A FORKED FORMAT OUTLIVES THE CODE THAT FORKED IT, BECAUSE THE ARTIFACTS PERSIST. 8// * A LAW THAT MUST BE RECALLED AT THE MOMENT OF TEMPTATION IS NOT A CONTROL; ONLY A MECHANISM IN 9// THE PATH IS -- so this is a gate, not another paragraph. 10// 11// SUBJECT: every NXE artifact ON DISK under the declared roots, classified against the declared layouts. 12// It reads BYTES, never source prose -- a scanner that reads comments measures the documentation. 13// 14// NO HARDCODED NUMBERS: every offset, header size, magic and baseline is a row in 15// knowledge/registry/nxe_layouts.conf (rule 11). The layout/root tables are sized from the conf's OWN 16// line count, so even the table capacity is derived rather than guessed. 17// NO SAMPLING: the roots are swept RECURSIVELY and IN FULL; getdents64 is looped until it returns 0 18// (one call is not a directory listing), and the single genuine bound -- the directory frontier -- 19// REFUSES at its cap instead of silently truncating (a cap reached in silence becomes a measurement 20// nobody knows is partial). 21// HONEST THIRD STATE: absent conf, zero declared layouts or zero artifacts end the run SKIP via gv_need, 22// never GREEN and never RED -- "I could not look" is not "I looked and it is fine". 23// RATCHET, NOT PERFECTION: three layouts exist TODAY, so a gate demanding one would be permanently RED 24// and everyone would learn to ignore it. The declared-layout count and the weak-integrity count are 25// ratchets that may only FALL. Convergence = delete a LAYOUT row and lower its RATCHET in one edit. 26// 27// THE IMPRECISION I CHOSE TO LIVE WITH, stated so the next reader does not mistake this for exact: 28// (1) A ratchet baseline is DECLARED, so adding a LAYOUT row and raising its RATCHET in the same edit 29// passes. That is deliberate -- the gate's job is to make a widening VISIBLE in the diff and 30// impossible to do by accident, not to prevent a considered decision. 31// (2) The population is artifacts ON DISK under the declared roots. An NXE emitted somewhere no ROOT 32// row covers is outside the claim; that is why the roots are data and the sweep is exhaustive 33// within them. "0 undeclared" always means "0 undeclared, in what was swept". 34// 35// argv[1] optionally overrides the conf path (pinned at registration). Exit 0 GREEN / 1 RED. 36// license_tier: ORIGINAL No hw writes (Rule 26): reads a conf + artifact bytes, writes stdout only. 37import "nx_syscalls.nx" 38import "nx_gate_verdict.nx" 39import "nx_sha256.nx" // integrity is RECOMPUTED, not believed: sha256_digest is the shipped one 40 41const NXC_CONF_DEFAULT: *u8 = "knowledge/registry/nxe_layouts.conf" as *u8 42const NXC_HASH: i64 = 35 // hash sign -- built as a value: the nx_cc lexer rejects it inside a literal 43const NXC_PIPE: i64 = 124 // pipe 44const NXC_NL: i64 = 10 // newline 45const NXC_SLASH: i64 = 47 // slash 46const NXC_MAGIC_BYTES: i64 = 4 // an NXE magic is 4 bytes: the format says so, not a tuning knob 47const NXC_DIGIT_LO: i64 = 48 // ASCII zero -- the magic's 4th byte is a VERSION DIGIT 48const NXC_DIGIT_HI: i64 = 57 // ASCII nine 49const NXC_FIELD_MAX: i64 = 10 // widest row grammar (LAYOUT) has 10 fields 50// Integrity kinds the gate can RECOMPUTE. An unrecognised kind is MALFORMED, never silently trusted: 51// UNKNOWN IS ITS OWN BUCKET, because the bucket it lands in becomes the number somebody plans against. 52const NXC_K_SHA256: i64 = 1 53const NXC_K_DJB2: i64 = 2 54const NXC_K_SUM64: i64 = 3 55const NXC_SHA256_BYTES: i64 = 32 56const NXC_DJB2_SEED: i64 = 5381 // the djb2 constants are the ALGORITHM, not tunables 57const NXC_DJB2_SHIFT: i64 = 5 58const NXC_WORD: i64 = 8 // text_off / text_size are 8-byte little-endian in EVERY layout 59// The ONE genuine bound: how many directories may be pending at once. Unknowable in advance, so it is 60// NAMED for that single purpose and its exhaustion is a REFUSAL that announces -- never a quiet stop. 61const NXC_DIR_FRONTIER_MAX: i64 = 4096 62const NXC_PATH_ARENA_BYTES: i64 = 4194304 63const NXC_SCRATCH: i64 = 512 64 65// Copy a conf field out to a NUL-terminated scratch so it can be printed / compared. 66func nxc_cp(src: *u8, o: i64, n: i64, dst: *u8, cap: i64) -> i64 { 67 var m: i64 = n 68 if m > (cap - 1) { m = cap - 1 } 69 if m < 0 { m = 0 } 70 var i: i64 = 0 71 while i < m { dst[i] = src[o + i]; i = i + 1 } 72 dst[m] = 0 as u8 73 return m 74} 75 76func nxc_streq(a: *u8, b: *u8) -> i64 { 77 var i: i64 = 0 78 var r: i64 = 0 - 1 79 while r < 0 { 80 let ca: i64 = a[i] as i64 81 let cb: i64 = b[i] as i64 82 if ca != cb { r = 0 } 83 if r < 0 { if ca == 0 { r = 1 } } 84 if r < 0 { i = i + 1 } 85 } 86 return r 87} 88 89// Decimal field -> integer. Returns -1 on any non-digit, so a malformed row is REFUSED, not defaulted. 90func nxc_num(src: *u8, o: i64, n: i64) -> i64 { 91 if n <= 0 { return 0 - 1 } 92 var v: i64 = 0 93 var i: i64 = 0 94 var bad: i64 = 0 95 while i < n { 96 let c: i64 = src[o + i] as i64 97 if c < NXC_DIGIT_LO { bad = 1 } else { if c > NXC_DIGIT_HI { bad = 1 } } 98 if bad == 0 { v = v * 10 + (c - NXC_DIGIT_LO) } 99 i = i + 1 100 } 101 if bad == 1 { return 0 - 1 } 102 return v 103} 104 105// Pack 4 magic bytes into one integer so comparison is a single ==. 106func nxc_m32(m: *u8, o: i64) -> i64 { 107 return (m[o] as i64) | ((m[o+1] as i64) << 8) | ((m[o+2] as i64) << 16) | ((m[o+3] as i64) << 24) 108} 109 110func nxc_r64(m: *u8, o: i64) -> i64 { 111 var v: i64 = 0 112 var i: i64 = 0 113 while i < NXC_WORD { v = v | ((m[o + i] as i64) << (i * 8)); i = i + 1 } 114 return v 115} 116 117// Read ONLY the header window of a file and take its size from lseek END. 118// v1 of this gate called sys_read_file per candidate -- i.e. it mmap'd EVERY regular file in the tree 119// whole, just to look at 4 bytes, and hung on the first large root. Nothing here needs the payload: 120// the size comes from lseek and every field under test lives in the header. 121// * NEVER ALLOCATE IN A HOT LOOP -- PASS THE BUFFER IN, AND COUNT SYSCALLS PER UNIT OF OUTPUT. 122// Returns bytes actually read into buf; szp[0] receives the TRUE file size (not the bytes read). 123func nxc_head(path: *u8, buf: *u8, want: i64, szp: *i64) -> i64 { 124 szp[0] = 0 125 let fd: i64 = sys_openat_rd(path) 126 if fd < 0 { return 0 } 127 let sz: i64 = sys_lseek(fd, 0, 2) 128 sys_lseek(fd, 0, 0) 129 var got: i64 = 0 130 var go: i64 = 1 131 while go == 1 { 132 let rem: i64 = want - got 133 if rem <= 0 { go = 0 } 134 if go == 1 { 135 let q: *u8 = buf + got 136 let r: i64 = sys_read(fd, q, rem) 137 if r <= 0 { go = 0 } 138 if r > 0 { got = got + r } 139 } 140 } 141 sys_close(fd) 142 szp[0] = sz 143 return got 144} 145 146// ---- INTEGRITY, RECOMPUTED --------------------------------------------------------------------- 147// v1 carried an `integrity` column and never checked it, so I shipped a row claiming "sha256" for a 148// layout whose writer computes DJB2 (nx_nxe.nx:22). I had inferred the kind from the magic instead of 149// reading the code. 150// * AN UNVERIFIED FIELD IN A REGISTRY IS AN ASSERTION WEARING THE COSTUME OF A MEASUREMENT. 151// These recompute the DECLARED kind over the artifact's own code section, so a mislabelled row fails. 152func nxc_djb2(m: *u8, off: i64, n: i64) -> i64 { 153 var h: i64 = NXC_DJB2_SEED 154 var i: i64 = 0 155 while i < n { h = ((h << NXC_DJB2_SHIFT) + h) + (m[off + i] as i64); i = i + 1 } 156 return h 157} 158// Wrapping sum of the payload's little-endian 64-bit words (the kernel image's declared scheme). 159func nxc_sum64(m: *u8, off: i64, n: i64) -> i64 { 160 var s: i64 = 0 161 var i: i64 = 0 162 while (i + NXC_WORD) <= n { s = s + nxc_r64(m, off + i); i = i + NXC_WORD } 163 return s 164} 165// 1 = the bytes stored at hoff ARE the declared hash of [toff, toff+tsz). 0 = they are not. 166func nxc_integ_ok(ab: *u8, asz: i64, toff: i64, tsz: i64, kind: i64, hoff: i64, hlen: i64) -> i64 { 167 if (toff + tsz) > asz { return 0 } 168 if (hoff + hlen) > asz { return 0 } 169 if kind == NXC_K_SHA256 { 170 if hlen != NXC_SHA256_BYTES { return 0 } 171 let want: *u8 = sys_mmap(NXC_SHA256_BYTES) 172 sha256_digest(((ab as i64) + toff) as *u8, tsz, want) 173 var i: i64 = 0 174 while i < NXC_SHA256_BYTES { if want[i] != ab[hoff + i] { return 0 } i = i + 1 } 175 return 1 176 } 177 var v: i64 = 0 178 if kind == NXC_K_DJB2 { v = nxc_djb2(ab, toff, tsz) } 179 if kind == NXC_K_SUM64 { v = nxc_sum64(ab, toff, tsz) } 180 if kind != NXC_K_DJB2 { if kind != NXC_K_SUM64 { return 0 } } 181 // the scalar kinds are stored as hlen little-endian bytes 182 var j: i64 = 0 183 while j < hlen { if ab[hoff + j] != (((v >> (j * 8)) & 255) as u8) { return 0 } j = j + 1 } 184 return 1 185} 186 187// Split one pipe row into field offsets/lengths. Returns the field count. 188func nxc_fields(buf: *u8, pos: i64, e: i64, fo: *i64, fl: *i64) -> i64 { 189 var fi: i64 = 0 190 fo[0] = pos 191 var i: i64 = pos 192 while i < e { 193 if buf[i] == (NXC_PIPE as u8) { 194 if fi < (NXC_FIELD_MAX - 1) { fl[fi] = i - fo[fi]; fi = fi + 1; fo[fi] = i + 1 } 195 } 196 i = i + 1 197 } 198 fl[fi] = e - fo[fi] 199 return fi + 1 200} 201 202// THE CLASSIFIER. A row matches only when ALL THREE agree: the magic, the header size the artifact 203// itself declares, and the partition (size == text_off + text_size). Two rows share the magic NXE1, so 204// magic alone cannot classify -- the artifact's own bytes disambiguate. Returns the match COUNT; a 205// count of 0 or >1 is a refusal at the call site, never silently coerced to a winner. 206// mav = bytes actually in the buffer (never read past them, or the gate faults instead of judging). 207// msz = the artifact's TRUE size on disk, which is what the partition tooth is about. 208func nxc_classify(m: *u8, mav: i64, msz: i64, nlay: i64, lmag: *i64, lhdr: *i64, loft: *i64, lofs: *i64, midx: *i64) -> i64 { 209 var hits: i64 = 0 210 if mav < NXC_MAGIC_BYTES { return 0 } 211 if msz < NXC_MAGIC_BYTES { return 0 } 212 let mg: i64 = nxc_m32(m, 0) 213 var i: i64 = 0 214 while i < nlay { 215 var ok: i64 = 1 216 if lmag[i] != mg { ok = 0 } 217 // Never read past the artifact: a short file fails the row, it does not fault the gate. 218 if ok == 1 { if (loft[i] + NXC_WORD) > msz { ok = 0 } } 219 if ok == 1 { if (lofs[i] + NXC_WORD) > msz { ok = 0 } } 220 if ok == 1 { if (loft[i] + NXC_WORD) > mav { ok = 0 } } 221 if ok == 1 { if (lofs[i] + NXC_WORD) > mav { ok = 0 } } 222 if ok == 1 { 223 let toff: i64 = nxc_r64(m, loft[i]) 224 let tsz: i64 = nxc_r64(m, lofs[i]) 225 if toff != lhdr[i] { ok = 0 } 226 if ok == 1 { if (toff + tsz) != msz { ok = 0 } } 227 } 228 if ok == 1 { hits = hits + 1; midx[0] = i } 229 i = i + 1 230 } 231 return hits 232} 233 234// Build dir + slash + name into dst; returns its length. 235func nxc_join(dst: *u8, dir: *u8, name: *u8) -> i64 { 236 var o: i64 = 0 237 var i: i64 = 0 238 while dir[i] != (0 as u8) { dst[o] = dir[i]; o = o + 1; i = i + 1 } 239 if o > 0 { if dst[o-1] != (NXC_SLASH as u8) { dst[o] = NXC_SLASH as u8; o = o + 1 } } 240 var j: i64 = 0 241 while name[j] != (0 as u8) { dst[o] = name[j]; o = o + 1; j = j + 1 } 242 dst[o] = 0 as u8 243 return o 244} 245 246func nxc_is_dot(n: *u8) -> i64 { 247 if n[0] != (46 as u8) { return 0 } 248 if n[1] == (0 as u8) { return 1 } 249 if n[1] == (46 as u8) { if n[2] == (0 as u8) { return 1 } } 250 return 0 251} 252 253func main(argc: i64, argv: *i64) -> i64 { 254 let ctr: *i64 = gv_ctr() 255 gv_head("NX-NXECONFORM -- every NXE artifact on disk classified against the DECLARED layouts (constitution A2)" as *u8) 256 257 var cpath: *u8 = NXC_CONF_DEFAULT 258 if argc >= 2 { let a1: i64 = argv[1]; cpath = a1 as *u8 } 259 260 // sys_read_file sizes its buffer from the file itself (lseek END) -- there is no read cap to guess. 261 let clenp: *i64 = sys_mmap(NXC_WORD) as *i64 262 let conf: *u8 = sys_read_file(cpath, clenp) 263 let cn: i64 = clenp[0] 264 if gv_need("nxe_layouts.conf readable" as *u8, (cn > 0) as i64, ctr) == 0 { 265 let rcS: i64 = gv_verdict("NXECONFORM" as *u8, ctr, "conf absent -- cannot look" as *u8) 266 sys_exit(rcS) 267 } 268 269 // Table capacity DERIVED from the conf's own line count: an exact upper bound, not a guess. 270 var nlines: i64 = 1 271 var q: i64 = 0 272 while q < cn { if conf[q] == (NXC_NL as u8) { nlines = nlines + 1 } q = q + 1 } 273 274 let lmag: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 275 let lhdr: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 276 let loft: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 277 let lofs: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 278 let lhoff: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 279 let lhlen: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 280 let lkind: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 281 let lweak: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 282 let lseen: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 283 let lido: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 284 let lidl: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 285 let rooto: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 286 let rootl: *i64 = sys_mmap(nlines * NXC_WORD) as *i64 287 let fo: *i64 = sys_mmap(NXC_FIELD_MAX * NXC_WORD) as *i64 288 let fl: *i64 = sys_mmap(NXC_FIELD_MAX * NXC_WORD) as *i64 289 let midx: *i64 = sys_mmap(NXC_WORD) as *i64 290 let sc: *u8 = sys_mmap(NXC_SCRATCH) 291 let sc2: *u8 = sys_mmap(NXC_SCRATCH) 292 293 var nlay: i64 = 0 294 var nroot: i64 = 0 295 var malformed: i64 = 0 296 var rat_lay: i64 = 0 - 1 297 var rat_weak: i64 = 0 - 1 298 var strongest_o: i64 = 0 299 var strongest_l: i64 = 0 300 301 // ---- pass 1: STRONGEST must be known before any layout can be graded against it ---------------- 302 var pos: i64 = 0 303 while pos < cn { 304 var e: i64 = pos 305 var scan: i64 = 1 306 while scan == 1 { 307 if e >= cn { scan = 0 } else { if conf[e] == (NXC_NL as u8) { scan = 0 } else { e = e + 1 } } 308 } 309 var skip: i64 = 0 310 if (e - pos) < 3 { skip = 1 } 311 if skip == 0 { if conf[pos] == (NXC_HASH as u8) { skip = 1 } } 312 if skip == 0 { 313 let nf: i64 = nxc_fields(conf, pos, e, fo, fl) 314 nxc_cp(conf, fo[0], fl[0], sc, NXC_SCRATCH) 315 if nxc_streq(sc, "STRONGEST" as *u8) == 1 { 316 if nf >= 2 { strongest_o = fo[1]; strongest_l = fl[1] } 317 } 318 } 319 pos = e + 1 320 } 321 322 // ---- pass 2: ROOT / LAYOUT / RATCHET ----------------------------------------------------------- 323 pos = 0 324 while pos < cn { 325 var e2: i64 = pos 326 var scan2: i64 = 1 327 while scan2 == 1 { 328 if e2 >= cn { scan2 = 0 } else { if conf[e2] == (NXC_NL as u8) { scan2 = 0 } else { e2 = e2 + 1 } } 329 } 330 var skip2: i64 = 0 331 if (e2 - pos) < 3 { skip2 = 1 } 332 if skip2 == 0 { if conf[pos] == (NXC_HASH as u8) { skip2 = 1 } } 333 if skip2 == 0 { 334 let nf: i64 = nxc_fields(conf, pos, e2, fo, fl) 335 nxc_cp(conf, fo[0], fl[0], sc, NXC_SCRATCH) 336 if nxc_streq(sc, "ROOT" as *u8) == 1 { 337 if nf >= 2 { rooto[nroot] = fo[1]; rootl[nroot] = fl[1]; nroot = nroot + 1 } 338 else { malformed = malformed + 1 } 339 } 340 if nxc_streq(sc, "LAYOUT" as *u8) == 1 { 341 if nf >= 10 { 342 if fl[2] == NXC_MAGIC_BYTES { 343 let h: i64 = nxc_num(conf, fo[3], fl[3]) 344 let a: i64 = nxc_num(conf, fo[4], fl[4]) 345 let b: i64 = nxc_num(conf, fo[5], fl[5]) 346 let ho: i64 = nxc_num(conf, fo[6], fl[6]) 347 let hl: i64 = nxc_num(conf, fo[7], fl[7]) 348 // resolve the integrity kind to something RECOMPUTABLE; unknown = malformed 349 nxc_cp(conf, fo[8], fl[8], sc2, NXC_SCRATCH) 350 var kd: i64 = 0 351 if nxc_streq(sc2, "sha256" as *u8) == 1 { kd = NXC_K_SHA256 } 352 if nxc_streq(sc2, "djb2" as *u8) == 1 { kd = NXC_K_DJB2 } 353 if nxc_streq(sc2, "sum64" as *u8) == 1 { kd = NXC_K_SUM64 } 354 if h < 0 { malformed = malformed + 1 } else { 355 if a < 0 { malformed = malformed + 1 } else { 356 if b < 0 { malformed = malformed + 1 } else { 357 if ho < 0 { malformed = malformed + 1 } else { 358 if hl < 0 { malformed = malformed + 1 } else { 359 if kd == 0 { malformed = malformed + 1 } else { 360 lmag[nlay] = nxc_m32(conf, fo[2]) 361 lhdr[nlay] = h 362 loft[nlay] = a 363 lofs[nlay] = b 364 lhoff[nlay] = ho 365 lhlen[nlay] = hl 366 lkind[nlay] = kd 367 lido[nlay] = fo[1] 368 lidl[nlay] = fl[1] 369 lseen[nlay] = 0 370 // weaker-than-constitutional integrity is the convergence worklist 371 nxc_cp(conf, strongest_o, strongest_l, sc, NXC_SCRATCH) 372 if nxc_streq(sc2, sc) == 1 { lweak[nlay] = 0 } else { lweak[nlay] = 1 } 373 nlay = nlay + 1 374 } } } } } } 375 } else { malformed = malformed + 1 } 376 } else { malformed = malformed + 1 } 377 } 378 if nxc_streq(sc, "RATCHET" as *u8) == 1 { 379 if nf >= 3 { 380 nxc_cp(conf, fo[1], fl[1], sc2, NXC_SCRATCH) 381 let v: i64 = nxc_num(conf, fo[2], fl[2]) 382 if v < 0 { malformed = malformed + 1 } 383 if v >= 0 { 384 if nxc_streq(sc2, "layouts" as *u8) == 1 { rat_lay = v } 385 if nxc_streq(sc2, "weak_integrity" as *u8) == 1 { rat_weak = v } 386 } 387 } else { malformed = malformed + 1 } 388 } 389 } 390 pos = e2 + 1 391 } 392 393 if gv_need("at least one LAYOUT declared" as *u8, (nlay > 0) as i64, ctr) == 0 { 394 let rcS2: i64 = gv_verdict("NXECONFORM" as *u8, ctr, "no layouts declared -- cannot look" as *u8) 395 sys_exit(rcS2) 396 } 397 if gv_need("at least one ROOT declared" as *u8, (nroot > 0) as i64, ctr) == 0 { 398 let rcS3: i64 = gv_verdict("NXECONFORM" as *u8, ctr, "no roots declared -- cannot look" as *u8) 399 sys_exit(rcS3) 400 } 401 402 // ---- the header window and the candidate rule, DERIVED from the declared rows ------------------ 403 var window: i64 = NXC_MAGIC_BYTES 404 var li0: i64 = 0 405 while li0 < nlay { 406 if (loft[li0] + NXC_WORD) > window { window = loft[li0] + NXC_WORD } 407 if (lofs[li0] + NXC_WORD) > window { window = lofs[li0] + NXC_WORD } 408 li0 = li0 + 1 409 } 410 // Every declared magic must share one format-family prefix; the 4th byte is the VERSION. 411 // A candidate is that prefix followed by a DIGIT -- so knowledge/status/nxe.log, whose first bytes 412 // are the ASCII letters NXE, is not mistaken for a binary. v1 tested the bare 3-byte prefix and 413 // reported three .log files as NXE artifacts. 414 // * A DETECTOR WITH FALSE POSITIVES IS WORSE THAN NONE -- IT TEACHES EVERYONE TO IGNORE IT. 415 // Requiring a digit still SEES an artifact carrying a version no row declares (that is the whole 416 // point of the undeclared bucket); it only stops prose from entering the population. 417 let pref_mask: i64 = (1 << ((NXC_MAGIC_BYTES - 1) * 8)) - 1 418 let pref3: i64 = lmag[0] & pref_mask 419 var pref_same: i64 = 1 420 li0 = 0 421 while li0 < nlay { if (lmag[li0] & pref_mask) != pref3 { pref_same = 0 } li0 = li0 + 1 } 422 gv_check("all declared magics share one format-family prefix" as *u8, pref_same, ctr) 423 let hbuf: *u8 = sys_mmap(window + NXC_WORD) 424 425 // ---- FULL RECURSIVE SWEEP of every declared root ----------------------------------------------- 426 let arena: *u8 = sys_mmap(NXC_PATH_ARENA_BYTES) 427 let stko: *i64 = sys_mmap(NXC_DIR_FRONTIER_MAX * NXC_WORD) as *i64 428 var apos: i64 = 0 429 var sp: i64 = 0 430 var frontier_overflow: i64 = 0 431 var arena_overflow: i64 = 0 432 433 var ri: i64 = 0 434 while ri < nroot { 435 let n: i64 = nxc_cp(conf, rooto[ri], rootl[ri], arena + apos, NXC_SCRATCH) 436 if sp < NXC_DIR_FRONTIER_MAX { stko[sp] = apos; sp = sp + 1 } else { frontier_overflow = 1 } 437 apos = apos + n + 1 438 ri = ri + 1 439 } 440 441 let dbuf: *u8 = sys_mmap(NXC_PATH_ARENA_BYTES) 442 let pbuf: *u8 = sys_mmap(NXC_SCRATCH * 8) 443 let alenp: *i64 = sys_mmap(NXC_WORD) as *i64 444 445 let bitepath: *u8 = sys_mmap(NXC_SCRATCH * 8) 446 let alenp2: *i64 = sys_mmap(NXC_WORD) as *i64 447 var files_seen: i64 = 0 448 var artifacts: i64 = 0 449 var unmatched: i64 = 0 450 var ambiguous: i64 = 0 451 var dirs_walked: i64 = 0 452 var integ_bad: i64 = 0 453 var integ_checked: i64 = 0 454 var bite_row: i64 = 0 - 1 455 456 while sp > 0 { 457 sp = sp - 1 458 let dpath: *u8 = arena + stko[sp] 459 let dfd: i64 = sys_openat_rd(dpath) 460 if dfd >= 0 { 461 dirs_walked = dirs_walked + 1 462 // ONE getdents64 CALL IS NOT A DIRECTORY LISTING -- loop until it returns 0. 463 var more: i64 = 1 464 while more == 1 { 465 let got: i64 = sys_getdents64(dfd, dbuf, NXC_PATH_ARENA_BYTES) 466 if got <= 0 { more = 0 } 467 if got > 0 { 468 var off: i64 = 0 469 while off < got { 470 let rec: *u8 = (dbuf as i64 + off) as *u8 471 let rl: i64 = dirent_reclen(rec) 472 let dt: i64 = dirent_type(rec) 473 let nm: *u8 = dirent_name(rec) 474 if nxc_is_dot(nm) == 0 { 475 let pl: i64 = nxc_join(pbuf, dpath, nm) 476 if dt == DT_DIR { 477 if (apos + pl + 1) < NXC_PATH_ARENA_BYTES { 478 var k: i64 = 0 479 while k <= pl { arena[apos + k] = pbuf[k]; k = k + 1 } 480 if sp < NXC_DIR_FRONTIER_MAX { stko[sp] = apos; sp = sp + 1 } 481 else { frontier_overflow = 1 } 482 apos = apos + pl + 1 483 } else { arena_overflow = 1 } 484 } 485 if dt == DT_REG { 486 files_seen = files_seen + 1 487 // ONE open, a bounded header read, size from lseek. The payload is 488 // never touched: nothing under test lives outside the header. 489 let agot: i64 = nxc_head(pbuf, hbuf, window, alenp) 490 let asz: i64 = alenp[0] 491 // Candidate by CONTENT (declared family prefix + version digit), never 492 // by file extension -- KERNEL.NXE and .nxe both qualify on their bytes. 493 var isnxe: i64 = 0 494 if agot >= NXC_MAGIC_BYTES { 495 if (nxc_m32(hbuf, 0) & pref_mask) == pref3 { 496 let v4: i64 = hbuf[NXC_MAGIC_BYTES - 1] as i64 497 if v4 >= NXC_DIGIT_LO { if v4 <= NXC_DIGIT_HI { isnxe = 1 } } 498 } 499 } 500 if isnxe == 1 { 501 artifacts = artifacts + 1 502 midx[0] = 0 - 1 503 let hits: i64 = nxc_classify(hbuf, agot, asz, nlay, lmag, lhdr, loft, lofs, midx) 504 gv_puts(" artifact " as *u8) 505 gv_puts(pbuf) 506 gv_puts(" bytes=" as *u8) 507 gv_num(asz) 508 if hits == 1 { 509 let r: i64 = midx[0] 510 lseen[r] = lseen[r] + 1 511 gv_puts(" layout=" as *u8) 512 nxc_cp(conf, lido[r], lidl[r], sc, NXC_SCRATCH) 513 gv_puts(sc) 514 // RECOMPUTE the declared integrity over the artifact's own code 515 // section. Only matched artifacts are read in full (3 of 77k), 516 // so the payload read stays off the hot path. 517 let full: *u8 = sys_read_file(pbuf, alenp2) 518 let fsz: i64 = alenp2[0] 519 var iok: i64 = 0 520 if fsz == asz { 521 iok = nxc_integ_ok(full, fsz, nxc_r64(full, loft[r]), nxc_r64(full, lofs[r]), lkind[r], lhoff[r], lhlen[r]) 522 } 523 integ_checked = integ_checked + 1 524 if iok == 1 { gv_puts(" integrity=VERIFIED" as *u8) } 525 if iok == 0 { integ_bad = integ_bad + 1; gv_puts(" integrity=MISMATCH-OR-MISLABELLED" as *u8) } 526 // remember one VERIFIED artifact as the bite subject 527 if bite_row < 0 { if iok == 1 { bite_row = r; nxc_cp(pbuf, 0, pl, bitepath, NXC_SCRATCH * 8) } } 528 } 529 if hits == 0 { unmatched = unmatched + 1; gv_puts(" layout=UNDECLARED" as *u8) } 530 if hits > 1 { ambiguous = ambiguous + 1; gv_puts(" layout=AMBIGUOUS" as *u8) } 531 gv_puts("\n" as *u8) 532 } 533 } 534 } 535 if rl <= 0 { off = got } else { off = off + rl } 536 } 537 } 538 } 539 sys_close(dfd) 540 } 541 } 542 543 // ---- REFUSE rather than publish a partial sweep as a total ------------------------------------- 544 gv_check("sweep complete: directory frontier never overflowed" as *u8, (frontier_overflow == 0) as i64, ctr) 545 gv_check("sweep complete: path arena never overflowed" as *u8, (arena_overflow == 0) as i64, ctr) 546 gv_check("conf has zero malformed rows" as *u8, (malformed == 0) as i64, ctr) 547 548 if gv_need("at least one NXE artifact found on disk" as *u8, (artifacts > 0) as i64, ctr) == 0 { 549 let rcS4: i64 = gv_verdict("NXECONFORM" as *u8, ctr, "no artifacts -- gate would be vacuous" as *u8) 550 sys_exit(rcS4) 551 } 552 553 gv_check("every artifact matches a DECLARED layout (0 undeclared)" as *u8, (unmatched == 0) as i64, ctr) 554 gv_check("no artifact matches two layouts (0 ambiguous)" as *u8, (ambiguous == 0) as i64, ctr) 555 // The row's integrity column is now a MEASUREMENT: recomputed over the artifact's own code section. 556 // This is the tooth that would have caught my own "sha256" mislabel on a djb2 layout. 557 gv_check("every artifact's DECLARED integrity kind RECOMPUTES to its stored hash" as *u8, (integ_bad == 0) as i64, ctr) 558 559 // BITE 4 -- tamper a real, VERIFIED artifact in memory: integrity must fail. A verifier that has 560 // only ever seen good bytes has not been shown to fire. 561 if bite_row >= 0 { 562 let bb: *u8 = sys_read_file(bitepath, alenp2) 563 let bsz: i64 = alenp2[0] 564 let bt: i64 = nxc_r64(bb, loft[bite_row]) 565 let bl: i64 = nxc_r64(bb, lofs[bite_row]) 566 let good_i: i64 = nxc_integ_ok(bb, bsz, bt, bl, lkind[bite_row], lhoff[bite_row], lhlen[bite_row]) 567 bb[bt] = (bb[bt] ^ (0xFF as u8)) 568 let bad_i: i64 = nxc_integ_ok(bb, bsz, bt, bl, lkind[bite_row], lhoff[bite_row], lhlen[bite_row]) 569 gv_bite("neg-control-tampered-payload: a flipped code byte FAILS the recomputed integrity" as *u8, 570 (bad_i == 0) as i64, (good_i == 0) as i64, ctr) 571 } 572 if bite_row < 0 { gv_need("one VERIFIED artifact to use as the tamper subject" as *u8, 0, ctr) } 573 574 // ---- the ratchets: these numbers may only FALL ------------------------------------------------- 575 var weak: i64 = 0 576 var li: i64 = 0 577 while li < nlay { if lweak[li] == 1 { weak = weak + 1 } li = li + 1 } 578 579 gv_check("RATCHET layouts declared in conf" as *u8, (rat_lay >= 0) as i64, ctr) 580 gv_check("RATCHET weak_integrity declared in conf" as *u8, (rat_weak >= 0) as i64, ctr) 581 gv_check("declared layouts <= ratchet (a fork may never widen)" as *u8, (nlay <= rat_lay) as i64, ctr) 582 gv_check("weak-integrity layouts <= ratchet (C01/C11 convergence)" as *u8, (weak <= rat_weak) as i64, ctr) 583 584 // ---- NON-VACUITY: the classifier must FIRE on bad bytes and stay SILENT on good ones ------------ 585 // Fixtures are assembled AT RUNTIME: a detector that scans for a pattern will otherwise find its own 586 // test fixture, and prose is source bytes too. 587 let fx: *u8 = sys_mmap(NXC_SCRATCH) 588 var fi2: i64 = 0 589 while fi2 < NXC_SCRATCH { fx[fi2] = 0 as u8; fi2 = fi2 + 1 } 590 // Build a GOOD artifact for layout row 0, from that row's OWN declared numbers -- never a literal. 591 let g_hdr: i64 = lhdr[0] 592 let g_off: i64 = loft[0] 593 let g_ofs: i64 = lofs[0] 594 let g_text: i64 = NXC_WORD // any non-zero payload; the sum is what is under test 595 let g_size: i64 = g_hdr + g_text 596 var bi: i64 = 0 597 while bi < NXC_MAGIC_BYTES { fx[bi] = ((lmag[0] >> (bi * 8)) & 255) as u8; bi = bi + 1 } 598 var wi: i64 = 0 599 while wi < NXC_WORD { fx[g_off + wi] = ((g_hdr >> (wi * 8)) & 255) as u8; wi = wi + 1 } 600 wi = 0 601 while wi < NXC_WORD { fx[g_ofs + wi] = ((g_text >> (wi * 8)) & 255) as u8; wi = wi + 1 } 602 603 midx[0] = 0 - 1 604 let good_hits: i64 = nxc_classify(fx, NXC_SCRATCH, g_size, nlay, lmag, lhdr, loft, lofs, midx) 605 // BITE 1 -- a magic no row declares must classify as UNDECLARED. 606 let saved0: u8 = fx[0] 607 fx[0] = 0x51 as u8 // Q: not an NXE magic under any declared row 608 midx[0] = 0 - 1 609 let bad_magic_hits: i64 = nxc_classify(fx, NXC_SCRATCH, g_size, nlay, lmag, lhdr, loft, lofs, midx) 610 fx[0] = saved0 611 gv_bite("neg-control-undeclared-magic: classifier refuses a magic no row declares" as *u8, 612 (bad_magic_hits == 0) as i64, (good_hits != 1) as i64, ctr) 613 614 // BITE 2 -- a TRUNCATED artifact must fail the partition, because size == text_off + text_size is 615 // the tooth that catches a short write and a layout mismatch with the same arithmetic. 616 midx[0] = 0 - 1 617 let trunc_hits: i64 = nxc_classify(fx, NXC_SCRATCH, g_size - 1, nlay, lmag, lhdr, loft, lofs, midx) 618 gv_bite("neg-control-truncated: partition size == text_off + text_size refuses a short artifact" as *u8, 619 (trunc_hits == 0) as i64, (good_hits != 1) as i64, ctr) 620 621 // BITE 3 -- a header claiming a size no row declares must not match. 622 var sv: i64 = 0 623 while sv < NXC_WORD { fx[g_off + sv] = (((g_hdr + 1) >> (sv * 8)) & 255) as u8; sv = sv + 1 } 624 midx[0] = 0 - 1 625 let skew_hits: i64 = nxc_classify(fx, NXC_SCRATCH, g_size, nlay, lmag, lhdr, loft, lofs, midx) 626 gv_bite("neg-control-header-skew: an undeclared header size is refused" as *u8, 627 (skew_hits == 0) as i64, (good_hits != 1) as i64, ctr) 628 629 // ---- the census, printed as a WORKLIST: a count without names is not actionable ---------------- 630 gv_puts(" layouts declared=" as *u8) 631 gv_num(nlay) 632 gv_puts(" ratchet=" as *u8) 633 gv_num(rat_lay) 634 gv_puts(" weak_integrity=" as *u8) 635 gv_num(weak) 636 gv_puts("/" as *u8) 637 gv_num(rat_weak) 638 gv_puts("\n" as *u8) 639 li = 0 640 while li < nlay { 641 gv_puts(" layout " as *u8) 642 nxc_cp(conf, lido[li], lidl[li], sc, NXC_SCRATCH) 643 gv_puts(sc) 644 gv_puts(" hdr=" as *u8) 645 gv_num(lhdr[li]) 646 gv_puts(" artifacts=" as *u8) 647 gv_num(lseen[li]) 648 if lweak[li] == 1 { gv_puts(" WEAK-INTEGRITY: converge onto the constitutional kind" as *u8) } 649 if lseen[li] == 0 { gv_puts(" NO ARTIFACT: retire this row or prove it is still emitted" as *u8) } 650 gv_puts("\n" as *u8) 651 li = li + 1 652 } 653 gv_puts(" swept dirs=" as *u8) 654 gv_num(dirs_walked) 655 gv_puts(" files=" as *u8) 656 gv_num(files_seen) 657 gv_puts(" nxe_artifacts=" as *u8) 658 gv_num(artifacts) 659 gv_puts(" undeclared=" as *u8) 660 gv_num(unmatched) 661 gv_puts(" ambiguous=" as *u8) 662 gv_num(ambiguous) 663 gv_puts(" integrity_checked=" as *u8) 664 gv_num(integ_checked) 665 gv_puts(" integrity_bad=" as *u8) 666 gv_num(integ_bad) 667 gv_puts("\n" as *u8) 668 669 let rc: i64 = gv_verdict("NXECONFORM" as *u8, ctr, "every NXE artifact classified; the fork is a shrinking ratchet, not a rediscovery" as *u8) 670 sys_exit(rc) 671 return 0 672}