code wiki / _hdl_build / nx_gate_roster_gate.nx

nx_gate_roster_gate.nx source

↩ module page · 249 lines · 15487 B

1// nx_gate_roster_gate.nx -- END-TO-END GATE for nx_gate_roster_run's ADMIT contract (journal -> roster conf). 2// 3// WHY: the roster is the estate's wiring vehicle for deployed-dark gates (lane B, 2026-08-18: 602 gates 4// admitted from trial journals). If `admit` mis-reads a journal, gates are wired blind or silently dropped 5// -- so the bridge itself needs teeth. Every tooth is a FIXTURE built at runtime under /tmp/<gate>/ (a gate 6// must never share its fixture with a production beat), fed to the DEPLOYED runner (`_offc` twin first, 7// then the estate root, resolved once and printed), and judged on the CONF/SUSPECT files it wrote and the 8// receipt it printed. gv_verdict base class: exit carries the verdict, teeth counted by construction. 9// 10// TEETH 11// T1 admit: partition line reconciles (admitted+already+suspects+rejected == gates) 12// T2 latest-row-wins: a gate whose rows go RED then GREEN is ADMITTED 13// T3 suspect: a GREEN row with ms >= deadline is written to the suspect list and NOT admitted 14// T4 additive merge: a gate already in the conf is counted already_in_conf and not duplicated 15// T5 reject: RED / ABSENT / TIMEOUT latest rows are rejected (absent from conf and suspects) 16// T6 neg-control: deadline 0 is REFUSED (rc 2) and touches neither file 17// T7 trial verb: a list naming a gate with no ./<name>.elf journals ABSENT exit=127 (never a pass) 18// T8 BITE: T3 fires on the at-deadline row and stays silent on a fast GREEN row 19// T9 argless mutates NOTHING: rc 2, and the production journal AND the cron-watched heartbeat are 20// byte-unchanged across the call. Asserted as STATE, not as a message -- a perfect usage string 21// proves nothing about whether the beat also ran, and this organ's argless default WAS the full 22// production beat until 2026-08-20, which is what made it unprovable by every argless probe 23// T10 a NAMED beat still does the real pass on a fixture roster (the fix must not disarm the beat) 24// T11 neg-control: that fixture beat stamps BESIDE its own journal and CANNOT forge the production 25// heartbeat. GRR_STAMP was a CONSTANT path, so any caller passing a fixture conf wrote it -- a 26// liveness signal any caller can write is a dead-man's switch any caller can hold down 27// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 28import "nx_gatekit_lib.nx" 29import "nx_gate_verdict.nx" 30 31const RG_DIR: *u8 = "/tmp/nx_gate_roster_gate/" 32const RG_JRNL: *u8 = "/tmp/nx_gate_roster_gate/trial.jrnl" 33const RG_CONF: *u8 = "/tmp/nx_gate_roster_gate/roster.conf" 34const RG_SUSP: *u8 = "/tmp/nx_gate_roster_gate/roster.conf.suspect" 35const RG_LIST: *u8 = "/tmp/nx_gate_roster_gate/trial.list" 36const RG_TJRNL: *u8 = "/tmp/nx_gate_roster_gate/trial2.jrnl" 37const RG_ELF1: *u8 = "_offc/nx_gate_roster_run.elf" 38const RG_ELF2: *u8 = "nx_gate_roster_run.elf" 39const RG_CAP: i64 = 65536 40const RG_DEADLINE: *u8 = "60000" 41const RG_MS_TRIAL: *u8 = "5000" 42// ARGLESS / BEAT teeth (2026-08-20). The runner's argless default USED TO BE the full production beat, 43// and its heartbeat path was a CONSTANT -- so any caller passing a fixture conf forged the cron-watched 44// production liveness signal. These are the production artifacts those teeth assert are UNTOUCHED, and 45// they are asserted as STATE (bytes), never as a message: a usage string proves nothing about whether 46// the beat also ran. 47const RG_PROD_JRNL: *u8 = "knowledge/status/gateroster.jrnl" 48const RG_PROD_STAMP: *u8 = "knowledge/status/gateroster.stamp" 49const RG_BCONF: *u8 = "/tmp/nx_gate_roster_gate/beat.conf" 50const RG_BJRNL: *u8 = "/tmp/nx_gate_roster_gate/beat.jrnl" 51const RG_BSTAMP: *u8 = "/tmp/nx_gate_roster_gate/beat.jrnl.stamp" 52const RG_BEAT_ROW: *u8 = "nx_definitely_absent_fixture_gate" 53const RG_ARGLESS_RC: i64 = 2 54// ORDER + BUDGET teeth (2026-09-18): the clock kills any job at its dispatch deadline, and a beat cut there 55// starved the conf's tail for four days. The fixture's conf lists the gates in the OPPOSITE of their staleness 56// order, so a runner that kept conf order would run the wrong gate first; its directive sets the kill bound 57// EQUAL to the per-gate deadline (a pass budget of zero), so exactly one gate may start per beat. 58const RG_LCONF: *u8 = "/tmp/nx_gate_roster_gate/lru.conf" 59const RG_LJRNL: *u8 = "/tmp/nx_gate_roster_gate/lru.jrnl" 60const RG_LSTAMP: *u8 = "/tmp/nx_gate_roster_gate/lru.jrnl.stamp" 61const RG_NCONF: *u8 = "/tmp/nx_gate_roster_gate/nobudget.conf" 62const RG_NJRNL: *u8 = "/tmp/nx_gate_roster_gate/nobudget.jrnl" 63const RG_NSTAMP: *u8 = "/tmp/nx_gate_roster_gate/nobudget.jrnl.stamp" 64 65func rg_has_line(path: *u8, name: *u8) -> i64 { 66 // a roster/suspect row is the bare name on its own line: match "<name>\n" after a newline or at start 67 let buf: *u8 = sys_mmap(RG_CAP) 68 let n: i64 = gk_read(path, buf, RG_CAP) 69 if n <= 0 { return 0 } 70 let l: i64 = gk_len(name) 71 var i: i64 = 0 72 while i + l <= n { 73 var at_start: i64 = 0 74 if i == 0 { at_start = 1 } 75 if i > 0 { if buf[i - 1] == (10 as u8) { at_start = 1 } } 76 if at_start == 1 { 77 var k: i64 = 0 78 var eq: i64 = 1 79 while k < l { if buf[i + k] != name[k] { eq = 0; k = l } else { k = k + 1 } } 80 if eq == 1 { 81 var endok: i64 = 0 82 if i + l == n { endok = 1 } 83 if i + l < n { if buf[i + l] == (10 as u8) { endok = 1 } } 84 if endok == 1 { return 1 } 85 } 86 } 87 i = i + 1 88 } 89 return 0 90} 91 92func main() -> i64 { 93 let ctr: *i64 = gv_ctr() 94 gv_head("nx_gate_roster_gate -- the journal->roster bridge must admit, suspect and reject exactly as declared" as *u8) 95 // resolve the deployed runner ONCE and say which 96 var elf: *u8 = RG_ELF1 97 if gk_exists(elf) == 0 { elf = RG_ELF2 } 98 if gv_need("deployed nx_gate_roster_run (_offc/ or estate root)" as *u8, gk_exists(elf), ctr) == 0 { 99 return gv_verdict("gate_roster" as *u8, ctr, "no deployed runner to drive" as *u8) 100 } 101 let m: *u8 = sys_mmap(4096) 102 var mo: i64 = gk_cat(m, 0, " runner=" as *u8) 103 mo = gk_cat(m, mo, elf) 104 mo = gk_cat(m, mo, "\n" as *u8) 105 gk_say(m, mo) 106 107 // ---- fixture: a journal with every class the bridge must classify ---- 108 gk_mkdir(RG_DIR) 109 gk_rm(RG_CONF) 110 gk_rm(RG_SUSP) 111 gk_write(RG_JRNL, "100\ttrial\tg_fast\tGREEN\texit=0\tms=5\n101\ttrial\tg_flip\tRED\texit=1\tms=2\n102\ttrial\tg_slow\tGREEN\texit=0\tms=60443\n103\ttrial\tg_skip\tSKIP\texit=3\tms=1\n104\ttrial\tg_flip\tGREEN\texit=0\tms=9\n105\ttrial\tg_dead\tTIMEOUT\texit=137\tms=60001\n106\ttrial\tg_gone\tABSENT\texit=127\tms=0\n107\ttrial\tg_red\tRED\texit=1\tms=3\n" as *u8) 112 gk_write(RG_CONF, "; roster fixture\ng_fast\n" as *u8) 113 114 let ob: *u8 = sys_mmap(RG_CAP) 115 let ol: *i64 = sys_mmap(16) as *i64 116 let rc: i64 = gk_run_capture(elf, "admit" as *u8, RG_JRNL, RG_DEADLINE, RG_CONF, ob, RG_CAP, ol) 117 // the runner takes [conf] as argv[4]; gk_run_capture carries 4 args, so the suspect list lands at the 118 // runner's DEFAULT: <conf>.suspect -- a sibling of the fixture conf, i.e. inside /tmp/<gate>/. That 119 // default is part of the contract under test (a fixed production default would make this gate write 120 // into a production artifact, which is exactly the fixture-sharing law this layout obeys). 121 var partition_ok: i64 = 0 122 if gk_out_has(ob, ol[0], "partition RECONCILES" as *u8) == 1 { partition_ok = 1 } 123 var t1: i64 = 0 124 if rc == 0 { if partition_ok == 1 { t1 = 1 } } 125 gv_check("T1 admit exits 0 and its partition line RECONCILES" as *u8, t1, ctr) 126 127 let flip_in: i64 = rg_has_line(RG_CONF, "g_flip" as *u8) 128 gv_check("T2 latest-row-wins: RED-then-GREEN gate is admitted to the conf" as *u8, flip_in, ctr) 129 130 let slow_in_conf: i64 = rg_has_line(RG_CONF, "g_slow" as *u8) 131 let slow_in_susp: i64 = rg_has_line(RG_SUSP, "g_slow" as *u8) 132 var t3: i64 = 0 133 if slow_in_conf == 0 { if slow_in_susp == 1 { t3 = 1 } } 134 gv_check("T3 suspect: at-deadline GREEN goes to the suspect list, not the conf" as *u8, t3, ctr) 135 136 var t4: i64 = 0 137 if gk_out_has(ob, ol[0], "already_in_conf=1" as *u8) == 1 { t4 = 1 } 138 let cnt_fast: i64 = gk_count(RG_CONF, "g_fast" as *u8) 139 if cnt_fast != 1 { t4 = 0 } 140 gv_check("T4 additive merge: the pre-existing row is counted already_in_conf and appears once" as *u8, t4, ctr) 141 142 var t5: i64 = 1 143 if rg_has_line(RG_CONF, "g_dead" as *u8) == 1 { t5 = 0 } 144 if rg_has_line(RG_CONF, "g_gone" as *u8) == 1 { t5 = 0 } 145 if rg_has_line(RG_CONF, "g_red" as *u8) == 1 { t5 = 0 } 146 if rg_has_line(RG_SUSP, "g_red" as *u8) == 1 { t5 = 0 } 147 if gk_out_has(ob, ol[0], "rejected=3" as *u8) == 0 { t5 = 0 } 148 gv_check("T5 reject: TIMEOUT/ABSENT/RED latest rows are in neither file and rejected=3" as *u8, t5, ctr) 149 150 // neg-control: deadline 0 refuses and writes nothing 151 let sz_before: i64 = gk_size(RG_CONF) 152 let ob2: *u8 = sys_mmap(RG_CAP) 153 let ol2: *i64 = sys_mmap(16) as *i64 154 let rc0: i64 = gk_run_capture(elf, "admit" as *u8, RG_JRNL, "0" as *u8, RG_CONF, ob2, RG_CAP, ol2) 155 var t6: i64 = 0 156 if rc0 == 2 { if gk_size(RG_CONF) == sz_before { t6 = 1 } } 157 gv_check("T6 neg-control: deadline 0 is REFUSED (rc 2) and the conf is untouched" as *u8, t6, ctr) 158 159 // trial verb on a list naming a gate that has no binary -> ABSENT exit=127 160 gk_write(RG_LIST, "; trial fixture\nnx_definitely_absent_fixture_gate\n" as *u8) 161 gk_rm(RG_TJRNL) 162 let ob3: *u8 = sys_mmap(RG_CAP) 163 let ol3: *i64 = sys_mmap(16) as *i64 164 gk_run_capture(elf, "trial" as *u8, RG_LIST, RG_TJRNL, RG_MS_TRIAL, ob3, RG_CAP, ol3) 165 var t7: i64 = 0 166 if gk_contains(RG_TJRNL, "nx_definitely_absent_fixture_gate\tABSENT\texit=127" as *u8) == 1 { t7 = 1 } 167 gv_check("T7 trial: a listed gate with no binary journals ABSENT exit=127, never a pass" as *u8, t7, ctr) 168 169 // BITE: the suspect rule fired on g_slow (bad) and did not fire on g_fast (good) 170 var bad: i64 = 0 171 if slow_in_susp == 1 { bad = 1 } 172 var good: i64 = 0 173 if rg_has_line(RG_SUSP, "g_fast" as *u8) == 1 { good = 1 } 174 gv_bite("T8 BITE: suspect rule fires on the at-deadline row, silent on the fast row" as *u8, bad, good, ctr) 175 176 // ---- ARGLESS MUST MUTATE NOTHING (2026-08-20). Asserted as STATE, never as a message: a runner 177 // that printed a perfect usage string and ran the beat anyway would pass a message check. 178 let pj0: i64 = gk_size(RG_PROD_JRNL) 179 let sb0: *u8 = sys_mmap(RG_CAP) 180 let sn0: i64 = gk_read(RG_PROD_STAMP, sb0, RG_CAP) 181 let sb1: *u8 = sys_mmap(RG_CAP) 182 let ob4: *u8 = sys_mmap(RG_CAP) 183 let ol4: *i64 = sys_mmap(16) as *i64 184 let rca: i64 = gk_run_capture(elf, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, ob4, RG_CAP, ol4) 185 let pj1: i64 = gk_size(RG_PROD_JRNL) 186 let sn1: i64 = gk_read(RG_PROD_STAMP, sb1, RG_CAP) 187 var t9: i64 = 0 188 if rca == RG_ARGLESS_RC { if pj1 == pj0 { if sn1 == sn0 { t9 = 1 } } } 189 if t9 == 1 { var q: i64 = 0; while q < sn0 { if sb1[q] != sb0[q] { t9 = 0; q = sn0 } else { q = q + 1 } } } 190 var m9: i64 = gk_cat(m, 0, " T9 argless rc=" as *u8) 191 m9 = gk_catn(m, m9, rca) 192 m9 = gk_cat(m, m9, " prod_journal_bytes " as *u8); m9 = gk_catn(m, m9, pj0) 193 m9 = gk_cat(m, m9, " -> " as *u8); m9 = gk_catn(m, m9, pj1) 194 m9 = gk_cat(m, m9, " prod_stamp_bytes " as *u8); m9 = gk_catn(m, m9, sn0) 195 m9 = gk_cat(m, m9, " -> " as *u8); m9 = gk_catn(m, m9, sn1) 196 m9 = gk_cat(m, m9, "\n" as *u8) 197 gk_say(m, m9) 198 gv_check("T9 argless refuses and mutates NOTHING: the production journal and heartbeat are byte-unchanged" as *u8, t9, ctr) 199 200 // a NAMED beat on a fixture roster still does the real pass, and stamps BESIDE its own journal 201 gk_write(RG_BCONF, "; beat fixture -- one row, deliberately a gate with no binary so the pass is cheap\nnx_definitely_absent_fixture_gate\n" as *u8) 202 gk_rm(RG_BJRNL) 203 gk_rm(RG_BSTAMP) 204 let ob5: *u8 = sys_mmap(RG_CAP) 205 let ol5: *i64 = sys_mmap(16) as *i64 206 let rcb: i64 = gk_run_capture(elf, "beat" as *u8, RG_BCONF, RG_BJRNL, RG_MS_TRIAL, ob5, RG_CAP, ol5) 207 var t10: i64 = 0 208 if gk_contains(RG_BJRNL, "nx_definitely_absent_fixture_gate\tABSENT\texit=127" as *u8) == 1 { if rcb == 1 { t10 = 1 } } 209 gv_check("T10 a NAMED beat still does the real pass: it journals its row and its exit carries the verdict" as *u8, t10, ctr) 210 211 let pj2: i64 = gk_size(RG_PROD_JRNL) 212 let sn2: i64 = gk_read(RG_PROD_STAMP, sb1, RG_CAP) 213 var t11: i64 = 0 214 if gk_exists(RG_BSTAMP) == 1 { if pj2 == pj0 { if sn2 == sn0 { 215 var same: i64 = 1 216 var q2: i64 = 0 217 while q2 < sn0 { if sb1[q2] != sb0[q2] { same = 0; q2 = sn0 } else { q2 = q2 + 1 } } 218 if same == 1 { t11 = 1 } 219 } } } 220 gv_check("T11 neg-control-fixture-beat-cannot-forge-production: it stamps beside its own journal and leaves the cron-watched heartbeat byte-unchanged" as *u8, t11, ctr) 221 222 // ---- ORDER + BUDGET (2026-09-18) ---- 223 gk_write(RG_LCONF, "; lru fixture: conf order is the REVERSE of staleness\n@dispatch_deadline_ms 5000\nnx_rgfx_new_gate\nnx_rgfx_old_gate\nnx_rgfx_never_gate\n" as *u8) 224 gk_write(RG_LJRNL, "100\troster\tnx_rgfx_old_gate\tGREEN\texit=0\tms=1\tran long ago\n900\troster\tnx_rgfx_new_gate\tGREEN\texit=0\tms=1\tran lately\n" as *u8) 225 gk_rm(RG_LSTAMP) 226 gv_check("T12-fixture-reached-the-condition: the stalest gate is LAST in conf order and has no journal row" as *u8, (gk_count(RG_LJRNL, "nx_rgfx_never_gate" as *u8) == 0) as i64, ctr) 227 let ob6: *u8 = sys_mmap(RG_CAP) 228 let ol6: *i64 = sys_mmap(16) as *i64 229 gk_run_capture(elf, "beat" as *u8, RG_LCONF, RG_LJRNL, RG_MS_TRIAL, ob6, RG_CAP, ol6) 230 var t12: i64 = 0 231 if gk_count(RG_LJRNL, "\tnx_rgfx_never_gate\tABSENT" as *u8) == 1 { if gk_count(RG_LJRNL, "\tnx_rgfx_new_gate\tABSENT" as *u8) == 0 { if gk_count(RG_LJRNL, "\tnx_rgfx_old_gate\tABSENT" as *u8) == 0 { t12 = 1 } } } 232 gv_check("T12 order: the never-run gate runs FIRST though the conf lists it last, and a zero budget starts exactly one" as *u8, t12, ctr) 233 gv_check("T13 budget: the beat's stamp names what it ran and what it deferred (ran=1 deferred=2)" as *u8, gk_contains(RG_LSTAMP, " ran=1 deferred=2 " as *u8), ctr) 234 let ob7: *u8 = sys_mmap(RG_CAP) 235 let ol7: *i64 = sys_mmap(16) as *i64 236 gk_run_capture(elf, "beat" as *u8, RG_LCONF, RG_LJRNL, RG_MS_TRIAL, ob7, RG_CAP, ol7) 237 var t14: i64 = 0 238 if gk_count(RG_LJRNL, "\tnx_rgfx_old_gate\tABSENT" as *u8) == 1 { if gk_count(RG_LJRNL, "\tnx_rgfx_new_gate\tABSENT" as *u8) == 0 { t14 = 1 } } 239 gv_check("T14 the NEXT beat runs the next stalest (the old row at 100, never the recent one at 900): no cursor, the journal decides" as *u8, t14, ctr) 240 gk_write(RG_NCONF, "; no directive: the old behaviour\nnx_rgfx_new_gate\nnx_rgfx_old_gate\nnx_rgfx_never_gate\n" as *u8) 241 gk_rm(RG_NJRNL) 242 gk_rm(RG_NSTAMP) 243 let ob8: *u8 = sys_mmap(RG_CAP) 244 let ol8: *i64 = sys_mmap(16) as *i64 245 gk_run_capture(elf, "beat" as *u8, RG_NCONF, RG_NJRNL, RG_MS_TRIAL, ob8, RG_CAP, ol8) 246 gv_check("T15 neg-control-no-directive-no-budget: every gate runs (ran=3 deferred=0), the pass the conf always had" as *u8, gk_contains(RG_NSTAMP, " ran=3 deferred=0 " as *u8), ctr) 247 248 return gv_verdict("gate_roster" as *u8, ctr, "admit classifies latest-wins/suspect/reject/merge as declared; trial reports ABSENT honestly; argless mutates nothing and a fixture beat cannot forge the production heartbeat" as *u8) 249}