code wiki / _hdl_build / nx_daemon_supervisor.nx

nx_daemon_supervisor.nx source

↩ module page · 828 lines · 48630 B

1// nx_daemon_supervisor.nx -- SOVEREIGN data-driven daemon supervisor. THE organ that makes daemon 2// lifecycle the ecosystem's job, not Claude's: a daemon is a REGISTRY ROW (data), not compiled into a 3// guard's target list and not nursed by a bash loop. Reads daemons.reg HOT every cycle, responds-health 4// probes each via hp_probe (SERVING / HUNG / REFUSED -- catches the wedge that PID/port checks miss), and 5// REVIVES the dead by fork+execve of the declared argv. 2-consecutive-fail discipline (in-memory, keyed by 6// name) so a single transient probe never triggers a relaunch. On HUNG (wedged, holding the port) it kills 7// the matching process first (the new instance could not bind otherwise), then launches. Zombies reaped 8// every cycle (wait4 WNOHANG). Add a daemon = a registry line + reload -- NO recompile, NO shell. 9// 10// BOUNDED-VSZ DISCIPLINE (2026-07-16): every reusable buffer is allocated ONCE before the loop and reused 11// each cycle. The hot loop performs ZERO sys_mmap. The prior version mmap'd per cycle -- fatally, it read 12// the registry with sys_read_file, whose 4 GiB default cap (used whenever lseek can't size the file) maps 13// 4 GiB of VSZ per cycle and never frees it. That drove VSZ to 116 GB in ~29 cycles, and under heuristic 14// overcommit fork() then returns -ENOMEM (proven: REVIVED ... pid=-12), so revives silently stopped. The 15// registry is now read into a fixed buffer via sys_read; ds_decw is temp-free; VSZ stays flat forever. 16// 17// daemons.reg (pipe-delimited; lines starting # or blank ignored; args are space-separated, no spaces-in-args): 18// <name> | <cwd> | <argv0 [arg1 arg2 ...]> | <health_port> | <arm: revive|watch> 19// health = hp_probe(port): ANY HTTP response on 127.0.0.1:port = healthy (401/404 count). 20// revive = relaunch (and kill-the-wedge) on 2 consecutive non-SERVING probes; watch = detect+log only. 21// license_tier: ORIGINAL module: nishi-core.ops.daemon_supervisor 22import "nx_syscalls.nx" 23import "nx_health_probe.nx" // hp_probe, HP_SERVING, HP_HUNG, HP_REFUSED, HP_BADRESP 24import "nx_metrics_ring.nx" // mr_append/mr_hash -- the supervisor WRITES its own health history (no separate collector) 25import "nx_dsup_lib.nx" // ds_decw/ds_sappend/ds_trailer/ds_conf_int/ds_stat_ppid -- PURE helpers, gate-driven (nx_daemon_supervisor_gate) 26const DS_MAGIC_1024: i64 = 1024 27const DS_MAGIC_65536: i64 = 65536 28const DS_MAGIC_65535: i64 = 65535 29const DS_MAGIC_8000: i64 = 8000 30const DS_MAGIC_2048: i64 = 2048 31const DS_MAGIC_2047: i64 = 2047 32const DS_MAGIC_10000: i64 = 10000 33 34const DS_REG: *u8 = "/volume1/homes/elderwesto/nishihost/daemons.reg" as *u8 35const DS_LOG: *u8 = "/volume1/homes/elderwesto/nishihost/daemon_supervisor.log" as *u8 36const DS_CYCLE_SEC: i64 = 15 37const DS_MAX: i64 = 64 38const DS_PROBE_TMO: i64 = 3 39const DS_REGCAP: i64 = 65536 40const DS_STATUS_PORT: i64 = 18095 41const DS_SHARED_SZ: i64 = 8192 42const DS_ROW_MAX: i64 = 256 // one /status row's bound (name<=64 + verdict + counters); reserved BEFORE every row append 43const DS_TRAILER_MAX: i64 = 256 // the progress trailer's bound (tick/row/last/stage ms); reserved so a tick is NEVER dropped for space 44const DS_RING: *u8 = "metrics.ring" as *u8 // sovereign bounded TSDB the supervisor writes inline 45 46func ds_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 47func ds_p(s: *u8) -> i64 { sys_write(1, s, ds_slen(s)); return 0 } 48func ds_log(s: *u8) -> i64 { 49 let fd: i64 = sys_openat_append(DS_LOG, 420) 50 if fd >= 0 { sys_write(fd, s, ds_slen(s)); sys_close(fd) } 51 sys_write(1, s, ds_slen(s)) 52 return 0 53} 54// ds_decw / ds_sappend live in nx_dsup_lib.nx (extracted 2026-09-02 so the gate drives the same code the daemon runs) 55 56// read the registry into a pre-allocated buffer (reused every cycle). Returns byte count (0 on error). 57// Deliberately NOT sys_read_file: that mmaps a fresh buffer per call (4 GiB when lseek can't size the file) 58// and never frees it -- the exact leak this rewrite exists to kill. 59func ds_read_reg(buf: *u8, cap: i64) -> i64 { 60 let fd: i64 = sys_openat_rd(DS_REG) 61 if fd < 0 { return 0 } 62 let n: i64 = sys_read(fd, buf, cap - 1) 63 sys_close(fd) 64 if n < 0 { return 0 } 65 return n 66} 67 68 69// ---- registry line/field walking (pipe fields) ---- 70func ds_next_line(buf: *u8, pos: i64, end: i64) -> i64 { 71 var p: i64 = pos 72 var go: i64 = 1 73 while go == 1 { if p >= end { go = 0 } else { if (buf[p] as i64) == 10 { p = p + 1; go = 0 } else { p = p + 1 } } } 74 return p 75} 76// end-offset of this line (the index of '\n' or end) 77func ds_line_end(buf: *u8, pos: i64, end: i64) -> i64 { 78 var p: i64 = pos 79 while p < end { if (buf[p] as i64) == 10 { return p } p = p + 1 } 80 return end 81} 82// copy pipe-field #idx (0-based) of the line buf[ls..le) into out (NUL-term, trimmed of edge spaces). ret len. 83func ds_field(buf: *u8, ls: i64, le: i64, idx: i64, out: *u8, cap: i64) -> i64 { 84 // advance fs past `idx` pipes to the start of the target field 85 var fs: i64 = ls 86 var seen: i64 = 0 87 while seen < idx { 88 if fs >= le { out[0] = 0 as u8; return 0 } 89 if (buf[fs] as i64) == 124 { seen = seen + 1 } 90 fs = fs + 1 91 } 92 // field end = next pipe or line end 93 var fe: i64 = fs 94 var g: i64 = 1 95 while g == 1 { if fe >= le { g = 0 } else { if (buf[fe] as i64) == 124 { g = 0 } else { fe = fe + 1 } } } 96 // trim leading spaces 97 var a: i64 = fs 98 var g2: i64 = 1 99 while g2 == 1 { if a >= fe { g2 = 0 } else { if (buf[a] as i64) == 32 { a = a + 1 } else { g2 = 0 } } } 100 // trim trailing spaces / CR 101 var b: i64 = fe 102 var g3: i64 = 1 103 while g3 == 1 { if b <= a { g3 = 0 } else { let c: i64 = buf[b - 1] as i64; if c == 32 { b = b - 1 } else { if c == 13 { b = b - 1 } else { g3 = 0 } } } } 104 var o: i64 = 0 105 var k: i64 = a 106 while k < b { if o < cap - 1 { out[o] = buf[k]; o = o + 1 } k = k + 1 } 107 out[o] = 0 as u8 108 return o 109} 110func ds_atoi(s: *u8) -> i64 { 111 var v: i64 = 0; var i: i64 = 0; var go: i64 = 1 112 while go == 1 { let c: i64 = s[i] as i64; if c < 48 { go = 0 } else { if c > 57 { go = 0 } else { v = v * 10 + (c - 48); i = i + 1 } } } 113 return v 114} 115func ds_streq(a: *u8, b: *u8) -> i64 { 116 var i: i64 = 0 117 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } 118 if b[i] != (0 as u8) { return 0 } 119 return 1 120} 121 122// ---- launch: fork, then (in the CHILD, matching the proven ah_run) build argv, chdir, execve ---- 123func ds_launch(cwd: *u8, cmd: *u8) -> i64 { 124 let pid: i64 = sys_fork() 125 if pid == 0 { 126 let work: *u8 = sys_mmap(DS_MAGIC_1024) 127 var n: i64 = 0 128 while cmd[n] != (0 as u8) { work[n] = cmd[n]; n = n + 1 } 129 work[n] = 0 as u8 130 let argv: *i64 = sys_mmap(64 * 8) as *i64 131 var ac: i64 = 0 132 var i: i64 = 0 133 var scan: i64 = 1 134 while scan == 1 { 135 var sk: i64 = 1 136 while sk == 1 { if i >= n { sk = 0 } else { if (work[i] as i64) == 32 { work[i] = 0 as u8; i = i + 1 } else { sk = 0 } } } 137 if i >= n { scan = 0 } 138 else { 139 if (work[i] as i64) == 34 { 140 // quoted token: "..." = ONE argv entry, quotes stripped -- needed for spaces-in-args 141 // (reader's live argv has the single argument `Nishi Wiki`, /proc-proven) 142 work[i] = 0 as u8 143 i = i + 1 144 if ac < 63 { argv[ac] = (((work as i64) + i)); ac = ac + 1 } 145 var qk: i64 = 1 146 while qk == 1 { if i >= n { qk = 0 } else { if (work[i] as i64) == 34 { work[i] = 0 as u8; i = i + 1; qk = 0 } else { i = i + 1 } } } 147 } 148 else { 149 if ac < 63 { argv[ac] = (((work as i64) + i)); ac = ac + 1 } 150 var tk: i64 = 1 151 while tk == 1 { if i >= n { tk = 0 } else { if (work[i] as i64) == 32 { tk = 0 } else { i = i + 1 } } } 152 } 153 } 154 } 155 argv[ac] = 0 156 let envp: *i64 = sys_mmap(8 * 4) as *i64 157 envp[0] = ("PATH=/usr/bin:/bin:/usr/local/bin" as *u8) as i64 158 envp[1] = ("HOME=/volume1/homes/elderwesto" as *u8) as i64 159 envp[2] = 0 160 sys_chdir(cwd) 161 let nul: i64 = sys_openat_rd("/dev/null\x00" as *u8) 162 if nul >= 0 { sys_dup3(nul, 0, 0) } 163 sys_execve_clean(argv[0] as *u8, argv, envp) 164 sys_exit(127) 165 } 166 return pid 167} 168 169// ---- kill any process whose /proc/<pid>/cmdline contains `needle` (used on HUNG to free the wedged port). 170// dbuf(dents)/path/cmdbuf allocated ONCE per call and munmap'd on exit -- NEVER sys_read_file (/proc lseek 171// is unknowable, so its 4 GiB fallback cap would map 4 GiB of VSZ per pid scanned). Runs only on HUNG revive. 172func ds_kill_wedged(needle: *u8) -> i64 { 173 let nlen: i64 = ds_slen(needle) 174 let dfd: i64 = sys_openat_rd("/proc\x00" as *u8) 175 if dfd < 0 { return 0 } 176 let dbuf: *u8 = sys_mmap(DS_MAGIC_65536) 177 let path: *u8 = sys_mmap(64) 178 let cmdbuf: *u8 = sys_mmap(DS_MAGIC_65536) 179 var killed: i64 = 0 180 var reading: i64 = 1 181 while reading == 1 { 182 let dn: i64 = sys_getdents64(dfd, dbuf, DS_MAGIC_65536) 183 if dn <= 0 { reading = 0 } 184 else { 185 var off: i64 = 0 186 while off < dn { 187 let recp: *u8 = (((dbuf as i64) + off)) as *u8 188 let reclen: i64 = dirent_reclen(recp) 189 let nm: *u8 = dirent_name(recp) 190 // numeric dir name -> a pid 191 if nm[0] >= (48 as u8) { if nm[0] <= (57 as u8) { 192 var pi: i64 = 0 193 let pre: *u8 = "/proc/" as *u8 194 while pre[pi] != (0 as u8) { path[pi] = pre[pi]; pi = pi + 1 } 195 var qi: i64 = 0 196 while nm[qi] != (0 as u8) { path[pi] = nm[qi]; pi = pi + 1; qi = qi + 1 } 197 let suf: *u8 = "/cmdline" as *u8 198 var si: i64 = 0 199 while suf[si] != (0 as u8) { path[pi] = suf[si]; pi = pi + 1; si = si + 1 } 200 path[pi] = 0 as u8 201 let cfd: i64 = sys_openat_rd(path) 202 if cfd >= 0 { 203 let clen: i64 = sys_read(cfd, cmdbuf, DS_MAGIC_65535) 204 sys_close(cfd) 205 if clen > 0 { 206 // cmdline is NUL-separated; replace NULs with spaces for substring search 207 var ci: i64 = 0 208 while ci < clen { if (cmdbuf[ci] as i64) == 0 { cmdbuf[ci] = 32 as u8 } ci = ci + 1 } 209 var found: i64 = 0 210 if clen >= nlen { 211 var s: i64 = 0 212 let last: i64 = clen - nlen 213 while s <= last { 214 var m: i64 = 0 215 var eq: i64 = 1 216 while m < nlen { if cmdbuf[s + m] != needle[m] { eq = 0; m = nlen } m = m + 1 } 217 if eq == 1 { found = 1; s = last + 1 } else { s = s + 1 } 218 } 219 } 220 if found == 1 { nx_kill(ds_atoi(nm), 9); killed = killed + 1 } 221 } 222 } 223 } } 224 off = off + reclen 225 } 226 } 227 } 228 sys_close(dfd) 229 sys_munmap(dbuf, DS_MAGIC_65536) 230 sys_munmap(path, 64) 231 sys_munmap(cmdbuf, DS_MAGIC_65536) 232 return killed 233} 234 235// ---- resolve the registry cmd's argv0 to an absolute binary path: "./x"|"x" -> cwd/x ; "/abs" -> as-is ---- 236func ds_resolve_bin(cwd: *u8, cmd: *u8, out: *u8) -> i64 { 237 var o: i64 = 0 238 var s: i64 = 0 239 if cmd[0] != (47 as u8) { 240 var ci: i64 = 0 241 while cwd[ci] != (0 as u8) { out[o] = cwd[ci]; o = o + 1; ci = ci + 1 } 242 if o > 0 { if out[o - 1] != (47 as u8) { out[o] = 47 as u8; o = o + 1 } } 243 if cmd[0] == (46 as u8) { if cmd[1] == (47 as u8) { s = 2 } } 244 } 245 var go: i64 = 1 246 while go == 1 { 247 if cmd[s] == (0 as u8) { go = 0 } 248 else { if (cmd[s] as i64) == 32 { go = 0 } 249 else { out[o] = cmd[s]; o = o + 1; s = s + 1 } } 250 } 251 out[o] = 0 as u8 252 return o 253} 254 255// ---- exe-identity sweep (ports the tools_selfheal.sh stale-inode port-theft guard into the organ) ---- 256// A daemon can look "healthy" while the WRONG binary serves: an instance running from a DELETED inode 257// (pre-deploy binary, or a port thief) responds fine but is stale code -- responds-health cannot see it 258// (this exact class ate a day of post-deploy checks on :18096). Identity = readlink /proc/<pid>/exe vs 259// the registry-resolved binary path. mode 0: return 1 if any "<bin> (deleted)" runner exists. mode 1: 260// kill -9 EVERY match (live or deleted -- mirrors tools_selfheal) and return the kill count. BY DESIGN 261// a deploy (mv new ELF over old) flips every revive row to the new binary within one cycle. Buffers are 262// caller-hoisted (bounded-VSZ); the readlink itself munmaps its own scratch. 263func ds_exe_sweep(bin: *u8, mode: i64, dbuf: *u8, path: *u8, rl: *u8) -> i64 { 264 let blen: i64 = ds_slen(bin) 265 let dfd: i64 = sys_openat_rd("/proc\x00" as *u8) 266 if dfd < 0 { return 0 } 267 var hit: i64 = 0 268 var reading: i64 = 1 269 while reading == 1 { 270 let dn: i64 = sys_getdents64(dfd, dbuf, DS_MAGIC_65536) 271 if dn <= 0 { reading = 0 } 272 else { 273 var off: i64 = 0 274 while off < dn { 275 let recp: *u8 = (((dbuf as i64) + off)) as *u8 276 let reclen: i64 = dirent_reclen(recp) 277 let nm: *u8 = dirent_name(recp) 278 if nm[0] >= (48 as u8) { if nm[0] <= (57 as u8) { 279 var pi: i64 = 0 280 let pre: *u8 = "/proc/" as *u8 281 while pre[pi] != (0 as u8) { path[pi] = pre[pi]; pi = pi + 1 } 282 var qi: i64 = 0 283 while nm[qi] != (0 as u8) { path[pi] = nm[qi]; pi = pi + 1; qi = qi + 1 } 284 let suf: *u8 = "/exe" as *u8 285 var si: i64 = 0 286 while suf[si] != (0 as u8) { path[pi] = suf[si]; pi = pi + 1; si = si + 1 } 287 path[pi] = 0 as u8 288 let n: i64 = sys_readlinkat(path, rl, 300) 289 if n >= blen { 290 var eq: i64 = 1 291 var k: i64 = 0 292 while k < blen { if rl[k] != bin[k] { eq = 0; k = blen } k = k + 1 } 293 if eq == 1 { 294 var kind: i64 = 0 295 if n == blen { kind = 1 } 296 if n == blen + 10 { 297 let dsx: *u8 = " (deleted)" as *u8 298 var dj: i64 = 0 299 var deq: i64 = 1 300 while dj < 10 { if rl[blen + dj] != dsx[dj] { deq = 0; dj = 10 } dj = dj + 1 } 301 if deq == 1 { kind = 2 } 302 } 303 if mode == 0 { if kind == 2 { hit = 1 } } 304 if mode == 1 { if kind > 0 { nx_kill(ds_atoi(nm), 9); hit = hit + 1 } } 305 } 306 } 307 } } 308 off = off + reclen 309 } 310 } 311 } 312 sys_close(dfd) 313 return hit 314} 315 316// ---- registry integrity gate (2026-07-16): the maturity census surfaced that daemons.reg is an 317// owner-writable plain file -> a local write injects revive-exec. We fork+exec nx_reg_sign VERIFY each 318// cycle (composition -- keeps the never-brick supervisor free of crypto) and apply a FAIL-SAFE policy 319// (below in main). The check itself can NEVER take the fleet down: any non-clean result falls to grace. 320// exit-code extract: signaled/stopped -> -1 (treated as check-unavailable, not tamper). 321func ds_exitcode(status: i64) -> i64 { 322 if (status & 127) != 0 { return 0 - 1 } 323 return (status >> 8) & 255 324} 325// returns: 0 valid · 3 invalid(TAMPER) · 4 sig-absent(grace) · 126 tool-missing · -1 signaled/timeout 326func ds_verify_reg() -> i64 { 327 let pid: i64 = sys_fork() 328 if pid == 0 { 329 let nul: i64 = sys_openat_rd("/dev/null\x00" as *u8) 330 if nul >= 0 { sys_dup3(nul, 1, 0); sys_dup3(nul, 2, 0) } 331 let argv: *i64 = sys_mmap(8 * 6) as *i64 332 argv[0] = ("./nx_reg_sign.elf" as *u8) as i64 333 argv[1] = ("verify" as *u8) as i64 334 argv[2] = ("daemons.reg" as *u8) as i64 335 argv[3] = ("tools_cap_secret.key" as *u8) as i64 336 argv[4] = 0 337 let envp: *i64 = sys_mmap(8 * 2) as *i64 338 envp[0] = 0 339 sys_execve_clean("./nx_reg_sign.elf" as *u8, argv, envp) 340 sys_exit(126) 341 } 342 if pid < 0 { return 0 - 1 } 343 let st: *i64 = sys_mmap(8) as *i64 344 var waited: i64 = 0 345 var rc: i64 = 0 - 1 346 var done: i64 = 0 347 while done == 0 { 348 let r: i64 = sys_wait4(pid, st, 1) 349 if r == pid { rc = ds_exitcode(st[0]); done = 1 } 350 else { 351 if waited >= DS_MAGIC_8000 { nx_kill(pid, 9); sys_wait4(pid, st, 0); done = 1 } 352 sys_sleep_ms(50) 353 waited = waited + 50 354 } 355 } 356 sys_munmap(st as *u8, 8) 357 return rc 358} 359 360// ---- sovereign /status server (forked child): serves the seqlock-shared fleet snapshot over HTTP on 361// 127.0.0.1:DS_STATUS_PORT. Replaces status FILES (tsv) entirely -- sovereign up and down: organ memory -> 362// shared page -> HTTP text only at the boundary (interop@boundary, sovereign@core). Exact Content-Length 363// (CL-LAW). The seqlock (seq odd=writer-active, re-check after copy) keeps reads tear-free without locks. 364// ---- PARENT PROBE (2026-09-02) -- the served page names the PARENT's kernel state ------------------------------ 365// Measured that day: three generations of this daemon published their initial snapshot and then never reached the 366// registry read, on the NAS only (the same binary ticks every 15 s on the laptop). From outside, a parent blocked in 367// D-state behind a btrfs transaction and a parent that died leave the SAME orphaned child serving the SAME page. 368// The child can answer that itself: /proc/self/stat field 4 is its parent's pid, and /proc/<ppid>/stat + wchan say 369// whether that parent is S, D, R or gone (ppid 1 = ORPHAN). One bounded read each, appended to every response, so 370// the /status page carries the discriminator hostctl's guard and every seat lacked. No syscall the estate lacks. 371const DS_PROC_CAP: i64 = 512 372func ds_proc_read(path: *u8, buf: *u8, cap: i64) -> i64 { 373 let fd: i64 = sys_openat_rd(path) 374 if fd < 0 { return 0 - 1 } 375 let n: i64 = sys_read(fd, buf, cap - 1) 376 sys_close(fd) 377 if n < 0 { return 0 - 1 } 378 buf[n] = 0 as u8 379 return n 380} 381// ds_stat_state_at / ds_atoi_at / ds_stat_ppid live in nx_dsup_lib.nx (gate-driven on real stat-line shapes) 382func ds_proc_path(dst: *u8, pid: i64, leaf: *u8) -> i64 { 383 var w: i64 = 0 384 w = ds_sappend(dst, w, "/proc/" as *u8) 385 w = w + ds_decw(pid, (((dst as i64) + w)) as *u8) 386 w = ds_sappend(dst, w, leaf) 387 dst[w] = 0 as u8 388 return w 389} 390// append "parent pid=<p> state=<c> wchan=<sym>\n" (or the ORPHAN / UNREADABLE form) to body at blen; bounded. 391func ds_parent_line(body: *u8, blen: i64, pst: *u8, pwc: *u8, ppath: *u8) -> i64 { 392 if blen + 128 > DS_SHARED_SZ { return blen } 393 var w: i64 = blen 394 let sn: i64 = ds_proc_read("/proc/self/stat" as *u8, pst, DS_PROC_CAP) 395 if sn <= 0 { w = ds_sappend(body, w, "parent UNREADABLE(self-stat)\n" as *u8); return w } 396 let ppid: i64 = ds_stat_ppid(pst, sn) 397 if ppid <= 1 { w = ds_sappend(body, w, "parent ORPHAN(ppid=" as *u8); w = w + ds_decw(ppid, (((body as i64) + w)) as *u8); w = ds_sappend(body, w, ") -- the supervisor loop is DEAD, this child serves its last snapshot\n" as *u8); return w } 398 ds_proc_path(ppath, ppid, "/stat" as *u8) 399 let pn: i64 = ds_proc_read(ppath, pst, DS_PROC_CAP) 400 ds_proc_path(ppath, ppid, "/wchan" as *u8) 401 let wn: i64 = ds_proc_read(ppath, pwc, DS_PROC_CAP) 402 w = ds_sappend(body, w, "parent pid=" as *u8); w = w + ds_decw(ppid, (((body as i64) + w)) as *u8) 403 w = ds_sappend(body, w, " state=" as *u8) 404 let sp: i64 = ds_stat_state_at(pst, pn) 405 if pn > 0 { if sp >= 0 { body[w] = pst[sp]; w = w + 1 } } 406 if pn <= 0 { w = ds_sappend(body, w, "?" as *u8) } 407 w = ds_sappend(body, w, " wchan=" as *u8) 408 var k: i64 = 0 409 while k < wn { if k < 64 { if pwc[k] != (10 as u8) { body[w] = pwc[k]; w = w + 1 } } k = k + 1 } 410 if wn <= 0 { w = ds_sappend(body, w, "?" as *u8) } 411 body[w] = 10 as u8; w = w + 1 412 return w 413} 414 415func ds_status_server(shm: *u8) -> i64 { 416 let shq: *i64 = shm as *i64 417 let lfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0) 418 if lfd < 0 { sys_exit(3) } 419 let one: *i64 = sys_mmap(8) as *i64 420 one[0] = 1 421 sys_setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, one as *u8, 4) 422 let sa: *u8 = sys_mmap(16) 423 hp_sockaddr(sa, DS_STATUS_PORT, 127, 0, 0, 1) 424 if sys_bind(lfd, sa, 16) < 0 { 425 // NAMED, not silent (2026-09-02): a bind refusal here used to exit(4) without a word, so an instance whose port 426 // was held by an orphaned status child of an earlier generation ran with NO status surface and hostctl's cycle 427 // guard read it as silence. The line below is what tells the next reader which of the two it is. 428 ds_log("nx_daemon_supervisor: /status child could NOT bind 127.0.0.1:18095 -- another holder owns the port (an orphaned status child of an earlier generation?); this instance runs with NO status surface and hostctl's cycle guard reads it as silent\n" as *u8) 429 sys_exit(4) 430 } 431 sys_listen(lfd, 16) 432 let req: *u8 = sys_mmap(DS_MAGIC_2048) 433 let body: *u8 = sys_mmap(DS_SHARED_SZ) 434 let out: *u8 = sys_mmap(DS_SHARED_SZ + 256) 435 let pst: *u8 = sys_mmap(DS_PROC_CAP) // parent probe scratch (hoisted: no per-request mmap) 436 let pwc: *u8 = sys_mmap(DS_PROC_CAP) 437 let ppath: *u8 = sys_mmap(64) 438 var run: i64 = 1 439 while run == 1 { 440 let afd: i64 = sys_accept(lfd) 441 if afd >= 0 { 442 sys_set_socket_timeout(afd, 3) 443 sys_read(afd, req, DS_MAGIC_2047) 444 var blen: i64 = 0 445 var got: i64 = 0 446 var tries: i64 = 0 447 while got == 0 { 448 let s1: i64 = shq[0] 449 if (s1 % 2) == 0 { 450 var bl: i64 = shq[1] 451 if bl > DS_SHARED_SZ - 16 { bl = DS_SHARED_SZ - 16 } 452 if bl < 0 { bl = 0 } 453 var ci: i64 = 0 454 while ci < bl { body[ci] = shm[16 + ci]; ci = ci + 1 } 455 if shq[0] == s1 { blen = bl; got = 1 } 456 } 457 tries = tries + 1 458 if tries > DS_MAGIC_10000 { got = 1 } 459 } 460 blen = ds_parent_line(body, blen, pst, pwc, ppath) 461 var w: i64 = 0 462 w = ds_sappend(out, w, "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\nContent-Length: " as *u8) 463 w = w + ds_decw(blen, (((out as i64) + w)) as *u8) 464 out[w] = 13 as u8; w = w + 1 465 out[w] = 10 as u8; w = w + 1 466 out[w] = 13 as u8; w = w + 1 467 out[w] = 10 as u8; w = w + 1 468 var bi: i64 = 0 469 while bi < blen { out[w] = body[bi]; w = w + 1; bi = bi + 1 } 470 sys_write(afd, out, w) 471 sys_close(afd) 472 } 473 } 474 return 0 475} 476 477// ---- BOUNDED LIFE, DATA-DRIVEN (2026-09-02, /compare/loadgov LV9 ds_self_recycle) ---------------------------- 478// MEASURED 2026-09-02: this daemon held 5.9 GB of a 24 GB swap (VmSize 9.5 GB, +24-32 kB/s), was EXEMPT-TERM in 479// resgov by the never-terminate-what-nothing-restarts law, and the execution-surface census read it as launched 480// by NOTHING in the estate -- so the largest swap holder on the box was the one process no governor could touch. 481// The clock already solves this shape (TLN_MAXWINDOWS: bounded windows per life, clean exit, hostctl respawns). 482// This is the same discipline for the fleet supervisor, ARMED BY DATA: knowledge/status/daemon_supervisor.conf 483// carries `life_cycles=<n>` (0 or absent = never recycle, i.e. today's behaviour byte-for-byte). It must stay 484// unarmed until a parent exists (hostctl's hc_guard_dsup, same day) -- a supervisor that exits with no reviver 485// leaves the fleet unsupervised, which is why the bound is a conf row and not a compiled constant. 486// PURE decision below so a gate can pin it; the exit path kills the /status child first so the new instance 487// can bind DS_STATUS_PORT instead of inheriting an orphan on it. 488const DS_LIFE_CONF: *u8 = "/volume1/homes/elderwesto/nishihost/knowledge/status/daemon_supervisor.conf" 489const DS_LIFE_CAP: i64 = 4096 490func ds_self_recycle(cyc: i64, life: i64) -> i64 { 491 if life <= 0 { return 0 } 492 if cyc >= life { return 1 } 493 return 0 494} 495func ds_life_cycles() -> i64 { 496 let szp: *i64 = sys_mmap(16) as *i64 497 let b: *u8 = sys_read_file(DS_LIFE_CONF, szp) 498 if (b as i64) == 0 { return 0 } 499 let n: i64 = szp[0] 500 // ROOT CAUSE OF THE SILENT SUPERVISOR (2026-09-02, measured by the status child's parent probe: parent state=R 501 // wchan=0 on every generation since this conf was armed, while the identical binary ticked every 15 s on a laptop 502 // that has NO conf). The key match that stood here exited its inner loop by writing 99 into the cursor, which then 503 // read key[99] -- 87 bytes PAST the 12-byte literal -- and looped for as long as that rodata byte was non-zero. 504 // nx_srclint's CURSOR-SENTINEL idiom, inside the organ that supervises the fleet. The match is now ds_conf_int 505 // (nx_dsup_lib): line-anchored, every exit a return, gate-driven with a NAS-shaped conf (nx_daemon_supervisor_gate). 506 let v: i64 = ds_conf_int(b, n, "life_cycles=" as *u8) 507 sys_munmap(b, n) 508 return v 509} 510 511// seqlock publish of stat[0..sw) followed by the trailer tb[0..tw): ONE writer (the parent); the /status child re-checks 512// the seq. Extracted 2026-09-02 so the initial snapshot, every per-row publish and the cycle-end publish are ONE ruler. 513func ds_publish(shm: *u8, shq: *i64, stat: *u8, sw: i64, tb: *u8, tw: i64) -> i64 { 514 shq[0] = shq[0] + 1 515 var pj: i64 = 0 516 while pj < sw { shm[16 + pj] = stat[pj]; pj = pj + 1 } 517 var tj: i64 = 0 518 while tj < tw { shm[16 + sw + tj] = tb[tj]; tj = tj + 1 } 519 shq[1] = sw + tw 520 shq[0] = shq[0] + 1 521 return 0 522} 523// ds_clamp0 / ds_trailer live in nx_dsup_lib.nx (the progress trailer is gate-pinned there) 524// a row past its own probe bound is blocked OUTSIDE the probe (exe sweep / ring append / fork = the storm's D-state) -- 525// name the stage in the log so the blocker is read, not guessed. lb is the hoisted 256 B line buffer. 526func ds_slow_row(lb: *u8, nm: *u8, total: i64, a: i64, b: i64, c: i64) -> i64 { 527 var w: i64 = 0 528 w = ds_sappend(lb, w, "supervisor: SLOW-ROW " as *u8); w = ds_sappend(lb, w, nm) 529 w = ds_sappend(lb, w, " ms=" as *u8); w = w + ds_decw(ds_clamp0(total), (((lb as i64) + w)) as *u8) 530 w = ds_sappend(lb, w, " sweep=" as *u8); w = w + ds_decw(ds_clamp0(a), (((lb as i64) + w)) as *u8) 531 w = ds_sappend(lb, w, " probe=" as *u8); w = w + ds_decw(ds_clamp0(b), (((lb as i64) + w)) as *u8) 532 w = ds_sappend(lb, w, " after=" as *u8); w = w + ds_decw(ds_clamp0(c), (((lb as i64) + w)) as *u8) 533 w = ds_sappend(lb, w, " (blocked outside the probe bound)\n" as *u8) 534 lb[w] = 0 as u8 535 return ds_log(lb) 536} 537func ds_cycle_log(lb: *u8, rows: i64, ms: i64) -> i64 { 538 var w: i64 = 0 539 w = ds_sappend(lb, w, "nx_daemon_supervisor: first cycle published rows=" as *u8); w = w + ds_decw(rows, (((lb as i64) + w)) as *u8) 540 w = ds_sappend(lb, w, " cycle_ms=" as *u8); w = w + ds_decw(ds_clamp0(ms), (((lb as i64) + w)) as *u8) 541 w = ds_sappend(lb, w, " (the /status snapshot now carries cycle=1 with rows)\n" as *u8) 542 lb[w] = 0 as u8 543 return ds_log(lb) 544} 545 546func main() -> i64 { 547 ds_log("nx_daemon_supervisor: LIVE -- data-driven fleet supervision from daemons.reg (responds-health + tls-probe + exe-identity + revive + /status, bounded-VSZ)\n" as *u8) 548 // per-name consecutive-fail state (parallel arrays, matched by name each cycle). names[] entries are 549 // persisted name copies (mmap'd once per NEW name, bounded to DS_MAX -- not a per-cycle allocation). 550 let names: *i64 = sys_mmap(DS_MAX * 8) as *i64 551 let fails: *i64 = sys_mmap(DS_MAX * 8) as *i64 552 var nstate: i64 = 0 553 // sovereign /status surface: THIS loop writes the fleet snapshot into a fork-shared seqlock page each 554 // cycle; a forked child serves it on 127.0.0.1:DS_STATUS_PORT. No tsv, no status files, no shell. 555 let shm: *u8 = sys_mmap_shared(DS_SHARED_SZ) 556 let shq: *i64 = shm as *i64 557 shq[0] = 0 558 shq[1] = 0 559 let sspid: i64 = sys_fork() 560 if sspid == 0 { ds_status_server(shm); sys_exit(0) } 561 var cyc: i64 = 0 562 // --- hoisted reusable buffers: allocated ONCE, reused every cycle. The loop below does ZERO sys_mmap. --- 563 let rst: *i64 = sys_mmap(8) as *i64 564 let regbuf: *u8 = sys_mmap(DS_REGCAP) 565 let nm: *u8 = sys_mmap(64) 566 let cwd: *u8 = sys_mmap(256) 567 let cmd: *u8 = sys_mmap(512) 568 let pb: *u8 = sys_mmap(16) 569 let arm: *u8 = sys_mmap(16) 570 let pt: *u8 = sys_mmap(16) 571 let lb: *u8 = sys_mmap(256) 572 let rb: *u8 = sys_mmap(256) 573 let sbin: *u8 = sys_mmap(320) 574 let sdbuf: *u8 = sys_mmap(DS_MAGIC_65536) 575 let spath: *u8 = sys_mmap(64) 576 let srl: *u8 = sys_mmap(320) 577 let stat: *u8 = sys_mmap(DS_SHARED_SZ) 578 let tb: *u8 = sys_mmap(DS_TRAILER_MAX) 579 var tick: i64 = 0 // monotonic publish counter (see ds_trailer) 580 // INITIAL SNAPSHOT (2026-09-02): publish `cycle=1 starting` BEFORE the first probe loop. The status child served an 581 // EMPTY body for the whole first cycle (and forever, when a parent died before its first publish), and hostctl's 582 // cycle guard could not tell "starting" from "orphaned". cycle=1 here, so the guard's first observation is an 583 // ADVANCE from its zeroed state; the loop's first publish repeats 1 and its second advances to 2. 584 var sw0: i64 = 0 585 sw0 = ds_sappend(stat, sw0, "nx_daemon_supervisor fleet (daemons.reg) cycle=1 starting -- first probe loop not yet complete\n" as *u8) 586 tick = tick + 1 587 let tw0: i64 = ds_trailer(tb, tick, 0, "-" as *u8, 0, 0, 0, 1, 0) 588 ds_publish(shm, shq, stat, sw0, tb, tw0) 589 let goodbuf: *u8 = sys_mmap(DS_REGCAP) // last integrity-VALID registry bytes (held on tamper) 590 var goodlen: i64 = 0 591 var trust_state: i64 = 0 - 1 // prev integrity state, for edge-triggered (no-spam) logging 592 var forever: i64 = 1 593 while forever == 1 { 594 // reap any exited launched children so they never zombie (reuses rst) 595 var reap: i64 = 1 596 while reap == 1 { if sys_wait4(0 - 1, rst, 1) > 0 { reap = 1 } else { reap = 0 } } 597 598 cyc = cyc + 1 599 var rowi: i64 = 0 // rows completed this cycle (the trailer's row=) 600 let t_cyc0: i64 = sys_now_realtime_ms() 601 // BOUNDED LIFE (2026-09-02): data-armed via daemon_supervisor.conf life_cycles=; 0/absent = never. Kills the 602 // /status child first so the respawned instance can bind DS_STATUS_PORT; the children in daemons.reg are NOT 603 // touched (they are setsid daemons and the next instance re-adopts them by name, exactly as after a crash). 604 if ds_self_recycle(cyc, ds_life_cycles()) == 1 { 605 ds_log("nx_daemon_supervisor: LIFE-RECYCLE -- cycle bound reached (daemon_supervisor.conf life_cycles); clean exit, the parent guard (nx_hostctl hc_guard_dsup) respawns a fresh instance; fleet daemons untouched\n" as *u8) 606 nx_kill(sspid, 9) 607 sys_exit(0) 608 } 609 let now: i64 = sys_now_realtime_sec() // one timestamp for this cycle's TSDB samples 610 var sw: i64 = 0 611 sw = ds_sappend(stat, sw, "nx_daemon_supervisor fleet (daemons.reg) cycle=" as *u8) 612 sw = sw + ds_decw(cyc, (((stat as i64) + sw)) as *u8) 613 614 var rlen: i64 = ds_read_reg(regbuf, DS_REGCAP) 615 // PRE-LOOP STAGE TICKS (2026-09-02): the registry read and the signature verify (a fork+exec of nx_reg_sign under an 616 // 8 s bound) run BEFORE the first row, so a parent that blocks or dies there publishes no row tick and the page reads 617 // exactly like a parent that never started its loop. Publish a tick after each stage, named in last=, so the page 618 // says WHICH pre-loop stage the parent last completed. ms_after carries the stage's own cost. 619 tick = tick + 1 620 let twg: i64 = ds_trailer(tb, tick, rowi, "stage:regread" as *u8, 0, 0, sys_now_realtime_ms() - t_cyc0, 1, 0) 621 ds_publish(shm, shq, stat, sw, tb, twg) 622 let t_vr0: i64 = sys_now_realtime_ms() 623 // ---- INTEGRITY GATE (verify-before-apply; FAIL-SAFE; never bricks) ---- 624 // signing is a DELIBERATE act (nx_reg_sign sign), so an un-re-signed change = "changed outside the 625 // signer" = the threat. valid -> apply + cache good. sig-absent -> grace (migration). invalid -> 626 // HOLD last-good (tamper caught + surfaced), or cold-start grace if no good yet. check-unavailable 627 // (tool missing/timeout) -> grace + a DISTINCT note (never a false tamper alarm). 628 let vrc: i64 = ds_verify_reg() 629 var trust: *u8 = "signed" as *u8 630 var tcode: i64 = 0 631 if vrc == 0 { 632 goodlen = rlen 633 var gi: i64 = 0; while gi < rlen { goodbuf[gi] = regbuf[gi]; gi = gi + 1 } 634 } else { if vrc == 4 { 635 trust = "unsigned-grace" as *u8; tcode = 1 636 goodlen = rlen 637 var gj: i64 = 0; while gj < rlen { goodbuf[gj] = regbuf[gj]; gj = gj + 1 } 638 } else { if vrc == 3 { 639 if goodlen > 0 { 640 trust = "HELD-TAMPER" as *u8; tcode = 2 641 var gk: i64 = 0; while gk < goodlen { regbuf[gk] = goodbuf[gk]; gk = gk + 1 } 642 rlen = goodlen 643 } else { trust = "UNVERIFIED-coldstart" as *u8; tcode = 3 } 644 } else { 645 // tool missing / signaled / timeout: cannot claim integrity, but do not brick or false-alarm 646 trust = "check-unavailable" as *u8; tcode = 4 647 if goodlen == 0 { goodlen = rlen; var gm: i64 = 0; while gm < rlen { goodbuf[gm] = regbuf[gm]; gm = gm + 1 } } 648 } } } 649 // edge-triggered security log (only on transition -- no 15s spam) 650 if tcode != trust_state { 651 var lw: i64 = 0 652 if tcode == 2 { lw = ds_sappend(lb, lw, "supervisor: SECURITY daemons.reg signature INVALID -> HOLDING last-good, refusing to apply (run nx_reg_sign after legit edits)\n" as *u8) } 653 else { if tcode == 3 { lw = ds_sappend(lb, lw, "supervisor: SECURITY daemons.reg INVALID at cold-start, no last-good -> grace-applied (CRITICAL: sign the registry)\n" as *u8) } 654 else { if tcode == 1 { lw = ds_sappend(lb, lw, "supervisor: NOTE daemons.reg UNSIGNED -> grace; run nx_reg_sign sign to enable tamper-evidence\n" as *u8) } 655 else { if tcode == 4 { lw = ds_sappend(lb, lw, "supervisor: NOTE integrity check unavailable (nx_reg_sign.elf?) -> grace-applied\n" as *u8) } 656 else { lw = ds_sappend(lb, lw, "supervisor: daemons.reg integrity OK (signed)\n" as *u8) } } } } 657 lb[lw] = 0 as u8 658 ds_log(lb) 659 trust_state = tcode 660 } 661 sw = ds_sappend(stat, sw, " integrity=" as *u8) 662 sw = ds_sappend(stat, sw, trust) 663 stat[sw] = 10 as u8 664 sw = sw + 1 665 tick = tick + 1 666 let twv: i64 = ds_trailer(tb, tick, rowi, "stage:verify" as *u8, 0, 0, sys_now_realtime_ms() - t_vr0, 1, 0) 667 ds_publish(shm, shq, stat, sw, tb, twv) 668 669 if rlen > 0 { 670 var pos: i64 = 0 671 while pos < rlen { 672 // skip blank / comment lines 673 if (regbuf[pos] as i64) == 35 { pos = ds_next_line(regbuf, pos, rlen) } 674 else { if (regbuf[pos] as i64) == 10 { pos = pos + 1 } 675 else { if (regbuf[pos] as i64) == 13 { pos = pos + 1 } 676 else { 677 let le: i64 = ds_line_end(regbuf, pos, rlen) 678 let nn: i64 = ds_field(regbuf, pos, le, 0, nm, 64) 679 ds_field(regbuf, pos, le, 1, cwd, 256) 680 ds_field(regbuf, pos, le, 2, cmd, 512) 681 ds_field(regbuf, pos, le, 3, pb, 16) 682 ds_field(regbuf, pos, le, 4, arm, 16) 683 ds_field(regbuf, pos, le, 5, pt, 16) // probe type: "tls" or "" (default http) 684 if nn > 0 { 685 let t_row0: i64 = sys_now_realtime_ms() 686 let port: i64 = ds_atoi(pb) 687 // find/allocate fail-state slot for this name 688 var slot: i64 = 0 - 1 689 var si: i64 = 0 690 while si < nstate { if ds_streq((names[si]) as *u8, nm) == 1 { slot = si; si = nstate } si = si + 1 } 691 if slot < 0 { if nstate < DS_MAX { 692 let np: *u8 = sys_mmap(64); var ci: i64 = 0; while nm[ci] != (0 as u8) { np[ci] = nm[ci]; ci = ci + 1 } np[ci] = 0 as u8 693 names[nstate] = np as i64; fails[nstate] = 0; slot = nstate; nstate = nstate + 1 694 } } 695 // arm semantics ladder: watch (observe) < guard (kill wedges + stale inodes; the 696 // PRIMARY owner relaunches -- control-plane wedge-arm parity) < revive (guard + the 697 // organ itself relaunches when nothing else does). 698 let is_rev: i64 = ds_streq(arm, "revive" as *u8) 699 let is_grd: i64 = ds_streq(arm, "guard" as *u8) 700 // exe-identity guard (revive+guard rows): a stale-inode runner serves "healthy" 701 // from pre-deploy code. KILL every match, then DON'T launch here -- a faster primary 702 // owner (nx_hostctl's ppid-respawn, seconds) relaunches from the new inode and the 703 // next probe sees SERVING; with no primary, the normal 2-fail discipline backstops. 704 // Launching here would contest the bind against the primary's respawn loop. 705 if is_rev + is_grd >= 1 { 706 ds_resolve_bin(cwd, cmd, sbin) 707 if ds_exe_sweep(sbin, 0, sdbuf, spath, srl) == 1 { 708 let nk: i64 = ds_exe_sweep(sbin, 1, sdbuf, spath, srl) 709 var rw: i64 = 0 710 let f1: *u8 = "supervisor: EXE-PURGE " as *u8; var fi: i64 = 0; while f1[fi] != (0 as u8) { rb[rw] = f1[fi]; rw = rw + 1; fi = fi + 1 } 711 var fn: i64 = 0; while nm[fn] != (0 as u8) { rb[rw] = nm[fn]; rw = rw + 1; fn = fn + 1 } 712 let f2: *u8 = " stale-inode killed=" as *u8; fi = 0; while f2[fi] != (0 as u8) { rb[rw] = f2[fi]; rw = rw + 1; fi = fi + 1 } 713 rw = rw + ds_decw(nk, (((rb as i64) + rw)) as *u8) 714 let f3: *u8 = " (relaunch: primary owner, else 2-fail backstop)" as *u8; fi = 0; while f3[fi] != (0 as u8) { rb[rw] = f3[fi]; rw = rw + 1; fi = fi + 1 } 715 rb[rw] = 10 as u8; rw = rw + 1; rb[rw] = 0 as u8 716 ds_log(rb) 717 } 718 } 719 let t_sw: i64 = sys_now_realtime_ms() 720 var v: i64 = 0 721 if ds_streq(pt, "tls" as *u8) == 1 { v = hp_probe_tls(port, DS_PROBE_TMO) } 722 else { if ds_streq(pt, "ws" as *u8) == 1 { v = hp_probe_ws(port, DS_PROBE_TMO) } 723 else { v = hp_probe(port, DS_PROBE_TMO) } } 724 let t_pr: i64 = sys_now_realtime_ms() 725 if v == HP_SERVING { if slot >= 0 { fails[slot] = 0 } } 726 else { 727 if slot >= 0 { fails[slot] = fails[slot] + 1 } 728 // slot < 0 means the name table filled (DS_MAX): fails[-1] reads the word BEFORE the 729 // array -- a garbage counter that then decides BOTH remediation (fc == 2 revives) and 730 // log suppression (fc <= 3 logs, else every 40th), so an over-capacity row could be 731 // silently never revived AND never logged -- invisible in both channels at once. 732 // The increment above was already guarded; this read was not. 733 var fc: i64 = 0 734 if slot >= 0 { fc = fails[slot] } 735 // log the down/hung sighting (reuses lb) 736 var w: i64 = 0 737 let m1: *u8 = "supervisor: " as *u8; var mi: i64 = 0; while m1[mi] != (0 as u8) { lb[w] = m1[mi]; w = w + 1; mi = mi + 1 } 738 var qi: i64 = 0; while nm[qi] != (0 as u8) { lb[w] = nm[qi]; w = w + 1; qi = qi + 1 } 739 let m2: *u8 = " probe=" as *u8; mi = 0; while m2[mi] != (0 as u8) { lb[w] = m2[mi]; w = w + 1; mi = mi + 1 } 740 let pv: *u8 = hp_name(v); var vi: i64 = 0; while pv[vi] != (0 as u8) { lb[w] = pv[vi]; w = w + 1; vi = vi + 1 } 741 let m3: *u8 = " fails=" as *u8; mi = 0; while m3[mi] != (0 as u8) { lb[w] = m3[mi]; w = w + 1; mi = mi + 1 } 742 w = w + ds_decw(fc, (((lb as i64) + w)) as *u8) 743 lb[w] = 10 as u8; w = w + 1; lb[w] = 0 as u8 744 // suppress steady-state down-spam on watch rows: log the transition (fails 1-3), 745 // then resurface every 40th cycle (~10 min). /status always shows live truth. 746 if fc <= 3 { ds_log(lb) } else { if (fc % 40) == 0 { ds_log(lb) } } 747 // ARMED remediation on 2 consecutive fails, split by verdict: 748 // HUNG -> KILL-ONLY (frees the wedged port; primary respawns, else the 749 // REFUSED path backstops next cycle -- never contest the bind) 750 // REFUSED -> revive rows launch (nothing is listening; safe to bind) 751 // BADRESP -> wrong process holds the port; surfaced via log//status only 752 if fc >= 2 { if is_rev + is_grd >= 1 { 753 if v == HP_HUNG { 754 let wk: i64 = ds_kill_wedged(cmd) 755 var ww: i64 = 0 756 let w1: *u8 = "supervisor: WEDGE-KILL " as *u8; var wi: i64 = 0; while w1[wi] != (0 as u8) { rb[ww] = w1[wi]; ww = ww + 1; wi = wi + 1 } 757 var wn: i64 = 0; while nm[wn] != (0 as u8) { rb[ww] = nm[wn]; ww = ww + 1; wn = wn + 1 } 758 let w2: *u8 = " killed=" as *u8; wi = 0; while w2[wi] != (0 as u8) { rb[ww] = w2[wi]; ww = ww + 1; wi = wi + 1 } 759 ww = ww + ds_decw(wk, (((rb as i64) + ww)) as *u8) 760 let w3: *u8 = " (relaunch: primary owner, else backstop)" as *u8; wi = 0; while w3[wi] != (0 as u8) { rb[ww] = w3[wi]; ww = ww + 1; wi = wi + 1 } 761 rb[ww] = 10 as u8; ww = ww + 1; rb[ww] = 0 as u8 762 ds_log(rb) 763 } 764 if v == HP_REFUSED { if is_rev == 1 { 765 let newpid: i64 = ds_launch(cwd, cmd) 766 var rw: i64 = 0 767 let r1: *u8 = "supervisor: REVIVED " as *u8; var ri: i64 = 0; while r1[ri] != (0 as u8) { rb[rw] = r1[ri]; rw = rw + 1; ri = ri + 1 } 768 var ni: i64 = 0; while nm[ni] != (0 as u8) { rb[rw] = nm[ni]; rw = rw + 1; ni = ni + 1 } 769 let r2: *u8 = " pid=" as *u8; ri = 0; while r2[ri] != (0 as u8) { rb[rw] = r2[ri]; rw = rw + 1; ri = ri + 1 } 770 rw = rw + ds_decw(newpid, (((rb as i64) + rw)) as *u8) 771 rb[rw] = 10 as u8; rw = rw + 1; rb[rw] = 0 as u8 772 ds_log(rb) 773 fails[slot] = 0 774 } } 775 } } 776 } 777 // SOVEREIGN TSDB (folded in 2026-07-16, operator "no sprawl"): the PRODUCER writes 778 // its own sample -- the supervisor already computed v (this cycle's probe) + the fail 779 // count, so it appends inline. No separate collector, no HTTP self-poll (that was 780 // sprawl re-deriving this organ's own output). Fail-safe: mr_append returns <0 on any 781 // error and is ignored -- a bounded data-file append can never brick (rule 26 = hw). 782 var rf: i64 = 0 783 if slot >= 0 { rf = fails[slot] } 784 mr_append(DS_RING, now, mr_hash(nm), v, rf) 785 // /status row: name verdict fails arm probe :port (bounded append) 786 if sw < DS_SHARED_SZ - DS_ROW_MAX - DS_TRAILER_MAX { 787 sw = ds_sappend(stat, sw, nm) 788 sw = ds_sappend(stat, sw, " " as *u8) 789 sw = ds_sappend(stat, sw, hp_name(v)) 790 sw = ds_sappend(stat, sw, " fails=" as *u8) 791 var fv: i64 = 0 792 if slot >= 0 { fv = fails[slot] } 793 sw = sw + ds_decw(fv, (((stat as i64) + sw)) as *u8) 794 sw = ds_sappend(stat, sw, " " as *u8) 795 sw = ds_sappend(stat, sw, arm) 796 sw = ds_sappend(stat, sw, " " as *u8) 797 if pt[0] == (0 as u8) { sw = ds_sappend(stat, sw, "http" as *u8) } else { sw = ds_sappend(stat, sw, pt) } 798 sw = ds_sappend(stat, sw, " :" as *u8) 799 sw = sw + ds_decw(port, (((stat as i64) + sw)) as *u8) 800 stat[sw] = 10 as u8 801 sw = sw + 1 802 } 803 // PER-ROW PROGRESS (2026-09-02): publish after EVERY row, not only at cycle end, so /status shows the row 804 // being worked and its stage costs while the cycle is in flight. A cycle-granular counter read "wedged" 805 // for a cycle that was merely slow under the storm; a row-granular tick names the slow stage instead. 806 rowi = rowi + 1 807 let t_ap: i64 = sys_now_realtime_ms() 808 tick = tick + 1 809 let twr: i64 = ds_trailer(tb, tick, rowi, nm, t_sw - t_row0, t_pr - t_sw, t_ap - t_pr, 1, 0) 810 ds_publish(shm, shq, stat, sw, tb, twr) 811 if t_ap - t_row0 > DS_PROBE_TMO * 1000 { ds_slow_row(lb, nm, t_ap - t_row0, t_sw - t_row0, t_pr - t_sw, t_ap - t_pr) } 812 } 813 pos = ds_next_line(regbuf, pos, rlen) 814 } } } 815 } 816 } 817 // seqlock publish of this cycle's snapshot (odd seq = writer active; readers re-check) 818 tick = tick + 1 819 let twc: i64 = ds_trailer(tb, tick, rowi, "-" as *u8, 0, 0, 0, 0, sys_now_realtime_ms() - t_cyc0) 820 ds_publish(shm, shq, stat, sw, tb, twc) 821 // the first boundary is LOGGED once (2026-09-02): a parent that dies inside its first cycle leaves no trace, and 822 // a parent that finishes it leaves this line -- the discriminator the orphan investigation lacked. Carries rows= and 823 // cycle_ms= so the first cycle's cost under whatever load it met is a number, not an adjective. 824 if cyc == 1 { ds_cycle_log(lb, rowi, sys_now_realtime_ms() - t_cyc0) } 825 sys_sleep_ms(DS_CYCLE_SEC * 1000) 826 } 827 return 0 828}