code wiki / (root) / nx_deploy_leash_gate.nx

nx_deploy_leash_gate.nx source

↩ module page · 95 lines · 4731 B

1// nx_deploy_leash_gate.nx -- gate for deployments-on-a-leash (owner accountability, anti-walk-away). 2// T1 PURE verdict table: alive+fresh=HEALTHY · alive+stale-beat=ABANDONED (the walk-away case, 3// invisible to pid-checks) · dead pid=DEAD (trumps fresh beat). 4// T2 DEAD roundtrip: registered deployment with a dead pid -> status reports DEAD, no reclaim. 5// T3 ABANDONED+RECLAIM: LIVE pid (this gate) with a FORCED-ancient beat -> walk reclaims: its 6// declared stop-file is touched + watch mark RECLAIMED (reads as RED in nx_watch = loud). 7// T4 HEALTHY: live pid + fresh beat -> HEALTHY, stop-file NOT touched. 8// T5 empty registry -> clean walk, verdict 0. 9// license_tier: ORIGINAL expect_exit: 0 10import "nx_deploy_leash.nx" 11 12func lz_reset() -> i64 { 13 sov_put(DL_STORE, "d:ids" as *u8, "x" as *u8, 0) 14 return 0 15} 16 17func main(argc: i64, argv: *i64) -> i64 { 18 std_putln("LEASH-GATE: deployments on a leash (owner-renewal liveness, reclaim on walk-away)" as *u8) 19 var pass: i64 = 0 20 // T1 pure table 21 let vh: i64 = dl_verdict(1, 10, 1000) 22 let va: i64 = dl_verdict(1, 5000, 1000) 23 let vd: i64 = dl_verdict(0, 10, 1000) 24 if vh == DL_HEALTHY && va == DL_ABANDONED && vd == DL_DEAD { pass = pass + 1; std_putln("T1 PASS verdict table (healthy/abandoned/dead; dead trumps fresh beat)" as *u8) } 25 if vh != DL_HEALTHY || va != DL_ABANDONED || vd != DL_DEAD { std_putln("T1 FAIL verdict table" as *u8) } 26 // T2 dead deployment 27 lz_reset() 28 ml_unlink("/tmp/lz_gate_dead_stop" as *u8) 29 dl_register("lz_dead" as *u8, "gate" as *u8, "fixture" as *u8, 88888888, 60000, "/tmp/lz_gate_dead_stop" as *u8) 30 let s2: i64 = dl_walk(0) 31 let sf2: i64 = sys_openat_rd("/tmp/lz_gate_dead_stop" as *u8) 32 if sf2 >= 0 { sys_close(sf2) } 33 if s2 == DL_DEAD && sf2 < 0 { pass = pass + 1; std_putln("T2 PASS dead pid -> DEAD, no reclaim action" as *u8) } 34 if s2 != DL_DEAD || sf2 >= 0 { std_puts("T2 FAIL s="); std_pdec(s2); std_puts("\n" as *u8) } 35 // T3 abandoned (live pid, ancient beat) -> walk reclaims via the DECLARED stop-file 36 lz_reset() 37 ml_unlink("/tmp/lz_gate_aband_stop" as *u8) 38 let me: i64 = sq_getpid_leash() 39 dl_register("lz_aband" as *u8, "gate" as *u8, "fixture" as *u8, me, 1000, "/tmp/lz_gate_aband_stop" as *u8) 40 let anc: *u8 = sys_mmap(64) as *u8 41 var ao: i64 = 0 42 anc[0] = 66 as u8; anc[1] = 69 as u8; anc[2] = 65 as u8; anc[3] = 84 as u8; anc[4] = 124 as u8 43 ao = 5 + std_itoa(sys_now_us() - 600000000, anc + 5) 44 anc[ao] = 0 as u8 45 sov_put_str("knowledge/store/watch_leash" as *u8, "lz_aband" as *u8, anc) 46 let s3: i64 = dl_walk(1) 47 let sf3: i64 = sys_openat_rd("/tmp/lz_gate_aband_stop" as *u8) 48 if sf3 >= 0 { sys_close(sf3) } 49 if s3 == DL_ABANDONED && sf3 >= 0 { pass = pass + 1; std_putln("T3 PASS walk-away reclaimed (live pid + stale beat -> stop-file touched + RECLAIMED mark)" as *u8) } 50 if s3 != DL_ABANDONED || sf3 < 0 { std_puts("T3 FAIL s="); std_pdec(s3); std_puts(" sf="); std_pdec(sf3); std_puts("\n" as *u8) } 51 // T4 healthy (live pid, fresh beat) 52 lz_reset() 53 ml_unlink("/tmp/lz_gate_ok_stop" as *u8) 54 dl_register("lz_ok" as *u8, "gate" as *u8, "fixture" as *u8, me, 600000, "/tmp/lz_gate_ok_stop" as *u8) 55 nw_mark("leash" as *u8, "lz_ok" as *u8, "BEAT" as *u8) 56 let s4: i64 = dl_walk(1) 57 let sf4: i64 = sys_openat_rd("/tmp/lz_gate_ok_stop" as *u8) 58 if sf4 >= 0 { sys_close(sf4) } 59 if s4 == DL_HEALTHY && sf4 < 0 { pass = pass + 1; std_putln("T4 PASS fresh-beat deployment HEALTHY, untouched" as *u8) } 60 if s4 != DL_HEALTHY || sf4 >= 0 { std_puts("T4 FAIL s="); std_pdec(s4); std_puts("\n" as *u8) } 61 // T5 empty registry 62 lz_reset() 63 let s5: i64 = dl_walk(1) 64 if s5 == 0 { pass = pass + 1; std_putln("T5 PASS empty registry -> clean walk" as *u8) } 65 if s5 != 0 { std_putln("T5 FAIL empty" as *u8) } 66 std_puts("LEASH-GATE pass=" as *u8) 67 std_pdec(pass) 68 if pass == 5 { 69 std_putln("/5 verdict=GREEN" as *u8) 70 sys_exit(0) 71 return 0 72 } 73 std_putln("/5 verdict=RED" as *u8) 74 sys_exit(1) 75 return 1 76} 77 78// own pid via /proc/self/stat (getpid has NO working const syscall form -- see gotchas 2026-07-16). 79func sq_getpid_leash() -> i64 { 80 let fd: i64 = sys_openat_rd("/proc/self/stat" as *u8) 81 if fd < 0 { return 0 - 1 } 82 let b: *u8 = sys_mmap(128) as *u8 83 let n: i64 = sys_read(fd, b, 127) 84 sys_close(fd) 85 if n <= 0 { return 0 - 1 } 86 var v: i64 = 0 87 var i: i64 = 0 88 var seen: i64 = 0 89 while i < n { 90 let c: i64 = b[i] as i64 91 if c >= 48 && c <= 57 { v = v * 10 + (c - 48); seen = 1; i = i + 1 } else { i = n } 92 } 93 if seen == 0 { return 0 - 1 } 94 return v 95}