code wiki / _hdl_build / nx_boot_revive.nx

nx_boot_revive.nx source

↩ module page · 661 lines · 32680 B

1// nx_boot_revive.nx -- the DOCTOR's boot-resurrection organ (verb: HEAL). CR1 of the 2// crash-recovery ladder (knowledge/specs/2026-06-10-crash-recovery-ladder.md). 3// 4// WHY: the 2026-06-10 Windows reboot proved recovery REQUIRED a live session: /tmp organs 5// were gone (4/16 present), the pulse daemon was dead, and the team self-healed only 6// LAZILY (tp_run heals the 11 pulse steps when a pulse happens to run) and only because a 7// session restarted the daemon by hand. This organ makes recovery a single durable unit a 8// boot hook fires with ZERO sessions: 9// (1) BOOT DETECT -- boot_epoch = now - /proc/uptime; one BOOT row per boot appended to 10// knowledge/status/boot_journal.log incl. dark_gap = boot_epoch - last DAEMON-BEAT 11// (how long the substrate was DOWN -- the crash is measured, not inferred). 12// (2) ORGAN REVIVE -- every E row of triage_expected.conf absent-but-recoverable is 13// rebuilt NOW via _offc/nx_sov_build_run.elf, each under a hard watchdog deadline 14// (conf B row, seconds; WNOHANG poll + SIGKILL reap, nx_guarded_run idiom -- a hung 15// build/run becomes a counted TIMEOUT, never a wedged boot). 16// (3) DAEMON REVIVE -- every D row not found in /proc is re-armed via the same runner 17// (the daemon's own pidfile dup-guard makes re-arming idempotent). 18// Durable REVIVE line -> knowledge/status/boot_revive.log. Verdict GREEN only if all 19// expected organs are present and daemons running and nothing timed out; W-lane and 20// no-source absences stay LOUD (named debts, never silently skipped). 21// (4) ORPHANED INTENTS (CR4) -- scan the intent WAL (knowledge/status/intent_wal.log, 22// INTENT-START/INTENT-DONE rows written by self-journaling work units like 23// nx_team_pulse): any START from BEFORE this boot with no DONE = work the crash 24// interrupted mid-flight; it is auto-FILED as a pm_plan row (owner=Conductor) and 25// marked INTENT-FILED in the WAL so re-runs never refile (idempotent). STARTs from 26// THIS boot are in-flight, never filed. 27// argv[1]=conf override, argv[2]=log override, argv[3]=journal override, 28// argv[4]=intent-WAL override, argv[5]=pm-plan override (gate fixtures). 29// Sovereign (syscalls only, no .sh). Run from nxc2 root. license_tier: ORIGINAL 30// (1c) REPLAY + RESUME (M6, crash-recovery capstone) -- on boot, REPLAY the WMS-R2 31// transition reflog (nx_ws_ledger.ledger_replay) to reconstruct the AUTHORITATIVE 32// current state of every workstream, then check WMS-M1 heartbeats 33// (nx_heartbeat_monitor.hbm_scan) to find streams that were IN-FLIGHT at the crash 34// (recently beating == HB_ALIVE) AND not marked DONE -> resume EXACTLY those. 35// Completed streams (state==BR_WS_DONE) are ignored; stale streams (HB_STALLED / 36// HB_UNKNOWN) are reported but NOT resumed (not in-flight at the crash boundary). 37// Each resume = ONE framed record via fa_appendz to a resume journal. The crash 38// that started this whole arc becomes a non-event. Purely ADDITIVE: existing 39// boot-detect / orphan-revive / organ-revive / daemon-revive are byte-identical. 40// argv[6]=ledger override, argv[7]=heartbeat override, argv[8]=resume-journal override, 41// argv[9]=now override (no hidden wall-clock for the gate), argv[10]=threshold override. 42import "nx_syscalls.nx" 43import "nx_ws_ledger.nx" 44import "nx_heartbeat_monitor.nx" 45const BR_MAGIC_65536: i64 = 65536 46const BR_MAGIC_1048592: i64 = 1048592 47const BR_MAGIC_1048576: i64 = 1048576 48const BR_MAGIC_16384: i64 = 16384 49const BR_MAGIC_65520: i64 = 65520 50 51const BR_WS_DONE: i64 = 3 // ledger DONE state code (ws_ledger gate: 0=TODO 1=WIP 2=VIEW 3=DONE 4=NOVEL; data-driven, Cardinal 11) 52const BR_HB_THRESHOLD: i64 = 120 // liveness window (sec): a beat within this == in-flight at crash; older == stale 53const BR_RESUME_MAXWS: i64 = 256 // ws-id range the replay state[] / scan ids[] can hold 54const BR_RESUME_CAP: i64 = 256 // bounded resume-journal record size (matches WMS RECCAP) 55const BR_TIMEOUT: i64 = 124 // GNU-timeout convention (nx_guarded_run idiom) 56const BR_SPAWN_FAIL: i64 = 125 // wait4 error 57const BR_SIGKILL: i64 = 9 // SIGTERM does not reap these hangs (2026-06-10 lesson) 58const BR_POLL_MS: i64 = 50 // watchdog poll granularity 59const BR_ARM_GRACE_MS: i64 = 200 // settle time between arming a daemon and recheck 60const BR_BOOT_JITTER: i64 = 90 // now-uptime recomputation jitter window (same boot if within) 61 62func _p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 63func _pn(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=48+(m%10);m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 } 64func _fp(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 65func _fn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(fd,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=48+(m%10);m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 } 66func br_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 67func br_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[off+i] = s[i]; i = i + 1 } return off + i } 68func br_exists(path: *u8) -> i64 { 69 let fd: i64 = sys_openat_rd(path) 70 if fd < 0 { return 0 } 71 sys_close(fd) 72 return 1 73} 74func br_read_all(path: *u8, buf: *u8, cap: i64) -> i64 { 75 let fd: i64 = sys_openat_rd(path) 76 if fd < 0 { return 0 } 77 var n: i64 = 0 78 var go: i64 = 1 79 while go == 1 { let base: i64 = buf as i64; let r: i64 = sys_read(fd, (base + n) as *u8, cap - n); if r <= 0 { go = 0 } else { n = n + r } if n >= cap { go = 0 } } 80 sys_close(fd) 81 return n 82} 83func br_contains(hay: *u8, n: i64, pat: *u8) -> i64 { 84 let pl: i64 = br_len(pat) 85 if pl == 0 { return 0 } 86 var i: i64 = 0 87 while i + pl <= n { 88 var k: i64 = 0 89 var hit: i64 = 1 90 while k < pl { if hay[i+k] != pat[k] { hit = 0; k = pl } else { k = k + 1 } } 91 if hit == 1 { return 1 } 92 i = i + 1 93 } 94 return 0 95} 96// LAST number following pat in buffer (-1 = no match) -- the triage idiom 97func br_last_num_after(hay: *u8, n: i64, pat: *u8) -> i64 { 98 let pl: i64 = br_len(pat) 99 if pl == 0 { return 0 - 1 } 100 var best: i64 = 0 - 1 101 var i: i64 = 0 102 while i + pl <= n { 103 var k: i64 = 0 104 var hit: i64 = 1 105 while k < pl { if hay[i+k] != pat[k] { hit = 0; k = pl } else { k = k + 1 } } 106 if hit == 1 { best = i + pl } 107 i = i + 1 108 } 109 if best < 0 { return 0 - 1 } 110 var v: i64 = 0 111 var q: i64 = best 112 var any: i64 = 0 113 while q < n { 114 if hay[q] >= (48 as u8) { if hay[q] <= (57 as u8) { v = v * 10 + ((hay[q] as i64) - 48); any = 1; q = q + 1 } else { q = n } } else { q = n } 115 } 116 if any == 0 { return 0 - 1 } 117 return v 118} 119func br_is_pid(name: *u8) -> i64 { 120 var i: i64 = 0 121 if name[0] == (0 as u8) { return 0 } 122 while name[i] != (0 as u8) { 123 if name[i] < (48 as u8) { return 0 } 124 if name[i] > (57 as u8) { return 0 } 125 i = i + 1 126 } 127 return 1 128} 129// organ presence: /tmp/<n>.sov.elf OR /tmp/<n>.elf OR _offc/<n>.elf (durable home counts) 130func br_organ_present(name: *u8) -> i64 { 131 let p: *u8 = sys_mmap(256) 132 var o: i64 = 0 133 o = br_cat(p, o, "/tmp/" as *u8); o = br_cat(p, o, name); o = br_cat(p, o, ".sov.elf" as *u8); p[o] = 0 as u8 134 if br_exists(p) == 1 { return 1 } 135 o = 0 136 o = br_cat(p, o, "/tmp/" as *u8); o = br_cat(p, o, name); o = br_cat(p, o, ".elf" as *u8); p[o] = 0 as u8 137 if br_exists(p) == 1 { return 1 } 138 o = 0 139 o = br_cat(p, o, "_offc/" as *u8); o = br_cat(p, o, name); o = br_cat(p, o, ".elf" as *u8); p[o] = 0 as u8 140 return br_exists(p) 141} 142// source presence mirrors the runner's lookup lanes 143func br_source_present(name: *u8) -> i64 { 144 let p: *u8 = sys_mmap(256) 145 var o: i64 = 0 146 o = br_cat(p, o, "runtime/_hdl_build/" as *u8); o = br_cat(p, o, name); o = br_cat(p, o, ".nx" as *u8); p[o] = 0 as u8 147 if br_exists(p) == 1 { return 1 } 148 o = 0 149 o = br_cat(p, o, "runtime/" as *u8); o = br_cat(p, o, name); o = br_cat(p, o, ".nx" as *u8); p[o] = 0 as u8 150 if br_exists(p) == 1 { return 1 } 151 o = 0 152 o = br_cat(p, o, "nxasm/" as *u8); o = br_cat(p, o, name); o = br_cat(p, o, ".nx" as *u8); p[o] = 0 as u8 153 return br_exists(p) 154} 155// run elf [a1] muted under a hard wall-clock deadline; WNOHANG poll + SIGKILL reap. 156// returns child exit / 128+sig / BR_TIMEOUT / BR_SPAWN_FAIL (nx_guarded_run idiom). 157func br_guarded(elf: *u8, a1: *u8, ms: i64) -> i64 { 158 let pid: i64 = sys_fork() 159 if pid == 0 { 160 let argv: *i64 = sys_mmap(32) as *i64 161 argv[0] = elf as i64 162 var i: i64 = 1 163 if (a1 as i64) != 0 { argv[i] = a1 as i64; i = i + 1 } 164 argv[i] = 0 165 let envp: *i64 = sys_mmap(16) as *i64; envp[0] = 0 166 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 167 if dn >= 0 { sys_dup3(dn, 1, 0); sys_dup3(dn, 2, 0) } 168 sys_execve(elf, argv, envp) 169 sys_exit(127) 170 } 171 let st: *i64 = sys_mmap(16) as *i64 172 let start: i64 = sys_now_ms() 173 var rc: i64 = 0 - 1 174 while rc < 0 { 175 let w: i64 = sys_wait4(pid, st, 1) 176 if w == pid { 177 let sig: i64 = st[0] & 0x7f 178 if sig != 0 { rc = 128 + sig } else { rc = (st[0] >> 8) & 0xff } 179 } 180 if w < 0 { rc = BR_SPAWN_FAIL } 181 if rc < 0 { 182 let el: i64 = sys_now_ms() - start 183 if el >= ms { 184 nx_kill(pid, BR_SIGKILL) 185 sys_wait4(pid, st, 0) 186 rc = BR_TIMEOUT 187 } else { sys_sleep_ms(BR_POLL_MS) } 188 } 189 } 190 return rc 191} 192// seconds since boot from /proc/uptime (leading integer); -1 if unreadable 193func br_uptime() -> i64 { 194 let b: *u8 = sys_mmap(128) 195 let n: i64 = br_read_all("/proc/uptime" as *u8, b, 120) 196 if n <= 0 { return 0 - 1 } 197 var v: i64 = 0 198 var i: i64 = 0 199 var go: i64 = 1 200 while go == 1 { 201 if i >= n { go = 0 } 202 else { 203 var dig: i64 = 0 204 if b[i] >= (48 as u8) { if b[i] <= (57 as u8) { dig = 1 } } 205 if dig == 1 { v = v * 10 + ((b[i] as i64) - 48); i = i + 1 } else { go = 0 } 206 } 207 } 208 return v 209} 210// does /proc/<nm>/cmdline contain sub? (one pid; 4 args, register path) 211func br_pid_match(nm: *u8, cmdl: *u8, ppath: *u8, sub: *u8) -> i64 { 212 var po: i64 = 0 213 po = br_cat(ppath, po, "/proc/" as *u8); po = br_cat(ppath, po, nm); po = br_cat(ppath, po, "/cmdline" as *u8); ppath[po] = 0 as u8 214 let cl: i64 = br_read_all(ppath, cmdl, 500) 215 if cl <= 0 { return 0 } 216 // ROBUST liveness: match only argv[0] (the executable), NOT the whole cmdline. A shell/grep/ 217 // session that merely MENTIONS the daemon name in a later arg (e.g. bash -lc '...name...') 218 // must NOT count as the daemon being alive -- otherwise a genuinely-dead daemon is never 219 // revived (a silent false-UP that keeps the substrate down). /proc/<pid>/cmdline is NUL- 220 // separated; argv[0] is the leading token, which for our daemons is the binary path. 221 var a0: i64 = 0 222 var go0: i64 = 1 223 while go0 == 1 { if a0 >= cl { go0 = 0 } else { if cmdl[a0] == (0 as u8) { go0 = 0 } else { a0 = a0 + 1 } } } 224 return br_contains(cmdl, a0, sub) 225} 226// is any live process's cmdline matching sub? (/proc sweep, triage idiom) 227func br_daemon_up(sub: *u8) -> i64 { 228 let pfd: i64 = sys_openat_rd("/proc" as *u8) 229 if pfd < 0 { return 0 } 230 let dirbuf: *u8 = sys_mmap(BR_MAGIC_65536) 231 let cmdl: *u8 = sys_mmap(512) 232 let ppath: *u8 = sys_mmap(256) 233 var found: i64 = 0 234 var done: i64 = 0 235 while done == 0 { 236 let nb: i64 = sys_getdents64(pfd, dirbuf, BR_MAGIC_65536) 237 if nb <= 0 { done = 1 } 238 else { 239 var off: i64 = 0 240 while off < nb { 241 let dbase: i64 = dirbuf as i64 242 let rec: *u8 = (dbase + off) as *u8 243 let rl: i64 = dirent_reclen(rec) 244 if rl <= 0 { off = nb } 245 else { 246 let nm: *u8 = dirent_name(rec) 247 if br_is_pid(nm) == 1 { found = found + br_pid_match(nm, cmdl, ppath, sub) } 248 off = off + rl 249 } 250 } 251 } 252 } 253 sys_close(pfd) 254 if found > 0 { return 1 } 255 return 0 256} 257// position right after pat inside [from,to) or -1 258func br_find_in(buf: *u8, from: i64, to: i64, pat: *u8) -> i64 { 259 let pl: i64 = br_len(pat) 260 var i: i64 = from 261 while i + pl <= to { 262 var k: i64 = 0 263 var hit: i64 = 1 264 while k < pl { if buf[i+k] != pat[k] { hit = 0; k = pl } else { k = k + 1 } } 265 if hit == 1 { return i + pl } 266 i = i + 1 267 } 268 return 0 - 1 269} 270// parse digits starting at pos (until non-digit or end); -1 if pos invalid or no digits 271func br_digits_at(buf: *u8, pos: i64, to: i64) -> i64 { 272 if pos < 0 { return 0 - 1 } 273 var v: i64 = 0 274 var any: i64 = 0 275 var q: i64 = pos 276 while q < to { 277 if buf[q] >= (48 as u8) { if buf[q] <= (57 as u8) { v = v * 10 + ((buf[q] as i64) - 48); any = 1; q = q + 1 } else { q = to } } else { q = to } 278 } 279 if any == 0 { return 0 - 1 } 280 return v 281} 282// CR4: file every intent that STARTED before this boot and never finished. WAL rows: 283// INTENT-START id= name= epoch= / INTENT-DONE id= / INTENT-FILED id= (our idempotence 284// mark). Orphan = START with no DONE, no FILED, start-epoch < boot_epoch. Returns count. 285func br_file_orphans(walpath: *u8, pmpath: *u8, boot_epoch: i64) -> i64 { 286 let w: *u8 = sys_mmap(BR_MAGIC_1048592) 287 let wn: i64 = br_read_all(walpath, w, BR_MAGIC_1048576) 288 if wn <= 0 { return 0 } 289 let sid: *i64 = sys_mmap(256*8) as *i64 290 let sep: *i64 = sys_mmap(256*8) as *i64 291 let snm: *i64 = sys_mmap(256*8) as *i64 292 var ns: i64 = 0 293 let did: *i64 = sys_mmap(512*8) as *i64 294 var ndone: i64 = 0 295 let fid: *i64 = sys_mmap(512*8) as *i64 296 var nfil: i64 = 0 297 let pool: *u8 = sys_mmap(BR_MAGIC_16384) 298 var poff: i64 = 0 299 var ci: i64 = 0 300 while ci < wn { 301 var le: i64 = ci 302 var scan: i64 = 1 303 while scan == 1 { 304 if le >= wn { scan = 0 } 305 else { if w[le] == (10 as u8) { scan = 0 } else { le = le + 1 } } 306 } 307 let ps: i64 = br_find_in(w, ci, le, "INTENT-START id=" as *u8) 308 if ps == ci + 16 { 309 let idv: i64 = br_digits_at(w, ps, le) 310 let ep: i64 = br_digits_at(w, br_find_in(w, ci, le, " epoch=" as *u8), le) 311 let np: i64 = br_find_in(w, ci, le, " name=" as *u8) 312 var keep: i64 = 1 313 if idv <= 0 { keep = 0 } 314 if np < 0 { keep = 0 } 315 if ns >= 256 { keep = 0 } 316 if keep == 1 { 317 sid[ns] = idv 318 sep[ns] = ep 319 let nptr: i64 = (pool as i64) + poff 320 var q: i64 = np 321 var s3: i64 = 1 322 while s3 == 1 { 323 if q >= le { s3 = 0 } 324 else { if w[q] == (32 as u8) { s3 = 0 } else { pool[poff] = w[q]; poff = poff + 1; q = q + 1 } } 325 } 326 pool[poff] = 0 as u8; poff = poff + 1 327 snm[ns] = nptr 328 ns = ns + 1 329 } 330 } 331 let pd: i64 = br_find_in(w, ci, le, "INTENT-DONE id=" as *u8) 332 if pd == ci + 15 { let dv: i64 = br_digits_at(w, pd, le); if dv > 0 { if ndone < 512 { did[ndone] = dv; ndone = ndone + 1 } } } 333 let pf: i64 = br_find_in(w, ci, le, "INTENT-FILED id=" as *u8) 334 if pf == ci + 16 { let fv: i64 = br_digits_at(w, pf, le); if fv > 0 { if nfil < 512 { fid[nfil] = fv; nfil = nfil + 1 } } } 335 ci = le + 1 336 } 337 var cnt: i64 = 0 338 var i: i64 = 0 339 while i < ns { 340 var orphan: i64 = 1 341 var k: i64 = 0 342 while k < ndone { if did[k] == sid[i] { orphan = 0 } k = k + 1 } 343 var k2: i64 = 0 344 while k2 < nfil { if fid[k2] == sid[i] { orphan = 0 } k2 = k2 + 1 } 345 if sep[i] < 0 { orphan = 0 } 346 if boot_epoch < 0 { orphan = 0 } 347 if sep[i] >= boot_epoch { orphan = 0 } 348 if orphan == 1 { 349 _p(" ORPHANED INTENT: " as *u8); _p(snm[i] as *u8); _p(" id=" as *u8); _pn(sid[i]); _p(" started epoch=" as *u8); _pn(sep[i]); _p(" never finished -- FILING\n" as *u8) 350 let pfd: i64 = sys_openat_append(pmpath, 0x1a4) 351 if pfd >= 0 { 352 _fp(pfd, "arc=CRASH-RECOVERY step=ORPHAN-INTENT FILED: step " as *u8); _fp(pfd, snm[i] as *u8) 353 _fp(pfd, " (intent id=" as *u8); _fn(pfd, sid[i]) 354 _fp(pfd, " started epoch=" as *u8); _fn(pfd, sep[i]) 355 _fp(pfd, ") never finished -- interrupted by crash/reboot (boot_epoch=" as *u8); _fn(pfd, boot_epoch) 356 _fp(pfd, "); re-verify its evidence owner=Conductor\n" as *u8) 357 sys_close(pfd) 358 } 359 let wfd: i64 = sys_openat_append(walpath, 0x1a4) 360 if wfd >= 0 { 361 _fp(wfd, "INTENT-FILED id=" as *u8); _fn(wfd, sid[i]) 362 _fp(wfd, " epoch=" as *u8); _fn(wfd, sys_now_realtime_sec()) 363 _fp(wfd, "\n" as *u8) 364 sys_close(wfd) 365 } 366 cnt = cnt + 1 367 } 368 i = i + 1 369 } 370 return cnt 371} 372// revive one organ row. counters: [0]=present [1]=revived [2]=fails [3]=wskip [4]=unrec [5]=timeouts 373func br_revive_one(en: *u8, lane: u8, budget: i64, c: *i64) -> i64 { 374 _p(" organ " as *u8); _p(en); _p(": " as *u8) 375 var state: i64 = 3 // 0 present / 1 W-lane / 2 no-source / 3 rebuild 376 if br_organ_present(en) == 1 { state = 0 } 377 if state == 3 { if lane == (87 as u8) { state = 1 } } 378 if state == 3 { if br_source_present(en) == 0 { state = 2 } } 379 if state == 0 { _p("PRESENT\n" as *u8); c[0] = c[0] + 1 } 380 if state == 1 { _p("ABSENT lane=W -- wheeler rebuild OWED (loud, not auto-healed here)\n" as *u8); c[3] = c[3] + 1 } 381 if state == 2 { _p("ABSENT + NO SOURCE -- UNRECOVERABLE!\n" as *u8); c[4] = c[4] + 1 } 382 if state == 3 { 383 let rc: i64 = br_guarded("_offc/nx_sov_build_run.elf" as *u8, en, budget * 1000) 384 if rc == BR_TIMEOUT { c[5] = c[5] + 1 } 385 if br_organ_present(en) == 1 { _p("REVIVED run_rc=" as *u8); _pn(rc); _p("\n" as *u8); c[1] = c[1] + 1 } 386 else { _p("REVIVE-FAIL rc=" as *u8); _pn(rc); _p("\n" as *u8); c[2] = c[2] + 1 } 387 } 388 return 0 389} 390// ---- (1c) M6: REPLAY the reflog + RESUME the in-flight streams ---- 391// Reconstructs authoritative current state from the WMS-R2 reflog (ledger_replay), 392// then for every workstream SEEN in the reflog asks WMS-M1 whether it was recently 393// beating (hbm_scan -> HB_ALIVE). RESUME predicate (the crash-recovery decision): 394// resume iff state[ws] != BR_WS_DONE (NOT completed) 395// AND verdicts[k] == HB_ALIVE (was in-flight / recently beating at crash) 396// A DONE stream is skipped (completed -> non-event). A not-done stream that is STALLED 397// or UNKNOWN is reported but NOT resumed (it was not in-flight at the crash boundary). 398// Each resume emits ONE framed record via fa_appendz (the WMS-R0 atomic locked single 399// write -- NEVER a sequence of sys_write) to the resume journal. 400// counters[0]=resumed [1]=completed_skipped [2]=ledger_flagged [3]=hb_flagged 401// [4]=stale_not_resumed [5]=streams_seen 402// `now`/`threshold` are CALLER PARAMETERS (gate injects fixtures, no hidden wall-clock). 403// Returns resumed_count. 404func br_replay_resume(ledgerpath: *u8, hbpath: *u8, resumepath: *u8, 405 now: i64, threshold: i64, boot_epoch: i64, counters: *i64) -> i64 { 406 // 1) REPLAY -> authoritative current state per ws (state[ws] = final new_st; -1 unseen) 407 let state: *i64 = sys_mmap(8 * BR_RESUME_MAXWS) as *i64 408 var si: i64 = 0 409 while si < BR_RESUME_MAXWS { state[si] = 0 - 1; si = si + 1 } 410 let louts: *i64 = sys_mmap(32) as *i64 411 ledger_replay(ledgerpath, state, louts, BR_RESUME_MAXWS) 412 let ledger_flagged: i64 = louts[2] 413 // 2) build ids[] = every ws seen in the reflog (state >= 0) 414 let ids: *i64 = sys_mmap(8 * BR_RESUME_MAXWS) as *i64 415 var nids: i64 = 0 416 var w: i64 = 0 417 while w < BR_RESUME_MAXWS { 418 if state[w] >= 0 { ids[nids] = w; nids = nids + 1 } 419 w = w + 1 420 } 421 // 3) liveness for those ids (HB_ALIVE == recently beating == in-flight at crash) 422 let verdicts: *i64 = sys_mmap(8 * BR_RESUME_MAXWS) as *i64 423 let houts: *i64 = sys_mmap(32) as *i64 424 hbm_scan(hbpath, now, threshold, ids, nids, verdicts, houts) 425 let hb_flagged: i64 = houts[2] 426 // 4) decide + resume 427 var resumed: i64 = 0 428 var completed: i64 = 0 429 var stale: i64 = 0 430 var k: i64 = 0 431 while k < nids { 432 let id: i64 = ids[k] 433 let st: i64 = state[id] 434 if st == BR_WS_DONE { 435 completed = completed + 1 436 } else { 437 if verdicts[k] == HB_ALIVE { 438 let lastb: i64 = hb_last_beat(hbpath, id) 439 // ONE framed record, ONE locked write (fa_appendz) -- the resume journal entry 440 let rec: *u8 = sys_mmap(BR_RESUME_CAP + 16) 441 var o: i64 = 0 442 o = fa_cat(rec, o, "BR-RESUME ws=\x00" as *u8) 443 o = fa_catn(rec, o, id) 444 o = fa_cat(rec, o, " state=\x00" as *u8) 445 o = fa_catn(rec, o, st) 446 o = fa_cat(rec, o, " last_beat=\x00" as *u8) 447 o = fa_catn(rec, o, lastb) 448 o = fa_cat(rec, o, " boot_epoch=\x00" as *u8) 449 o = fa_catn(rec, o, boot_epoch) 450 o = fa_cat(rec, o, " END\x00" as *u8) 451 rec[o] = 0 as u8 452 fa_appendz(resumepath, rec, BR_RESUME_CAP) 453 _p(" IN-FLIGHT RESUME: ws=" as *u8); _pn(id); _p(" state=" as *u8); _pn(st); _p(" last_beat=" as *u8); _pn(lastb); _p(" (recently beating at crash -- resuming)\n" as *u8) 454 resumed = resumed + 1 455 } else { 456 // not-done but not recently beating: report, do NOT resume 457 _p(" stale (not in-flight at crash): ws=" as *u8); _pn(id); _p(" state=" as *u8); _pn(st); _p(" verdict=" as *u8); _pn(verdicts[k]); _p(" -- NOT resumed\n" as *u8) 458 stale = stale + 1 459 } 460 } 461 k = k + 1 462 } 463 counters[0] = resumed 464 counters[1] = completed 465 counters[2] = ledger_flagged 466 counters[3] = hb_flagged 467 counters[4] = stale 468 counters[5] = nids 469 return resumed 470} 471func main(argc: i64, argv: *i64) -> i64 { 472 _p("=== BOOT REVIVE (Doctor): resurrect organs + daemons after a crash/reboot, zero sessions needed ===\n" as *u8) 473 var confpath: *u8 = "knowledge/status/triage_expected.conf" as *u8 474 if argc >= 2 { confpath = argv[1] as *u8 } 475 var logpath: *u8 = "knowledge/status/boot_revive.log" as *u8 476 if argc >= 3 { logpath = argv[2] as *u8 } 477 var journalpath: *u8 = "knowledge/status/boot_journal.log" as *u8 478 if argc >= 4 { journalpath = argv[3] as *u8 } 479 // ---- parse conf: E organ rows, D daemon rows, B per-organ build budget (sec) ---- 480 let conf: *u8 = sys_mmap(BR_MAGIC_65536) 481 let cn: i64 = br_read_all(confpath, conf, BR_MAGIC_65520) 482 if cn <= 0 { _p(" REVIVE: conf MISSING (" as *u8); _p(confpath); _p(") -- fail loud\n" as *u8); sys_exit(1); return 1 } 483 let pool: *u8 = sys_mmap(BR_MAGIC_16384) 484 var poff: i64 = 0 485 let enames: *i64 = sys_mmap(64*8) as *i64 486 let elanes: *u8 = sys_mmap(64) 487 var ne: i64 = 0 488 let dnames: *i64 = sys_mmap(16*8) as *i64 489 var nd: i64 = 0 490 var budget: i64 = 0 491 var ci: i64 = 0 492 while ci < cn { 493 var le: i64 = ci 494 var scan: i64 = 1 495 while scan == 1 { 496 if le >= cn { scan = 0 } 497 else { if conf[le] == (10 as u8) { scan = 0 } else { le = le + 1 } } 498 } 499 if conf[ci] == (69 as u8) { 500 var te: i64 = ci + 2 501 var s2: i64 = 1 502 while s2 == 1 { 503 if te >= le { s2 = 0 } 504 else { if conf[te] == (32 as u8) { s2 = 0 } else { te = te + 1 } } 505 } 506 let nptr: i64 = (pool as i64) + poff 507 var q: i64 = ci + 2 508 while q < te { pool[poff] = conf[q]; poff = poff + 1; q = q + 1 } 509 pool[poff] = 0 as u8; poff = poff + 1 510 if ne < 64 { 511 enames[ne] = nptr 512 elanes[ne] = 83 as u8 513 if te + 1 < le { elanes[ne] = conf[te+1] } 514 ne = ne + 1 515 } 516 } 517 if conf[ci] == (68 as u8) { 518 let dptr: i64 = (pool as i64) + poff 519 var q2: i64 = ci + 2 520 while q2 < le { pool[poff] = conf[q2]; poff = poff + 1; q2 = q2 + 1 } 521 pool[poff] = 0 as u8; poff = poff + 1 522 if nd < 16 { dnames[nd] = dptr; nd = nd + 1 } 523 } 524 if conf[ci] == (66 as u8) { 525 var bv: i64 = 0 526 var q3: i64 = ci + 2 527 while q3 < le { 528 if conf[q3] >= (48 as u8) { if conf[q3] <= (57 as u8) { bv = bv * 10 + ((conf[q3] as i64) - 48) } } 529 q3 = q3 + 1 530 } 531 budget = bv 532 } 533 ci = le + 1 534 } 535 if budget <= 0 { _p(" REVIVE: B row MISSING in conf (per-organ watchdog budget, seconds) -- fail loud\n" as *u8); sys_exit(1); return 1 } 536 // ---- (1) boot detect + durable journal (one BOOT row per boot) ---- 537 let now: i64 = sys_now_realtime_sec() 538 let up: i64 = br_uptime() 539 var boot_epoch: i64 = 0 - 1 540 if up >= 0 { boot_epoch = now - up } 541 let jbuf: *u8 = sys_mmap(BR_MAGIC_1048592) 542 let jn: i64 = br_read_all(journalpath, jbuf, BR_MAGIC_1048576) 543 let last_boot: i64 = br_last_num_after(jbuf, jn, "BOOT boot_epoch=" as *u8) 544 var new_boot: i64 = 1 545 if boot_epoch < 0 { new_boot = 0 } 546 if last_boot > 0 { 547 var dd: i64 = boot_epoch - last_boot 548 if dd < 0 { dd = 0 - dd } 549 if dd <= BR_BOOT_JITTER { new_boot = 0 } 550 } 551 var dark_gap: i64 = 0 - 1 552 if new_boot == 1 { 553 let hbuf: *u8 = sys_mmap(BR_MAGIC_1048592) 554 let hn: i64 = br_read_all("knowledge/status/pulse_daemon.log" as *u8, hbuf, BR_MAGIC_1048576) 555 let last_beat: i64 = br_last_num_after(hbuf, hn, "DAEMON-BEAT epoch=" as *u8) 556 if last_beat > 0 { dark_gap = boot_epoch - last_beat; if dark_gap < 0 { dark_gap = 0 } } 557 let jfd: i64 = sys_openat_append(journalpath, 0x1a4) 558 if jfd >= 0 { 559 _fp(jfd, "BOOT boot_epoch=" as *u8); _fn(jfd, boot_epoch) 560 _fp(jfd, " revive_epoch=" as *u8); _fn(jfd, now) 561 _fp(jfd, " dark_gap=" as *u8); _fn(jfd, dark_gap) 562 _fp(jfd, "\n" as *u8) 563 sys_close(jfd) 564 } 565 _p(" NEW BOOT detected: boot_epoch=" as *u8); _pn(boot_epoch); _p(" dark_gap=" as *u8); _pn(dark_gap); _p("s (substrate downtime, measured)\n" as *u8) 566 } else { 567 _p(" same boot as last journal row (no BOOT row appended)\n" as *u8) 568 } 569 // ---- (1b) orphaned intents (CR4): file work the crash interrupted mid-flight ---- 570 var walpath: *u8 = "knowledge/status/intent_wal.log" as *u8 571 if argc >= 5 { walpath = argv[4] as *u8 } 572 var pmpath: *u8 = "knowledge/status/pm_plan_durable.log" as *u8 573 if argc >= 6 { pmpath = argv[5] as *u8 } 574 _p(" -- ORPHANED INTENTS (started before this boot, never finished) --\n" as *u8) 575 let orphans: i64 = br_file_orphans(walpath, pmpath, boot_epoch) 576 if orphans == 0 { _p(" (none)\n" as *u8) } 577 // ---- (1c) REPLAY + RESUME (M6): reconstruct + resume exactly the in-flight streams ---- 578 var ledgerpath: *u8 = "knowledge/status/ws_ledger.log" as *u8 579 if argc >= 7 { ledgerpath = argv[6] as *u8 } 580 var hbpath: *u8 = "knowledge/status/heartbeat.log" as *u8 581 if argc >= 8 { hbpath = argv[7] as *u8 } 582 var resumepath: *u8 = "knowledge/status/boot_resume.log" as *u8 583 if argc >= 9 { resumepath = argv[8] as *u8 } 584 var rr_now: i64 = sys_now_realtime_sec() 585 if argc >= 10 { rr_now = br_digits_at(argv[9] as *u8, 0, br_len(argv[9] as *u8)) } 586 var rr_thr: i64 = BR_HB_THRESHOLD 587 if argc >= 11 { rr_thr = br_digits_at(argv[10] as *u8, 0, br_len(argv[10] as *u8)) } 588 _p(" -- REPLAY + RESUME (M6: reconstruct authoritative state, resume in-flight streams) --\n" as *u8) 589 let rc6: *i64 = sys_mmap(8*8) as *i64 590 var rz: i64 = 0 591 while rz < 8 { rc6[rz] = 0; rz = rz + 1 } 592 br_replay_resume(ledgerpath, hbpath, resumepath, rr_now, rr_thr, boot_epoch, rc6) 593 let streams_resumed: i64 = rc6[0] 594 let streams_completed: i64 = rc6[1] 595 let ledger_flagged: i64 = rc6[2] 596 let hb_flagged: i64 = rc6[3] 597 _p(" resumed=" as *u8); _pn(streams_resumed); _p(" completed_skipped=" as *u8); _pn(streams_completed); _p(" stale_not_resumed=" as *u8); _pn(rc6[4]); _p(" streams_seen=" as *u8); _pn(rc6[5]); _p(" ledger_flagged=" as *u8); _pn(ledger_flagged); _p(" hb_flagged=" as *u8); _pn(hb_flagged); _p("\n" as *u8) 598 if streams_resumed == 0 { _p(" (no in-flight streams to resume -- clean boot is a non-event)\n" as *u8) } 599 // ---- (2) proactive organ revive (watchdog-bounded per organ) ---- 600 let c: *i64 = sys_mmap(8*8) as *i64 601 var z: i64 = 0 602 while z < 8 { c[z] = 0; z = z + 1 } 603 _p(" -- ORGANS (expected E rows: rebuild every recoverable absence NOW) --\n" as *u8) 604 var ei: i64 = 0 605 while ei < ne { br_revive_one(enames[ei] as *u8, elanes[ei], budget, c); ei = ei + 1 } 606 // ---- (3) daemon revive (idempotent via the daemon's own pidfile dup-guard) ---- 607 var dstart: i64 = 0 608 var dfail: i64 = 0 609 var drun: i64 = 0 610 _p(" -- DAEMONS (expected D rows: re-arm every one not in /proc) --\n" as *u8) 611 var dvi: i64 = 0 612 while dvi < nd { 613 let dsub: *u8 = dnames[dvi] as *u8 614 _p(" daemon " as *u8); _p(dsub); _p(": " as *u8) 615 if br_daemon_up(dsub) == 1 { _p("RUNNING\n" as *u8); drun = drun + 1 } 616 else { 617 let rcd: i64 = br_guarded("_offc/nx_sov_build_run.elf" as *u8, dsub, budget * 1000) 618 if rcd == BR_TIMEOUT { c[5] = c[5] + 1 } 619 sys_sleep_ms(BR_ARM_GRACE_MS) 620 if br_daemon_up(dsub) == 1 { _p("RE-ARMED rc=" as *u8); _pn(rcd); _p("\n" as *u8); dstart = dstart + 1 } 621 else { _p("ARM-FAIL rc=" as *u8); _pn(rcd); _p("\n" as *u8); dfail = dfail + 1 } 622 } 623 dvi = dvi + 1 624 } 625 // ---- verdict + durable REVIVE line ---- 626 var verdict: i64 = 0 627 if c[2] > 0 { verdict = 1 } 628 if c[3] > 0 { verdict = 1 } 629 if c[4] > 0 { verdict = 1 } 630 if c[5] > 0 { verdict = 1 } 631 if dfail > 0 { verdict = 1 } 632 if ledger_flagged > 0 { verdict = 1 } // M6: reflog corruption surfaced, never swallowed 633 if hb_flagged > 0 { verdict = 1 } // M6: heartbeat-channel corruption surfaced 634 let lfd: i64 = sys_openat_append(logpath, 0x1a4) 635 if lfd >= 0 { 636 _fp(lfd, "REVIVE epoch=" as *u8); _fn(lfd, now) 637 _fp(lfd, " new_boot=" as *u8); _fn(lfd, new_boot) 638 _fp(lfd, " boot_epoch=" as *u8); _fn(lfd, boot_epoch) 639 _fp(lfd, " organs_present=" as *u8); _fn(lfd, c[0]) 640 _fp(lfd, " organs_revived=" as *u8); _fn(lfd, c[1]) 641 _fp(lfd, " revive_fails=" as *u8); _fn(lfd, c[2]) 642 _fp(lfd, " lane_w_skipped=" as *u8); _fn(lfd, c[3]) 643 _fp(lfd, " unrecoverable=" as *u8); _fn(lfd, c[4]) 644 _fp(lfd, " timeouts=" as *u8); _fn(lfd, c[5]) 645 _fp(lfd, " intents_orphaned=" as *u8); _fn(lfd, orphans) 646 _fp(lfd, " daemons_running=" as *u8); _fn(lfd, drun) 647 _fp(lfd, " daemons_started=" as *u8); _fn(lfd, dstart) 648 _fp(lfd, " daemon_fails=" as *u8); _fn(lfd, dfail) 649 _fp(lfd, " streams_resumed=" as *u8); _fn(lfd, streams_resumed) 650 _fp(lfd, " streams_completed=" as *u8); _fn(lfd, streams_completed) 651 _fp(lfd, " ledger_flagged=" as *u8); _fn(lfd, ledger_flagged) 652 _fp(lfd, " hb_flagged=" as *u8); _fn(lfd, hb_flagged) 653 if verdict == 0 { _fp(lfd, " verdict=GREEN\n" as *u8) } else { _fp(lfd, " verdict=ATTENTION\n" as *u8) } 654 sys_close(lfd) 655 } 656 _p(" durable: " as *u8); _p(logpath); _p(" + " as *u8); _p(journalpath); _p("\n" as *u8) 657 if verdict == 0 { _p(" BOOT REVIVE: GREEN (everything expected is present/running)\n" as *u8); sys_exit(0); return 0 } 658 _p(" BOOT REVIVE: ATTENTION (revive-fail / W-lane absence / no-source / timeout / daemon down)\n" as *u8) 659 sys_exit(1) 660 return 1 661}