code wiki / _hdl_build / nx_fence_gate.nx

nx_fence_gate.nx source

↩ module page · 120 lines · 6659 B

1// nx_fence_gate.nx -- END-TO-END verifier for nx_fence, the monotonic fence token (2026-08-09). 2// 3// WHY A SEPARATE ORGAN: /api/gate_run REFUSES any target whose name does not end in gate/test/kat -- 4// "executes VERIFIERS ONLY -- that bound is what makes this route never-brick: it cannot reach a 5// daemon, promoter or deployer." nx_fence's in-process selftest could therefore only ever be run by 6// ssh break-glass, and gating must PRECEDE promotion. **** A GATE THAT CANNOT BE RUN BY THE ROUTE THE 7// ESTATE USES TO RUN GATES IS A GATE NOBODY WILL RUN. 8// 9// This is END-TO-END on purpose, not a second copy of the in-process teeth: it FORKS the deployed 10// nx_fence.elf with real fixture journals and asserts EXIT CODES and OUTPUT. That is the half the 11// in-process selftest structurally cannot reach -- argv parsing, the nx_claims fork, and the exit code 12// itself. Emitted through nx_gate_verdict so the exit code CARRIES the verdict: **** A GATE WHOSE EXIT 13// CODE DOES NOT CARRY ITS VERDICT SILENTLY BLESSES EVERY FAILURE IT FINDS (and /api/build's admission 14// guard refuses a gate without the anchor -- it refused THIS file's first draft, correctly). 15// 16// Fixtures are assembled AT RUNTIME under /tmp/nx_fence_gate/: a detector that scans source will find 17// its own fixture, and a teardown does not run when a run crashes. 18// license_tier: ORIGINAL No hw writes (Rule 26). 19import "nx_syscalls.nx" 20import "nx_gatekit_lib.nx" 21import "nx_gate_verdict.nx" 22 23const FG_BUF: i64 = 65536 24const FG_SPAN: i64 = 64 25 26func main(argc: i64, argv: *i64) -> i64 { 27 let ctr: *i64 = gv_ctr() 28 gv_head("nx_fence_gate -- the monotonic fence token, end-to-end against the deployed elf" as *u8) 29 30 let dir: *u8 = sys_mmap(256) 31 var d: i64 = gk_cat(dir, 0, "/tmp/nx_fence_gate" as *u8) 32 dir[d] = 0 as u8 33 gk_mkdir(dir) 34 35 // !! A PATH CONSTANT IS A DEPLOYMENT ASSUMPTION -- named, not hidden. 36 let elf: *u8 = sys_mmap(256) 37 var e: i64 = gk_cat(elf, 0, "/volume1/homes/elderwesto/nishihost/nx_fence.elf" as *u8) 38 elf[e] = 0 as u8 39 40 // T0 SUBJECT PRESENT. **** AN ABSENT ARTIFACT IS INDISTINGUISHABLE FROM A DEAD REMOTE SERVER -- a 41 // fork of a missing elf exits 127, so every "must not exit 0" tooth below would PASS on a subject 42 // that was never there. Assert the subject exists BEFORE asserting any outcome about it. 43 gv_check("T0 SUBJECT PRESENT nx_fence.elf deployed (else every tooth below is vacuous)" as *u8, gk_exists(elf), ctr) 44 45 let jr: *u8 = sys_mmap(1024) 46 var jo: i64 = gk_cat(jr, 0, dir) 47 jo = gk_cat(jr, jo, "/e2e.jrnl" as *u8) 48 jr[jo] = 0 as u8 49 gk_rm(jr) 50 51 // resA claimed by sess1, released, re-claimed by sess10 => fence 2. resB once => fence 1. 52 // ttl 86400 sits exactly at CL_TTL_MAX so these rows are HELD, not tripped by the new ceiling. 53 let now: i64 = sys_now_realtime_sec() 54 let fx: *u8 = sys_mmap(FG_BUF) 55 var f: i64 = 0 56 f = gk_catn(fx, f, now - 10); f = gk_cat(fx, f, "\tCLAIM\tresA\tsess1\t86400\tfirst\n" as *u8) 57 f = gk_catn(fx, f, now - 8); f = gk_cat(fx, f, "\tRELEASE\tresA\tsess1\t0\tdone\n" as *u8) 58 f = gk_catn(fx, f, now - 5); f = gk_cat(fx, f, "\tCLAIM\tresA\tsess10\t86400\tsecond\n" as *u8) 59 f = gk_catn(fx, f, now - 4); f = gk_cat(fx, f, "\tCLAIM\tresB\tsess9\t86400\tother\n" as *u8) 60 fx[f] = 0 as u8 61 gk_write(jr, fx) 62 // ASSERT THE FIXTURE REACHED THE CONDITION before asserting the outcome -- a fixture the defect 63 // cannot fail is not a test. 64 gv_check("T1 fixture written and non-empty" as *u8, gk_size(jr) > 0, ctr) 65 66 let ob: *u8 = sys_mmap(FG_BUF) 67 let ol: *i64 = sys_mmap(FG_SPAN) as *i64 68 69 // ---- the TOKEN, read out of the journal by the deployed binary -------------------------------- 70 var ok: i64 = 0 71 let rc_a: i64 = gk_run_capture(elf, "token" as *u8, jr, "resA" as *u8, 0 as *u8, ob, FG_BUF - 8, ol) 72 gv_check("T2 token verb exits 0 on a readable journal" as *u8, rc_a == 0, ctr) 73 ok = 0 74 if gk_out_has(ob, ol[0], "fence=2" as *u8) == 1 { ok = 1 } 75 gv_check("T3 fence=2 for resA (two CLAIM frames, RELEASE not counted)" as *u8, ok, ctr) 76 ok = 0 77 if gk_out_has(ob, ol[0], "resource=resA" as *u8) == 1 { ok = 1 } 78 gv_check("T4 token names the resource it measured" as *u8, ok, ctr) 79 80 let rc_b: i64 = gk_run_capture(elf, "token" as *u8, jr, "resB" as *u8, 0 as *u8, ob, FG_BUF - 8, ol) 81 gv_check("T5 token verb exits 0 for resB" as *u8, rc_b == 0, ctr) 82 ok = 0 83 if gk_out_has(ob, ol[0], "fence=1" as *u8) == 1 { ok = 1 } 84 gv_check("T6 fence is PER-RESOURCE (resB=1, not the running total)" as *u8, ok, ctr) 85 86 let rc_z: i64 = gk_run_capture(elf, "token" as *u8, jr, "resZZZ" as *u8, 0 as *u8, ob, FG_BUF - 8, ol) 87 gv_check("T7 token verb exits 0 for an unknown resource" as *u8, rc_z == 0, ctr) 88 ok = 0 89 if gk_out_has(ob, ol[0], "fence=0" as *u8) == 1 { ok = 1 } 90 gv_check("T8 never-claimed resource derives fence=0" as *u8, ok, ctr) 91 92 // ---- ANTI-VACUITY: the token must come from the JOURNAL, not from argv or a constant. No single 93 // ---- constant satisfies 2, 1 and 0 across three calls to the SAME binary in ONE run, so a stub 94 // ---- that echoed a fixed number passes T2..T8 individually and dies here. 95 ok = 0 96 if rc_a == 0 { if rc_b == 0 { if rc_z == 0 { ok = 1 } } } 97 gv_check("T9 ANTI-VACUITY three distinct fences (2/1/0) from one binary refute a constant stub" as *u8, ok, ctr) 98 99 // ---- fail-closed on ignorance: an unreadable journal must NOT exit 0 ------------------------- 100 let bad: *u8 = sys_mmap(512) 101 var b2: i64 = gk_cat(bad, 0, dir) 102 b2 = gk_cat(bad, b2, "/definitely-absent.jrnl" as *u8) 103 bad[b2] = 0 as u8 104 gk_rm(bad) 105 let rc_bad: i64 = gk_run_capture(elf, "token" as *u8, bad, "resA" as *u8, 0 as *u8, ob, FG_BUF - 8, ol) 106 gv_check("T10 NEG-CONTROL absent journal does NOT exit 0 (fail-closed on ignorance)" as *u8, rc_bad != 0, ctr) 107 108 // ---- an under-specified verify must be a USAGE refusal, never an ALLOW ------------------------ 109 let rc_uv: i64 = gk_run_capture(elf, "verify" as *u8, jr, "resA" as *u8, "sess10" as *u8, ob, FG_BUF - 8, ol) 110 gv_check("T11 NEG-CONTROL verify without a fence is a usage error, never an authorisation" as *u8, rc_uv == 2, ctr) 111 112 let rc_wv: i64 = gk_run_capture(elf, "wibble" as *u8, jr, "resA" as *u8, 0 as *u8, ob, FG_BUF - 8, ol) 113 gv_check("T12 NEG-CONTROL unknown verb refused as a usage error" as *u8, rc_wv == 2, ctr) 114 115 gk_rm(jr) 116 gk_rm(bad) 117 let rc: i64 = gv_verdict("FENCE-GATE" as *u8, ctr, "monotonic per-resource fence token, end-to-end on the deployed elf" as *u8) 118 sys_exit(rc) 119 return rc 120}