code wiki / _hdl_build / nx_gate_bite.nx

nx_gate_bite.nx source

↩ module page · 1197 lines · 62091 B

1// nx_gate_bite.nx -- NON-VACUITY BY MUTATION. Answers the one question a green gate cannot answer about 2// itself: CAN THIS GATE EVER FAIL? Closes debt seq1344; the two-operator design closes seq1413. 3// 4// REWRITTEN (rule 3, not patched a fourth time). The first version accumulated four corrections in one 5// session -- an anchor-blind judge, a vacuity overclaim, uncounted invalid mutants, and a single operator. 6// Each was a real defect and the accumulation was the signal to rewrite rather than keep patching. 7// 8// THE METHOD (mutation testing, the 2026 field standard): perturb the SOURCE the gate is supposed to be 9// judging, rebuild, and require the gate to go RED. Killing ONE mutant proves the gate bites; we stop at 10// the first kill because the question is binary, not a score. 11// 12// ★★TWO OPERATORS, ESCALATED -- because ONE OPERATOR CANNOT REACH EVERY ASSERTION SURFACE. 13// phase 1 COMPARISON (`==` -> `!=`): reaches logic. Kills nx_raci_gate, nx_medbill_{nsa,codes,recon,civic}. 14// phase 2 LITERAL (flip a letter inside a copy string): reaches OUTPUT. MEASURED: nx_healthhelp_site_gate 15// asserts on rendered page TEXT (tone phrases, absence of "fight"/"arsenal"), so a comparison flip in a 16// path that does not change emitted copy is a survivor BY CONSTRUCTION -- not a hollow gate. A 17// single-operator harness makes every text-asserting gate permanently unprovable and would slander all 18// of them. The operator must be chosen by what the gate ASSERTS ON, so we try both before concluding. 19// 20// ★A MUTANT THAT DOES NOT COMPILE IS NOT A KILL. nx_sov_build_run RUNS the gate as its final step, so a 21// non-zero build exit means EITHER the gate went RED (real kill) OR the source failed to compile (proves 22// only that I broke the code). Counting the second as the first would let this organ certify non-vacuity it 23// never observed -- the `green>=1` overclaim rebuilt inside the tool built to catch it. 24// 25// ★NO KILL IS NOT PROOF OF VACUITY. Killing one mutant proves a gate CAN fail; failing to kill N proves 26// only that those N perturbations did not reach its assertions. INCONCLUSIVE is the honest word. 27// 28// ★THE JUDGE IS DIALECT-TOLERANT. Gates do not all speak one form: nx_medbill_nsa_gate ends 29// `ADV3 ...: GREEN` with NO `verdict=` anchor. Reading "anchor absent" as "not green" made an earlier build 30// of this organ report a 21/21 gate as broken -- an instrument reporting its own blindness as the subject's 31// defect. Prefer the verdict line; fall back to the exit code; always print which judge decided. 32// 33// FAIL-SAFE BY CONSTRUCTION (rule 26 spirit): pristine bytes held before the first mutation, the mutation 34// window is the narrowest possible (mutate -> build -> RESTORE -> only then judge), the restore is 35// byte-verified, and the organ REFUSES to exit 0 if it cannot prove the restore. 36// 37// usage: nx_gate_bite <gate_target> <source.nx> [max_sites] [aim <func> <skip> | aimlist <func>] (CWD = nxc2 root) 38// AIMED MODE (2026-08-03, debt 1785779063): mutation testing has THREE axes -- assertion strength, fixture 39// coverage, and SITE REACHABILITY. Position-picked sites in a large shared subject land in guards, early 40// helpers and sibling codecs the gate never executes, and A TOOTH CANNOT KILL A MUTANT THAT NEVER EXECUTES. 41// `aim <func> <skip>` mutates numeric sites inside the ONE function the expert names, skipping the first 42// <skip> (the leading guard block); `aimlist <func>` prints every numeric site with context, NO mutation and 43// NO build, so the skip is chosen by reading, never by guessing. A kill stays a kill: the mutant must 44// compile and the gate must go RED -- aiming changes which mutants are TRIED, never what counts as proof. 45// exit 0 = BITES 1 = INCONCLUSIVE 2 = UNCONTROLLED (not green at baseline) 3 = RESTORE FAILED 4 = AIM-ABSENT 5 = BASELINE-UNBUILDABLE (pristine source fails the build lane; every judgment would run the PROMOTED elf) 46// 4 = SUBJECT-UNREADABLE (the .gates 4th field names a file we cannot open -- a CONFIG fault). 47// Split out of 2 on 2026-08-01: sharing a code with UNCONTROLLED made every missing subject read 48// as a broken gate. AN EXIT CODE IS A DIAGNOSIS; two failures under one code is a misdiagnosis 49// waiting to be printed. 50// license_tier: ORIGINAL 51import "nx_syscalls.nx" 52import "nx_gate_green.nx" 53import "nx_sha256.nx" 54import "nx_artifact_root.nx" 55import "nx_guarded_run.nx" 56const GB_MAGIC_4096: i64 = 4096 57const GB_MAGIC_1024: i64 = 1024 58 59const GB_MAXSRC: i64 = 4194304 60const GB_DEF_SITES: i64 = 4 61 62// Shared run state as module statics, declared ABOVE every reader (a function defined textually before a 63// static it reads does not resolve to that datum). This also keeps the mutate/build/judge helper down to 64// two scalar arguments, avoiding the multi-pointer-arg call gotchas. 65static gb_orig: *u8 66static gb_work: *u8 67static gb_src: *u8 68static gb_target: *u8 69static gb_outp: *u8 70static gb_on: i64 71static gb_tried: i64 72static gb_invalid: i64 73static gb_void: i64 // build-lane faults (ASM-FAIL/ADMIT/CANON): no fresh artifact, judgment VOID -- neither valid nor invalid-mutant 74static gb_judge_kind: i64 75static gb_timedout: i64 76// A mutant that never TERMINATES has not SURVIVED -- it never emitted a verdict at all. Observed live 77// 2026-08-01: a comparison mutation in nx_media_extract.nx spun in state R for 11 minutes (the subject 78// has ZERO network calls, so this was an induced infinite loop, not an I/O block) and the old unbounded 79// sys_wait4 simply waited -- later sites were never scored, so the domain could never reach redseen>0. 80// Wired to nx_guarded_run, which ALREADY solved this (fork + wait4 WNOHANG + deadline + SIGKILL). 81const GB_MUTANT_DEADLINE_MS: i64 = 120000 82// Per-gate override rows: knowledge/bite_deadline.conf `<gate_target><TAB><deadline_ms>` -- the default 83// above is the induced-infinite-loop killer for seconds-class gates; a full-sweep bench (nx_vcodec_bgop_bench 84// ~40min qp10-40) legitimately outruns it, and under the flat cap its BASELINE read exit=124 -> UNCONTROLLED: 85// the instrument indicting a subject it never let finish (2026-08-03). Rule-11: the threshold is now data. 86static gb_deadline_ms: i64 87 88func w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 89func wn(v: i64) -> i64 { let t: *u8=sys_mmap(28); var m: i64=v; var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let b: *u8=sys_mmap(28); var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 90 91func gb_read(path: *u8, buf: *u8, cap: i64) -> i64 { 92 let fd: i64 = sys_openat_rd(path) 93 if fd < 0 { return 0 - 1 } 94 var tot: i64 = 0 95 var go: i64 = 1 96 while go == 1 { 97 let n: i64 = sys_read(fd, ((buf as i64)+tot) as *u8, cap - tot) 98 if n <= 0 { go = 0 } else { tot = tot + n; if tot >= cap { go = 0 } } 99 } 100 sys_close(fd) 101 return tot 102} 103func gb_write(path: *u8, buf: *u8, n: i64) -> i64 { 104 let fd: i64 = sys_openat_wr(path, 0x1a4) 105 if fd < 0 { return 0 - 1 } 106 sys_write(fd, buf, n) 107 sys_close(fd) 108 return n 109} 110 111// Load the per-gate run deadline: last matching `<gate><TAB><ms>` row of knowledge/bite_deadline.conf wins; 112// absent file/row -> GB_MUTANT_DEADLINE_MS. A conf value <= 0 is ignored (fail-safe: never a zero deadline). 113func gb_load_deadline(target: *u8) -> i64 { 114 gb_deadline_ms = GB_MUTANT_DEADLINE_MS 115 let b: *u8 = sys_mmap(GB_MAGIC_4096) 116 let n: i64 = gb_read("knowledge/bite_deadline.conf\x00" as *u8, b, GB_MAGIC_4096 - 1) 117 if n <= 0 { return 0 } 118 var tl: i64 = 0 119 while target[tl] != (0 as u8) { tl = tl + 1 } 120 var i: i64 = 0 121 while i < n { 122 var m: i64 = 1 123 var j: i64 = 0 124 while j < tl { 125 if i + j >= n { m = 0; j = tl } else { if b[i+j] != target[j] { m = 0; j = tl } else { j = j + 1 } } 126 } 127 if m == 1 { if i + tl < n { if b[i+tl] == (9 as u8) { 128 var v: i64 = 0 129 var k2: i64 = i + tl + 1 130 while k2 < n { 131 let c: i64 = b[k2] as i64 132 if c < 48 { k2 = n } else { if c > 57 { k2 = n } else { v = v*10 + (c - 48); k2 = k2 + 1 } } 133 } 134 if v > 0 { gb_deadline_ms = v } 135 } } } 136 while i < n { if b[i] == (10 as u8) { break } i = i + 1 } 137 i = i + 1 138 } 139 return 0 140} 141 142// Is offset p inside a `//` comment line? Mutating a comment yields a no-op mutant -- a guaranteed survivor 143// that would slander the gate. An operator that can emit no-op mutants measures the OPERATOR, not the gate. 144func gb_in_comment(b: *u8, p: i64) -> i64 { 145 var s: i64 = p 146 while s > 0 { if b[s-1] == (10 as u8) { break } s = s - 1 } 147 var i: i64 = s 148 while i < p { if b[i] != (32 as u8) { if b[i] != (9 as u8) { break } } i = i + 1 } 149 if i + 1 < p { if b[i] == (47 as u8) { if b[i+1] == (47 as u8) { return 1 } } } 150 // TRAILING comments too (2026-08-03, debt 1785779063): `var xe: i64 = 4 // cols 4,8` -- the 4,8 in 151 // the comment were eligible numeric sites, and a mutant in a comment is a survivor BY CONSTRUCTION 152 // that burns a full gate run and slanders the gate. Quote-parity keeps string content ("https://") out. 153 var q: i64 = 0 154 var j: i64 = s 155 while j < p { 156 if b[j] == (34 as u8) { var esc2: i64 = 0; if j > 0 { if b[j-1] == (92 as u8) { esc2 = 1 } } if esc2 == 0 { q = q + 1 } } 157 if b[j] == (47 as u8) { if j + 1 < p { if b[j+1] == (47 as u8) { if (q % 2) == 0 { return 1 } } } } 158 j = j + 1 159 } 160 return 0 161} 162 163// ---- OPERATOR 1: COMPARISON. Offset of the k-th mutable `==` OR `!=`, or -1. ---- 164// ★★★★★★OPERATOR REPERTOIRE IS A COVERAGE AXIS IN ITS OWN RIGHT. Until 2026-08-04 this matched ONLY `==` 165// and SKIPPED `!=` outright, so nx_probe_ctor -- whose single assertion is `if (o as i64) != 0` -- reported 166// ZERO comparison sites: operator 1 printed a header and nothing else, the run fell through to weaker 167// operators, and the verdict came back killed=0 INCONCLUSIVE. THAT IS INDISTINGUISHABLE FROM A VACUOUS 168// GATE AT A GLANCE and it was nothing of the kind: the one mutation that flips the assertion (`!=` -> `==`) 169// simply did not exist in the instrument's vocabulary. `if x != 0` is the estate's standard refusal shape, 170// so the blind spot was aimed squarely at the code we most want witnessed. Fix is symmetric and additive: 171// both directions are sites, gb_cmp_flip picks the byte, and a kill still demands COMPILES + gate goes RED. 172func gb_site_cmp(b: *u8, n: i64, k: i64) -> i64 { 173 var seen: i64 = 0 174 var i: i64 = 1 175 while i < n - 2 { 176 if b[i] == (33 as u8) { if b[i+1] == (61 as u8) { 177 var okn: i64 = 1 178 if b[i+2] == (61 as u8) { okn = 0 } 179 if b[i-1] == (61 as u8) { okn = 0 } 180 if okn == 1 { if gb_in_comment(b, i) == 1 { okn = 0 } } 181 if okn == 1 { if seen == k { return i } seen = seen + 1; i = i + 1 } 182 } } 183 if b[i] == (61 as u8) { if b[i+1] == (61 as u8) { 184 var ok: i64 = 1 185 if b[i-1] == (61 as u8) { ok = 0 } 186 if b[i-1] == (33 as u8) { ok = 0 } 187 if b[i-1] == (60 as u8) { ok = 0 } 188 if b[i-1] == (62 as u8) { ok = 0 } 189 if b[i+2] == (61 as u8) { ok = 0 } 190 if ok == 1 { if gb_in_comment(b, i) == 1 { ok = 0 } } 191 if ok == 1 { if seen == k { return i } seen = seen + 1; i = i + 1 } 192 } } 193 i = i + 1 194 } 195 return 0 - 1 196} 197 198// ---- OPERATOR 3: NUMERIC CONSTANT. The operator that reaches CONSTANT-TIME CODE. ---- 199// MEASURED 2026-08-01 on nx_x25519_kat_gate: operator 1 found ZERO `==` sites in a 21500 B subject and 200// the whole run returned valid_mutants=0 -- INCONCLUSIVE, so browser could not reach redseen>0 at all. 201// THE REASON IS STRUCTURAL, NOT A BUG IN THE SUBJECT: constant-time crypto is deliberately BRANCHLESS. 202// Data-dependent comparisons are exactly what such code is written to avoid, so a mutation operator that 203// only flips `==` is blind to the entire class -- and that class is the KAT gates, i.e. the ORACLE-eligible 204// evidence, the most independent we have. 205// ★★★★★★A MUTATION OPERATOR THAT ONLY TARGETS BRANCHES CANNOT SCORE BRANCHLESS CODE -- AND THE CODE MOST 206// WORTH PROVING IS OFTEN THE CODE WRITTEN NOT TO BRANCH. 207// Perturbing a numeric literal is the right probe here: a KAT compares against published vectors, so ANY 208// changed constant must falsify it. A gate that survives a changed constant is not checking arithmetic. 209// Bump the LAST digit of a decimal run (9 -> 8 so we never create a leading-zero or overflow shape), and 210// skip hex (0x..) so we do not corrupt the multi-limb field constants into uncompilable tokens. 211func gb_site_num(b: *u8, n: i64, k: i64) -> i64 { 212 var seen: i64 = 0 213 var i: i64 = 1 214 while i < n - 1 { 215 let c: i64 = b[i] as i64 216 if c >= 48 { if c <= 57 { 217 // last digit of the run only 218 let nx: i64 = b[i+1] as i64 219 var islast: i64 = 1 220 if nx >= 48 { if nx <= 57 { islast = 0 } } 221 if islast == 1 { 222 let pv: i64 = b[i-1] as i64 223 var ok: i64 = 1 224 // not an identifier tail (a1, x2), not hex, not a version-ish dotted token 225 if pv == 120 { ok = 0 } 226 if pv >= 97 { if pv <= 122 { ok = 0 } } 227 if pv >= 65 { if pv <= 90 { ok = 0 } } 228 if pv == 95 { ok = 0 } 229 if pv == 46 { ok = 0 } 230 if ok == 1 { if gb_in_comment(b, i) == 1 { ok = 0 } } 231 if ok == 1 { if seen == k { return i } seen = seen + 1 } 232 } 233 } } 234 i = i + 1 235 } 236 return 0 - 1 237} 238 239// ---- OPERATOR 2a: NEEDLE-GUIDED LITERAL. Aim at what the gate SAYS it checks. ---- 240// MEASURED cost of NOT aiming: nx_healthhelp_site_gate needed 27 valid mutants (27 full rebuilds) before a 241// linear scan happened to land on the phrase it asserts. Comparison kills, by contrast, land at site 0-1. 242// But the gate is not a black box -- its source NAMES its needles (`mbc_contains(page, "working with your 243// provider")`). Reading them and mutating those phrases FIRST turns a linear hunt into a direct hit. 244// ★This is the honest form of test-aware mutation: we are not weakening the test to make it pass, we are 245// using the test's own declared expectations to find the perturbation that would falsify it. If a needle 246// the gate names does not appear in the subject at all, that is itself informative -- the gate is asserting 247// on text this subject never produces. 248static gb_gsrc: *u8 249static gb_gn: i64 250 251func gb_find(hay: *u8, hn: i64, ned: *u8, nl: i64) -> i64 { 252 if nl <= 0 { return 0 - 1 } 253 var i: i64 = 0 254 while i + nl <= hn { 255 var j: i64 = 0 256 var m: i64 = 1 257 while j < nl { if hay[i+j] != ned[j] { m = 0; j = nl } else { j = j + 1 } } 258 if m == 1 { return i } 259 i = i + 1 260 } 261 return 0 - 1 262} 263 264// Load the gate's own source so we can read its needles. Two known homes for a gate organ. 265func gb_load_gate_src(target: *u8) -> i64 { 266 let cand: *u8 = sys_mmap(512) 267 let res: *u8 = sys_mmap(512) 268 var o: i64 = 0 269 let p1: *u8 = "runtime/" 270 var q: i64 = 0 271 while p1[q] != (0 as u8) { cand[o] = p1[q]; o = o + 1; q = q + 1 } 272 q = 0 273 while target[q] != (0 as u8) { cand[o] = target[q]; o = o + 1; q = q + 1 } 274 let sfx: *u8 = ".nx" 275 q = 0 276 while sfx[q] != (0 as u8) { cand[o] = sfx[q]; o = o + 1; q = q + 1 } 277 cand[o] = 0 as u8 278 gb_gsrc = sys_mmap(GB_MAXSRC) 279 if ar_resolve(cand, res) == 1 { gb_gn = gb_read(res, gb_gsrc, GB_MAXSRC); return gb_gn } 280 o = 0 281 let p2: *u8 = "runtime/_hdl_build/" 282 q = 0 283 while p2[q] != (0 as u8) { cand[o] = p2[q]; o = o + 1; q = q + 1 } 284 q = 0 285 while target[q] != (0 as u8) { cand[o] = target[q]; o = o + 1; q = q + 1 } 286 q = 0 287 while sfx[q] != (0 as u8) { cand[o] = sfx[q]; o = o + 1; q = q + 1 } 288 cand[o] = 0 as u8 289 if ar_resolve(cand, res) == 1 { gb_gn = gb_read(res, gb_gsrc, GB_MAXSRC); return gb_gn } 290 gb_gn = 0 291 return 0 292} 293 294// ★MISDIRECTED-GATE AUDIT. Count the gate's named needles that are NOT present in the declared subject. 295// This is a finding, not noise: a gate asserting on text the subject never produces means the .gates 4th 296// field points at the wrong file, and every mutation of that file is doomed to be INCONCLUSIVE. Without 297// this line the symptom (no kill) looks identical to a weak gate -- which is precisely the confusion that 298// cost this session two false accusations. Report the ratio; do not guess a better subject. 299func gb_ident_ch(c: i64) -> i64 { 300 if c >= 48 { if c <= 57 { return 1 } } 301 if c >= 65 { if c <= 90 { return 1 } } 302 if c >= 97 { if c <= 122 { return 1 } } 303 if c == 95 { return 1 } 304 return 0 305} 306 307// First mutable == OR != at or after `from`. Predicate MIRRORS gb_site_cmp; gb_site_cmp itself is UNTOUCHED. 308// ★OPERATOR REPERTOIRE IS A FOURTH COVERAGE AXIS (2026-08-04, found on nx_probe_ctor): this used to match 309// ONLY `==` and to EXPLICITLY SKIP `!=` (the b[i-1]=='!' guard below), so a subject whose only comparison 310// is `!=` reported ZERO comparison sites -- operator 1 printed nothing at all and the bite fell through to 311// weaker operators and returned killed=0. That reads exactly like a vacuous gate and is NOT one: the ONE 312// mutation that would have flipped the assertion was not in the instrument's vocabulary. Refusal-style 313// code (`if x != 0 { ok = 1 }`) is precisely where this bites, and that shape is everywhere in this estate. 314// Both directions are now sites; gb_cmp_flip decides which byte to write, so a kill still requires the 315// mutant to COMPILE and the gate to go RED -- the bar is unchanged, only the reachable mutant set grows. 316func gb_cmp_flip(b: *u8, off: i64) -> i64 { 317 if b[off] == (33 as u8) { return 61 } 318 return 33 319} 320func gb_cmp_at(b: *u8, n: i64, from: i64) -> i64 { 321 var i: i64 = from 322 if i < 1 { i = 1 } 323 while i < n - 2 { 324 if b[i] == (33 as u8) { if b[i+1] == (61 as u8) { 325 var okn: i64 = 1 326 if b[i+2] == (61 as u8) { okn = 0 } 327 if b[i-1] == (61 as u8) { okn = 0 } 328 if okn == 1 { if gb_in_comment(b, i) == 1 { okn = 0 } } 329 if okn == 1 { return i } 330 } } 331 if b[i] == (61 as u8) { if b[i+1] == (61 as u8) { 332 var ok: i64 = 1 333 if b[i-1] == (61 as u8) { ok = 0 } 334 if b[i-1] == (33 as u8) { ok = 0 } 335 if b[i-1] == (60 as u8) { ok = 0 } 336 if b[i-1] == (62 as u8) { ok = 0 } 337 if b[i+2] == (61 as u8) { ok = 0 } 338 if ok == 1 { if gb_in_comment(b, i) == 1 { ok = 0 } } 339 if ok == 1 { return i } 340 } } 341 i = i + 1 342 } 343 return 0 - 1 344} 345 346// k-th identifier in the GATE source immediately followed by ( -- i.e. a call the gate makes. 347// First mutable numeric constant at or after `from`. Predicate MIRRORS gb_site_num; that fn is UNTOUCHED. 348func gb_num_at(b: *u8, n: i64, from: i64) -> i64 { 349 var i: i64 = from 350 if i < 1 { i = 1 } 351 while i < n - 1 { 352 let c: i64 = b[i] as i64 353 if c >= 48 { if c <= 57 { 354 let nx: i64 = b[i+1] as i64 355 var islast: i64 = 1 356 if nx >= 48 { if nx <= 57 { islast = 0 } } 357 if islast == 1 { 358 let pv: i64 = b[i-1] as i64 359 var ok: i64 = 1 360 if pv == 120 { ok = 0 } 361 if pv >= 97 { if pv <= 122 { ok = 0 } } 362 if pv >= 65 { if pv <= 90 { ok = 0 } } 363 if pv == 95 { ok = 0 } 364 if pv == 46 { ok = 0 } 365 if ok == 1 { if gb_in_comment(b, i) == 1 { ok = 0 } } 366 if ok == 1 { return i } 367 } 368 } } 369 i = i + 1 370 } 371 return 0 - 1 372} 373 374// ---- AIMED-MODE SUPPORT (2026-08-03, debt 1785779063). Locate `func <name>(` in the SUBJECT and bound it 375// by the next top-level `\nfunc ` so aimed sites stay inside the ONE function the expert named. ---- 376static gb_aim_end: i64 377func gb_aim_find(name: *u8) -> i64 { 378 let apat: *u8 = sys_mmap(240) 379 var po: i64 = 0 380 let fw2: *u8 = "func " as *u8 381 var z2: i64 = 0 382 while z2 < 5 { apat[po] = fw2[z2]; po = po + 1; z2 = z2 + 1 } 383 z2 = 0 384 while name[z2] != (0 as u8) { if po < 230 { apat[po] = name[z2]; po = po + 1 } z2 = z2 + 1 } 385 apat[po] = 40 as u8 386 po = po + 1 387 let d: i64 = gb_find(gb_orig, gb_on, apat, po) 388 gb_aim_end = gb_on 389 if d < 0 { return 0 - 1 } 390 let nf: *u8 = "\nfunc " as *u8 391 var sc2: i64 = d + po 392 while sc2 < gb_on - 6 { 393 var mm: i64 = 1 394 var mj: i64 = 0 395 while mj < 6 { if gb_orig[sc2 + mj] != nf[mj] { mm = 0; mj = 6 } else { mj = mj + 1 } } 396 if mm == 1 { gb_aim_end = sc2; sc2 = gb_on } else { sc2 = sc2 + 1 } 397 } 398 return d 399} 400 401func gb_gate_call(k: i64, out: *u8, cap: i64) -> i64 { 402 var seen: i64 = 0 403 var i: i64 = 0 404 while i < gb_gn { 405 var start: i64 = 0 406 let c: i64 = gb_gsrc[i] as i64 407 if c >= 97 { if c <= 122 { start = 1 } } 408 if c == 95 { start = 1 } 409 var prev_id: i64 = 0 410 if i > 0 { if gb_ident_ch(gb_gsrc[i-1] as i64) == 1 { prev_id = 1 } } 411 var nxt: i64 = i + 1 412 if start == 1 { if prev_id == 0 { 413 var e: i64 = i 414 while e < gb_gn { if gb_ident_ch(gb_gsrc[e] as i64) == 0 { break } e = e + 1 } 415 if e > i { nxt = e } 416 if e < gb_gn { if gb_gsrc[e] == (40 as u8) { 417 let L: i64 = e - i 418 if L >= 4 { if L < cap - 1 { 419 if seen == k { 420 var q: i64 = 0 421 while q < L { out[q] = gb_gsrc[i+q]; q = q + 1 } 422 out[L] = 0 as u8 423 return L 424 } 425 seen = seen + 1 426 } } 427 } } 428 } } 429 i = nxt 430 } 431 return 0 - 1 432} 433 434func gb_needle_audit(b: *u8, n: i64) -> i64 { 435 if gb_gn <= 0 { return 0 } 436 let ned: *u8 = sys_mmap(GB_MAGIC_4096) 437 var found: i64 = 0 438 var missing: i64 = 0 439 var i: i64 = 0 440 while i < gb_gn - 1 { 441 if gb_gsrc[i] == (34 as u8) { 442 var j: i64 = i + 1 443 var spaces: i64 = 0 444 var ended: i64 = 0 445 while j < gb_gn { 446 let c: i64 = gb_gsrc[j] as i64 447 if c == 34 { ended = 1; break } 448 if c == 10 { break } 449 if c == 32 { spaces = spaces + 1 } 450 j = j + 1 451 } 452 var clen: i64 = j - i - 1 453 if clen >= 4 { if gb_gsrc[i+1+clen-4] == (92 as u8) { clen = clen - 4 } } 454 if ended == 1 { if clen >= 10 { if spaces >= 1 { 455 var c2: i64 = 0 456 while c2 < clen { ned[c2] = gb_gsrc[i+1+c2]; c2 = c2 + 1 } 457 if gb_find(b, n, ned, clen) >= 0 { found = found + 1 } else { missing = missing + 1 } 458 } } } 459 i = j + 1 460 } else { i = i + 1 } 461 } 462 // ⚠HONEST READING OF THIS RATIO: `absent` is INFLATED by design. This counts every prose literal in the 463 // gate, and most of a gate's literals are its own chk() LABELS ("TONE: partnership framing present"), 464 // which were never claims about the subject. So a high `absent` is expected and means nothing on its 465 // own. Only found==0 is a real signal, and that is the only case that warns. Separating true needles 466 // from labels needs call-site parsing (which literal is an argument to a contains-style assertion) -- 467 // a real rung, deliberately not faked here with a keyword guess. 468 w(" needle audit: present_in_subject="); wn(found); w(" not_found="); wn(missing) 469 w(" (not_found is inflated: gate labels are literals too -- only present=0 is a signal)") 470 // ⚠SUPPRESSED WHEN THE GATE IMPORTS THE SUBJECT. Measured 2026-08-01: this fired on 471 // nx_x25519_kat_gate, whose .gates subject is CORRECT (runtime/nx_x25519.nx exists and the gate 472 // imports it at line 14). Its assertion labels are EXTERNAL CITATIONS -- "T1 RFC 7748 5.2 test-1" -- 473 // which by construction never appear in an implementation file, so found==0 is expected for the whole 474 // KAT class. ★★★★★A HEURISTIC THAT ASSUMES A GATE QUOTES ITS SUBJECT MISFIRES ON EXACTLY THE GATES 475 // WHOSE LABELS CITE AN EXTERNAL AUTHORITY -- i.e. on the ORACLE-eligible evidence, the most 476 // independent we have. An import is hard proof the pairing is intentional, so it outranks the guess. 477 var imports_subject: i64 = 0 478 if gb_gn > 0 { 479 var sb: i64 = 0 480 var se: i64 = 0 481 var z: i64 = 0 482 while gb_src[z] != (0 as u8) { if gb_src[z] == (47 as u8) { sb = z + 1 } z = z + 1 } 483 se = z 484 if se - sb > 3 { if gb_find(gb_gsrc, gb_gn, ((gb_src as i64) + sb) as *u8, se - sb) >= 0 { imports_subject = 1 } } 485 } 486 if imports_subject == 1 { w(" (gate names this subject in its own source -- pairing confirmed, misdirection check suppressed)") } 487 if imports_subject == 0 { if found == 0 { if missing > 0 { w("\n <- MISDIRECTED-GATE: no named phrase of this gate appears in the declared subject; the .gates 4th field is likely the wrong file") } } } 488 w("\n") 489 return found 490} 491 492// The k-th needle-guided site: take the k-th prose literal from the GATE source, locate it in the SUBJECT, 493// and return a mutable word-start inside that occurrence. 494func gb_site_needle(b: *u8, n: i64, k: i64) -> i64 { 495 if gb_gn <= 0 { return 0 - 1 } 496 let ned: *u8 = sys_mmap(GB_MAGIC_4096) 497 var seen: i64 = 0 498 var i: i64 = 0 499 while i < gb_gn - 1 { 500 if gb_gsrc[i] == (34 as u8) { 501 var j: i64 = i + 1 502 var spaces: i64 = 0 503 var ended: i64 = 0 504 while j < gb_gn { 505 let c: i64 = gb_gsrc[j] as i64 506 if c == 34 { ended = 1; break } 507 if c == 10 { break } 508 if c == 32 { spaces = spaces + 1 } 509 j = j + 1 510 } 511 var clen: i64 = j - i - 1 512 // strip a trailing \x00 -- the gate writes needles NUL-terminated, the subject embeds the bare text 513 if clen >= 4 { if gb_gsrc[i+1+clen-4] == (92 as u8) { clen = clen - 4 } } 514 if ended == 1 { if clen >= 10 { if spaces >= 1 { 515 var c2: i64 = 0 516 while c2 < clen { ned[c2] = gb_gsrc[i+1+c2]; c2 = c2 + 1 } 517 let at: i64 = gb_find(b, n, ned, clen) 518 if at >= 0 { 519 var w: i64 = at + 1 520 let lim: i64 = at + clen 521 while w < lim { 522 let cc: i64 = b[w] as i64 523 if b[w-1] == (32 as u8) { 524 var isal: i64 = 0 525 if cc >= 97 { if cc <= 121 { isal = 1 } } 526 if cc >= 65 { if cc <= 89 { isal = 1 } } 527 if isal == 1 { 528 if seen == k { return w } 529 seen = seen + 1 530 w = lim 531 } 532 } 533 w = w + 1 534 } 535 } 536 } } } 537 i = j + 1 538 } else { i = i + 1 } 539 } 540 return 0 - 1 541} 542 543// ---- OPERATOR 2: LITERAL. Offset of a mutable letter inside the k-th eligible string literal, or -1. ---- 544// ★THE SELECTION RULE IS "FIRST LETTER OF AN INTERIOR WORD" -- a position preceded by a SPACE and followed 545// by a letter. That is prose BY CONSTRUCTION, so it can never land inside an escape sequence, and it needs 546// no blacklist to stay safe. 547// The first cut blacklisted backslash, '/' and '.' to avoid mutating paths, and consequently selected 548// NOTHING: every literal in this codebase ends `\x00`, and prose is full of '.' and '/' ("CPT/HCPCS/ICD-10"). 549// MEASURED: it reported `valid_mutants=0` on nx_healthhelp_site.nx while the very phrase the gate asserts on 550// -- "working with your provider" -- sat in that file. ★A FILTER THAT EXCLUDES ITS OWN TARGET CLASS reports 551// "nothing to test" and reads exactly like "nothing to find"; requiring a SPACE separates prose from paths 552// far better than banning the characters prose is made of. 553// ★ENUMERATE WORD-STARTS GLOBALLY, NOT ONE PER LITERAL. The first version offered a single position per 554// string literal, which is far too coarse here: this codebase emits page copy as HUGE HTML blobs (one 555// literal on nx_healthhelp_site.nx:53 is ~1000 chars). Mutating one word in a 1000-char blob almost never 556// touches the specific phrase a gate asserts on, so 17 mutants across 17 literals all survived while the 557// asserted phrase sat untouched inside one of them. Site k is now the k-th mutable word-start ANYWHERE 558// inside any string literal, which actually covers the copy. 559func gb_site_lit(b: *u8, n: i64, k: i64) -> i64 { 560 var seen: i64 = 0 561 var inlit: i64 = 0 562 var i: i64 = 0 563 while i < n - 1 { 564 let c: i64 = b[i] as i64 565 if c == 34 { 566 var esc: i64 = 0 567 if i > 0 { if b[i-1] == (92 as u8) { esc = 1 } } 568 if esc == 0 { if inlit == 1 { inlit = 0 } else { if gb_in_comment(b, i) == 0 { inlit = 1 } } } 569 i = i + 1 570 } else { 571 if inlit == 1 { if c == 10 { inlit = 0 } else { 572 if b[i-1] == (32 as u8) { 573 var isal: i64 = 0 574 if c >= 97 { if c <= 121 { isal = 1 } } 575 if c >= 65 { if c <= 89 { isal = 1 } } 576 if isal == 1 { 577 let d: i64 = b[i+1] as i64 578 var nxal: i64 = 0 579 if d >= 97 { if d <= 122 { nxal = 1 } } 580 if d >= 65 { if d <= 90 { nxal = 1 } } 581 if nxal == 1 { 582 if seen == k { return i } 583 seen = seen + 1 584 } 585 } 586 } 587 } } 588 i = i + 1 589 } 590 } 591 return 0 - 1 592} 593 594// Rebuild the gate, capturing all output. Returns the builder's exit code. 595func gb_build() -> i64 { 596 let pid: i64 = sys_fork() 597 if pid == 0 { 598 let ofd: i64 = sys_openat_wr(gb_outp, 0x1a4) 599 if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) } 600 // ★THE BUILDER PATH MUST BE RESOLVED TOO -- THIRD INSTANCE OF THIS CLASS (2026-07-30). 601 // Hardcoded, this reads ./_offc/nx_sov_build_run.elf; on the NAS the builder lives at 602 // buildroot/_offc/. So execve failed, gb_build returned 127, the BASELINE was never green, and 603 // EVERY gate on the NAS reported UNCONTROLLED -> redseen=0 for every domain -> clause 4 604 // (non-vacuity) of the evidence law was STRUCTURALLY UNREACHABLE on the machine that serves the 605 // claims. The whole mechanistic half of the honesty board was pinned at zero by one literal. 606 // ⚠I have now shipped this exact defect three times (pg_run in nx_plane_repair_gate was the 607 // second) INSIDE the tooling built to kill it. A hardcoded artifact path is not a small sin here: 608 // it fails as 127, which every caller reads as "the subject is broken" rather than "I could not 609 // find my own tool" -- an instrument reporting its own blindness as the subject's defect. 610 let elfres: *u8 = sys_mmap(GB_MAGIC_1024) 611 var elf: *u8 = "_offc/nx_sov_build_run.elf\x00" as *u8 612 if ar_resolve(elf, elfres) == 1 { elf = elfres } 613 // ★AND ITS WORKING DIRECTORY -- the layer under the path. nx_sov_build_run probes runtime/ and 614 // runtime/_hdl_build/ RELATIVE TO CWD. Forked from the serving root it finds no sources and exits 2 615 // (SOURCE-NOT-FOUND), which the baseline reads as "gate not green" -- the SAME misattribution one 616 // layer on, and it kept every NAS gate UNCONTROLLED even after the path was resolved. /api/build 617 // works only because hostctl happens to run the builder from buildroot/. 618 // Derive the root from WHERE THE BUILDER WAS ACTUALLY FOUND (the prefix before "_offc/") rather than 619 // naming buildroot/ here -- naming it would be a second hardcoded path curing the first. On the 620 // laptop ar_resolve yields a bare "_offc/..." so the prefix is empty and nothing changes. 621 let broot: *u8 = sys_mmap(GB_MAGIC_1024) 622 var q: i64 = 0 623 var cut: i64 = 0 - 1 624 while elf[q] != (0 as u8) { 625 if elf[q] == (95 as u8) { if elf[q+1] == (111 as u8) { if elf[q+2] == (102 as u8) { if elf[q+3] == (102 as u8) { if elf[q+4] == (99 as u8) { cut = q } } } } } 626 q = q + 1 627 } 628 if cut > 0 { var bn: i64 = 0; while bn < cut - 1 { broot[bn] = elf[bn]; bn = bn + 1 } broot[bn] = 0 as u8; sys_chdir(broot) } 629 // invoke by the name that is valid in the NEW cwd (the resolved path was relative to the old one) 630 let rel: *u8 = "_offc/nx_sov_build_run.elf\x00" as *u8 631 // ★★BUILD ONLY -- DO NOT LET THE BUILDER RUN THE GATE. nx_sov_build_run compiles AND runs as its 632 // last step, which forces ONE cwd on TWO steps that need different ones: compiling needs the build 633 // root (it probes runtime/ relative to cwd), the gate needs the SERVING root (it reads fixtures like 634 // nishi_raci.tsv relative to cwd). PROVEN with one binary and two directories: nx_raci_gate.elf is 635 // 5/5 GREEN from ~/nishihost and 4/5 RED from ~/nishihost/buildroot. Bundled, every NAS gate read 636 // UNCONTROLLED and redseen stayed 0 for every domain. 637 // ★This also makes COMPILE-FAIL vs GATE-RED STRUCTURAL rather than a string match on mixed output: 638 // the build's exit and the gate's exit are now two separate observations of two separate things. 639 let argv: *i64 = sys_mmap(32) as *i64 640 argv[0] = rel as i64 641 argv[1] = gb_target as i64 642 argv[2] = "--build-only\x00" as *u8 as i64 643 argv[3] = 0 644 let envp: *i64 = sys_mmap(16) as *i64 645 envp[0] = 0 646 sys_execve(rel, argv, envp) 647 sys_exit(127) 648 } 649 let stp: *i64 = sys_mmap(16) as *i64 650 sys_wait4(pid, stp, 0) 651 let sig: i64 = stp[0] & 0x7f 652 if sig != 0 { return 128 + sig } 653 return (stp[0] >> 8) & 0xff 654} 655 656func gb_out_has(needle: *u8) -> i64 { 657 let buf: *u8 = sys_mmap(1 << 20) 658 let n: i64 = gb_read(gb_outp, buf, (1 << 20) - 1) 659 if n <= 0 { return 0 } 660 if gg_last(buf, n, needle) >= 0 { return 1 } 661 return 0 662} 663 664// ★RUN THE GATE OURSELVES, FROM THE CWD WE WERE STARTED IN -- the other half of the build/run split. 665// The parent never chdirs (only the build CHILD does), so this fork inherits the serving root and the gate 666// finds its fixtures. Output OVERWRITES gb_outp on purpose: the COMPILE-FAIL check has already consumed the 667// build output by the time this runs, so the judge below reads gate output and nothing else. 668func gb_rungate() -> i64 { 669 let gpath: *u8 = sys_mmap(GB_MAGIC_1024) 670 var gn: i64 = 0 671 while gb_target[gn] != (0 as u8) { gpath[gn] = gb_target[gn]; gn = gn + 1 } 672 let sfx: *u8 = ".elf\x00" as *u8 673 var sj: i64 = 0 674 while sfx[sj] != (0 as u8) { gpath[gn] = sfx[sj]; gn = gn + 1; sj = sj + 1 } 675 gpath[gn] = 0 as u8 676 // ⚠★RUN THE FRESHLY BUILT ARTIFACT, NOT THE PROMOTED ONE. Splitting build from run introduced this: 677 // --build-only leaves the new binary at <buildroot>/_build/<target>.sov.elf, while <target>.elf at the 678 // serving root is the PROMOTED binary, compiled from UNMUTATED source. Resolving the promoted name made 679 // every mutant survive BY CONSTRUCTION and reported INCONCLUSIVE -- a false negative that would have 680 // silently understated coverage forever, and exactly the class this organ exists to catch. Caught by 681 // asking why a gate known to be killable produced no kill in 12 sites. 682 let bpath: *u8 = sys_mmap(GB_MAGIC_1024) 683 var bn2: i64 = 0 684 let bpre: *u8 = "_build/\x00" as *u8 685 var bk: i64 = 0 686 while bpre[bk] != (0 as u8) { bpath[bn2] = bpre[bk]; bn2 = bn2 + 1; bk = bk + 1 } 687 bk = 0 688 while gb_target[bk] != (0 as u8) { bpath[bn2] = gb_target[bk]; bn2 = bn2 + 1; bk = bk + 1 } 689 let bsfx: *u8 = ".sov.elf\x00" as *u8 690 bk = 0 691 while bsfx[bk] != (0 as u8) { bpath[bn2] = bsfx[bk]; bn2 = bn2 + 1; bk = bk + 1 } 692 bpath[bn2] = 0 as u8 693 let gres: *u8 = sys_mmap(GB_MAGIC_1024) 694 var gelf: *u8 = gpath 695 if ar_resolve(bpath, gres) == 1 { gelf = gres } else { if ar_resolve(gpath, gres) == 1 { gelf = gres } } 696 w(" running: "); w(gelf); w("\n") 697 let ofd: i64 = sys_openat_wr(gb_outp, 0x1a4) 698 let av: *i64 = sys_mmap(32) as *i64 699 av[0] = gelf as i64 700 av[1] = 0 701 let ev: *i64 = sys_mmap(16) as *i64 702 ev[0] = 0 703 var gdl: i64 = gb_deadline_ms 704 if gdl <= 0 { gdl = GB_MUTANT_DEADLINE_MS } 705 let rc: i64 = nx_guarded_run(gelf, av, ev, gdl, ofd, ofd) 706 if ofd >= 0 { sys_close(ofd) } 707 if rc == NX_GR_TIMEOUT { gb_timedout = 1 } 708 return rc 709} 710 711// Dialect-tolerant verdict: the `verdict=` line if present, else the exit code. 712func gb_green(rc: i64) -> i64 { 713 let buf: *u8 = sys_mmap(1 << 20) 714 let n: i64 = gb_read(gb_outp, buf, (1 << 20) - 1) 715 gb_judge_kind = 0 716 if n <= 0 { if rc == 0 { return 1 } return 0 } 717 if gg_last(buf, n, "verdict=" as *u8) >= 0 { 718 gb_judge_kind = 1 719 return gg_line_green(buf, n, "verdict=" as *u8, "GREEN" as *u8) 720 } 721 if rc == 0 { return 1 } 722 return 0 723} 724 725// Mutate one byte, rebuild, restore, judge. Returns 1 if this mutant was KILLED. 726func gb_try(off: i64, newbyte: i64) -> i64 { 727 var c: i64 = 0 728 while c < gb_on { gb_work[c] = gb_orig[c]; c = c + 1 } 729 gb_work[off] = newbyte as u8 730 gb_write(gb_src, gb_work, gb_on) 731 let rc: i64 = gb_build() 732 gb_write(gb_src, gb_orig, gb_on) // mutation window closes before we even look at the result 733 w(" @off="); wn(off); w(" build_exit="); wn(rc) 734 if gb_out_has("COMPILE-FAIL" as *u8) == 1 { 735 gb_invalid = gb_invalid + 1 736 w(" -> INVALID MUTANT (did not compile; excluded, NOT a kill)\n") 737 return 0 738 } 739 // ★★CLASSIFY BY EXIT CODE, NOT ONLY THE STRING. Caught live on nx_project 2026-08-04: the builder 740 // exits 4 = SBR_ASM_FAIL (also 6 = ADMIT-REFUSED, 7 = CANON-REFUSED), none of which print COMPILE-FAIL, 741 // so every such build fell through here as "compiled" -- and gb_rungate then judged the PROMOTED elf, 742 // compiled from UNMUTATED source. 19 mutants across two runs all read SURVIVED against a binary the 743 // mutation never entered. The string check above must STAY (the builder is known to exit 0 on some 744 // compile-fails), but a NONZERO exit means NO FRESH ARTIFACT EXISTS and the judgment is VOID -- a 745 // third category, distinct from both a killed and an uncompilable mutant. 746 if rc != 0 { 747 gb_void = gb_void + 1 748 w(" -> VOID (build lane exit="); wn(rc); w(": 3=compile 4=asm 6=admit 7=canon -- no fresh artifact; judging would run the PROMOTED elf; excluded, NOT a survivor)\n") 749 return 0 750 } 751 gb_tried = gb_tried + 1 752 // it compiled -- now RUN the gate from the serving root and judge THAT, not the builder's exit 753 gb_timedout = 0 754 let grc: i64 = gb_rungate() 755 if gb_timedout == 1 { 756 w(" -> KILLED-BY-TIMEOUT (mutant never terminated; it emitted no verdict, so it did NOT survive)\n") 757 return 1 758 } 759 if gb_green(grc) == 1 { w(" -> SURVIVED (gate still GREEN)\n"); return 0 } 760 w(" -> KILLED (gate went RED on a mutant that COMPILED)\n") 761 return 1 762} 763 764func main(argc: i64, argv: *i64) -> i64 { 765 if argc < 3 { w("usage: nx_gate_bite <gate_target> <source.nx> [max_sites] [aim <func> <skip> | aimlist <func>]\n"); sys_exit(2); return 2 } 766 gb_target = argv[1] as *u8 767 gb_src = argv[2] as *u8 768 gb_load_deadline(gb_target) 769 // ★RESOLVE THE SUBJECT THROUGH THE SHARED ROOTS TABLE (seq1398 adoption residual, closed 2026-07-30). 770 // The GATE source has gone through ar_resolve since round 8, but the SUBJECT was still opened exactly as 771 // written -- so on the NAS, where promote installs binaries FLAT at the serving root and sources live 772 // under buildroot/, a .gates 4th field of `runtime/_hdl_build/nx_raci.nx` read ABSENT and every domain 773 // scored redseen=0. Non-vacuity was structurally unreachable ON THE MACHINE THAT SERVES THE CLAIMS, 774 // which is the D3 off-host defect one layer down. 775 // ⚠Resolve ONCE and repoint gb_src, because this path is also used to MUTATE (368), RESTORE (370) and 776 // BYTE-VERIFY (468). Resolving only the read would read one file and write another -- which would defeat 777 // the restore guarantee, the one invariant that keeps this organ from damaging the corpus. 778 // ar_resolve leaves out == input and returns 0 when it cannot resolve (its T5 neg-control), so an 779 // unresolvable subject still falls through to the honest ABSENT message below, naming what was asked for. 780 let gb_sres: *u8 = sys_mmap(GB_MAGIC_1024) 781 if ar_resolve(gb_src, gb_sres) == 1 { gb_src = gb_sres } 782 gb_outp = "knowledge/status/bite_run.out\x00" as *u8 783 var maxs: i64 = GB_DEF_SITES 784 if argc > 3 { 785 maxs = 0 786 var badnum: i64 = 0 787 let a: *u8 = argv[3] as *u8 788 var i: i64 = 0 789 while a[i] != (0 as u8) { 790 let dv: i64 = (a[i] as i64) - 48 791 if dv < 0 { badnum = 1 } else { if dv > 9 { badnum = 1 } else { maxs = maxs*10 + dv } } 792 i = i + 1 793 } 794 // A NON-NUMERIC 3rd arg must REFUSE, not parse as garbage: `aim` misplaced here would decode to 795 // maxs=5579 and launch a five-thousand-site sweep. AN APPLIER INVOKED WRONG = ONE THAT DOESN'T EXIST. 796 if badnum == 1 { 797 w("usage: nx_gate_bite <gate_target> <source.nx> [max_sites] [aim <func> <skip> | aimlist <func>]\n") 798 sys_exit(2); return 2 799 } 800 if maxs <= 0 { maxs = GB_DEF_SITES } 801 } 802 var aimmode: i64 = 0 803 var aimskip: i64 = 0 804 var aimf: *u8 = "-" as *u8 805 if argc > 4 { 806 let am: *u8 = argv[4] as *u8 807 if am[0] == (97 as u8) { if am[1] == (105 as u8) { if am[2] == (109 as u8) { 808 if am[3] == (0 as u8) { if argc > 6 { 809 aimmode = 1 810 aimf = argv[5] as *u8 811 let sk: *u8 = argv[6] as *u8 812 var si2: i64 = 0 813 while sk[si2] != (0 as u8) { aimskip = aimskip*10 + ((sk[si2] as i64) - 48); si2 = si2 + 1 } 814 if aimskip < 0 { aimskip = 0 } 815 } } 816 if am[3] == (108 as u8) { if argc > 5 { 817 aimmode = 2 818 aimf = argv[5] as *u8 819 } } 820 } } } 821 } 822 823 w("=== nx_gate_bite -- can this gate ever fail? (2 operators, first-kill-wins) ===\n") 824 w(" gate="); w(gb_target); w(" subject="); w(gb_src); w(" max_sites_per_operator="); wn(maxs); w("\n") 825 w(" deadline_ms="); wn(gb_deadline_ms); w("\n") 826 827 gb_orig = sys_mmap(GB_MAXSRC) 828 gb_on = gb_read(gb_src, gb_orig, GB_MAXSRC) 829 // ★EXIT 4, NOT 2. Exit 2 means UNCONTROLLED = "the gate is not green at its own baseline", i.e. an 830 // accusation against the GATE. A subject we cannot READ is an accusation against the .gates ROW, and 831 // the two demand opposite work: fix the gate vs fix one config field. Sharing a code made the sweep 832 // render a missing file as "UNCONTROLLED (gate not green at baseline)", which is how librarian's 833 // nx_orchestrate_gate -- a gate that is 13/13 GREEN -- got reported as broken for an entire evening 834 // while the real fault was a .gates 4th field naming runtime/nx_orchestrate.nx, a file that does not 835 // exist. ★★★★★★AN INSTRUMENT THAT CANNOT REACH ITS SUBJECT MUST SAY SO, NOT INDICT THE SUBJECT -- 836 // and an EXIT CODE IS A DIAGNOSIS: two failures sharing one code guarantee a misdiagnosis downstream. 837 if gb_on <= 0 { 838 w(" ABSENT: cannot read the subject source (check the .gates 4th field -- this is a CONFIG fault, not a gate fault)\n") 839 sys_exit(4); return 4 840 } 841 // AIMLIST: enumerate the numeric sites of ONE function with context and exit. NO mutation, NO build, 842 // NO baseline -- this is the READING step that makes an aimed bite a measurement instead of a guess 843 // (a wrong by-eye site count costs a full 40-minute gate round; this costs milliseconds). 844 if aimmode == 2 { 845 let ad: i64 = gb_aim_find(aimf) 846 if ad < 0 { 847 w(" AIM-ABSENT: no `func "); w(aimf); w("(` in the subject -- check the function name (an AIM fault, not a gate fault)\n") 848 sys_exit(4); return 4 849 } 850 w(" aimlist: func "); w(aimf); w(" @off="); wn(ad); w(" end="); wn(gb_aim_end); w(" (numeric sites; NO mutation, NO build)\n") 851 var from2: i64 = ad 852 var idx: i64 = 0 853 var listing: i64 = 1 854 while listing == 1 { 855 let aoff: i64 = gb_num_at(gb_orig, gb_on, from2) 856 var stop1: i64 = 0 857 if aoff < 0 { stop1 = 1 } 858 if stop1 == 0 { if aoff >= gb_aim_end { stop1 = 1 } } 859 if stop1 == 1 { listing = 0 } else { 860 from2 = aoff + 1 861 let ctx: *u8 = sys_mmap(64) 862 var ci: i64 = 0 863 var cs: i64 = aoff - 10 864 if cs < 0 { cs = 0 } 865 while cs < aoff + 10 { 866 if cs < gb_on { 867 var cc2: i64 = gb_orig[cs] as i64 868 if cc2 == 10 { cc2 = 32 } 869 if cc2 == 9 { cc2 = 32 } 870 ctx[ci] = cc2 as u8 871 ci = ci + 1 872 } 873 cs = cs + 1 874 } 875 ctx[ci] = 0 as u8 876 w(" site "); wn(idx); w(" @off="); wn(aoff); w(" |"); w(ctx); w("|\n") 877 idx = idx + 1 878 } 879 } 880 w(" total_numeric_sites="); wn(idx); w("\n") 881 sys_exit(0) 882 return 0 883 } 884 gb_work = sys_mmap(GB_MAXSRC) 885 gb_tried = 0 886 gb_invalid = 0 887 gb_void = 0 888 889 // Baseline: the gate must be GREEN before we break anything, or no observation is attributable. 890 let brc: i64 = gb_build() 891 // build and run are now SEPARATE observations: a non-zero build exit means the code did not compile, 892 // a non-green gate means the gate failed. Reporting both stops the baseline blaming the gate for a 893 // build problem -- the misattribution that kept every NAS gate reading UNCONTROLLED. 894 let grc: i64 = gb_rungate() 895 let base: i64 = gb_green(grc) 896 w(" baseline: build_exit="); wn(brc); w(" gate_exit="); wn(grc); w(" green="); wn(base) 897 if gb_judge_kind == 1 { w(" judge=verdict-line\n") } else { w(" judge=exit-code (gate emits no verdict= anchor)\n") } 898 // ★★A GREEN BASELINE OVER A FAILED BUILD IS NOT A BASELINE. If the PRISTINE source does not build 899 // (any nonzero exit), the green just observed came from the PROMOTED elf -- so every mutant would be 900 // judged against a binary the mutation cannot enter, and killed=0 is guaranteed BY CONSTRUCTION. 901 // nx_project read exactly this way twice before the hole was found: baseline build_exit=4 (ASM-FAIL) 902 // printed in plain sight, and nothing refused. A bite whose subject cannot build must say SO, loudly, 903 // as its verdict -- that the live tool is NOT REPRODUCIBLE FROM SOURCE is itself a sev-worthy finding. 904 if brc != 0 { 905 w(" BASELINE-UNBUILDABLE: pristine source failed the build lane (exit="); wn(brc) 906 w(", 3=compile 4=asm 6=admit 7=canon) -- the green above is the PROMOTED elf, not this source.\n") 907 w(" Every mutant judgment would be VOID. Fix the build (or the lane) first; this is a real finding, not noise.\n") 908 w("VERDICT: verdict=RED (BASELINE-UNBUILDABLE -- the registered tool is not reproducible from its own source)\n") 909 sys_exit(5); return 5 910 } 911 if base != 1 { 912 w(" UNCONTROLLED: the gate is not GREEN before mutation -- fix that first\n") 913 sys_exit(2); return 2 914 } 915 916 var killed: i64 = 0 917 // AIMED MODE: mutate numeric sites inside the ONE function the expert named, skipping the first 918 // <skip> sites (the leading guard block). Runs INSTEAD of the positional sweep: maxs is zeroed after, 919 // so every operator below enumerates nothing -- their headers print, their budgets are spent here. 920 // The verdict record and restore guarantee are UNCHANGED: a kill still requires a compiling mutant 921 // and a RED gate, so aiming changes which mutants are TRIED, never what counts as proof. 922 if aimmode == 1 { 923 w(" -- AIMED: operator-3 numeric mutation inside one named function (sweep budget zeroed) --\n") 924 let ad2: i64 = gb_aim_find(aimf) 925 if ad2 < 0 { 926 w(" AIM-ABSENT: no `func "); w(aimf); w("(` in the subject -- check the function name (an AIM fault, not a gate fault)\n") 927 sys_exit(4); return 4 928 } 929 w(" aim: func "); w(aimf); w(" @off="); wn(ad2); w(" end="); wn(gb_aim_end); w(" skip="); wn(aimskip); w("\n") 930 var ak: i64 = 0 931 var from3: i64 = ad2 932 var idx2: i64 = 0 933 while ak < maxs { 934 let aoff2: i64 = gb_num_at(gb_orig, gb_on, from3) 935 var stop2: i64 = 0 936 if aoff2 < 0 { stop2 = 1 } 937 if stop2 == 0 { if aoff2 >= gb_aim_end { stop2 = 1 } } 938 if stop2 == 1 { 939 w(" aim: numeric sites exhausted at idx="); wn(idx2); w("\n") 940 ak = maxs 941 } else { 942 from3 = aoff2 + 1 943 if idx2 >= aimskip { 944 var nda: i64 = (gb_orig[aoff2] as i64) + 1 945 if nda > 57 { nda = 56 } 946 w(" aim num site "); wn(idx2) 947 if gb_try(aoff2, nda) == 1 { killed = 1; ak = maxs } else { ak = ak + 1 } 948 } 949 idx2 = idx2 + 1 950 } 951 } 952 maxs = 0 953 } 954 w(" -- operator 1: COMPARISON (reaches logic) --\n") 955 var k: i64 = 0 956 while k < maxs { 957 let off: i64 = gb_site_cmp(gb_orig, gb_on, k) 958 if off < 0 { k = maxs } else { 959 w(" cmp site "); wn(k) 960 if gb_try(off, gb_cmp_flip(gb_orig, off)) == 1 { killed = 1; k = maxs } 961 k = k + 1 962 } 963 } 964 965 if killed == 0 { 966 // 2a: aim at the phrases the gate's own source names, before any linear scan. 967 gb_load_gate_src(gb_target) 968 if gb_gn > 0 { 969 w(" -- operator 2a: NEEDLE-GUIDED (aimed at phrases the gate itself asserts on) --\n") 970 gb_needle_audit(gb_orig, gb_on) 971 k = 0 972 while k < maxs { 973 let noff: i64 = gb_site_needle(gb_orig, gb_on, k) 974 if noff < 0 { k = maxs } else { 975 var nb2: i64 = (gb_orig[noff] as i64) + 1 976 if nb2 == 123 { nb2 = 97 } 977 if nb2 == 91 { nb2 = 65 } 978 w(" needle site "); wn(k) 979 if gb_try(noff, nb2) == 1 { killed = 1; k = maxs } 980 k = k + 1 981 } 982 } 983 } else { w(" (gate source not found -- skipping needle-guided phase)\n") } 984 } 985 986 if killed == 0 { 987 w(" -- operator 2b: LITERAL linear scan (reaches rendered output) --\n") 988 k = 0 989 while k < maxs { 990 let off: i64 = gb_site_lit(gb_orig, gb_on, k) 991 if off < 0 { k = maxs } else { 992 var nb: i64 = (gb_orig[off] as i64) + 1 993 if nb == 123 { nb = 97 } 994 if nb == 91 { nb = 65 } 995 w(" lit site "); wn(k) 996 if gb_try(off, nb) == 1 { killed = 1; k = maxs } 997 k = k + 1 998 } 999 } 1000 } 1001 1002 // OPERATOR 3 runs LAST but is the only one that reaches branchless code. Kept as a distinct phase 1003 // rather than folded into 2b because a changed CONSTANT and a changed STRING falsify different things: 1004 // 2b perturbs rendered output, this perturbs ARITHMETIC. For a KAT the arithmetic is the claim. 1005 if killed == 0 { 1006 w(" -- operator 3: NUMERIC CONSTANT (reaches branchless/constant-time code) --\n") 1007 k = 0 1008 while k < maxs { 1009 let noff2: i64 = gb_site_num(gb_orig, gb_on, k) 1010 if noff2 < 0 { k = maxs } else { 1011 // 9 -> 8, everything else +1: never creates a leading zero, never overflows the run 1012 var nd: i64 = (gb_orig[noff2] as i64) + 1 1013 if nd > 57 { nd = 56 } 1014 w(" num site "); wn(k) 1015 if gb_try(noff2, nd) == 1 { killed = 1; k = maxs } 1016 k = k + 1 1017 } 1018 } 1019 } 1020 1021 // ---- OPERATOR 4: SYMBOL-TARGETED. Aim where the GATE actually reaches. ---- 1022 // Operators 1/3 pick sites by FILE POSITION, so a bounded run on a large subject only ever mutates the 1023 // first kilobyte. MEASURED 2026-08-01: sites 864/936 in a 150261B subject -> killed=0, while the SAME 1024 // gate killed at off=4421 in a 10915B subject. Uniform striding was implemented, MEASURED and REVERTED 1025 // (debt 1785637001): at a fixed budget it MOVES the blind spot instead of shrinking it, and it lost a 1026 // kill that dense sampling had already found. Targeting is what position-based sampling cannot give. 1027 // Operator 2a tried this with string LITERALS and reported present_in_subject=0, because a gate's 1028 // literals are mostly its own chk() LABELS -- prose that was never a claim about the subject. An 1029 // IDENTIFIER is not prose: if the gate CALLS sym and the subject DEFINES func sym(, that is a site the 1030 // gate demonstrably reaches, established by parsing rather than by guessing. 1031 // ADDITIVE BY CONSTRUCTION: runs only when 1/2b/3 found no kill, so it can never remove an existing one. 1032 if killed == 0 { 1033 w(" -- operator 4: SYMBOL-TARGETED (mutate inside functions the GATE CALLS) --\n") 1034 let sym: *u8 = sys_mmap(200) 1035 let pat: *u8 = sys_mmap(240) 1036 var si: i64 = 0 1037 var used: i64 = 0 1038 let tried: *i64 = sys_mmap(8 * 64) as *i64 1039 var ntried: i64 = 0 1040 var scanning: i64 = 1 1041 while scanning == 1 { 1042 if used >= maxs { scanning = 0 } else { 1043 let L: i64 = gb_gate_call(si, sym, 200) 1044 if L < 0 { scanning = 0 } else { 1045 si = si + 1 1046 var po: i64 = 0 1047 let fw: *u8 = "func " as *u8 1048 var z: i64 = 0 1049 while z < 5 { pat[po] = fw[z]; po = po + 1; z = z + 1 } 1050 z = 0 1051 while z < L { pat[po] = sym[z]; po = po + 1; z = z + 1 } 1052 pat[po] = 40 as u8 1053 po = po + 1 1054 let d: i64 = gb_find(gb_orig, gb_on, pat, po) 1055 if d >= 0 { 1056 let off4: i64 = gb_cmp_at(gb_orig, gb_on, d) 1057 // DEDUP: many functions share the next downstream ==, so without this the budget is 1058 // burned re-mutating ONE site. MEASURED on nx_vcodec_band_gate: 26 valid mutants and 1059 // exactly ONE distinct offset (39064), because vv_enc_band and vv_dec_band both 1060 // resolved forward to the same comparison. Requiring a strictly LATER offset makes 1061 // every attempt a genuinely new site and turns max_sites into a real budget. 1062 if off4 >= 0 { 1063 // A MONOTONIC dedup was tried first and was WRONG: symbols are not ordered by 1064 // definition offset, so requiring a strictly later site discarded every candidate 1065 // defined earlier in the file and left exactly ONE distinct offset again. A tried-SET 1066 // is the correct shape -- order-independent, and it is what makes max_sites a budget 1067 // over DISTINCT sites rather than over attempts. 1068 var dup: i64 = 0 1069 var q2: i64 = 0 1070 while q2 < ntried { if tried[q2] == off4 { dup = 1 } q2 = q2 + 1 } 1071 if dup == 0 { 1072 if ntried < 64 { tried[ntried] = off4; ntried = ntried + 1 } 1073 w(" sym site "); w(sym) 1074 used = used + 1 1075 if gb_try(off4, gb_cmp_flip(gb_orig, off4)) == 1 { killed = 1; scanning = 0 } 1076 } 1077 } 1078 // AIM + BRANCHLESS REACH. Operator 4 aimed well but reused operator 1s == predicate, 1079 // so it inherited its blindness: constant-time and table-driven code is written NOT to 1080 // branch, and that is exactly the code most worth proving. Same aim, operator 3s 1081 // mutation -- perturb a NUMERIC constant inside the function the gate calls. 1082 if killed == 0 { 1083 let noff4: i64 = gb_num_at(gb_orig, gb_on, d) 1084 if noff4 >= 0 { 1085 var dupn: i64 = 0 1086 var q3: i64 = 0 1087 while q3 < ntried { if tried[q3] == noff4 { dupn = 1 } q3 = q3 + 1 } 1088 if dupn == 0 { 1089 if ntried < 64 { tried[ntried] = noff4; ntried = ntried + 1 } 1090 var nd4: i64 = (gb_orig[noff4] as i64) + 1 1091 if nd4 > 57 { nd4 = 56 } 1092 w(" sym num "); w(sym) 1093 used = used + 1 1094 if gb_try(noff4, nd4) == 1 { killed = 1; scanning = 0 } 1095 } 1096 } 1097 } 1098 } 1099 } 1100 } 1101 } 1102 } 1103 1104 // VERIFY THE RESTORE against the pristine copy. The organ refuses to report success over a damaged tree. 1105 let back: *u8 = sys_mmap(GB_MAXSRC) 1106 let bn: i64 = gb_read(gb_src, back, GB_MAXSRC) 1107 var same: i64 = 1 1108 if bn != gb_on { same = 0 } else { 1109 var j: i64 = 0 1110 while j < gb_on { if back[j] != gb_orig[j] { same = 0; j = gb_on } else { j = j + 1 } } 1111 } 1112 if same != 1 { 1113 w(" RESTORE-FAILED: subject does NOT match its pristine bytes -- CORPUS AT RISK\n") 1114 sys_exit(3); return 3 1115 } 1116 w(" restore verified: "); wn(bn); w(" bytes byte-identical to pristine\n") 1117 gb_build() // leave a clean binary: the last build was from mutated source 1118 1119 // Record the observation, bound to WHAT was measured and WHERE (a bite record is only true of the 1120 // gate-and-subject pair it was measured on; the same gate built on two hosts has different digests). 1121 let sd: *u8 = sys_mmap(32) 1122 sha256_digest(gb_orig, gb_on, sd) 1123 let vb: *u8 = sys_mmap(GB_MAGIC_1024) 1124 var o: i64 = 0 1125 let k1: *u8 = "killed=" 1126 var q: i64 = 0 1127 while k1[q] != (0 as u8) { vb[o] = k1[q]; o = o + 1; q = q + 1 } 1128 vb[o] = (48 + killed) as u8; o = o + 1 1129 let tb: *u8 = sys_mmap(28) 1130 let k2: *u8 = " valid_mutants=" 1131 q = 0 1132 while k2[q] != (0 as u8) { vb[o] = k2[q]; o = o + 1; q = q + 1 } 1133 var m: i64 = gb_tried 1134 var kk: i64 = 0 1135 if m == 0 { tb[0] = 48 as u8; kk = 1 } 1136 while m > 0 { tb[kk] = (48 + (m % 10)) as u8; m = m / 10; kk = kk + 1 } 1137 var z: i64 = kk - 1 1138 while z >= 0 { vb[o] = tb[z]; o = o + 1; z = z - 1 } 1139 let k2b: *u8 = " invalid=" 1140 q = 0 1141 while k2b[q] != (0 as u8) { vb[o] = k2b[q]; o = o + 1; q = q + 1 } 1142 m = gb_invalid 1143 kk = 0 1144 if m == 0 { tb[0] = 48 as u8; kk = 1 } 1145 while m > 0 { tb[kk] = (48 + (m % 10)) as u8; m = m / 10; kk = kk + 1 } 1146 z = kk - 1 1147 while z >= 0 { vb[o] = tb[z]; o = o + 1; z = z - 1 } 1148 let k3: *u8 = " epoch=" 1149 q = 0 1150 while k3[q] != (0 as u8) { vb[o] = k3[q]; o = o + 1; q = q + 1 } 1151 m = sys_now_realtime_sec() 1152 kk = 0 1153 if m == 0 { tb[0] = 48 as u8; kk = 1 } 1154 while m > 0 { tb[kk] = (48 + (m % 10)) as u8; m = m / 10; kk = kk + 1 } 1155 z = kk - 1 1156 while z >= 0 { vb[o] = tb[z]; o = o + 1; z = z - 1 } 1157 let k4: *u8 = " subjectdig=" 1158 q = 0 1159 while k4[q] != (0 as u8) { vb[o] = k4[q]; o = o + 1; q = q + 1 } 1160 let hexd: *u8 = "0123456789abcdef" 1161 var hj: i64 = 0 1162 while hj < 32 { 1163 let hb: i64 = sd[hj] as i64 1164 vb[o] = hexd[(hb >> 4) & 15]; o = o + 1 1165 vb[o] = hexd[hb & 15]; o = o + 1 1166 hj = hj + 1 1167 } 1168 let k5: *u8 = " host=" 1169 q = 0 1170 while k5[q] != (0 as u8) { vb[o] = k5[q]; o = o + 1; q = q + 1 } 1171 let hb2: *u8 = sys_mmap(256) 1172 let hn: i64 = gb_read("/etc/hostname\x00" as *u8, hb2, 255) 1173 if hn <= 0 { vb[o] = 63 as u8; o = o + 1 } else { 1174 var hk: i64 = 0 1175 while hk < hn { if hb2[hk] == (10 as u8) { break } vb[o] = hb2[hk]; o = o + 1; hk = hk + 1 } 1176 } 1177 vb[o] = 10 as u8; o = o + 1 1178 let vp: *u8 = sys_mmap(256) 1179 var vo: i64 = 0 1180 let vpre: *u8 = "knowledge/status/bite_" 1181 q = 0 1182 while vpre[q] != (0 as u8) { vp[vo] = vpre[q]; vo = vo + 1; q = q + 1 } 1183 q = 0 1184 while gb_target[q] != (0 as u8) { vp[vo] = gb_target[q]; vo = vo + 1; q = q + 1 } 1185 let vsfx: *u8 = ".verdict" 1186 q = 0 1187 while vsfx[q] != (0 as u8) { vp[vo] = vsfx[q]; vo = vo + 1; q = q + 1 } 1188 vp[vo] = 0 as u8 1189 gb_write(vp, vb, o) 1190 1191 w(" valid_mutants="); wn(gb_tried); w(" invalid_uncompilable="); wn(gb_invalid); w(" void_build_lane="); wn(gb_void); w(" killed="); wn(killed); w("\n") 1192 if killed == 1 { w("VERDICT: verdict=GREEN (gate BITES -- a compiling mutant was killed, non-vacuity proven)\n"); sys_exit(0); return 0 } 1193 w("VERDICT: verdict=RED (INCONCLUSIVE -- no kill across BOTH operators in "); wn(gb_tried) 1194 w(" valid mutant(s); NOT proof of vacuity, only that these perturbations did not reach its assertions)\n") 1195 sys_exit(1) 1196 return 1 1197}