code wiki / _hdl_build / nx_gate_baseline_harness.nx

nx_gate_baseline_harness.nx source

↩ module page · 344 lines · 13378 B

1// nx_gate_baseline_harness.nx -- retrofit a REGRESSION BASELINE onto ANY gate with ZERO gate-source edits. 2// 3// The sensor-gap risk map ([[project-nishi-sensor-gap-census-2026-07-14]]) measured 87% of ~3675 gates with 4// NO regression baseline = they can silently backslide. Hand-editing thousands of gates would be a patch 5// cascade (rule 3) -- so this harness wraps the RUNNER instead: it forks the sovereign build lane on a gate, 6// captures the gate's output + exit code, and banks/guards a per-gate baseline ledger. Wrapping a gate = 7// running one command; the gate's source is never touched. 8// 9// usage: nx_gate_baseline_harness <gate-name> [--rebase] 10// first run -> CAPTURE: bank {rc, int-vector of output} to knowledge/status/gatebase_<gate>.tsv 11// later runs -> GUARD: rc must MATCH the banked rc (universal invariant, judged); 12// numeric drift is SURFACED per position (informational, NOT judged -- 13// auto-judging unknown numbers directionally would make a LYING sensor; 14// per-gate directional specs are the v2 data-row hook). 15// --rebase -> re-bank current state as the new baseline (explicit operator action; refused on rc!=0). 16// 17// LIAR-KILLERS on the harness itself: 18// * signal-aware exit decode (128+sig, the proven sbr_run idiom) -- a SEGFAULTED gate can never read as GREEN. 19// * a red run is REFUSED as a baseline -- a broken state can never become "the standard". 20// * an absent/unreadable output = RED (evidence-grounding: no evidence, no verdict). 21// * ledger writes are atomic (tmp + renameat); only /tmp/gatebase_*.out + knowledge/status/gatebase_*.tsv 22// are ever written -- no gate source is touched (never-brick by construction). 23// Sovereign nx_cc->nxasm; forks _offc/nx_sov_build_run.elf (no gcc, no sh). Run with CWD=nxc2 root. 24// license_tier: ORIGINAL 25import "syscalls.nx" 26import "runtime.nx" 27import "nx_handoff_gate.nx" 28const GBH_MAGIC_4096: i64 = 4096 29const GBH_MAGIC_1048576: i64 = 1048576 30 31const GBH_MAX_VALS: i64 = 64 32 33// append NUL-terminated s into dst at off; return new offset (no NUL written) -- the sbr_cat idiom 34func gbh_cat(dst: *u8, off: i64, s: *u8) -> i64 { 35 var i: i64 = 0 36 while s[i] != (0 as u8) { dst[off+i] = s[i]; i = i + 1 } 37 return off + i 38} 39 40// fork + redirect + execve + wait4; returns WEXITSTATUS or 128+signal (signal-aware: a crashed 41// child must NEVER decode as rc=0 -- the proven nx_sov_build_run liar-kill). 42func gbh_run(path: *u8, argv: *i64, envp: *i64, redir_out: i64, redir_err: i64) -> i64 { 43 let pid: i64 = sys_fork() 44 if pid == 0 { 45 if redir_out >= 0 { sys_dup3(redir_out, 1, 0) } 46 if redir_err >= 0 { sys_dup3(redir_err, 2, 0) } 47 sys_execve(path, argv, envp) 48 sys_exit(127) 49 } 50 let st: *i64 = sys_mmap(16) as *i64 51 sys_wait4(pid, st, 0) 52 let sig: i64 = st[0] & 0x7f 53 if sig != 0 { return 128 + sig } 54 return (st[0] >> 8) & 0xff 55} 56 57// case-sensitive contains (lane failure markers are exact strings) 58func gbh_has(buf: *u8, len: i64, lit: *u8) -> i64 { 59 var nl: i64 = 0 60 while lit[nl] != (0 as u8) { nl = nl + 1 } 61 if nl == 0 { return 1 } 62 var i: i64 = 0 63 while i + nl <= len { 64 var j: i64 = 0 65 var ok: i64 = 1 66 while j < nl { 67 if buf[i+j] != lit[j] { ok = 0; j = nl } else { j = j + 1 } 68 } 69 if ok == 1 { return 1 } 70 i = i + 1 71 } 72 return 0 73} 74 75// bounded whole-file read; bytes read, or -1 if unopenable (absent evidence is reported, never invented) 76func gbh_read(path: *u8, buf: *u8, cap: i64) -> i64 { 77 let fd: i64 = sys_openat_rd(path) 78 if fd < 0 { return 0 - 1 } 79 var total: i64 = 0 80 var go: i64 = 1 81 while go == 1 { 82 go = 0 83 let tail: *u8 = ((buf as i64) + total) as *u8 84 let n: i64 = sys_read(fd, tail, cap - total) 85 if n > 0 { total = total + n; if total < cap { go = 1 } } 86 } 87 sys_close(fd) 88 return total 89} 90 91// render non-negative n into dst at off; return new offset (declared BEFORE gbh_bank per the 92// forward-static-ref gotcha: declare before use) 93func gbh_num(dst: *u8, off: i64, n: i64) -> i64 { 94 var m: i64 = n 95 if m < 0 { m = 0 } 96 let t: *u8 = sys_mmap(28) 97 var k: i64 = 0 98 if m == 0 { t[0] = 48 as u8; k = 1 } 99 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 100 var i: i64 = 0 101 while i < k { dst[off+i] = t[k-1-i]; i = i + 1 } 102 return off + k 103} 104 105// atomically write the ledger line: rc \t count \t v0..v(k-1) 106func gbh_bank(ledger: *u8, ltmp: *u8, rc: i64, count: i64, vals: *i64, k: i64) -> i64 { 107 let fd: i64 = sys_openat_wr(ltmp, 0x1a4) 108 if fd < 0 { return 0 - 1 } 109 let line: *u8 = sys_mmap(GBH_MAGIC_4096) 110 var o: i64 = 0 111 o = gbh_num(line, o, rc) 112 line[o] = 9 as u8 113 o = o + 1 114 o = gbh_num(line, o, count) 115 var i: i64 = 0 116 while i < k { 117 line[o] = 9 as u8 118 o = o + 1 119 o = gbh_num(line, o, vals[i]) 120 i = i + 1 121 } 122 line[o] = 10 as u8 123 o = o + 1 124 sys_write(fd, line, o) 125 sys_close(fd) 126 sys_renameat(ltmp, ledger) 127 return 0 128} 129 130func main(argc: i64, argv: *i64) -> i64 { 131 if argc < 2 { 132 print("usage: nx_gate_baseline_harness <gate-name> [--rebase]\n" as *u8) 133 sys_exit(2) 134 return 2 135 } 136 let name: *u8 = argv[1] as *u8 137 var rebase: i64 = 0 138 if argc >= 3 { 139 let fl: *u8 = argv[2] as *u8 140 if fl[0] == (45 as u8) { if fl[1] == (45 as u8) { if fl[2] == (114 as u8) { rebase = 1 } } } 141 } 142 143 print("=== nx_gate_baseline_harness: " as *u8) 144 print(name) 145 print(" ===\n" as *u8) 146 147 // paths 148 let outp: *u8 = sys_mmap(512) 149 var o: i64 = 0 150 o = gbh_cat(outp, o, "/tmp/gatebase_" as *u8) 151 o = gbh_cat(outp, o, name) 152 o = gbh_cat(outp, o, ".out" as *u8) 153 outp[o] = 0 as u8 154 let ledger: *u8 = sys_mmap(512) 155 o = 0 156 o = gbh_cat(ledger, o, "knowledge/status/gatebase_" as *u8) 157 o = gbh_cat(ledger, o, name) 158 o = gbh_cat(ledger, o, ".tsv" as *u8) 159 ledger[o] = 0 as u8 160 let ltmp: *u8 = sys_mmap(512) 161 o = 0 162 o = gbh_cat(ltmp, o, ledger) 163 o = gbh_cat(ltmp, o, ".tmp" as *u8) 164 ltmp[o] = 0 as u8 165 166 // run the gate through the sovereign lane, both streams captured 167 let envp: *i64 = sys_mmap(8 * 4) as *i64 168 envp[0] = ("PATH=/usr/bin:/bin" as *u8) as i64 169 envp[1] = 0 170 let runner: *u8 = "_offc/nx_sov_build_run.elf" as *u8 171 let ofd: i64 = sys_openat_wr(outp, 0x1a4) 172 if ofd < 0 { 173 print(" [RED] cannot open capture file\n" as *u8) 174 sys_exit(1) 175 return 1 176 } 177 let ra: *i64 = sys_mmap(8 * 4) as *i64 178 ra[0] = runner as i64 179 ra[1] = name as i64 180 ra[2] = 0 181 let rc: i64 = gbh_run(runner, ra, envp, ofd, ofd) 182 sys_close(ofd) 183 184 print(" run rc=" as *u8) 185 print_i64(rc) 186 if rc > 128 { print(" (SIGNAL-DEATH: crashed gate can never read GREEN)" as *u8) } 187 print("\n" as *u8) 188 189 // extract the numeric telemetry vector from the captured output 190 let buf: *u8 = sys_mmap(GBH_MAGIC_1048576 + 16) 191 let blen: i64 = gbh_read(outp, buf, GBH_MAGIC_1048576) 192 if blen < 0 { 193 print(" [RED] no captured output (evidence missing -> no verdict can be banked)\n" as *u8) 194 sys_exit(1) 195 return 1 196 } 197 let vals: *i64 = sys_mmap(8 * GBH_MAX_VALS) as *i64 198 let count: i64 = hg_parse_ints(buf, blen, vals, GBH_MAX_VALS) 199 var stored: i64 = count 200 if stored > GBH_MAX_VALS { stored = GBH_MAX_VALS } 201 print(" telemetry ints=" as *u8) 202 print_i64(count) 203 print(" (stored " as *u8) 204 print_i64(stored) 205 print(") bytes=" as *u8) 206 print_i64(blen) 207 print("\n" as *u8) 208 209 // load / capture / guard the baseline 210 let banked: *i64 = sys_mmap(8 * (GBH_MAX_VALS + 8)) as *i64 211 let bn: i64 = hg_baseline_load(ledger, banked, GBH_MAX_VALS + 2) 212 213 if bn < 0 { 214 // CAPTURE MODE -- but NEVER bank a broken state as the standard (liar-kill) 215 if rc != 0 { 216 // EVIDENCE-GROUNDED refusal class (from the captured lane output, not guessed from rc -- 217 // rc=4 could be a no-main LIBRARY failing to assemble, NOT a broken gate; conflating them 218 // would be a FALSE FINDING): BUILD-COMPILE-FAIL / BUILD-ASM-FAIL(lib?) / NOT-FOUND / 219 // GATE-CRASH (ran, died to a signal) / GATE-RED (ran, failed honestly). 220 var cls: i64 = ("GATE-RED" as *u8) as i64 221 if rc > 128 { cls = ("GATE-CRASH" as *u8) as i64 } 222 if gbh_has(buf, blen, "COMPILE-FAIL" as *u8) == 1 { cls = ("BUILD-COMPILE-FAIL" as *u8) as i64 } 223 if gbh_has(buf, blen, "NXASM-FAIL" as *u8) == 1 { cls = ("BUILD-ASM-FAIL-LIB?" as *u8) as i64 } 224 if gbh_has(buf, blen, "NXASM-CRASHED" as *u8) == 1 { cls = ("BUILD-ASM-CRASH" as *u8) as i64 } 225 if gbh_has(buf, blen, "SOURCE-NOT-FOUND" as *u8) == 1 { cls = ("NOT-FOUND" as *u8) as i64 } 226 // env-dependent gates (live creds/secrets absent) are QUARANTINED, not "broken" -- calling an 227 // un-provisioned live gate broken would be a false finding (proven: nx_acme_dns01_propagation_gate) 228 if gbh_has(buf, blen, "creds read FAIL" as *u8) == 1 { cls = ("ENV-MISSING-CREDS" as *u8) as i64 } 229 if gbh_has(buf, blen, "nxsecret" as *u8) == 1 { cls = ("ENV-MISSING-CREDS" as *u8) as i64 } 230 print(" [RED] first run rc!=0 class=" as *u8) 231 print(cls as *u8) 232 print(" -> REFUSING to capture a broken state as baseline\n" as *u8) 233 // bank the refusal marker so sweeps skip known cases (a later successful capture writes the 234 // real .tsv, which SUPERSEDES the marker -- no stale-lie path, no unlink needed) 235 let mpath: *u8 = sys_mmap(512) 236 var mo: i64 = 0 237 mo = gbh_cat(mpath, mo, ledger) 238 mo = gbh_cat(mpath, mo, ".refused" as *u8) 239 mpath[mo] = 0 as u8 240 let mtmp: *u8 = sys_mmap(512) 241 mo = 0 242 mo = gbh_cat(mtmp, mo, mpath) 243 mo = gbh_cat(mtmp, mo, ".tmp" as *u8) 244 mtmp[mo] = 0 as u8 245 let mfd: i64 = sys_openat_wr(mtmp, 0x1a4) 246 if mfd >= 0 { 247 let ml: *u8 = sys_mmap(256) 248 var o2: i64 = 0 249 o2 = gbh_cat(ml, o2, cls as *u8) 250 ml[o2] = 9 as u8 251 o2 = o2 + 1 252 o2 = gbh_cat(ml, o2, "rc" as *u8) 253 ml[o2] = 9 as u8 254 o2 = o2 + 1 255 o2 = gbh_num(ml, o2, rc) 256 ml[o2] = 10 as u8 257 o2 = o2 + 1 258 sys_write(mfd, ml, o2) 259 sys_close(mfd) 260 sys_renameat(mtmp, mpath) 261 print(" refusal marker banked -> " as *u8) 262 print(mpath) 263 print("\n" as *u8) 264 } 265 sys_exit(1) 266 return 1 267 } 268 gbh_bank(ledger, ltmp, rc, count, vals, stored) 269 print(" BASELINE CAPTURED -> " as *u8) 270 print(ledger) 271 print("\n=== verdict: GREEN (rc=0; baseline banked; future runs are guarded) ===\n" as *u8) 272 sys_exit(0) 273 return 0 274 } 275 276 // GUARD MODE 277 let brc: i64 = banked[0] 278 let bcount: i64 = banked[1] 279 var red: i64 = 0 280 if rc != brc { red = 1 } 281 print(" guard: rc=" as *u8) 282 print_i64(rc) 283 print(" vs banked rc=" as *u8) 284 print_i64(brc) 285 if rc == brc { print(" MATCH\n" as *u8) } else { print(" MISMATCH -> RED\n" as *u8) } 286 287 // drift sensor (surfaced, not judged): which telemetry positions moved 288 var bstored: i64 = bcount 289 if bstored > GBH_MAX_VALS { bstored = GBH_MAX_VALS } 290 var ncmp: i64 = stored 291 if bstored < ncmp { ncmp = bstored } 292 var ndiff: i64 = 0 293 var shown: i64 = 0 294 var i: i64 = 0 295 while i < ncmp { 296 if vals[i] != banked[2+i] { 297 ndiff = ndiff + 1 298 if shown < 5 { 299 print(" drift[" as *u8) 300 print_i64(i) 301 print("] " as *u8) 302 print_i64(banked[2+i]) 303 print(" -> " as *u8) 304 print_i64(vals[i]) 305 print("\n" as *u8) 306 shown = shown + 1 307 } 308 } 309 i = i + 1 310 } 311 if count != bcount { 312 print(" drift: telemetry count " as *u8) 313 print_i64(bcount) 314 print(" -> " as *u8) 315 print_i64(count) 316 print("\n" as *u8) 317 ndiff = ndiff + 1 318 } 319 if ndiff == 0 { print(" telemetry STABLE (bit-identical int vector)\n" as *u8) } 320 if ndiff > 0 { 321 print(" telemetry DRIFT positions=" as *u8) 322 print_i64(ndiff) 323 print(" (informational; promote to a directional per-gate spec to judge)\n" as *u8) 324 } 325 326 // explicit rebase (refused on a red run -- never bank broken) 327 if rebase == 1 { 328 if rc == 0 { 329 gbh_bank(ledger, ltmp, rc, count, vals, stored) 330 print(" REBASED baseline from current run (operator-explicit)\n" as *u8) 331 } else { 332 print(" [refused] --rebase with rc!=0 (never bank a broken state)\n" as *u8) 333 } 334 } 335 336 if red == 0 { 337 print("=== verdict: GREEN (exit invariant held; drift surfaced above) ===\n" as *u8) 338 sys_exit(0) 339 return 0 340 } 341 print("=== verdict: RED (exit-code regression vs banked baseline) ===\n" as *u8) 342 sys_exit(1) 343 return 1 344}