code wiki / (root) / nx_deploy_guard.nx

nx_deploy_guard.nx source

↩ module page · 54 lines · 2990 B

1// nx_deploy_guard.nx -- ENFORCED adversarial deploy gate (census gap #1, the ratchet that makes "adversarial 2// verification is REQUIRED" enforced, not advisory). NO mutating control-plane action (selfswap/deploy/restart/etc.) 3// runs unless the adversarial CI is GREEN: it runs nx_adversarial_ci FAIL-CLOSED, and ONLY on GREEN does it invoke 4// nx_aw_hostctl <sub>. A RED suite -> DEPLOY BLOCKED, nothing changes. Composes _offc/nx_adversarial_ci.elf + 5// _offc/nx_aw_hostctl.elf. Usage: nx_deploy_guard <nx_aw_hostctl-sub> [arg] (e.g. nx_deploy_guard selfswap). license_tier: ORIGINAL 6import "nx_syscalls.nx" 7import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 8 9const DG_CI: *u8 = "_offc/nx_adversarial_ci.elf" as *u8 10const DG_HOSTCTL: *u8 = "_offc/nx_aw_hostctl.elf" as *u8 11 12func dg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 13// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 14// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 15// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 16// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 17func dg_putn(v: i64) -> i64 { nxi_out(v); return 0 } 18 19// fork+exec path [a1] [a2], INHERIT stdout/stderr (visible), wait, return WEXITSTATUS (128+sig on a crash). 20func dg_run(path: *u8, a1: *u8, a2: *u8) -> i64 { 21 let pid: i64 = sys_fork() 22 if pid == 0 { 23 let argv: *i64 = sys_mmap(32) as *i64 24 argv[0] = path as i64; var ai: i64 = 1 25 if (a1 as i64) != 0 { argv[ai] = a1 as i64; ai = ai + 1 } 26 if (a2 as i64) != 0 { argv[ai] = a2 as i64; ai = ai + 1 } 27 argv[ai] = 0 28 let envp: *i64 = sys_mmap(16) as *i64; envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 29 sys_execve(path, argv, envp) 30 sys_exit(127) 31 } 32 let st: *i64 = sys_mmap(16) as *i64 33 sys_wait4(pid, st, 0) 34 let sig: i64 = st[0] & 0x7f 35 if sig != 0 { return 128 + sig } 36 return (st[0] >> 8) & 0xff 37} 38 39func main(argc: i64, argv: *i64) -> i64 { 40 if argc < 2 { dg_puts("usage: nx_deploy_guard <nx_aw_hostctl-sub> [arg] (e.g. selfswap) -- CI-gated deploy\n" as *u8); sys_exit(2); return 2 } 41 let sub: *u8 = argv[1] as *u8 42 var a2: *u8 = 0 as *u8 43 if argc >= 3 { a2 = argv[2] as *u8 } 44 dg_puts("=== nx_deploy_guard: the adversarial CI (fail-closed) MUST pass before '" as *u8); dg_puts(sub); dg_puts("' ===\n" as *u8) 45 let ci: i64 = dg_run(DG_CI, 0 as *u8, 0 as *u8) 46 if ci != 0 { 47 dg_puts("\nDEPLOY BLOCKED: adversarial CI RED (exit=" as *u8); dg_putn(ci); dg_puts(") -- NOTHING deployed. Fix the RED gate first.\n" as *u8) 48 sys_exit(1); return 1 49 } 50 dg_puts("\nadversarial CI GREEN -> proceeding: nx_aw_hostctl " as *u8); dg_puts(sub); dg_puts("\n" as *u8) 51 let rc: i64 = dg_run(DG_HOSTCTL, sub, a2) 52 sys_exit(rc) 53 return rc 54}