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}