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}