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}