code wiki / _hdl_build / nx_jobhealth_gate.nx

nx_jobhealth_gate.nx source

↩ module page · 105 lines · 5016 B

1// nx_jobhealth_gate.nx -- DOES EVERY REGISTERED CLOCK JOB HAVE AN ORGAN THAT CAN ACTUALLY BE EXECUTED? 2// 3// WHY THIS EXISTS. Measured 2026-08-01: four clock jobs (p384kat, tls12prf, gaterollup, feedgate) had not 4// written a verdict in 6.1 DAYS. The scheduler was healthy the whole time -- proven by registering a fresh 5// job with an ABSOLUTE organ path and watching it dispatch within ~120s. The real cause is that those rows 6// carry BARE-NAME organ paths (nx_p384_ecdh_gate.elf, ...) and no such file exists at the dispatcher's cwd. 7// clk_dispatch_run chmods, forks, execs, and treats a child exit of 127 as "did not run" -- deliberately 8// NOT counting it as dispatched. That is honest accounting AND a silent failure: the job dies on every 9// single tick, the plane still lists it, and the health snapshot still reports the scheduler UP. 10// 11// I ALMOST FILED THAT AS "THE SCHEDULER IS DEAD" (sev-8, retracted within minutes). Four jobs stopping 12// within 40 seconds of each other looked like one dispatcher failure; it was four identical exec failures. 13// AN INFERENCE FROM CORRELATED TIMESTAMPS IS A HYPOTHESIS, NOT A DIAGNOSIS -- this gate is the cheap 14// discriminator I should have had, made standing so nobody has to re-derive it. 15// 16// THE 2026 JOB-QUEUE RULE THIS IMPLEMENTS: "if a job can fail without showing up somewhere you look, it 17// will -- make lost work impossible to ignore." Mature queues answer with a dead-letter queue plus 18// staleness alerting; this substrate has neither, so a registration that can NEVER execute is 19// indistinguishable from one that simply has not come due yet. 20// 21// WHY STAT AND NOT EXEC: a health check must never become an arbitrary-code trigger. Readability is 22// exactly the predicate execve fails on with 127, so this catches the real class without running anything. 23// 24// Rides nx_gate_verdict (migrate-on-touch law D001/L009 -- a new gate must inherit the base class rather 25// than hand-roll its verdict, so the verdict is emitted in ONE place and cannot be written before the work). 26// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 27import "nx_store_seed_lib.nx" 28import "nx_gate_verdict.nx" 29 30const JH_PLANE: *u8 = "knowledge/store/clockjobs-" 31const JH_CAP: i64 = 65536 32 33// EXACTLY THE PREDICATE execve FAILS ON WITH 127: can this path be opened for reading? 34func jh_resolves(path: *u8) -> i64 { 35 let fd: i64 = sys_openat_rd(path) 36 if fd < 0 { return 0 } 37 sys_close(fd) 38 return 1 39} 40 41func main() -> i64 { 42 gv_head("=== nx_jobhealth_gate: can every registered clock job actually be executed? ===" as *u8) 43 let ctr: *i64 = gv_ctr() 44 45 let buf: *u8 = sys_mmap(JH_CAP) 46 let dn: i64 = sts_load(JH_PLANE, buf, JH_CAP) 47 48 // T1 -- an EMPTY plane would make the organ check vacuously true, so prove there is something to check 49 var rows: i64 = 0 50 var q: i64 = 0 51 while q < dn { if buf[q] == (10 as u8) { rows = rows + 1 } q = q + 1 } 52 var nonempty: i64 = 0 53 if rows > 0 { nonempty = 1 } 54 gv_check("clockjobs plane is non-empty (else the organ check is vacuous)" as *u8, nonempty, ctr) 55 56 // T2 -- every organ path (col 2) resolves to a readable file 57 var unresolved: i64 = 0 58 var checked: i64 = 0 59 let nm: *u8 = sys_mmap(256) 60 let og: *u8 = sys_mmap(512) 61 var i: i64 = 0 62 var ls: i64 = 0 63 while i < dn { 64 if buf[i] == (10 as u8) { 65 if i > ls { 66 var f: i64 = 0 67 var p: i64 = ls 68 var w: i64 = 0 69 var g: i64 = 0 70 while p < i { 71 if buf[p] == (9 as u8) { f = f + 1 } else { 72 if f == 0 { if w < 255 { nm[w] = buf[p]; w = w + 1 } } 73 else { if f == 2 { if g < 511 { og[g] = buf[p]; g = g + 1 } } } 74 } 75 p = p + 1 76 } 77 nm[w] = 0 as u8 78 og[g] = 0 as u8 79 if g > 0 { 80 checked = checked + 1 81 if jh_resolves(og) == 0 { 82 unresolved = unresolved + 1 83 gv_head(" UNRESOLVABLE-ORGAN -- dies at exec with 127 on EVERY tick:" as *u8) 84 gv_head(nm) 85 gv_head(og) 86 } 87 } 88 } 89 ls = i + 1 90 } 91 i = i + 1 92 } 93 var allres: i64 = 0 94 if unresolved == 0 { allres = 1 } 95 gv_check("every registered clock organ resolves to a readable file" as *u8, allres, ctr) 96 97 // T3 -- NON-VACUITY: the predicate must be able to say NO, or T2's pass proves nothing 98 var neg: i64 = 0 99 if jh_resolves("knowledge/_nx_jobhealth_absent_control.elf" as *u8) == 0 { neg = 1 } 100 gv_check("non-vacuity: an impossible path is REPORTED unresolvable" as *u8, neg, ctr) 101 102 let rc: i64 = gv_verdict("JOBHEALTH-GATE" as *u8, ctr, "every clockjobs organ is executable; a bare name that cannot exec dies silently every tick" as *u8) 103 sys_exit(rc) 104 return rc 105}