code wiki / _hdl_build / nx_cron_watch.nx

nx_cron_watch.nx source

↩ module page · 454 lines · 27337 B

1// nx_cron_watch.nx -- CRON/AUTOMATION FRESHNESS SUPERVISOR (operator: "prevent things like this... 2// supervised"; the next silent-failure class after API-contract drift + lib drift = a scheduled job that 3// SILENTLY STOPS FIRING, e.g. seq22 team_pulse died unnoticed). SOTA = the dead-man's-switch / heartbeat 4// model (Healthchecks.io "expected period + grace time", Cronitor, Dead Man's Snitch): a job pings on its 5// schedule; a check-in missed beyond a grace window -> STALE/alert. Sovereign twist: the heartbeat is each 6// job's own evidence-log `ts=<epoch>` (no external SaaS; evidence-layer native). Data-driven (rule 11): 7// knowledge/registry/cron_heartbeats.tsv rows name<TAB>heartbeat-file<TAB>ts-marker<TAB>max-age-secs<TAB>remediation. 8// max-age = expected-interval + grace. age = now - ts. age>max-age -> STALE. missing ts -> STALE (never fired). 9// nx_cron_watch check [manifest] (JSON: per watch fresh/stale + age + verdict GREEN/STALE-DETECTED) 10// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 11import "nx_syscalls.nx" 12// SSOT IS NOW THE SEG-STORE PLANE, NOT THE TSV (standing law "no tsv -- nishi formats", operator 13// 2026-07-20 "get rid of all these tsvs and migrate to native nishi information management"). 14import "nx_store_seed_lib.nx" 15 16const CW_CAP: i64 = 262144 17const CW_TAB: i64 = 9 18const CW_NL: i64 = 10 19const CW_HASH: i64 = 35 20const CW_STDERR: i64 = 2 21const CW_SPAN: i64 = 16 22const CW_EXIT_USAGE: i64 = 2 23 24func cw_werr(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(CW_STDERR, s, n); return 0 } 25func cw_vlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 26func cw_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o] = s[i]; o = o + 1; i = i + 1 } return o } 27func cw_catn(d: *u8, o: i64, v: i64) -> i64 { let t: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { d[o] = 45 as u8; o = o + 1; m = 0 - m } var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } var i: i64 = 0; while i < k { d[o] = t[k-1-i]; o = o + 1; i = i + 1 } return o } 28func cw_cat_esc(d: *u8, o: i64, q: *u8, s: i64, e: i64) -> i64 { var i: i64 = s; while i < e { var c: i64 = q[i] as i64; if c == 34 { c = 39 } if c == 92 { c = 47 } if c < 32 { c = 32 } d[o] = c as u8; o = o + 1; i = i + 1 } return o } 29// TAIL-READ (2026-08-02, debt 1785708737). This used to read from byte 0 up to `cap`, so once an 30// append-only stamp log grew past CW_CAP the watch only ever saw the HEAD of the file -- and computed 31// "latest" from the OLDEST bytes it could afford. MEASURED: surfsentinel-beat reported last_ts=1784445800 32// (~14.6 DAYS stale) while the log's real tail showed a COMPLETED run 23 minutes earlier. The guard aged 33// BACKWARDS as its subject got healthier, and screamed louder the longer the job ran correctly. 34// A FRESHNESS CHECK MUST READ THE TAIL. Seek to max(0, size-cap) so the newest evidence is always in the 35// window; a file smaller than cap is read whole exactly as before. 36func cw_read(path: *u8, buf: *u8, cap: i64) -> i64 { 37 let fd: i64 = sys_openat_rd(path) 38 if fd < 0 { return 0 - 1 } 39 let size: i64 = sys_lseek(fd, 0, 2) 40 if size > cap { sys_lseek(fd, size - cap, 0) } else { sys_lseek(fd, 0, 0) } 41 var n: i64 = 0 42 var go: i64 = 1 43 while go == 1 { let r: i64 = sys_read(fd, ((buf as i64) + n) as *u8, cap - n); if r <= 0 { go = 0 } else { n = n + r } if n >= cap { go = 0 } } 44 sys_close(fd) 45 return n 46} 47// find <marker> substring, then parse the decimal number immediately following it. -1 if not found. 48func cw_num_after(buf: *u8, n: i64, marker: *u8) -> i64 { 49 var ml: i64 = 0 50 while marker[ml] != (0 as u8) { ml = ml + 1 } 51 if ml == 0 { return 0 - 1 } 52 var last: i64 = 0 - 1 53 var found: i64 = 0 54 var i: i64 = 0 55 while i + ml <= n { 56 var j: i64 = 0 57 var ok: i64 = 1 58 while j < ml { if buf[i+j] != marker[j] { ok = 0; j = ml } else { j = j + 1 } } 59 if ok == 1 { 60 var p: i64 = i + ml 61 var v: i64 = 0 62 var got: i64 = 0 63 var go: i64 = 1 64 while go == 1 { if p >= n { go = 0 } else { let c: i64 = buf[p] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); got = 1; p = p + 1 } else { go = 0 } } else { go = 0 } } } 65 // LAST MATCH WINS (2026-08-02, debt 1785708737 -- the twin of the tail-read above). This used to 66 // `return v` on the FIRST marker found, which is correct only for a single-line stamp file 67 // (`date > log`). Every APPEND-only evidence log (`>>`) puts the FRESHEST stamp LAST, so the 68 // first match is the OLDEST run -- the watch then reports a healthy hourly job as weeks stale. 69 // That is why the single-line watches (planeguard/guardcheck) read correctly while the appending 70 // ones (surfsentinel) did not: first==last only when there is one line. 71 if got == 1 { last = v; found = 1 } 72 } 73 i = i + 1 74 } 75 if found == 1 { return last } 76 return 0 - 1 77} 78func cw_le(q: *u8, i: i64, n: i64) -> i64 { var e: i64 = i; var s: i64 = 1; while s == 1 { if e >= n { s = 0 } else { if q[e] == (CW_NL as u8) { s = 0 } else { e = e + 1 } } } return e } 79func cw_col(q: *u8, ls: i64, le: i64, c: i64, out: *i64) -> i64 { 80 var col: i64 = 0 81 var p: i64 = ls 82 while col < c { 83 var s: i64 = 1 84 while s == 1 { if p >= le { return 0 } if q[p] == (CW_TAB as u8) { s = 0 } else { p = p + 1 } } 85 p = p + 1 86 col = col + 1 87 } 88 var e: i64 = p 89 var s2: i64 = 1 90 while s2 == 1 { if e >= le { s2 = 0 } else { if q[e] == (CW_TAB as u8) { s2 = 0 } else { e = e + 1 } } } 91 out[0] = p 92 out[1] = e 93 return 1 94} 95func cw_cstr(q: *u8, s: i64, e: i64, dst: *u8) -> i64 { var i: i64 = 0; while s + i < e { dst[i] = q[s+i]; i = i + 1 } dst[i] = 0 as u8; return i } 96func cw_atoi_span(q: *u8, s: i64, e: i64) -> i64 { var v: i64 = 0; var i: i64 = s; while i < e { let c: i64 = q[i] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } i = i + 1 } return v } 97func cw_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 98func cw_pn(v: i64) -> i64 { 99 let t: *u8 = sys_mmap(28) 100 var m: i64 = v 101 var k: i64 = 0 102 if m <= 0 { t[0] = 48 as u8; k = 1 } else { while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } } 103 let b: *u8 = sys_mmap(28) 104 var i: i64 = 0 105 while i < k { b[i] = t[k-1-i]; i = i + 1 } 106 sys_write(1, b, k) 107 return 0 108} 109func cw_has(q: *u8, n: i64, ned: *u8, nl: i64) -> i64 { 110 if nl <= 0 { return 0 } 111 if n < nl { return 0 } 112 var i: i64 = 0 113 while i <= n - nl { 114 var j: i64 = 0 115 var m: i64 = 1 116 while j < nl { if q[i+j] != ned[j] { m = 0; j = nl } else { j = j + 1 } } 117 if m == 1 { return 1 } 118 i = i + 1 119 } 120 return 0 121} 122// Extract the first nx_<identifier> from a cron row. Stops at the first non-identifier byte, so 123// "/nishihost/nx_buildroot_guard.cron.sh" and "./nx_barcheck.elf" both yield the bare organ name -- 124// which is the token the heartbeat manifest's remediation text actually names. 125func cw_token(q: *u8, ls: i64, le: i64, dst: *u8) -> i64 { 126 var i: i64 = ls 127 while i + 3 <= le { 128 if q[i] == (110 as u8) { if q[i+1] == (120 as u8) { if q[i+2] == (95 as u8) { 129 var k: i64 = 0 130 var p: i64 = i 131 while p < le { 132 let c: i64 = q[p] as i64 133 var ok: i64 = 0 134 if c >= 97 { if c <= 122 { ok = 1 } } 135 if c >= 48 { if c <= 57 { ok = 1 } } 136 if c == 95 { ok = 1 } 137 if ok == 0 { p = le } else { dst[k] = q[p]; k = k + 1; p = p + 1 } 138 } 139 dst[k] = 0 as u8 140 return k 141 } } } 142 i = i + 1 143 } 144 return 0 145} 146 147// ROW-SCOPED declaration check. The first cut used the flat cw_has over the whole manifest, which 148// would have counted a `covers=` token appearing in a COMMENT -- and this file's header comments do 149// mention organ names. That is the same looseness as the heuristic it replaces, only tighter, so 150// calling it EXACT would have been an overclaim on my own instrument. This walks DATA ROWS ONLY 151// (leading '#' skipped) and requires the token inside one of them. 152// THE MANIFEST SOURCE, PLANE-FIRST. nx_tsv_migrate seeded knowledge/store/cronwatch- from the tsv and 153// ROUND-TRIP VERIFIED it (13 data rows in, 13 back, verified=1). Reading the plane FIRST is the whole 154// point: a migration whose READER still opens the old file has produced a MIRROR, not an SSOT, and a 155// mirror is just a second thing to drift. That is exactly the trap F871 hit -- landmine- sat as a 156// mirror until the reader moved, and rung 2 had to INVERT it. 157// THE TSV FALLBACK STAYS until the file is retired. This can therefore never be the change that blinds 158// the supervisor: an absent or empty plane degrades to the previous behaviour instead of reporting 159// zero watches, which for a dead-man's-switch would read GREEN while watching nothing. 160// srcout[0]: 1 = plane, 0 = tsv. ANNOUNCED by the callers -- a monitor that will not say where its 161// truth came from is one silent migration away from watching a file nobody updates any more. 162func cw_manifest(out: *u8, cap: i64, srcout: *i64) -> i64 { 163 let n: i64 = sts_load("knowledge/store/cronwatch-" as *u8, out, cap) 164 if n > 0 { srcout[0] = 1; return n } 165 srcout[0] = 0 166 return cw_read("knowledge/registry/cron_heartbeats.tsv" as *u8, out, cap) 167} 168// declared: an okverdict= marker longer than this is truncated, which would make the containment test 169// unreliable -- 256 is far beyond any verdict sentinel in the estate (the longest today is 13 chars). 170const CW_MARKCAP: i64 = 256 171 172// Find `key` in hay and copy the token that follows it (up to whitespace) into out. Returns the token 173// length, or 0 if the key is absent. Used for the row-level okverdict= declaration. 174func cw_tok_after(hay: *u8, hn: i64, key: *u8, out: *u8, cap: i64) -> i64 { 175 var kl: i64 = 0 176 while key[kl] != (0 as u8) { kl = kl + 1 } 177 if kl == 0 { return 0 } 178 if hn < kl { return 0 } 179 var i: i64 = 0 180 while i <= hn - kl { 181 var m: i64 = 1 182 var c: i64 = 0 183 while c < kl { 184 if hay[i + c] != key[c] { m = 0; c = kl } else { c = c + 1 } 185 } 186 if m == 1 { 187 var j: i64 = i + kl 188 var w: i64 = 0 189 var go: i64 = 1 190 while go == 1 { 191 if j >= hn { go = 0 } else { 192 if w >= cap - 1 { go = 0 } else { 193 let ch: i64 = hay[j] as i64 194 if ch <= 32 { go = 0 } else { out[w] = hay[j]; w = w + 1; j = j + 1 } 195 } 196 } 197 } 198 out[w] = 0 as u8 199 return w 200 } 201 i = i + 1 202 } 203 return 0 204} 205 206func cw_row_declares(man: *u8, mn: i64, needle: *u8, nl: i64) -> i64 { 207 var i: i64 = 0 208 while i < mn { 209 let le: i64 = cw_le(man, i, mn) 210 if le > i { if man[i] != (CW_HASH as u8) { 211 if cw_has(((man as i64) + i) as *u8, le - i, needle, nl) == 1 { return 1 } 212 } } 213 i = le + 1 214 } 215 return 0 216} 217func main(argc: i64, argv: *i64) -> i64 { 218 // ---- verb `cover`: THE DENOMINATOR CHECK ---------------------------------------------------- 219 // `check` answers "are the jobs I was TOLD to watch fresh?" and returns GREEN over a hand-kept list. 220 // MEASURED 2026-08-06: it watched 9 while cron.reg scheduled ~62, so 53 jobs could stop firing and 221 // every board still read GREEN -- a monitor reporting on its manifest, not on the fleet. This verb 222 // makes the DENOMINATOR the scheduler's own SSOT: every non-comment cron.reg row must map to a 223 // watched job, and the ones that do not are NAMED. 224 // ENVELOPE -- CORRECTED 2026-08-06 ON ITS OWN FIRST RUN. The draft claimed `unwatched` was a LOWER 225 // BOUND. That was WRONG and the first run refuted it, so the claim is retracted here rather than left 226 // standing. The join is a NAME HEURISTIC and is unreliable in BOTH directions: 227 // OVER-reports the gap: surfsentinel-beat DOES watch nx_surfsentinel.cron.sh, but the manifest names 228 // it "nx_plan_run.elf surfsentinel", which carries no nx_surfsentinel token -> reads UNWATCHED. 229 // UNDER-reports the gap: a remediation string that merely MENTIONS an organ counts as covered. 230 // AND THE DENOMINATOR IS STILL INCOMPLETE, which is the same defect this verb was built to expose: 231 // cron.reg is only ONE of TWO schedulers. The clock store (knowledge/store/clockjobs-) schedules 232 // netobs-beat and evidence-beat, which have no cron.reg row at all -- which is why `watched` here (6) 233 // is smaller than the manifest's live watch count (9). This verb therefore measures CRON-ROW coverage 234 // ONLY, and the ratio is INDICATIVE, never exact. 235 // THE FIX THAT WOULD MAKE IT EXACT: give cron_heartbeats.tsv an explicit column naming the scheduled 236 // row each watch covers, so the join is a DECLARED LINK instead of a string guess -- the same move as 237 // re-keying a plane by column name instead of ordinal. Until then this number is a floor-lit estimate 238 // and is labelled as one. A row with no nx_ token is counted separately as unmatchable. 239 if argc > 1 { 240 let v0: *u8 = argv[1] as *u8 241 if v0[0] == (99 as u8) { if v0[1] == (111 as u8) { 242 let reg: *u8 = sys_mmap(CW_CAP) 243 let rn: i64 = cw_read("cron.reg" as *u8, reg, CW_CAP) 244 if rn <= 0 { cw_werr("CW-FAIL cron.reg unreadable -- coverage is UNDEFINED, refusing to print a ratio\n" as *u8); sys_exit(1); return 1 } 245 let man2: *u8 = sys_mmap(CW_CAP) 246 let msrc2: *i64 = sys_mmap(CW_SPAN) as *i64 247 let mn2: i64 = cw_manifest(man2, CW_CAP, msrc2) 248 if mn2 <= 0 { cw_werr("CW-FAIL heartbeat manifest unreadable -- coverage UNDEFINED\n" as *u8); sys_exit(1); return 1 } 249 let tok: *u8 = sys_mmap(256) 250 // HOISTED OUT OF THE LOOP DELIBERATELY. An mmap per iteration is the exact defect that took 251 // 28.5GB of a 36GB host in nx_ts_lumadiff -- at PAGE granularity every loop turn leaks 4096B. 252 let dbuf: *u8 = sys_mmap(320) 253 var sched: i64 = 0 254 var cov: i64 = 0 255 var unw: i64 = 0 256 var notok: i64 = 0 257 var decl: i64 = 0 258 var guess: i64 = 0 259 var ri: i64 = 0 260 cw_p("=== nx_cron_watch cover -- scheduled rows (cron.reg) vs watched jobs (cron_heartbeats.tsv) ===\n" as *u8) 261 while ri < rn { 262 let rle: i64 = cw_le(reg, ri, rn) 263 if rle > ri { 264 if reg[ri] != (CW_HASH as u8) { 265 sched = sched + 1 266 let tl: i64 = cw_token(reg, ri, rle, tok) 267 if tl == 0 { 268 notok = notok + 1 269 cw_p(" NO-TOKEN (row names no nx_ organ; cannot be joined)\n" as *u8) 270 } else { 271 // DECLARED LINK FIRST (2026-08-06). This verb's own envelope named the fix and 272 // then went on guessing: `covers=<token>` in a manifest row is an EXPLICIT claim 273 // that this watch covers that scheduled row, and it cannot be satisfied by prose 274 // that merely mentions the organ. The bare-substring heuristic is KEPT as a 275 // fallback so no existing row regresses (rule 19) -- but the two are now COUNTED 276 // SEPARATELY and both printed, because a coverage number that blends proof with 277 // guesswork is not a coverage number. 278 // ★AN INSTRUMENT THAT CANNOT SAY WHICH PART OF ITS ANSWER IS A GUESS IS REPORTING 279 // CONFIDENCE IT HAS NOT EARNED. 280 var dl: i64 = cw_cat(dbuf, 0, "covers=" as *u8) 281 var ti: i64 = 0 282 while ti < tl { dbuf[dl] = tok[ti]; dl = dl + 1; ti = ti + 1 } 283 dbuf[dl] = 0 as u8 284 if cw_row_declares(man2, mn2, dbuf, dl) == 1 { cov = cov + 1; decl = decl + 1 } else { 285 if cw_has(man2, mn2, tok, tl) == 1 { cov = cov + 1; guess = guess + 1 } else { 286 unw = unw + 1 287 cw_p(" UNWATCHED " as *u8); cw_p(tok); cw_p("\n" as *u8) 288 } 289 } 290 } 291 } 292 } 293 ri = rle + 1 294 } 295 cw_p("\n scheduled=" as *u8); cw_pn(sched) 296 cw_p(" watched=" as *u8); cw_pn(cov) 297 cw_p(" unwatched=" as *u8); cw_pn(unw) 298 cw_p(" unmatchable=" as *u8); cw_pn(notok) 299 cw_p(" declared=" as *u8); cw_pn(decl) 300 cw_p(" guessed=" as *u8); cw_pn(guess) 301 if sched > 0 { cw_p(" coverage_permil=" as *u8); cw_pn((cov * 1000) / sched) } 302 if sched > 0 { cw_p(" DECLARED_permil=" as *u8); cw_pn((decl * 1000) / sched) } 303 cw_p("\n ENVELOPE: TWO JOINS, COUNTED SEPARATELY. `declared` counts rows matched by an explicit\n" as *u8) 304 cw_p(" covers=<token> inside a DATA ROW of the manifest (comments excluded, so a token mentioned\n" as *u8) 305 cw_p(" in prose cannot satisfy it) -- that half is EXACT. `guessed` counts rows matched\n" as *u8) 306 cw_p(" only by the legacy name heuristic, and is the ONLY part of coverage_permil you should\n" as *u8) 307 cw_p(" distrust. DECLARED_permil is the number that has been EARNED rather than estimated.\n" as *u8) 308 cw_p(" TO TURN A GUESS INTO A FACT: add `covers=<nx_token>` to that watch's remediation field.\n" as *u8) 309 cw_p(" Legacy heuristic detail, unreliable in BOTH directions -- a watch whose remediation\n" as *u8) 310 cw_p(" names the job without an nx_ token reads UNWATCHED (surfsentinel-beat does), and a string\n" as *u8) 311 cw_p(" that merely mentions an organ reads watched. cron.reg is also only ONE of TWO schedulers:\n" as *u8) 312 cw_p(" the clock store carries netobs/evidence beats with no cron row, so `watched` here is lower\n" as *u8) 313 cw_p(" than the manifest's live watch count. This ratio is INDICATIVE, not exact; an explicit\n" as *u8) 314 cw_p(" scheduled-row column in cron_heartbeats.tsv would make the join a DECLARED LINK, not a guess.\n" as *u8) 315 if unw == 0 { if notok == 0 { cw_p("VERDICT=GREEN (every scheduled row maps to a watched job)\n" as *u8); sys_exit(0); return 0 } } 316 cw_p("VERDICT=GAP (a scheduled job can stop firing without any watch going stale)\n" as *u8) 317 sys_exit(1); return 1 318 } } 319 } 320 321 // single verb (check); argv[1] optionally overrides the manifest path if it looks like a path 322 var mpath: *u8 = "knowledge/registry/cron_heartbeats.tsv" as *u8 323 var mexpl: i64 = 0 324 if argc > 2 { mpath = argv[2] as *u8; mexpl = 1 } 325 let man: *u8 = sys_mmap(CW_CAP) 326 let msrc: *i64 = sys_mmap(CW_SPAN) as *i64 327 msrc[0] = 0 328 // AN EXPLICIT PATH ARGUMENT STILL WINS. Gates and probes point this verb at fixture manifests, and 329 // silently reading the production plane instead would make every such run a lie about what it 330 // tested -- the same class as a gate that writes to the path it measures. 331 var mn: i64 = 0 332 if mexpl == 1 { mn = cw_read(mpath, man, CW_CAP) } else { mn = cw_manifest(man, CW_CAP, msrc) } 333 if mn <= 0 { cw_werr("CW-FAIL manifest empty or unreadable\n" as *u8); sys_exit(1); return 1 } 334 let now: i64 = sys_now_realtime_sec() 335 // SELF-STAMP -- THE SUPERVISOR HAD NO DEAD-MAN'S-SWITCH OF ITS OWN. nx_cron_watch is scheduled in 336 // cron.reg and read UNWATCHED in its OWN cover report: if it stopped firing, nothing would notice, 337 // and every board would go on reading GREEN off a manifest that nobody was checking any more. The 338 // instrument that exists to catch silent stoppage was the one thing whose silent stoppage was 339 // invisible. 340 // ⚠HONEST LIMIT, STATED RATHER THAN PAPERED OVER: A SUPERVISOR CANNOT FULLY SUPERVISE ITSELF. If 341 // this organ never runs it never writes this stamp AND never reads it, so the row can only ever go 342 // stale-but-unread. This closes the PARTIAL case -- the organ runs by some path while its schedule 343 // row is inert -- and the TOTAL-death case is left to an EXTERNAL prober, which is named in the 344 // cron-watch-self remediation. A guard whose blind spot is documented is worth far more than one 345 // whose blind spot is discovered during an outage. 346 let stb: *u8 = sys_mmap(CW_SPAN * 8) 347 var so: i64 = cw_cat(stb, 0, "cron_watch ts=" as *u8) 348 so = cw_catn(stb, so, now) 349 stb[so] = 10 as u8 350 so = so + 1 351 let stfd: i64 = sys_openat_wr("knowledge/status/cron_watch.stamp" as *u8, 0x1a4) 352 if stfd >= 0 { sys_write(stfd, stb, so); sys_close(stfd) } 353 let fbuf: *u8 = sys_mmap(CW_CAP) 354 let fpath: *u8 = sys_mmap(512) 355 let tmark: *u8 = sys_mmap(64) 356 let c0: *i64 = sys_mmap(CW_SPAN) as *i64 357 let c1: *i64 = sys_mmap(CW_SPAN) as *i64 358 let c2: *i64 = sys_mmap(CW_SPAN) as *i64 359 let c3: *i64 = sys_mmap(CW_SPAN) as *i64 360 let c4: *i64 = sys_mmap(CW_SPAN) as *i64 361 let out: *u8 = sys_mmap(CW_CAP) 362 var o: i64 = 0 363 o = cw_cat(out, o, "{\"verb\":\"check\",\"epoch\":" as *u8) 364 o = cw_catn(out, o, now) 365 // DECLARE THE SOURCE. During a registry migration the single most valuable field is which copy 366 // was actually read: "plane" means the seg-store is authoritative, "tsv" means the plane was 367 // empty or absent and this run FELL BACK. Without it, the day someone edits the retired tsv and 368 // sees no effect is a debugging session instead of one glance. 369 o = cw_cat(out, o, ",\"manifest_src\":\"" as *u8) 370 if msrc[0] == 1 { o = cw_cat(out, o, "plane" as *u8) } else { o = cw_cat(out, o, "tsv" as *u8) } 371 o = cw_cat(out, o, "\"" as *u8) 372 o = cw_cat(out, o, ",\"watches\":[" as *u8) 373 var total: i64 = 0 374 var stale: i64 = 0 375 var unhealthycnt: i64 = 0 376 let rembuf: *u8 = sys_mmap(CW_CAP) 377 let okbuf: *u8 = sys_mmap(CW_MARKCAP) 378 var emitted: i64 = 0 379 var i: i64 = 0 380 while i < mn { 381 let le: i64 = cw_le(man, i, mn) 382 if le > i { if (man[i] as i64) != CW_HASH { 383 if cw_col(man, i, le, 0, c0) == 1 { if cw_col(man, i, le, 1, c1) == 1 { if cw_col(man, i, le, 2, c2) == 1 { if cw_col(man, i, le, 3, c3) == 1 { 384 cw_cstr(man, c1[0], c1[1], fpath) 385 cw_cstr(man, c2[0], c2[1], tmark) 386 let maxage: i64 = cw_atoi_span(man, c3[0], c3[1]) 387 total = total + 1 388 let fn: i64 = cw_read(fpath, fbuf, CW_CAP) 389 var ts: i64 = 0 - 1 390 if fn > 0 { ts = cw_num_after(fbuf, fn, tmark) } 391 var age: i64 = 0 - 1 392 var fresh: i64 = 0 393 if ts >= 0 { age = now - ts; if age < 0 { age = 0 } if age <= maxage { fresh = 1 } } 394 if fresh == 0 { stale = stale + 1 } 395 // OUTCOME, not just liveness. A row may declare okverdict=<marker> in its remediation 396 // column (same convention as covers=); if it does, the evidence file must CONTAIN that 397 // marker or the watch is UNHEALTHY even while perfectly fresh. 398 // MEASURED 2026-08-07: the mgmt API was unreachable for ~25 minutes and this monitor 399 // reported api-contract-probe FRESH for the whole outage -- because it read only ts= 400 // and ignored the VERDICT= the probe was honestly writing 401 // ("VERDICT=UNKNOWN api-contract probe-fetch-failed ... fail-static"). 402 // ★★★★★THE INSTRUMENT REPORTED CORRECTLY AND THE MONITOR READ THE WRONG FIELD. 403 // ★A DEAD-MAN'S-SWITCH ANSWERS "DID IT RUN", NEVER "DID IT PASS" -- SO ASK BOTH. 404 // Declared GOOD rather than BAD deliberately: anything that is not the ok marker counts 405 // as unhealthy, including failure states nobody has enumerated yet. Fail-closed. 406 // IMPRECISION, DECLARED: the scan covers the file's READ WINDOW, not strictly the newest 407 // record. For the single-line rotating stamps these rows point at those are identical; 408 // for an append-only log with history they are not, and an older GREEN still present in 409 // the window would mask a later failure. Rows without okverdict= behave EXACTLY as 410 // before, so this is additive and no existing watch changes meaning. 411 var unhealthy: i64 = 0 412 if cw_col(man, i, le, 4, c4) == 1 { 413 cw_cstr(man, c4[0], c4[1], rembuf) 414 var rl: i64 = 0 415 while rembuf[rl] != (0 as u8) { rl = rl + 1 } 416 let okm: i64 = cw_tok_after(rembuf, rl, "okverdict=" as *u8, okbuf, CW_MARKCAP) 417 if okm > 0 { 418 if fn <= 0 { unhealthy = 1 } else { 419 if cw_has(fbuf, fn, okbuf, okm) == 0 { unhealthy = 1 } 420 } 421 } 422 } 423 if unhealthy == 1 { unhealthycnt = unhealthycnt + 1 } 424 if emitted > 0 { o = cw_cat(out, o, "," as *u8) } 425 o = cw_cat(out, o, "{\"name\":\"" as *u8) 426 o = cw_cat_esc(out, o, man, c0[0], c0[1]) 427 o = cw_cat(out, o, "\",\"last_ts\":" as *u8) 428 o = cw_catn(out, o, ts) 429 o = cw_cat(out, o, ",\"age_secs\":" as *u8) 430 o = cw_catn(out, o, age) 431 o = cw_cat(out, o, ",\"max_age\":" as *u8) 432 o = cw_catn(out, o, maxage) 433 o = cw_cat(out, o, ",\"fresh\":" as *u8) 434 o = cw_catn(out, o, fresh) 435 o = cw_cat(out, o, ",\"unhealthy\":" as *u8) 436 o = cw_catn(out, o, unhealthy) 437 if fresh == 0 { if cw_col(man, i, le, 4, c4) == 1 { o = cw_cat(out, o, ",\"remediation\":\"" as *u8); o = cw_cat_esc(out, o, man, c4[0], c4[1]); o = cw_cat(out, o, "\"" as *u8) } } 438 o = cw_cat(out, o, "}" as *u8) 439 emitted = emitted + 1 440 } } } } 441 } } 442 i = le + 1 443 } 444 o = cw_cat(out, o, "],\"total\":" as *u8) 445 o = cw_catn(out, o, total) 446 o = cw_cat(out, o, ",\"stale\":" as *u8) 447 o = cw_catn(out, o, stale) 448 o = cw_cat(out, o, ",\"verdict\":\"" as *u8) 449 if stale == 0 { o = cw_cat(out, o, "GREEN" as *u8) } else { o = cw_cat(out, o, "STALE-DETECTED" as *u8) } 450 o = cw_cat(out, o, "\",\"envelope\":\"manifest + each heartbeat/stamp file read bounded per CW_CAP; a job whose evidence exceeds the cap reads TRUNCATED and could be misjudged stale/fresh -- declared per the scale-law (F846), never silent\"}\n" as *u8) 451 sys_write(1, out, o) 452 sys_exit(0) 453 return 0 454}