code wiki / (root) / nx_state_spool_gate.nx

nx_state_spool_gate.nx source

↩ module page · 131 lines · 6304 B

1// nx_state_spool_gate.nx -- liar-killed GATE for the store-and-forward state spool (CR-R1a). 2// Proves NAS-first/local-fallback semantics OFFLINE via the deterministic fixture transport 3// (nx_spool_txfix: argv[1] contains "ok" -> delivered, else fail): spooled lines persist; a 4// working transport drains them; a FAILING transport keeps them (offline = NOTHING LOST -- the 5// negative control); partial failure keeps exactly the failed lines in order without blocking 6// later lines; a MISSING transport binary keeps everything (fail-safe, never fabricates 7// delivery); empty spool is a no-op. usage: nx_state_spool_gate [txfix_elf] 8// license_tier: ORIGINAL expect_exit: 0 9import "nx_syscalls.nx" 10import "nx_state_spool_core.nx" 11import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc); explicit, not leaned on transitively 12 13func t_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 14 15// MIGRATED to the shared emitter 2026-08-06 (debt 1785516350). The old body mmapped a 32-byte 16// scratch and never freed it -- 4096B leaked per call at page granularity. nxi_out runs the SAME 17// ccz_cat_num digits through a shim that always frees, so emitted bytes are identical. 18func t_putn(v: i64) -> i64 { nxi_out(v); return 0 } 19 20func t_check(name: *u8, got: i64, want: i64, passp: *i64) -> i64 { 21 t_puts("T " as *u8) 22 t_puts(name) 23 t_puts(" got=" as *u8) 24 t_putn(got) 25 t_puts(" want=" as *u8) 26 t_putn(want) 27 if got == want { t_puts(" PASS\n" as *u8); passp[0] = passp[0] + 1 } else { t_puts(" FAIL\n" as *u8) } 28 return 0 29} 30 31// count occurrences of needle in the spool file (bounded read) 32func t_count(path: *u8, needle: *u8) -> i64 { 33 let buf: *u8 = sys_mmap(65536) 34 let n: i64 = ccz_read(path, buf, 65535) 35 if n <= 0 { return 0 } 36 let nl: i64 = ccz_slen(needle) 37 var cnt: i64 = 0 38 var i: i64 = 0 39 while i + nl <= n { 40 var k: i64 = 0 41 var ok: i64 = 1 42 while k < nl { if buf[i+k] != needle[k] { ok = 0; k = nl } k = k + 1 } 43 if ok == 1 { cnt = cnt + 1; i = i + nl } else { i = i + 1 } 44 } 45 return cnt 46} 47 48func main(argc: i64, argv: *i64) -> i64 { 49 // TRANSPORT RESOLUTION (2026-08-06). The default was /tmp/nx_spool_txfix.sov.elf and nothing else 50 // was ever tried. NAS /tmp is mounted noexec, so the fixture could never be executed: ALL FIVE 51 // drain tests failed while the two that never exec it passed. The gate read 2/7 RED for a purely 52 // environmental reason, and that is indistinguishable from a real regression unless you notice the 53 // failures partition EXACTLY along "does this test exec the transport". Probe an executable 54 // location first and PRINT the chosen one, so this gate can never again report the subject as 55 // broken because of its own harness. An explicit argv[1] still wins. 56 var tx: *u8 = "../nx_spool_txfix.elf" as *u8 57 let x0: i64 = sys_openat_rd(tx) 58 if x0 >= 0 { sys_close(x0) } else { 59 tx = "./nx_spool_txfix.elf" as *u8 60 let x1: i64 = sys_openat_rd(tx) 61 if x1 >= 0 { sys_close(x1) } else { tx = "/tmp/nx_spool_txfix.sov.elf" as *u8 } 62 } 63 if argc >= 2 { tx = argv[1] as *u8 } 64 t_puts("SSP-GATE transport=" as *u8); t_puts(tx); t_puts("\n" as *u8) 65 let pass: *i64 = sys_mmap(16) as *i64 66 pass[0] = 0 67 let sp: *u8 = "/tmp/ssp_gate.spool" as *u8 68 let lk: *u8 = "/tmp/ssp_gate.spool.lock" as *u8 69 let tp: *u8 = "/tmp/ssp_gate.spool.tmp" as *u8 70 let sent: *i64 = sys_mmap(16) as *i64 71 let kept: *i64 = sys_mmap(16) as *i64 72 73 // reset any prior fixture state (drain-to-empty with a spool that may not exist is T6's job; 74 // here just truncate) 75 let rfd: i64 = sys_openat_wr(sp, 420) 76 if rfd >= 0 { sys_close(rfd) } 77 78 // T1 spool persists lines 79 ssp_spool(sp, lk, "beat ok alpha" as *u8) 80 ssp_spool(sp, lk, "beat ok bravo" as *u8) 81 t_check("spool-persists" as *u8, t_count(sp, "beat ok " as *u8), 2, pass) 82 83 // T2 drain with working transport -> all delivered, spool empty 84 ssp_drain(sp, lk, tp, tx, sent, kept) 85 var ok2: i64 = 0 86 if sent[0] == 2 { if kept[0] == 0 { if t_count(sp, "beat" as *u8) == 0 { ok2 = 1 } } } 87 t_check("drain-delivers-all" as *u8, ok2, 1, pass) 88 89 // T3 NEG-CONTROL: failing transport -> nothing lost (offline is a normal state) 90 ssp_spool(sp, lk, "beat FAIL charlie" as *u8) 91 ssp_drain(sp, lk, tp, tx, sent, kept) 92 var ok3: i64 = 0 93 if sent[0] == 0 { if kept[0] == 1 { if t_count(sp, "FAIL charlie" as *u8) == 1 { ok3 = 1 } } } 94 t_check("negctl-offline-keeps" as *u8, ok3, 1, pass) 95 96 // T4 partial: ok + FAIL + ok -> 2 delivered, exactly the failed one kept 97 ssp_spool(sp, lk, "beat ok delta" as *u8) 98 ssp_spool(sp, lk, "beat ok echo" as *u8) 99 ssp_drain(sp, lk, tp, tx, sent, kept) 100 var ok4: i64 = 0 101 if sent[0] == 2 { if kept[0] == 1 { if t_count(sp, "FAIL charlie" as *u8) == 1 { if t_count(sp, "ok delta" as *u8) == 0 { ok4 = 1 } } } } 102 t_check("partial-drain-order" as *u8, ok4, 1, pass) 103 104 // T5 head-of-line non-blocking: a new deliverable line drains PAST the stuck one 105 ssp_spool(sp, lk, "beat ok foxtrot" as *u8) 106 ssp_drain(sp, lk, tp, tx, sent, kept) 107 var ok5: i64 = 0 108 if sent[0] == 1 { if kept[0] == 1 { if t_count(sp, "FAIL charlie" as *u8) == 1 { ok5 = 1 } } } 109 t_check("head-of-line-nonblocking" as *u8, ok5, 1, pass) 110 111 // T6 missing transport binary -> exec fails (127) -> everything kept (never fabricates delivery) 112 ssp_drain(sp, lk, tp, "/tmp/ssp_gate_no_such_transport.elf" as *u8, sent, kept) 113 var ok6: i64 = 0 114 if sent[0] == 0 { if kept[0] == 1 { if t_count(sp, "FAIL charlie" as *u8) == 1 { ok6 = 1 } } } 115 t_check("missing-transport-failsafe" as *u8, ok6, 1, pass) 116 117 // T7 empty spool drain = clean no-op (drain the kept line away first with a fresh truncate) 118 let zfd: i64 = sys_openat_wr(sp, 420) 119 if zfd >= 0 { sys_close(zfd) } 120 ssp_drain(sp, lk, tp, tx, sent, kept) 121 var ok7: i64 = 0 122 if sent[0] == 0 { if kept[0] == 0 { ok7 = 1 } } 123 t_check("empty-spool-noop" as *u8, ok7, 1, pass) 124 125 t_puts("SSP-GATE pass=" as *u8) 126 t_putn(pass[0]) 127 t_puts("/7 verdict=" as *u8) 128 if pass[0] == 7 { t_puts("GREEN\n" as *u8); return 0 } 129 t_puts("RED\n" as *u8) 130 return 1 131}