code wiki / _hdl_build / nx_deadman.nx
nx_deadman.nx source
↩ module page · 47 lines · 2544 B
1// nx_deadman.nx -- PROOF-OF-LIFE dead-man's switch for succession (the "death nobody reports" gap). Normal
2// activity (every login/validate) is a HEARTBEAT. After prolonged silence the account escalates toward
3// succession -- but with a VETO WINDOW during which a single login (heartbeat) cancels it, so a living user
4// on a long trip is never wrongly succeeded. State = a file holding the last-activity epoch (decimal text).
5// nx_dm_heartbeat(state_file, now) -- record activity
6// nx_dm_read_last(state_file) -- last-activity epoch, or -1
7// nx_dm_status(last, now, silence_secs, veto_secs):
8// ALIVE = silent < silence_secs (active; nothing happens)
9// PENDING = silence_secs <= silent < silence+veto (silent; ALERT the user, contacts may be notified,
10// succession may START but NOT finalize -- vetoable)
11// EXPIRED = silent >= silence_secs + veto_secs (silent through the veto window; succession PROCEEDS,
12// i.e. nx_succession_recover / nx_social_auth_recover)
13// Pure status (no real-world judgement); the actual notify/alert is a real-world side channel. license_tier: ORIGINAL
14import "nx_syscalls.nx"
15
16const NX_DM_ALIVE: i64 = 0
17const NX_DM_PENDING: i64 = 1
18const NX_DM_EXPIRED: i64 = 2
19
20func nx_dm_status(last_activity: i64, now: i64, silence_secs: i64, veto_secs: i64) -> i64 {
21 let silent: i64 = now - last_activity
22 if silent < silence_secs { return NX_DM_ALIVE }
23 if silent < silence_secs + veto_secs { return NX_DM_PENDING }
24 return NX_DM_EXPIRED
25}
26
27func nx_dm_heartbeat(state_file: *u8, now: i64) -> i64 {
28 let fd: i64 = sys_openat_wr(state_file, 0x180)
29 if fd < 0 { return 0 - 1 }
30 let t: *u8 = sys_mmap(28); var m: i64 = now; var k: i64 = 0
31 if m == 0 { t[0] = 48 as u8; k = 1 }
32 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
33 let bb: *u8 = sys_mmap(28); var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
34 sys_write(fd, bb, k)
35 sys_close(fd)
36 return 0
37}
38
39func nx_dm_read_last(state_file: *u8) -> i64 {
40 let lenbox: *i64 = sys_mmap(16) as *i64; lenbox[0] = 0
41 let buf: *u8 = sys_read_file(state_file, lenbox)
42 if (buf as i64) == 0 { return 0 - 1 }
43 if lenbox[0] < 1 { return 0 - 1 }
44 var v: i64 = 0; var i: i64 = 0
45 while i < lenbox[0] { let c: i64 = buf[i] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } i = i + 1 }
46 return v
47}