code wiki / (root) / nx_adversarial_ci.nx

nx_adversarial_ci.nx source

↩ module page · 70 lines · 3825 B

1// nx_adversarial_ci.nx -- CONTINUOUS ADVERSARIAL CI (census gap #1): runs the adversarial gate suite (data-driven 2// from knowledge/adversarial_gates.conf, one gate module-name per line) via the sovereign build+run, FAIL-CLOSED: 3// ANY gate RED (nonzero exit, incl. a SEGV -> 128+sig, never a silent pass) -> CI RED. WIRE before selfswap in the 4// deploy plane so nothing ships unless the adversarial suite is GREEN. Composes _offc/nx_sov_build_run.elf. license_tier: ORIGINAL 5import "nx_syscalls.nx" 6import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 7 8const CI_CONF: *u8 = "knowledge/adversarial_gates.conf" as *u8 9const CI_RUNNER: *u8 = "_offc/nx_sov_build_run.elf" as *u8 10 11func ci_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 12// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 13// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 14// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 15// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 16func ci_putn(v: i64) -> i64 { nxi_out(v); return 0 } 17 18// fork+exec nx_sov_build_run <gate>; child output -> /dev/null; WEXITSTATUS (0 = GREEN), or 128+signal on a crash. 19func ci_run_gate(gate: *u8) -> i64 { 20 let pid: i64 = sys_fork() 21 if pid == 0 { 22 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 420) 23 if dn >= 0 { sys_dup3(dn, 1, 0); sys_dup3(dn, 2, 0) } 24 let argv: *i64 = sys_mmap(32) as *i64 25 argv[0] = CI_RUNNER as i64; argv[1] = gate as i64; argv[2] = 0 26 let envp: *i64 = sys_mmap(16) as *i64; envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 27 sys_execve(CI_RUNNER, argv, envp) 28 sys_exit(127) 29 } 30 let st: *i64 = sys_mmap(16) as *i64 31 sys_wait4(pid, st, 0) 32 let sig: i64 = st[0] & 0x7f 33 if sig != 0 { return 128 + sig } 34 return (st[0] >> 8) & 0xff 35} 36 37func main() -> i64 { 38 ci_puts("=== nx_adversarial_ci: run the adversarial gate suite FAIL-CLOSED (gate before deploy/selfswap) ===\n" as *u8) 39 let szp: *i64 = sys_mmap(16) as *i64 40 let buf: *u8 = sys_read_file(CI_CONF, szp) 41 if (buf as i64) == 0 { ci_puts("FATAL: no knowledge/adversarial_gates.conf -> fail-closed: RED\n" as *u8); sys_exit(1); return 1 } 42 let n: i64 = szp[0] 43 var pass: i64 = 0; var red: i64 = 0; var tot: i64 = 0 44 let gname: *u8 = sys_mmap(256) 45 var ls: i64 = 0; var i: i64 = 0 46 while i <= n { 47 var eol: i64 = 0 48 if i == n { eol = 1 } else { if buf[i] == (10 as u8) { eol = 1 } } 49 if eol == 1 { 50 var ll: i64 = i - ls 51 if ll > 0 { if buf[ls + ll - 1] == (13 as u8) { ll = ll - 1 } } // CRLF-safe 52 if ll > 0 { if buf[ls] != (35 as u8) { // skip '#' comments 53 var c: i64 = 0; while c < ll { gname[c] = buf[ls + c]; c = c + 1 } gname[ll] = 0 as u8 54 tot = tot + 1 55 ci_puts(" " as *u8); ci_puts(gname); ci_puts(" ... " as *u8) 56 let rc: i64 = ci_run_gate(gname) 57 if rc == 0 { pass = pass + 1; ci_puts("GREEN\n" as *u8) } else { red = red + 1; ci_puts("RED (exit=" as *u8); ci_putn(rc); ci_puts(")\n" as *u8) } 58 } } 59 ls = i + 1 60 } 61 i = i + 1 62 } 63 ci_puts("\n=== adversarial CI: " as *u8); ci_putn(pass); ci_puts("/" as *u8); ci_putn(tot); ci_puts(" gates GREEN ===\n" as *u8) 64 if red == 0 { if tot > 0 { 65 ci_puts("ADVERSARIAL-CI GREEN -- the adversarial suite passed; safe to deploy.\n" as *u8) 66 sys_exit(0); return 0 67 } } 68 ci_puts("ADVERSARIAL-CI RED -- DO NOT DEPLOY (fail-closed; a gate is RED or the suite is empty).\n" as *u8) 69 sys_exit(1); return 1 70}