code wiki / _hdl_build / nx_ws_board_live_gate.nx
nx_ws_board_live_gate.nx source
↩ module page · 309 lines · 14098 B
1// nx_ws_board_live_gate.nx -- THE REFEREE for the M2 board's LIVE-STREAM upgrade:
2// (a) the retired 512 enumeration cap, and (b) FRESH liveness (active=alive-NOW, not a
3// one-time ACTIVE stamp). Operator law for this rung: "the 2 is not a one-time thing
4// like energy -- the data must be fresh and alive." This gate proves the board honors it.
5//
6// HERMETIC fixtures (controlled, NOT production claims):
7// prefix wsblive- : ws:empires=E-LIVE ; 5 named streams with KNOWN last_touched, so an
8// INJECTED now/window makes each verdict deterministic (no wall-clock):
9// FRESH-A ACTIVE lt=1000 -> @now=1010,win=60 age=10 -> ALIVE
10// STALE-A ACTIVE lt=100 -> @now=1010,win=60 age=910 -> STALLED
11// UNK-A ACTIVE lt=0 -> no activity -> UNKNOWN
12// HB-A ACTIVE lt=100 BUT a fresh heartbeat beat @1000 -> ALIVE (live channel wins)
13// BLK-A BLOCKED lt=1000 -> @now=1010,win=60 age=10 -> ALIVE
14// + config key ws:cfg:fresh_window_sec=123 (proves the window is DATA, not baked).
15// prefix wsbcap- : 600 complete DONE streams in ONE empire -- > the old 512 cap.
16//
17// POSITIVE (all must hold):
18// T1 named-count==5 T2 FRESH-A=ALIVE T3 STALE-A=STALLED
19// T4 UNK-A=UNKNOWN T5 HB-A=ALIVE (heartbeat overrides a stale last_touched)
20// T6 summary EXACT (active=4 alive=2 stalled=1 unknown=1 ; blocked=1 alive=1)
21// T7 cap-gone: wb_board_p(wsbcap-) total==600 (the 512 cap would have truncated)
22// T8 config: wb_cfg_int reads 123 from the store, returns the floor 999 when absent
23//
24// NEGATIVE CONTROLS (a GREEN with no working neg-control is INVALID):
25// N1 threshold-is-REAL : re-run @win=2000 -> STALE-A flips ALIVE AND a_stalled==0
26// (proves the window is a live parameter, not a magic number).
27// N2 stale-active-NOT-counted-alive : @win=60, a_stalled>=1 AND a_alive < active_total
28// (the literal "an ACTIVE label alone is not 'alive'" control).
29// N3 detector-sees-diff : a_stalled differs across the two windows (1 vs 0).
30//
31// GREEN only if T1..T8 AND N1..N3 all hold. Evidence rows + verdict -> knowledge/status/
32// ws_board_live_gate.log via the MANDATORY fa_appendz one-buffer-one-locked-write. Exit
33// 0 GREEN / 1 RED. Sovereign: imports only the WMS/heartbeat stack + nx_syscalls (no gcc).
34// license_tier: ORIGINAL
35import "nx_ws_board.nx"
36import "nx_workstream_store.nx"
37import "nx_heartbeat_str.nx"
38import "nx_seg_store.nx"
39import "nx_framed_append.nx"
40import "nx_syscalls.nx"
41
42const WBLG_LOG: *u8 = "knowledge/status/ws_board_live_gate.log"
43const WBLG_LIVE: *u8 = "knowledge/store/wsblive-"
44const WBLG_CAP: *u8 = "knowledge/store/wsbcap-"
45const WBLG_RECCAP: i64 = 512
46const WBLG_NCAP: i64 = 600 // cap-fixture size: deliberately > the retired 512 cap
47
48func wblg_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
49
50func wblg_streq(a: *u8, b: *u8) -> i64 {
51 var i: i64 = 0
52 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 }
53 if b[i] != (0 as u8) { return 0 }
54 return 1
55}
56
57func wblg_cat(dst: *u8, off: i64, s: *u8) -> i64 {
58 var i: i64 = 0
59 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 }
60 return off + i
61}
62func wblg_catn(dst: *u8, off: i64, v: i64) -> i64 {
63 var m: i64 = v; var o: i64 = off
64 if m < 0 { m = 0 - m }
65 let t: *u8 = sys_mmap(28); var k: i64 = 0
66 if m == 0 { t[0] = 48 as u8; k = 1 }
67 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
68 var i: i64 = 0
69 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 }
70 return o + k
71}
72
73// idempotent single-record seed (skip-if-unchanged) -- mirrors wbg_seed_one.
74func wblg_streq_store(prefix: *u8, key: *u8, val: *u8) -> i64 {
75 let pq: *i64 = sys_mmap(16) as *i64
76 let lq: *i64 = sys_mmap(16) as *i64
77 if ss_get(prefix, key, pq, lq) != 1 { return 0 }
78 let b: *u8 = pq[0] as *u8
79 let n: i64 = lq[0]
80 let vl: i64 = wblg_len(val)
81 if n != vl { return 0 }
82 var i: i64 = 0
83 while i < n { if b[i] != val[i] { return 0 } i = i + 1 }
84 return 1
85}
86func wblg_seed_one(prefix: *u8, key: *u8, val: *u8) -> i64 {
87 if wblg_streq_store(prefix, key, val) == 1 { return 1 }
88 let w: *i64 = ss_begin()
89 ss_add(w, 1, key, val, wblg_len(val))
90 let segid: i64 = ws_seg_next(prefix)
91 return ss_commit(prefix, w, segid)
92}
93
94// CAP fixture: N complete DONE streams committed in ONE segment (idempotent: skip if the
95// index already exists). One batch keeps the store to a single segment -- re-runs add no
96// segments (no manifest-cap growth).
97func wblg_seed_cap(prefix: *u8, n: i64) -> i64 {
98 let pq: *i64 = sys_mmap(16) as *i64
99 let lq: *i64 = sys_mmap(16) as *i64
100 if ss_get(prefix, "ws:ids" as *u8, pq, lq) == 1 { return 1 }
101 let w: *i64 = ss_begin()
102 ss_add(w, 1, "ws:empires" as *u8, "E-CAP" as *u8, 5)
103 // ws:ids = "C-1\tC-2\t...\tC-n"
104 let idsbuf: *u8 = sys_mmap(n * 10 + 64)
105 var o: i64 = 0
106 var i: i64 = 1
107 while i <= n {
108 if i > 1 { idsbuf[o] = 9 as u8; o = o + 1 }
109 o = wblg_cat(idsbuf, o, "C-" as *u8)
110 o = wblg_catn(idsbuf, o, i)
111 i = i + 1
112 }
113 ss_add(w, 1, "ws:ids" as *u8, idsbuf, o)
114 // each record: "C-i\tE-CAP\tDONE\t500\tm\to\t-"
115 i = 1
116 while i <= n {
117 let key: *u8 = sys_mmap(32)
118 var ko: i64 = 0
119 ko = wblg_cat(key, ko, "ws:C-" as *u8)
120 ko = wblg_catn(key, ko, i)
121 key[ko] = 0 as u8
122 let val: *u8 = sys_mmap(64)
123 var vo: i64 = 0
124 vo = wblg_cat(val, vo, "C-" as *u8)
125 vo = wblg_catn(val, vo, i)
126 vo = wblg_cat(val, vo, "\tE-CAP\tDONE\t500\tm\to\t-" as *u8)
127 ss_add(w, 1, key, val, vo)
128 i = i + 1
129 }
130 let segid: i64 = ws_seg_next(prefix)
131 return ss_commit(prefix, w, segid)
132}
133
134// find the named-stream row whose id == `id`; return its base index, or -1.
135func wblg_find(streams: *i64, n: i64, id: *u8) -> i64 {
136 var i: i64 = 0
137 while i < n {
138 let base: i64 = i * WB_SW
139 if wblg_streq(streams[base + 0] as *u8, id) == 1 { return base }
140 i = i + 1
141 }
142 return 0 - 1
143}
144
145// unique /tmp path = <stem><epoch>.<pid>.log
146func wblg_tmppath(out: *u8, stem: *u8, epoch: i64, pid: i64) -> i64 {
147 var o: i64 = 0
148 o = wblg_cat(out, o, stem)
149 o = wblg_catn(out, o, epoch)
150 o = wblg_cat(out, o, "." as *u8)
151 o = wblg_catn(out, o, pid)
152 o = wblg_cat(out, o, ".log" as *u8)
153 out[o] = 0 as u8
154 return o
155}
156
157// one PASS/FAIL row: one buffer, one locked fa_appendz (eat-own-dogfood) + stdout mirror.
158func wblg_row(name: *u8, pass: i64) -> i64 {
159 let buf: *u8 = sys_mmap(WBLG_RECCAP + 16)
160 var o: i64 = 0
161 o = wblg_cat(buf, o, "WSBL row=\x00" as *u8)
162 o = wblg_cat(buf, o, name)
163 if pass == 1 { o = wblg_cat(buf, o, " verdict=PASS\x00" as *u8) } else { o = wblg_cat(buf, o, " verdict=FAIL\x00" as *u8) }
164 buf[o] = 0 as u8
165 fa_appendz(WBLG_LOG, buf, WBLG_RECCAP)
166 sys_write(1, " \x00" as *u8, 2)
167 var n: i64 = 0; while name[n] != (0 as u8) { n = n + 1 } sys_write(1, name, n)
168 if pass == 1 { sys_write(1, " PASS\n\x00" as *u8, 6) } else { sys_write(1, " FAIL\n\x00" as *u8, 6) }
169 return 0
170}
171
172func main() -> i64 {
173 let epoch: i64 = sys_now_realtime_sec()
174 let pid: i64 = __syscall(39, 0, 0, 0, 0, 0, 0)
175
176 // ===== seed the liveness fixture (idempotent / additive) =====
177 wblg_seed_one(WBLG_LIVE, "ws:empires" as *u8, "E-LIVE" as *u8)
178 wblg_seed_one(WBLG_LIVE, "ws:ids" as *u8, "FRESH-A\tSTALE-A\tUNK-A\tHB-A\tBLK-A" as *u8)
179 wblg_seed_one(WBLG_LIVE, "ws:FRESH-A" as *u8, "FRESH-A\tE-LIVE\tACTIVE\t1000\tmem\torgan\t-" as *u8)
180 wblg_seed_one(WBLG_LIVE, "ws:STALE-A" as *u8, "STALE-A\tE-LIVE\tACTIVE\t100\tmem\torgan\t-" as *u8)
181 wblg_seed_one(WBLG_LIVE, "ws:UNK-A" as *u8, "UNK-A\tE-LIVE\tACTIVE\t0\tmem\torgan\t-" as *u8)
182 wblg_seed_one(WBLG_LIVE, "ws:HB-A" as *u8, "HB-A\tE-LIVE\tACTIVE\t100\tmem\torgan\t-" as *u8)
183 wblg_seed_one(WBLG_LIVE, "ws:BLK-A" as *u8, "BLK-A\tE-LIVE\tBLOCKED\t1000\tmem\torgan\t-" as *u8)
184 wblg_seed_one(WBLG_LIVE, "ws:cfg:fresh_window_sec" as *u8, "123" as *u8)
185
186 // ===== seed the cap fixture (600 streams in one batch) =====
187 wblg_seed_cap(WBLG_CAP, WBLG_NCAP)
188
189 // ===== heartbeat channel: a fresh beat for HB-A at epoch 1000 =====
190 let hbp: *u8 = sys_mmap(256)
191 wblg_tmppath(hbp, "/tmp/wsblive_hb." as *u8, epoch, pid)
192 let h0: i64 = sys_openat_wr(hbp, 0x1a4)
193 if h0 > 0 { sys_close(h0) }
194 hb_beat_s_at(hbp, "HB-A" as *u8, 1000, 0, pid)
195
196 // ===== RUN A: inject now=1010 window=60 (deterministic verdicts) =====
197 let nids: i64 = wb_count_ids(WBLG_LIVE)
198 let streams: *i64 = sys_mmap(8 * WB_SW * (nids + 16)) as *i64
199 let lsm: *i64 = sys_mmap(8 * 16) as *i64
200 let named: i64 = wb_live_streams_p(WBLG_LIVE, hbp, 1010, 60, streams, nids + 16, lsm)
201
202 var t1: i64 = 0
203 if named == 5 { t1 = 1 }
204 let bf: i64 = wblg_find(streams, named, "FRESH-A" as *u8)
205 let bs: i64 = wblg_find(streams, named, "STALE-A" as *u8)
206 let bu: i64 = wblg_find(streams, named, "UNK-A" as *u8)
207 let bh: i64 = wblg_find(streams, named, "HB-A" as *u8)
208 var t2: i64 = 0
209 if bf >= 0 { if streams[bf + 2] == HBS_ALIVE { t2 = 1 } }
210 var t3: i64 = 0
211 if bs >= 0 { if streams[bs + 2] == HBS_STALLED { t3 = 1 } }
212 var t4: i64 = 0
213 if bu >= 0 { if streams[bu + 2] == HBS_UNKNOWN { t4 = 1 } }
214 var t5: i64 = 0
215 if bh >= 0 { if streams[bh + 2] == HBS_ALIVE { t5 = 1 } }
216 var t6: i64 = 0
217 if lsm[0] == 4 { if lsm[1] == 2 { if lsm[2] == 1 { if lsm[3] == 1 {
218 if lsm[4] == 1 { if lsm[5] == 1 { t6 = 1 } } } } } }
219 // N2: a labeled-ACTIVE stream that is stale is NOT counted alive
220 var n2: i64 = 0
221 if lsm[2] >= 1 { if lsm[1] < lsm[0] { n2 = 1 } }
222
223 // ===== RUN B: now=1010 window=2000 (STALE-A must flip ALIVE) =====
224 let streams2: *i64 = sys_mmap(8 * WB_SW * (nids + 16)) as *i64
225 let lsm2: *i64 = sys_mmap(8 * 16) as *i64
226 let named2: i64 = wb_live_streams_p(WBLG_LIVE, hbp, 1010, 2000, streams2, nids + 16, lsm2)
227 let bs2: i64 = wblg_find(streams2, named2, "STALE-A" as *u8)
228 var n1: i64 = 0
229 if bs2 >= 0 { if streams2[bs2 + 2] == HBS_ALIVE { if lsm2[2] == 0 { n1 = 1 } } }
230 var n3: i64 = 0
231 if lsm[2] != lsm2[2] { if lsm[2] == 1 { if lsm2[2] == 0 { n3 = 1 } } }
232
233 // ===== T7 CAP: total enumerated == 600 (> the retired 512) =====
234 let rows: *i64 = sys_mmap(8 * WB_MAXEMP * WB_ROWW) as *i64
235 let ec: *i64 = sys_mmap(16) as *i64
236 let sm: *i64 = sys_mmap(64) as *i64
237 let rcap: i64 = wb_board_p(WBLG_CAP, 0 as *u8, rows, WB_MAXEMP, ec, sm)
238 var t7: i64 = 0
239 if rcap >= 0 { if sm[0] == WBLG_NCAP { t7 = 1 } }
240
241 // ===== T8 CONFIG: stored 123 read; absent key -> floor 999 =====
242 var t8: i64 = 0
243 if wb_cfg_int(WBLG_LIVE, "ws:cfg:fresh_window_sec" as *u8, 999) == 123 {
244 if wb_cfg_int(WBLG_LIVE, "ws:cfg:absent" as *u8, 999) == 999 { t8 = 1 }
245 }
246
247 // ===== tally (T1..T8 + N1..N3 = 11) =====
248 var passes: i64 = 0
249 if t1 == 1 { passes = passes + 1 }
250 if t2 == 1 { passes = passes + 1 }
251 if t3 == 1 { passes = passes + 1 }
252 if t4 == 1 { passes = passes + 1 }
253 if t5 == 1 { passes = passes + 1 }
254 if t6 == 1 { passes = passes + 1 }
255 if t7 == 1 { passes = passes + 1 }
256 if t8 == 1 { passes = passes + 1 }
257 if n1 == 1 { passes = passes + 1 }
258 if n2 == 1 { passes = passes + 1 }
259 if n3 == 1 { passes = passes + 1 }
260 var green: i64 = 0
261 if passes == 11 { green = 1 }
262
263 sys_write(1, "M2 board LIVE gate (cap-lift + fresh-liveness + 3 neg-controls)\n\x00" as *u8, 63)
264 wblg_row("T1-named-count==5 \x00" as *u8, t1)
265 wblg_row("T2-FRESH=ALIVE \x00" as *u8, t2)
266 wblg_row("T3-STALE=STALLED \x00" as *u8, t3)
267 wblg_row("T4-UNK=UNKNOWN \x00" as *u8, t4)
268 wblg_row("T5-HB-overrides=ALIVE \x00" as *u8, t5)
269 wblg_row("T6-summary-exact \x00" as *u8, t6)
270 wblg_row("T7-cap-gone(600>512) \x00" as *u8, t7)
271 wblg_row("T8-config-driven-window \x00" as *u8, t8)
272 wblg_row("N1-threshold-is-real \x00" as *u8, n1)
273 wblg_row("N2-stale-active-not-live\x00" as *u8, n2)
274 wblg_row("N3-detector-sees-diff \x00" as *u8, n3)
275
276 let vb: *u8 = sys_mmap(WBLG_RECCAP + 16)
277 var o: i64 = 0
278 o = wblg_cat(vb, o, "WS-BOARD-LIVE verdict=\x00" as *u8)
279 if green == 1 { o = wblg_cat(vb, o, "GREEN\x00" as *u8) } else { o = wblg_cat(vb, o, "RED\x00" as *u8) }
280 o = wblg_cat(vb, o, " passes=\x00" as *u8)
281 o = wblg_catn(vb, o, passes)
282 o = wblg_cat(vb, o, "/11 total_live_streams=\x00" as *u8)
283 o = wblg_catn(vb, o, sm[0])
284 o = wblg_cat(vb, o, " (cap-was=512) a_alive=\x00" as *u8); o = wblg_catn(vb, o, lsm[1])
285 o = wblg_cat(vb, o, " a_stalled=\x00" as *u8); o = wblg_catn(vb, o, lsm[2])
286 o = wblg_cat(vb, o, " a_unknown=\x00" as *u8); o = wblg_catn(vb, o, lsm[3])
287 if green == 0 {
288 o = wblg_cat(vb, o, " reason=\x00" as *u8)
289 if t1 == 0 { o = wblg_cat(vb, o, "count-wrong \x00" as *u8) }
290 if t2 == 0 { o = wblg_cat(vb, o, "fresh-not-alive \x00" as *u8) }
291 if t3 == 0 { o = wblg_cat(vb, o, "stale-not-stalled \x00" as *u8) }
292 if t4 == 0 { o = wblg_cat(vb, o, "unk-not-unknown \x00" as *u8) }
293 if t5 == 0 { o = wblg_cat(vb, o, "heartbeat-override-failed \x00" as *u8) }
294 if t6 == 0 { o = wblg_cat(vb, o, "summary-wrong \x00" as *u8) }
295 if t7 == 0 { o = wblg_cat(vb, o, "cap-still-truncates \x00" as *u8) }
296 if t8 == 0 { o = wblg_cat(vb, o, "config-not-read \x00" as *u8) }
297 if n1 == 0 { o = wblg_cat(vb, o, "threshold-baked \x00" as *u8) }
298 if n2 == 0 { o = wblg_cat(vb, o, "stale-counted-alive \x00" as *u8) }
299 if n3 == 0 { o = wblg_cat(vb, o, "detector-blind \x00" as *u8) }
300 }
301 o = wblg_cat(vb, o, " END\x00" as *u8)
302 vb[o] = 0 as u8
303 fa_appendz(WBLG_LOG, vb, WBLG_RECCAP)
304 sys_write(1, vb, o)
305 sys_write(1, "\n\x00" as *u8, 1)
306
307 if green == 1 { return 0 }
308 return 1
309}