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}