code wiki / _hdl_build / nx_deadman_gate.nx
nx_deadman_gate.nx source
↩ module page · 64 lines · 2774 B
1// nx_deadman_gate.nx -- REFEREE for the proof-of-life dead-man's switch. Deterministic (fixed clock):
2// silence=100s, veto=50s, now=2000000.
3// T1 just beat (silent 0) -> ALIVE
4// T2 silent 120 (in [100,150)) -> PENDING (alert + vetoable)
5// T3 silent 200 (>= 150) -> EXPIRED (succession proceeds)
6// T4 PENDING then a heartbeat -> ALIVE (a living user's login VETOES succession)
7// T5 heartbeat round-trips through the state file (write now -> read == now)
8// GREEN iff T1..T5. Sovereign: nx_deadman + nx_syscalls. license_tier: ORIGINAL
9import "nx_deadman.nx"
10import "nx_syscalls.nx"
11
12func g_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
13func g_row(name: *u8, ok: i64) -> i64 {
14 if ok == 1 { g_w(" PASS " as *u8) }
15 if ok != 1 { g_w(" FAIL " as *u8) }
16 g_w(name); g_w("\n" as *u8)
17 return ok
18}
19
20func main() -> i64 {
21 g_w("dead-man's switch gate: silence -> succession, but a login VETOES it (no wrongful succession)\n" as *u8)
22 let state: *u8 = "/tmp/nx_dm_state.log" as *u8
23 let now: i64 = 2000000
24 let silence: i64 = 100
25 let veto: i64 = 50
26 var pass: i64 = 0
27
28 // ---- T5 first: heartbeat round-trip (establishes ALIVE state) ----
29 nx_dm_heartbeat(state, now)
30 let last: i64 = nx_dm_read_last(state)
31 var t5: i64 = 0
32 if last == now { t5 = 1 }
33
34 // ---- T1: just beat -> ALIVE ----
35 var t1: i64 = 0
36 if nx_dm_status(last, now, silence, veto) == NX_DM_ALIVE { t1 = 1 }
37 pass = pass + g_row("T1 active (just beat) -> ALIVE\x00" as *u8, t1)
38
39 // ---- T2: silent 120 -> PENDING ----
40 var t2: i64 = 0
41 if nx_dm_status(now - 120, now, silence, veto) == NX_DM_PENDING { t2 = 1 }
42 pass = pass + g_row("T2 silent 120s -> PENDING (alert, vetoable)\x00" as *u8, t2)
43
44 // ---- T3: silent 200 -> EXPIRED ----
45 var t3: i64 = 0
46 if nx_dm_status(now - 200, now, silence, veto) == NX_DM_EXPIRED { t3 = 1 }
47 pass = pass + g_row("T3 silent 200s -> EXPIRED (succession proceeds)\x00" as *u8, t3)
48
49 // ---- T4: PENDING then a heartbeat -> ALIVE (veto) ----
50 var t4: i64 = 0
51 if nx_dm_status(now - 120, now, silence, veto) == NX_DM_PENDING {
52 nx_dm_heartbeat(state, now)
53 let last2: i64 = nx_dm_read_last(state)
54 if nx_dm_status(last2, now, silence, veto) == NX_DM_ALIVE { t4 = 1 }
55 }
56 pass = pass + g_row("T4 a login during PENDING -> ALIVE (succession VETOED)\x00" as *u8, t4)
57
58 pass = pass + g_row("T5 heartbeat round-trips through the state file\x00" as *u8, t5)
59
60 if pass == 5 { g_w("DEADMAN GATE GREEN 5/5 (silence escalates; a login vetoes; no wrongful succession)\n" as *u8); sys_exit(0) }
61 g_w("DEADMAN GATE RED\n" as *u8)
62 sys_exit(1)
63 return 1
64}