code wiki / _hdl_build / nx_gate_mutation_probe.nx

nx_gate_mutation_probe.nx source

↩ module page · 540 lines · 22444 B

1// nx_gate_mutation_probe.nx -- SOVEREIGN MUTATION TESTING of gate sensor power (the SOTA ruler). 2// 3// Grounding (fetched live 2026-07-14 via nx_https_get, en.wikipedia.org/wiki/Mutation_testing): "the 4// mutation score is the number of mutants killed / total number of mutants"; goal #1 = "identify weakly 5// tested pieces of code (mutants not killed)". Lineage: Lipton 1971, DeMillo/Lipton/Sayward 1978, Budd 6// 1980. RULER = industry-standard; TOOL = GREENFIELD on NishiLang (PIT=JVM, mutmut=Py, Mull=LLVM -- none 7// run here) => sovereign-built, guarded by internal liar-killers per [[feedback-3rd-party-proving-for-nonnovel]]. 8// 9// TWO MODES: 10// (no args) CURATED v1: fixed pair (runtime/nx_handoff_gate.nx x its proof gate), 11// 6 hand-designed killable mutants -> GREEN iff 6/6 killed. This is the 12// REGRESSION GATE on the sensor stack's power (baseline-wrapped). 13// <subject> <gate> [budget] GENERIC v2: ANY lib x gate pair (naming law nx_X / nx_X_gate). 14// Auto-generates mutants with classic operators (ROR: < > <= >= == != ; 15// AOR: + -) at sites OUTSIDE comments/strings (region mask -- mutating a 16// comment is a guaranteed FALSE survivor), evenly spread over the file. 17// Survivors are reported as FINDINGS (op + line) = the liar-killer 18// worklist; score is DATA (verdict = pipeline soundness, not score). 19// ⚠kills assume the gate is idempotent (re-run-stable). 20// 21// LIAR-KILLERS ON THE PROBE ITSELF (both modes): 22// * IDENTITY CONTROL -- an unmutated copy MUST stay GREEN (pipeline introduces no fault; models the 23// equivalent-mutant honesty case). Identity RED => all results VOID. 24// * NEEDLE/SITE-NOT-FOUND = RED -- never silently skip. 25// * import needle is BUILT AT RUNTIME as `import "<subject>.nx"` (quote bytes composed) so a comment 26// mentioning the filename can never eat the splice (the v1 trap, killed generally). 27// * signal-aware rc decode (128+sig). 28// NEVER-BRICK: originals READ-ONLY; only __mutprobe_* copies written, then ARCHIVED to knowledge/mutprobe/. 29// Sovereign nx_cc->nxasm; CWD=nxc2 root. license_tier: ORIGINAL 30import "syscalls.nx" 31import "runtime.nx" 32import "nx_syscalls.nx" // nx_setsid, nx_kill, sys_prlimit, sys_sleep_ms, WNOHANG, RLIMIT_* 33 34// Bounds for a DELIBERATELY BROKEN program. Named consts, not inline numbers, because someone will need 35// to raise them for a genuinely slow gate and must be able to find them. A real gate run on this host is 36// seconds; 180s is ~30x headroom, so a mutant that exceeds it is hung, not merely slow. 37const MP_MUTANT_DEADLINE_MS: i64 = 180000 // wall-clock ceiling per mutant run 38const MP_POLL_MS: i64 = 250 // liveness poll interval (WNOHANG) 39const MP_MUTANT_CPU_S: i64 = 240 // RLIMIT_CPU: a spinner dies even if wall-clock is generous 40const MP_MUTANT_AS_BYTES: i64 = 4294967296 // RLIMIT_AS 4GiB: a mutated size allocates, then FAILS -- not the host 41const K_MAGIC_1048576: i64 = 1048576 42 43func mp_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 44 45func mp_cat(dst: *u8, off: i64, s: *u8) -> i64 { 46 var i: i64 = 0 47 while s[i] != (0 as u8) { dst[off+i] = s[i]; i = i + 1 } 48 return off + i 49} 50 51func mp_read(path: *u8, buf: *u8, cap: i64) -> i64 { 52 let fd: i64 = sys_openat_rd(path) 53 if fd < 0 { return 0 - 1 } 54 var total: i64 = 0 55 var go: i64 = 1 56 while go == 1 { 57 go = 0 58 let tail: *u8 = ((buf as i64) + total) as *u8 59 let n: i64 = sys_read(fd, tail, cap - total) 60 if n > 0 { total = total + n; if total < cap { go = 1 } } 61 } 62 sys_close(fd) 63 return total 64} 65 66func mp_write(path: *u8, buf: *u8, len: i64) -> i64 { 67 let fd: i64 = sys_openat_wr(path, 0x1a4) 68 if fd < 0 { return 0 - 1 } 69 sys_write(fd, buf, len) 70 sys_close(fd) 71 return 0 72} 73 74func mp_find(hay: *u8, hlen: i64, needle: *u8) -> i64 { 75 let nl: i64 = mp_slen(needle) 76 if nl == 0 { return 0 - 1 } 77 var i: i64 = 0 78 while i + nl <= hlen { 79 var j: i64 = 0 80 var ok: i64 = 1 81 while j < nl { 82 if hay[i+j] != needle[j] { ok = 0; j = nl } else { j = j + 1 } 83 } 84 if ok == 1 { return i } 85 i = i + 1 86 } 87 return 0 - 1 88} 89 90func mp_splice(hay: *u8, hlen: i64, needle: *u8, repl: *u8, out: *u8) -> i64 { 91 let at: i64 = mp_find(hay, hlen, needle) 92 if at < 0 { return 0 - 1 } 93 let nl: i64 = mp_slen(needle) 94 let rl: i64 = mp_slen(repl) 95 var i: i64 = 0 96 while i < at { out[i] = hay[i]; i = i + 1 } 97 var j: i64 = 0 98 while j < rl { out[at+j] = repl[j]; j = j + 1 } 99 var k: i64 = at + nl 100 while k < hlen { out[at + rl + (k - at - nl)] = hay[k]; k = k + 1 } 101 return hlen - nl + rl 102} 103 104// 1-based line number of byte offset (for survivor findings) 105func mp_line_of(src: *u8, off: i64) -> i64 { 106 var ln: i64 = 1 107 var i: i64 = 0 108 while i < off { 109 if src[i] == (10 as u8) { ln = ln + 1 } 110 i = i + 1 111 } 112 return ln 113} 114 115// region mask: mark[i]=1 iff byte i is inside a // comment or a "..." string literal 116func mp_mask(src: *u8, len: i64, mark: *u8) -> i64 { 117 var i: i64 = 0 118 var st: i64 = 0 119 while i < len { 120 let c: i64 = src[i] as i64 121 var m: i64 = 0 122 var done: i64 = 0 123 if st == 1 { 124 m = 1 125 if c == 10 { st = 0 } 126 done = 1 127 } 128 if done == 0 { 129 if st == 2 { 130 m = 1 131 if c == 34 { st = 0 } 132 done = 1 133 } 134 } 135 if done == 0 { 136 if c == 34 { st = 2; m = 1 } 137 if c == 47 { if i + 1 < len { if src[i+1] == (47 as u8) { st = 1; m = 1 } } } 138 } 139 mark[i] = m as u8 140 i = i + 1 141 } 142 return 0 143} 144 145// token match at position i, fully unmasked 146func mp_tok_at(src: *u8, len: i64, mark: *u8, i: i64, tok: *u8) -> i64 { 147 let tl: i64 = mp_slen(tok) 148 if i + tl > len { return 0 } 149 var j: i64 = 0 150 while j < tl { 151 if src[i+j] != tok[j] { return 0 } 152 if mark[i+j] != (0 as u8) { return 0 } 153 j = j + 1 154 } 155 return 1 156} 157 158// scan all mutation sites (op table order = longest tokens first); returns count (capped at maxs) 159func mp_scan(src: *u8, len: i64, mark: *u8, toks: *i64, nops: i64, sites: *i64, ops: *i64, maxs: i64) -> i64 { 160 var count: i64 = 0 161 var i: i64 = 0 162 while i < len { 163 var adv: i64 = 1 164 var k: i64 = 0 165 while k < nops { 166 if mp_tok_at(src, len, mark, i, (toks[k]) as *u8) == 1 { 167 if count < maxs { 168 sites[count] = i 169 ops[count] = k 170 count = count + 1 171 } 172 adv = mp_slen((toks[k]) as *u8) 173 k = nops 174 } else { k = k + 1 } 175 } 176 i = i + adv 177 } 178 return count 179} 180 181// fork the sovereign lane on __mutprobe_gate; both streams -> /tmp capture; signal-aware rc 182func mp_run_lane(envp: *i64) -> i64 { 183 let runner: *u8 = "_offc/nx_sov_build_run.elf" as *u8 184 let ofd: i64 = sys_openat_wr("/tmp/mutprobe_run.out" as *u8, 0x1a4) 185 let av: *i64 = sys_mmap(8 * 4) as *i64 186 av[0] = runner as i64 187 av[1] = ("__mutprobe_gate" as *u8) as i64 188 av[2] = 0 189 let pid: i64 = sys_fork() 190 if pid == 0 { 191 // NEW SESSION so the mutant and everything IT forks share one process group we can kill as a 192 // unit. Without this, killing the runner ORPHANS the gate it forked: measured live 2026-08-01, 193 // four __mutprobe_gate processes reparented to init and span for 2650s, 3325s and 3411s of CPU 194 // each (~2.6 CPU-hours) after I killed their probes. They drove host load past 99. 195 nx_setsid() 196 // BOUND WHAT A DELIBERATELY-BROKEN PROGRAM MAY CONSUME. Mutation testing exists to produce 197 // wrong code; a mutated length or stride can request arbitrary memory, and a mutated loop 198 // counter can spin forever. Uncapped, the test rig becomes the outage -- the same shape as the 199 // 16.7GB OOM that took this box to 819MB free earlier today. 200 // nx_prlimit, NOT sys_prlimit: the compiler bakes some sys_* bodies by name and the nx_ prefix 201 // avoids that trap (documented at nx_syscalls.nx:358). Takes *u8 to a rlimit64 {cur, max}. 202 let rl: *u8 = sys_mmap(16) 203 let rli: *i64 = rl as *i64 204 rli[0] = MP_MUTANT_CPU_S; rli[1] = MP_MUTANT_CPU_S 205 nx_prlimit(0, RLIMIT_CPU, rl, 0 as *u8) 206 let ra: *u8 = sys_mmap(16) 207 let rai: *i64 = ra as *i64 208 rai[0] = MP_MUTANT_AS_BYTES; rai[1] = MP_MUTANT_AS_BYTES 209 nx_prlimit(0, RLIMIT_AS, ra, 0 as *u8) 210 if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) } 211 sys_execve(runner, av, envp) 212 sys_exit(127) 213 } 214 // ---- BOUNDED WAIT (2026-08-01) ---- 215 // Was `sys_wait4(pid, st, 0)` -- a BLOCKING wait with no deadline. A mutant that hangs (which is a 216 // NORMAL outcome: flipping a loop counter's `+` to `-` makes it non-terminating) stalled the probe 217 // forever, which stalled the whole sweep, and killing the probe left the spinner orphaned. 218 // LAW: A HARNESS THAT DELIBERATELY RUNS BROKEN CODE MUST BOUND BOTH ITS RUNTIME AND ITS RESOURCES -- 219 // an unbounded wait on a program you MUTATED is a promise that the mutation always terminates, and 220 // the whole point of mutation is that it does not. 221 // rc=124 on timeout, matching the `timeout(1)` convention this codebase already reads as 222 // "the deadline talking, not the subject". A hung mutant is a KILLED mutant: the gate failed to 223 // return a verdict, which is exactly the failure the tooth is meant to detect. 224 let st: *i64 = sys_mmap(16) as *i64 225 var waited: i64 = 0 226 var timedout: i64 = 0 227 var done: i64 = 0 228 while done == 0 { 229 let r: i64 = sys_wait4(pid, st, WNOHANG) 230 if r == pid { done = 1 } 231 if r != pid { 232 if waited >= MP_MUTANT_DEADLINE_MS { 233 nx_kill(0 - pid, 9) // negative pid = the whole process GROUP (needs the setsid above) 234 nx_kill(pid, 9) // and the leader itself, in case setsid failed 235 sys_wait4(pid, st, 0) // reap the corpse so we leave no zombie 236 timedout = 1 237 done = 1 238 } 239 if waited < MP_MUTANT_DEADLINE_MS { 240 sys_sleep_ms(MP_POLL_MS) 241 waited = waited + MP_POLL_MS 242 } 243 } 244 } 245 if ofd >= 0 { sys_close(ofd) } 246 if timedout == 1 { return 124 } 247 let sig: i64 = st[0] & 0x7f 248 if sig != 0 { return 128 + sig } 249 return (st[0] >> 8) & 0xff 250} 251 252func mp_archive() -> i64 { 253 sys_mkdir("knowledge/mutprobe" as *u8, 0x1ed) 254 sys_renameat("runtime/_hdl_build/__mutprobe_lib.nx" as *u8, "knowledge/mutprobe/__mutprobe_lib.nx" as *u8) 255 sys_renameat("runtime/_hdl_build/__mutprobe_gate.nx" as *u8, "knowledge/mutprobe/__mutprobe_gate.nx" as *u8) 256 return 0 257} 258 259// ---- GENERIC v2 mode --------------------------------------------------- 260func run_generic(subject: *u8, gatename: *u8, budget: i64) -> i64 { 261 print("=== nx_gate_mutation_probe GENERIC: subject=" as *u8) 262 print(subject) 263 print(" gate=" as *u8) 264 print(gatename) 265 print(" budget=" as *u8) 266 print_i64(budget) 267 print(" ===\n" as *u8) 268 269 let cap: i64 = K_MAGIC_1048576 270 let lib: *u8 = sys_mmap(cap + 16) 271 let gate: *u8 = sys_mmap(cap + 16) 272 let mut: *u8 = sys_mmap(cap + 16) 273 let mgate: *u8 = sys_mmap(cap + 16) 274 let mark: *u8 = sys_mmap(cap + 16) 275 276 // subject path: _hdl_build first, then runtime/ 277 let spath: *u8 = sys_mmap(512) 278 var o: i64 = 0 279 o = mp_cat(spath, o, "runtime/_hdl_build/" as *u8) 280 o = mp_cat(spath, o, subject) 281 o = mp_cat(spath, o, ".nx" as *u8) 282 spath[o] = 0 as u8 283 var liblen: i64 = mp_read(spath, lib, cap) 284 if liblen < 0 { 285 o = 0 286 o = mp_cat(spath, o, "runtime/" as *u8) 287 o = mp_cat(spath, o, subject) 288 o = mp_cat(spath, o, ".nx" as *u8) 289 spath[o] = 0 as u8 290 liblen = mp_read(spath, lib, cap) 291 } 292 if liblen <= 0 { print(" [RED] subject not found\n" as *u8); sys_exit(1); return 1 } 293 294 let gpath: *u8 = sys_mmap(512) 295 o = 0 296 o = mp_cat(gpath, o, "runtime/_hdl_build/" as *u8) 297 o = mp_cat(gpath, o, gatename) 298 o = mp_cat(gpath, o, ".nx" as *u8) 299 gpath[o] = 0 as u8 300 let gatelen: i64 = mp_read(gpath, gate, cap) 301 if gatelen <= 0 { print(" [RED] gate not found\n" as *u8); sys_exit(1); return 1 } 302 303 // runtime-built import needle: import "<subject>.nx" (quote bytes composed -> comment-proof) 304 let needle: *u8 = sys_mmap(512) 305 o = 0 306 o = mp_cat(needle, o, "import " as *u8) 307 needle[o] = 34 as u8 308 o = o + 1 309 o = mp_cat(needle, o, subject) 310 o = mp_cat(needle, o, ".nx" as *u8) 311 needle[o] = 34 as u8 312 o = o + 1 313 needle[o] = 0 as u8 314 let repl: *u8 = sys_mmap(512) 315 o = 0 316 o = mp_cat(repl, o, "import " as *u8) 317 repl[o] = 34 as u8 318 o = o + 1 319 o = mp_cat(repl, o, "__mutprobe_lib.nx" as *u8) 320 repl[o] = 34 as u8 321 o = o + 1 322 repl[o] = 0 as u8 323 324 let mgatelen: i64 = mp_splice(gate, gatelen, needle, repl, mgate) 325 if mgatelen < 0 { print(" [RED] gate does not import the subject (needle absent)\n" as *u8); sys_exit(1); return 1 } 326 mp_write("runtime/_hdl_build/__mutprobe_gate.nx" as *u8, mgate, mgatelen) 327 328 let envp: *i64 = sys_mmap(8 * 4) as *i64 329 envp[0] = ("PATH=/usr/bin:/bin" as *u8) as i64 330 envp[1] = 0 331 332 // operator table (longest tokens FIRST so ' <= ' wins over ' < ') 333 let toks: *i64 = sys_mmap(8 * 16) as *i64 334 let rpls: *i64 = sys_mmap(8 * 16) as *i64 335 toks[0] = (" <= " as *u8) as i64; rpls[0] = (" >= " as *u8) as i64 336 toks[1] = (" >= " as *u8) as i64; rpls[1] = (" <= " as *u8) as i64 337 toks[2] = (" == " as *u8) as i64; rpls[2] = (" != " as *u8) as i64 338 toks[3] = (" != " as *u8) as i64; rpls[3] = (" == " as *u8) as i64 339 toks[4] = (" < " as *u8) as i64; rpls[4] = (" > " as *u8) as i64 340 toks[5] = (" > " as *u8) as i64; rpls[5] = (" < " as *u8) as i64 341 toks[6] = (" + " as *u8) as i64; rpls[6] = (" - " as *u8) as i64 342 let nops: i64 = 7 343 344 mp_mask(lib, liblen, mark) 345 let sites: *i64 = sys_mmap(8 * 512) as *i64 346 let opsat: *i64 = sys_mmap(8 * 512) as *i64 347 let nsites: i64 = mp_scan(lib, liblen, mark, toks, nops, sites, opsat, 512) 348 print(" mutation sites found (outside comments/strings) = " as *u8) 349 print_i64(nsites) 350 print("\n" as *u8) 351 if nsites == 0 { print(" [RED] nothing to mutate (probe inapplicable)\n" as *u8); mp_archive(); sys_exit(1); return 1 } 352 353 // IDENTITY CONTROL 354 mp_write("runtime/_hdl_build/__mutprobe_lib.nx" as *u8, lib, liblen) 355 let rc0: i64 = mp_run_lane(envp) 356 print(" [identity control] rc=" as *u8) 357 print_i64(rc0) 358 if rc0 != 0 { 359 print(" RED -- pipeline unsound for this pair (gate may self-reference; results VOID)\n" as *u8) 360 mp_archive() 361 sys_exit(1) 362 return 1 363 } 364 print(" GREEN (pipeline sound)\n" as *u8) 365 366 var nrun: i64 = budget 367 if nsites < nrun { nrun = nsites } 368 var killed: i64 = 0 369 var survived: i64 = 0 370 var m: i64 = 0 371 while m < nrun { 372 let pick: i64 = (m * nsites) / nrun 373 let at: i64 = sites[pick] 374 let op: i64 = opsat[pick] 375 // copy subject + patch the token bytes in place (same length) 376 var ci: i64 = 0 377 while ci < liblen { mut[ci] = lib[ci]; ci = ci + 1 } 378 let rp: *u8 = (rpls[op]) as *u8 379 let tl: i64 = mp_slen((toks[op]) as *u8) 380 var pj: i64 = 0 381 while pj < tl { mut[at+pj] = rp[pj]; pj = pj + 1 } 382 mp_write("runtime/_hdl_build/__mutprobe_lib.nx" as *u8, mut, liblen) 383 let rc: i64 = mp_run_lane(envp) 384 print(" [mutant " as *u8) 385 print_i64(m + 1) 386 print("/" as *u8) 387 print_i64(nrun) 388 print(" op '" as *u8) 389 print((toks[op]) as *u8) 390 print("'->'" as *u8) 391 print(rp) 392 print("' line " as *u8) 393 print_i64(mp_line_of(lib, at)) 394 print("] rc=" as *u8) 395 print_i64(rc) 396 if rc != 0 { killed = killed + 1; print(" KILLED\n" as *u8) } 397 if rc == 0 { 398 survived = survived + 1 399 print(" *** SURVIVED -> gate blind at this site (liar-killer worklist)\n" as *u8) 400 } 401 m = m + 1 402 } 403 404 mp_archive() 405 print("---- mutation score: " as *u8) 406 print_i64(killed) 407 print("/" as *u8) 408 print_i64(nrun) 409 print(" killed, " as *u8) 410 print_i64(survived) 411 print(" survived (findings; score=data, verdict=pipeline soundness) ----\n" as *u8) 412 print("=== verdict: GREEN (identity sound; score measured; survivors above are the retrofit worklist) ===\n" as *u8) 413 sys_exit(0) 414 return 0 415} 416 417func main(argc: i64, argv: *i64) -> i64 { 418 if argc >= 3 { 419 var budget: i64 = 5 420 if argc >= 4 { 421 let b: *u8 = argv[3] as *u8 422 var v: i64 = 0 423 var bi: i64 = 0 424 while b[bi] != (0 as u8) { 425 let d: i64 = b[bi] as i64 426 if d >= 48 { if d <= 57 { v = v * 10 + (d - 48) } } 427 bi = bi + 1 428 } 429 if v > 0 { budget = v } 430 } 431 return run_generic(argv[1] as *u8, argv[2] as *u8, budget) 432 } 433 434 // ---------------- CURATED v1 mode (the baseline-wrapped regression gate) ---------------- 435 print("=== nx_gate_mutation_probe: sovereign mutation score of the handoff sensor stack ===\n" as *u8) 436 print(" ruler: mutation score = killed/total (DeMillo-Lipton-Sayward line, fetched+grounded 2026-07-14)\n" as *u8) 437 438 let libp: *u8 = "runtime/nx_handoff_gate.nx" as *u8 439 let gatep: *u8 = "runtime/_hdl_build/nx_handoff_gate_proof.nx" as *u8 440 let mlibp: *u8 = "runtime/_hdl_build/__mutprobe_lib.nx" as *u8 441 let mgatep: *u8 = "runtime/_hdl_build/__mutprobe_gate.nx" as *u8 442 443 let cap: i64 = K_MAGIC_1048576 444 let lib: *u8 = sys_mmap(cap + 16) 445 let gate: *u8 = sys_mmap(cap + 16) 446 let mut: *u8 = sys_mmap(cap + 16) 447 let mgate: *u8 = sys_mmap(cap + 16) 448 449 let liblen: i64 = mp_read(libp, lib, cap) 450 let gatelen: i64 = mp_read(gatep, gate, cap) 451 if liblen <= 0 { print(" [RED] cannot read subject lib\n" as *u8); sys_exit(1); return 1 } 452 if gatelen <= 0 { print(" [RED] cannot read gate\n" as *u8); sys_exit(1); return 1 } 453 454 let mgatelen: i64 = mp_splice(gate, gatelen, "nx_handoff_gate.nx" as *u8, "__mutprobe_lib.nx" as *u8, mgate) 455 if mgatelen < 0 { print(" [RED] import-splice needle absent in gate\n" as *u8); sys_exit(1); return 1 } 456 mp_write(mgatep, mgate, mgatelen) 457 458 let envp: *i64 = sys_mmap(8 * 4) as *i64 459 envp[0] = ("PATH=/usr/bin:/bin" as *u8) as i64 460 envp[1] = 0 461 462 let names: *i64 = sys_mmap(8 * 8) as *i64 463 let ndl: *i64 = sys_mmap(8 * 8) as *i64 464 let rpl: *i64 = sys_mmap(8 * 8) as *i64 465 names[0] = ("M1 neg-control flip (<= to >=)" as *u8) as i64 466 ndl[0] = ("if wrong_score <= floor" as *u8) as i64 467 rpl[0] = ("if wrong_score >= floor" as *u8) as i64 468 names[1] = ("M2 monotonic reversal blinded (return 0 to 1)" as *u8) as i64 469 ndl[1] = ("if vals[i] < vals[i-1] { return 0 }" as *u8) as i64 470 rpl[1] = ("if vals[i] < vals[i-1] { return 1 }" as *u8) as i64 471 names[2] = ("M3 invariant_le flip (<= to >=)" as *u8) as i64 472 ndl[2] = ("if a <= b { return 1 }" as *u8) as i64 473 rpl[2] = ("if a >= b { return 1 }" as *u8) as i64 474 names[3] = ("M4 no_backslide flip (< to >)" as *u8) as i64 475 ndl[3] = ("if cur[i] < base[i] { return 0 }" as *u8) as i64 476 rpl[3] = ("if cur[i] > base[i] { return 0 }" as *u8) as i64 477 names[4] = ("M5 parse arithmetic nudge (*10 to *11)" as *u8) as i64 478 ndl[4] = ("val = val * 10 + (d - 48)" as *u8) as i64 479 rpl[4] = ("val = val * 11 + (d - 48)" as *u8) as i64 480 names[5] = ("M6 worst-drop localizer flip (> to <)" as *u8) as i64 481 ndl[5] = ("if drop > wdrop { wdrop = drop; worst = i }" as *u8) as i64 482 rpl[5] = ("if drop < wdrop { wdrop = drop; worst = i }" as *u8) as i64 483 let nmut: i64 = 6 484 485 mp_write(mlibp, lib, liblen) 486 let rc0: i64 = mp_run_lane(envp) 487 print(" [M0 identity control] rc=" as *u8) 488 print_i64(rc0) 489 var probe_ok: i64 = 1 490 if rc0 == 0 { print(" GREEN (pipeline sound: unmutated copy passes)\n" as *u8) } 491 if rc0 != 0 { print(" RED -- probe pipeline itself broke the build; ALL results below are VOID\n" as *u8); probe_ok = 0 } 492 493 var killed: i64 = 0 494 var survived: i64 = 0 495 var notfound: i64 = 0 496 var m: i64 = 0 497 while m < nmut { 498 print(" [" as *u8) 499 print((names[m]) as *u8) 500 print("] " as *u8) 501 let mlen: i64 = mp_splice(lib, liblen, (ndl[m]) as *u8, (rpl[m]) as *u8, mut) 502 if mlen < 0 { 503 notfound = notfound + 1 504 print("NEEDLE-NOT-FOUND (probe out of sync with lib) -> RED\n" as *u8) 505 } 506 if mlen >= 0 { 507 mp_write(mlibp, mut, mlen) 508 let rc: i64 = mp_run_lane(envp) 509 print("rc=" as *u8) 510 print_i64(rc) 511 if rc != 0 { killed = killed + 1; print(" KILLED (gate caught the injected fault)\n" as *u8) } 512 if rc == 0 { survived = survived + 1; print(" *** SURVIVED -> the gate is BLIND to this fault (add a liar-killer here)\n" as *u8) } 513 } 514 m = m + 1 515 } 516 517 mp_archive() 518 519 print("---- mutation score: " as *u8) 520 print_i64(killed) 521 print("/" as *u8) 522 print_i64(nmut) 523 print(" killed, " as *u8) 524 print_i64(survived) 525 print(" survived, " as *u8) 526 print_i64(notfound) 527 print(" not-found ----\n" as *u8) 528 var green: i64 = 1 529 if probe_ok != 1 { green = 0 } 530 if notfound != 0 { green = 0 } 531 if survived != 0 { green = 0 } 532 if green == 1 { 533 print("=== verdict: GREEN (identity sound; 6/6 mutants killed = the sensor stack provably catches these fault classes; regression-gates the proof gate's sensor power) ===\n" as *u8) 534 sys_exit(0) 535 return 0 536 } 537 print("=== verdict: RED (probe broken, needle drift, or SURVIVORS = measured sensor blindness -- fix with new liar-killers, never by weakening mutants) ===\n" as *u8) 538 sys_exit(1) 539 return 1 540}