code wiki / _hdl_build / nx_restart_strategy_gate.nx

nx_restart_strategy_gate.nx source

↩ module page · 81 lines · 5686 B

1// nx_restart_strategy_gate.nx -- MEASURED gate for the S-class supervision restart strategy. Pure/offline. Proves 2// the crash-loop CONTAINMENT the operator wants (vs today's infinite restart): a flapping daemon is QUARANTINED 3// once it exceeds the OTP restart intensity, with exponential-backoff+jitter spacing and correct window aging. 4// T1 within intensity -> RESTART 5// T2 over intensity -> QUARANTINE (contained, not looped) 6// T3 exponential backoff capped -> 100,200,400,800,... -> cap 7// T4 window ages out old crashes -> a now-stable daemon is NOT quarantined for ancient crashes 8// T5 jitter bounded [d/2, d] -> no thundering herd 9// T6 the LIVE crash-loop case -> gallery/vroom-style rapid restarts -> QUARANTINE (the operator's exact bug, contained) 10// GREEN iff 6/6. Appends knowledge/status/restart_strategy_gate.log. license_tier: ORIGINAL 11import "nx_restart_strategy.nx" 12import "nx_syscalls.nx" 13 14func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 15func g_num(v: i64) -> i64 { 16 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } 17 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } 18 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 19 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0 20} 21func g_w(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 } 22func g_wn(fd: i64, v: i64) -> i64 { 23 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m } 24 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } 25 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 26 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(fd, bb, k); return 0 27} 28 29func main() -> i64 { 30 g_puts("=== RESTART STRATEGY GATE (S-class crash-loop containment: OTP intensity + exp backoff + jitter) ===\n" as *u8) 31 let now: i64 = 1000 32 let win: i64 = 5 33 let maxr: i64 = 5 34 var pass: i64 = 0 35 36 // T1: 3 restarts within the 5s window, max 5 -> RESTART 37 let t1a: *i64 = sys_mmap(8 * 8) as *i64; t1a[0] = 997; t1a[1] = 998; t1a[2] = 999 38 var c1: i64 = 0; if rs_should_restart(t1a, 3, now, win, maxr) == RS_RESTART { c1 = 1 } pass = pass + c1 39 g_puts(" T1 within intensity -> RESTART: "); if c1 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 40 41 // T2: 6 restarts within the window, max 5 -> QUARANTINE 42 let t2a: *i64 = sys_mmap(8 * 8) as *i64; t2a[0] = 995; t2a[1] = 996; t2a[2] = 997; t2a[3] = 998; t2a[4] = 999; t2a[5] = 1000 43 var c2: i64 = 0; if rs_should_restart(t2a, 6, now, win, maxr) == RS_QUARANTINE { c2 = 1 } pass = pass + c2 44 g_puts(" T2 over intensity -> QUARANTINE: "); if c2 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 45 46 // T3: exponential backoff, capped at 30000 47 var c3: i64 = 0 48 if rs_backoff_ms(0, 100, 30000) == 100 { if rs_backoff_ms(1, 100, 30000) == 200 { if rs_backoff_ms(2, 100, 30000) == 400 { if rs_backoff_ms(3, 100, 30000) == 800 { if rs_backoff_ms(20, 100, 30000) == 30000 { c3 = 1 } } } } } 49 pass = pass + c3 50 g_puts(" T3 exp backoff 100,200,400,800..cap(20)=30000: "); if c3 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 51 52 // T4: 7 ancient crashes (all ~900s ago, outside the 5s window) -> 0 in-window -> RESTART (not punished for old history) 53 let t4a: *i64 = sys_mmap(8 * 8) as *i64; var z: i64 = 0; while z < 7 { t4a[z] = 100 + z; z = z + 1 } 54 var c4: i64 = 0; if rs_should_restart(t4a, 7, now, win, maxr) == RS_RESTART { c4 = 1 } pass = pass + c4 55 g_puts(" T4 window ages out old crashes -> RESTART: "); if c4 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 56 57 // T5: jitter stays within [d/2, d] for several seeds 58 var c5: i64 = 1 59 let d: i64 = 800 60 var s: i64 = 0 61 while s < 20 { let j: i64 = rs_jitter_ms(d, s * 37 + 11); if j < d / 2 { c5 = 0 } if j > d { c5 = 0 } s = s + 1 } 62 pass = pass + c5 63 g_puts(" T5 jitter bounded [d/2,d] (no thundering herd): "); if c5 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 64 65 // T6: the LIVE crash-loop (gallery/vroom): 8 rapid restarts in the window -> QUARANTINE (the operator's bug, contained) 66 let t6a: *i64 = sys_mmap(8 * 16) as *i64; var q: i64 = 0; while q < 8 { t6a[q] = 996 + (q % 5); q = q + 1 } 67 var c6: i64 = 0; if rs_should_restart(t6a, 8, now, win, maxr) == RS_QUARANTINE { c6 = 1 } pass = pass + c6 68 g_puts(" T6 live crash-loop -> QUARANTINE (contained): "); if c6 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) } 69 70 g_puts("----\nRESTART-STRATEGY rows=6 pass="); g_num(pass); g_puts("\n" as *u8) 71 let lg: i64 = sys_openat_append("knowledge/status/restart_strategy_gate.log" as *u8, 0x1a4) 72 if lg >= 0 { 73 g_w(lg, "RESTART-STRATEGY within_restart="); g_wn(lg, c1); g_w(lg, " over_quarantine="); g_wn(lg, c2); g_w(lg, " exp_backoff="); g_wn(lg, c3) 74 g_w(lg, " window_aging="); g_wn(lg, c4); g_w(lg, " jitter_bounded="); g_wn(lg, c5); g_w(lg, " crashloop_contained="); g_wn(lg, c6) 75 g_w(lg, " rows=6 pass="); g_wn(lg, pass) 76 if pass == 6 { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } 77 sys_close(lg) 78 } 79 if pass == 6 { g_puts("RESTART-STRATEGY GREEN (crash-loops CONTAINED by OTP intensity + exp backoff + jitter -- measured)\n" as *u8); sys_exit(0); return 0 } 80 g_puts("RESTART-STRATEGY RED\n" as *u8); sys_exit(1); return 1 81}