code wiki / _hdl_build / nx_heartbeat_registry_gate.nx

nx_heartbeat_registry_gate.nx source

↩ module page · 169 lines · 7092 B

1// nx_heartbeat_registry_gate.nx -- the REFEREE for WMS LIVE-2 (registry-sourced string-keyed monitor). 2// 3// Proves hbm_scan_registry auto-monitors EVERY registered workstream from the R1 SSOT (no hardcoded 4// id list, no int/string bridge), with correct per-stream liveness AND a mandatory negative control: 5// setup: seed a fresh registry ws:ids = {HB-A, HB-B, HB-C, HB-D}; beat HB-A & HB-B FRESH, HB-C STALE 6// (old beat), leave HB-D NEVER beaten; append one TORN heartbeat line. 7// T1 coverage : scan returns nids == 4 -- every registered stream was sourced from ws:ids. 8// T2 alive : HB-A and HB-B (beaten within threshold) read HBS_ALIVE. 9// T3 stalled(NEG): HB-C (beaten long ago) reads HBS_STALLED -- a crashed stream surfaces, the 10// detector is NOT a constant-ALIVE. 11// T4 unknown(NEG): HB-D (registered but NEVER beaten) reads HBS_UNKNOWN -- the monitor never 12// fabricates liveness for a stream it has no beat for. 13// T5 torn-flag : the corrupt line is FLAGGED (flagged>=1), never silently dropped. 14// GREEN(0) iff T1..T5. Fresh /tmp artifacts per run (disposable). Self-log via fa_appendz. 15// Sovereign: nx_heartbeat_str + nx_workstream_store + nx_framed_append + nx_syscalls. 16// license_tier: ORIGINAL 17import "nx_heartbeat_str.nx" 18import "nx_workstream_store.nx" 19import "nx_framed_append.nx" 20import "nx_syscalls.nx" 21 22const HBR_LOG: *u8 = "knowledge/status/heartbeat_registry_gate.log" 23const HBR_REC: i64 = 256 24 25func so(s: *u8) -> i64 { 26 var n: i64 = 0 27 while s[n] != (0 as u8) { n = n + 1 } 28 sys_write(1, s, n) 29 return 0 30} 31func son(v: i64) -> i64 { 32 let bb: *u8 = sys_mmap(28) 33 var m: i64 = v 34 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 35 let t: *u8 = sys_mmap(28) 36 var k: i64 = 0 37 if m == 0 { t[0] = 48 as u8; k = 1 } 38 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 39 var i: i64 = 0 40 while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 41 sys_write(1, bb, k) 42 return 0 43} 44func hr_cat(dst: *u8, off: i64, s: *u8) -> i64 { 45 var i: i64 = 0 46 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 } 47 return off + i 48} 49func hr_catn(dst: *u8, off: i64, v: i64) -> i64 { 50 var m: i64 = v 51 var o: i64 = off 52 if m == 0 { dst[o] = 48 as u8; return o + 1 } 53 let t: *u8 = sys_mmap(28) 54 var k: i64 = 0 55 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 56 var i: i64 = 0 57 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 } 58 return o + k 59} 60func hr_path(out: *u8, tag: *u8, epoch: i64, suffix: *u8) -> i64 { 61 var o: i64 = 0 62 o = hr_cat(out, o, "/tmp/" as *u8) 63 o = hr_cat(out, o, tag) 64 o = hr_catn(out, o, epoch) 65 o = hr_cat(out, o, suffix) 66 out[o] = 0 as u8 67 return o 68} 69// append a raw NUL-term line (its own '\n') to path 70func hr_rawline(path: *u8, s: *u8) -> i64 { 71 var n: i64 = 0 72 while s[n] != (0 as u8) { n = n + 1 } 73 let fd: i64 = sys_openat_append(path, 0x1a4) 74 if fd < 0 { return 0 - 1 } 75 sys_write(fd, s, n) 76 sys_close(fd) 77 return 0 78} 79// verdict of id `id` in the scan output (correlate by id string, not array position); -99 if absent. 80func find_verdict(out_ids: *i64, verdicts: *i64, n: i64, id: *u8) -> i64 { 81 var k: i64 = 0 82 while k < n { 83 if hbs_streq(out_ids[k] as *u8, id) == 1 { return verdicts[k] } 84 k = k + 1 85 } 86 return 0 - 99 87} 88 89func main() -> i64 { 90 let epoch: i64 = sys_now_realtime_sec() 91 let prefix: *u8 = sys_mmap(128) 92 let hbpath: *u8 = sys_mmap(128) 93 hr_path(prefix, "hbreg" as *u8, epoch, "-" as *u8) 94 hr_path(hbpath, "hbrhb" as *u8, epoch, ".log" as *u8) 95 96 // seed a fresh registry: ws:ids = HB-A HB-B HB-C HB-D 97 ws_put_p(prefix, "ws:ids" as *u8, "HB-A\tHB-B\tHB-C\tHB-D" as *u8) 98 99 // fresh heartbeat channel 100 let h0: i64 = sys_openat_wr(hbpath, 0x1a4) 101 if h0 > 0 { sys_close(h0) } 102 let pid: i64 = __syscall(39, 0, 0, 0, 0, 0, 0) 103 hb_beat_s_at(hbpath, "HB-A" as *u8, 990, 0, pid) // fresh (age 10 at now=1000) 104 hb_beat_s_at(hbpath, "HB-B" as *u8, 995, 0, pid) // fresh (age 5) 105 hb_beat_s_at(hbpath, "HB-C" as *u8, 900, 0, pid) // STALE (age 100 > thr 60) 106 // HB-D: registered but NEVER beaten 107 // one TORN line (missing the " END" anchor) 108 hr_rawline(hbpath, "HBX ws=HB-A epoch=999 seq=9 actor=1 BROKEN\n" as *u8) 109 110 let out_ids: *i64 = sys_mmap(8 * 64) as *i64 111 let verdicts: *i64 = sys_mmap(8 * 64) as *i64 112 let outs: *i64 = sys_mmap(64) as *i64 113 let nids: i64 = hbm_scan_registry(hbpath, prefix, 1000, 60, out_ids, verdicts, outs, 64) 114 let flagged: i64 = outs[2] 115 116 let vA: i64 = find_verdict(out_ids, verdicts, nids, "HB-A" as *u8) 117 let vB: i64 = find_verdict(out_ids, verdicts, nids, "HB-B" as *u8) 118 let vC: i64 = find_verdict(out_ids, verdicts, nids, "HB-C" as *u8) 119 let vD: i64 = find_verdict(out_ids, verdicts, nids, "HB-D" as *u8) 120 121 var t1: i64 = 0 122 if nids == 4 { t1 = 1 } 123 var t2: i64 = 0 124 if vA == HBS_ALIVE { if vB == HBS_ALIVE { t2 = 1 } } 125 var t3: i64 = 0 126 if vC == HBS_STALLED { t3 = 1 } 127 var t4: i64 = 0 128 if vD == HBS_UNKNOWN { t4 = 1 } 129 var t5: i64 = 0 130 if flagged >= 1 { t5 = 1 } 131 132 var green: i64 = 1 133 if t1 == 0 { green = 0 } 134 if t2 == 0 { green = 0 } 135 if t3 == 0 { green = 0 } 136 if t4 == 0 { green = 0 } 137 if t5 == 0 { green = 0 } 138 139 so("WMS LIVE-2 registry-sourced string-keyed heartbeat monitor gate\n" as *u8) 140 so(" T1 coverage nids=" as *u8); son(nids); so("/4" as *u8) 141 if t1 == 1 { so(" PASS\n" as *u8) } else { so(" FAIL\n" as *u8) } 142 so(" T2 alive HB-A=" as *u8); son(vA); so(" HB-B=" as *u8); son(vB); so(" (0=ALIVE)" as *u8) 143 if t2 == 1 { so(" PASS\n" as *u8) } else { so(" FAIL\n" as *u8) } 144 so(" T3 stalled (NEG) HB-C=" as *u8); son(vC); so(" (1=STALLED)" as *u8) 145 if t3 == 1 { so(" PASS\n" as *u8) } else { so(" FAIL\n" as *u8) } 146 so(" T4 unknown (NEG) HB-D=" as *u8); son(vD); so(" (2=UNKNOWN)" as *u8) 147 if t4 == 1 { so(" PASS\n" as *u8) } else { so(" FAIL\n" as *u8) } 148 so(" T5 torn-flag flagged=" as *u8); son(flagged) 149 if t5 == 1 { so(" PASS(corruption-surfaced)\n" as *u8) } else { so(" FAIL\n" as *u8) } 150 so("verdict=" as *u8) 151 if green == 1 { so("GREEN\n" as *u8) } else { so("RED\n" as *u8) } 152 153 let rec: *u8 = sys_mmap(HBR_REC + 16) 154 var o: i64 = 0 155 o = hr_cat(rec, o, "WMS-LIVE2 epoch=" as *u8); o = hr_catn(rec, o, epoch) 156 o = hr_cat(rec, o, " nids=" as *u8); o = hr_catn(rec, o, nids) 157 o = hr_cat(rec, o, " vA=" as *u8); o = hr_catn(rec, o, vA) 158 o = hr_cat(rec, o, " vB=" as *u8); o = hr_catn(rec, o, vB) 159 o = hr_cat(rec, o, " vC=" as *u8); o = hr_catn(rec, o, vC) 160 o = hr_cat(rec, o, " vD=" as *u8); o = hr_catn(rec, o, vD) 161 o = hr_cat(rec, o, " flagged=" as *u8); o = hr_catn(rec, o, flagged) 162 o = hr_cat(rec, o, " verdict=" as *u8) 163 if green == 1 { o = hr_cat(rec, o, "GREEN" as *u8) } else { o = hr_cat(rec, o, "RED" as *u8) } 164 rec[o] = 0 as u8 165 fa_appendz(HBR_LOG, rec, HBR_REC) 166 167 if green == 1 { return 0 } 168 return 1 169}