code wiki / (root) / nx_deploy_leash.nx

nx_deploy_leash.nx source

↩ module page · 270 lines · 10774 B

1// nx_deploy_leash.nx -- DEPLOYMENTS ON A LEASH (operator 2026-07-16: "owners take accountability... 2// models loaded into resources and the owner walks away... someone should have our deployments on a 3// leash, not just let them wander loose -- part of the RACI"). Every long-lived deployment (model 4// seat, serve daemon, heavy holder) REGISTERS: accountable owner + purpose + pid + renewal TTL + its 5// own STOP-PATH (a declared graceful kill-switch -- reclaim is never a blind kill). The leash is 6// RENEWAL-BASED liveness of the OWNER'S USE (nx_watch beats on every use), NOT process liveness -- 7// a seat daemon stays alive forever, so pid-checks can never catch walk-away. SOTA norm this matches: 8// K8s lease renewal / SLURM walltime / Ray actor liveness -- resources held AGAINST RENEWAL. 9// register <name> <owner> <purpose> <pid> <renew_ttl_ms> <stop_path> (also starts the leash clock) 10// beat = nx_watch beat leash <name> (consumers beat on every USE; no new plumbing) 11// walk supervisor's rounds: HEALTHY / ABANDONED(alive+stale-beat -> touch stop_path, mark 12// RECLAIMED) / DEAD(pid gone). Exit = worst seen (0 none/healthy, 2 dead, 3 abandoned). 13// status same scan, print-only (no reclaim actions). 14// Store: knowledge/store/leash key d:<name> = "name|owner|purpose|pid|ttl_ms|stop_path|reg_us" 15// (latest-wins), d:ids index under flock. Beat clock: knowledge/store/watch_leash via nx_watch. 16// RACI: supervisor R (walks the leash) · pm A (owns the box) · conductor C · every workstream I. 17// license_tier: ORIGINAL 18import "nx_watch.nx" 19import "nx_model_lane_core.nx" 20const DL_MAGIC_262144: i64 = 262144 21const DL_MAGIC_262143: i64 = 262143 22const DL_MAGIC_999999999: i64 = 999999999 23 24const DL_STORE: *u8 = "knowledge/store/leash" 25const DL_LOCK: *u8 = "knowledge/status/leash.lock" 26const DL_HEALTHY: i64 = 0 27const DL_DEAD: i64 = 2 28const DL_ABANDONED: i64 = 3 29 30// PURE leash verdict: dead pid trumps; else stale beat = abandoned; else healthy. gate-core. 31func dl_verdict(pid_alive: i64, beat_age_ms: i64, renew_ttl_ms: i64) -> i64 { 32 if pid_alive == 0 { return DL_DEAD } 33 if beat_age_ms > renew_ttl_ms { return DL_ABANDONED } 34 return DL_HEALTHY 35} 36 37// "d:<name>" key (NUL-term). 38func dl_key(name: *u8, out: *u8) -> i64 { 39 out[0] = 100 as u8 40 out[1] = 58 as u8 41 var i: i64 = 0 42 while name[i] != (0 as u8) { out[2 + i] = name[i]; i = i + 1 } 43 out[2 + i] = 0 as u8 44 return 2 + i 45} 46 47// ensure name in d:ids under flock (same proven pattern as the swarm queue index). 48func dl_add_id(name: *u8) -> i64 { 49 let lf: i64 = sys_openat_append(DL_LOCK, 0x1a4) 50 if lf >= 0 { sys_flock(lf, SYS_LOCK_EX) } 51 let ids: *u8 = sys_mmap(DL_MAGIC_262144) as *u8 52 let idn: i64 = sov_get_copy(DL_STORE, "d:ids" as *u8, ids, DL_MAGIC_262143) 53 var nl: i64 = 0 54 while name[nl] != (0 as u8) { nl = nl + 1 } 55 var have: i64 = 0 56 if idn > 0 { 57 var i: i64 = 0 58 while i < idn { 59 var e: i64 = i 60 var sc: i64 = 1 61 while sc == 1 { 62 if e >= idn { sc = 0 } 63 if sc == 1 { if ids[e] == (10 as u8) { sc = 0 } else { e = e + 1 } } 64 } 65 if e - i == nl { 66 var m: i64 = 0 67 var eq: i64 = 1 68 while m < nl { if ids[i + m] != name[m] { eq = 0; m = nl } else { m = m + 1 } } 69 if eq == 1 { have = 1 } 70 } 71 i = e + 1 72 } 73 } 74 if have == 0 { 75 var o: i64 = idn 76 if o < 0 { o = 0 } 77 var m: i64 = 0 78 while m < nl { ids[o] = name[m]; o = o + 1; m = m + 1 } 79 ids[o] = 10 as u8 80 o = o + 1 81 sov_put(DL_STORE, "d:ids" as *u8, ids, o) 82 } 83 if lf >= 0 { sys_flock(lf, SYS_LOCK_UN); sys_close(lf) } 84 return 0 85} 86 87// row = "name|owner|purpose|pid|ttl_ms|stop_path|reg_us" 88func dl_register(name: *u8, owner: *u8, purpose: *u8, pid: i64, ttl_ms: i64, stop_path: *u8) -> i64 { 89 let row: *u8 = sys_mmap(512) as *u8 90 var o: i64 = 0 91 var i: i64 = 0 92 while name[i] != (0 as u8) { row[o] = name[i]; o = o + 1; i = i + 1 } 93 row[o] = 124 as u8; o = o + 1 94 i = 0 95 while owner[i] != (0 as u8) { row[o] = owner[i]; o = o + 1; i = i + 1 } 96 row[o] = 124 as u8; o = o + 1 97 i = 0 98 while purpose[i] != (0 as u8) { row[o] = purpose[i]; o = o + 1; i = i + 1 } 99 row[o] = 124 as u8; o = o + 1 100 o = o + std_itoa(pid, row + o) 101 row[o] = 124 as u8; o = o + 1 102 o = o + std_itoa(ttl_ms, row + o) 103 row[o] = 124 as u8; o = o + 1 104 i = 0 105 while stop_path[i] != (0 as u8) { row[o] = stop_path[i]; o = o + 1; i = i + 1 } 106 row[o] = 124 as u8; o = o + 1 107 o = o + std_itoa(sys_now_us(), row + o) 108 row[o] = 0 as u8 109 let key: *u8 = sys_mmap(96) as *u8 110 dl_key(name, key) 111 sov_put(DL_STORE, key, row, o) 112 dl_add_id(name) 113 // start the leash clock: REGISTERED is a live custom state in nx_watch (never-beaten age = since now) 114 nw_mark("leash" as *u8, name, "REGISTERED" as *u8) 115 return 0 116} 117 118// copy |-field k of row[0..n) into out (NUL-term); returns len or -1. 119func dl_field(row: *u8, n: i64, k: i64, out: *u8, cap: i64) -> i64 { 120 var field: i64 = 0 121 var o: i64 = 0 122 var i: i64 = 0 123 while i < n { 124 let c: i64 = row[i] as i64 125 if c == 124 { field = field + 1; if field > k { i = n } } 126 if c != 124 { if field == k { if o < cap - 1 { out[o] = row[i]; o = o + 1 } } } 127 if i < n { i = i + 1 } 128 } 129 out[o] = 0 as u8 130 if field < k { return 0 - 1 } 131 return o 132} 133 134// walk (act=1) or status (act=0): scan every registered deployment, verdict each, reclaim ABANDONED 135// when act=1 (touch its declared stop_path + mark RECLAIMED). Returns worst verdict. 136func dl_walk(act: i64) -> i64 { 137 let ids: *u8 = sys_mmap(DL_MAGIC_262144) as *u8 138 let idn: i64 = sov_get_copy(DL_STORE, "d:ids" as *u8, ids, DL_MAGIC_262143) 139 if idn <= 0 { std_putln("LEASH no deployments registered" as *u8) return 0 } 140 let key: *u8 = sys_mmap(96) as *u8 141 let row: *u8 = sys_mmap(512) as *u8 142 let fb: *u8 = sys_mmap(256) as *u8 143 let name: *u8 = sys_mmap(96) as *u8 144 let word: *u8 = sys_mmap(64) as *u8 145 let age: *i64 = sys_mmap(8) as *i64 146 var worst: i64 = 0 147 var total: i64 = 0 148 var healthy: i64 = 0 149 var abandoned: i64 = 0 150 var dead: i64 = 0 151 var i: i64 = 0 152 while i < idn { 153 var e: i64 = i 154 var sc: i64 = 1 155 while sc == 1 { 156 if e >= idn { sc = 0 } 157 if sc == 1 { if ids[e] == (10 as u8) { sc = 0 } else { e = e + 1 } } 158 } 159 let nl: i64 = e - i 160 if nl > 0 && nl < 90 { 161 var m: i64 = 0 162 while m < nl { name[m] = ids[i + m]; m = m + 1 } 163 name[nl] = 0 as u8 164 dl_key(name, key) 165 let vn: i64 = sov_get_copy(DL_STORE, key, row, 511) 166 if vn > 0 { 167 row[vn] = 0 as u8 168 total = total + 1 169 let pid: i64 = sq_field_int(row, vn, 3) 170 let ttl: i64 = sq_field_int(row, vn, 4) 171 let alive: i64 = ml_pid_alive(pid) 172 var bage: i64 = DL_MAGIC_999999999 173 let cls: i64 = nw_read("leash" as *u8, name, word, age) 174 if cls >= 0 { bage = age[0] } 175 let v: i64 = dl_verdict(alive, bage, ttl) 176 std_puts("LEASH " as *u8) 177 std_puts(name) 178 std_puts(" owner=" as *u8) 179 dl_field(row, vn, 1, fb, 255) 180 std_puts(fb) 181 std_puts(" pid=" as *u8) 182 std_pdec(pid) 183 std_puts(" beat_age_ms=" as *u8) 184 std_pdec(bage) 185 std_puts(" -> " as *u8) 186 if v == DL_HEALTHY { healthy = healthy + 1; std_putln("HEALTHY" as *u8) } 187 if v == DL_DEAD { dead = dead + 1; std_putln("DEAD (pid gone; row stays for history)" as *u8) } 188 if v == DL_ABANDONED { 189 abandoned = abandoned + 1 190 if act == 1 { 191 dl_field(row, vn, 5, fb, 255) 192 let sf: i64 = sys_openat_wr(fb, 0x1a4) 193 if sf >= 0 { sys_close(sf) } 194 nw_mark("leash" as *u8, name, "RECLAIMED" as *u8) 195 std_puts("ABANDONED -> RECLAIMED (owner walked away; stop-file " as *u8) 196 std_puts(fb) 197 std_putln(" touched)" as *u8) 198 } 199 if act != 1 { std_putln("ABANDONED (walk would reclaim)" as *u8) } 200 } 201 if v > worst { worst = v } 202 } 203 } 204 i = e + 1 205 } 206 std_puts("LEASH walked total=" as *u8) 207 std_pdec(total) 208 std_puts(" healthy=" as *u8) 209 std_pdec(healthy) 210 std_puts(" abandoned=" as *u8) 211 std_pdec(abandoned) 212 std_puts(" dead=" as *u8) 213 std_pdec(dead) 214 std_puts("\n" as *u8) 215 return worst 216} 217 218// integer |-field k (digits only) -- local sibling of the queue's parser to stay import-light. 219func sq_field_int(row: *u8, n: i64, k: i64) -> i64 { 220 var field: i64 = 0 221 var v: i64 = 0 222 var seen: i64 = 0 223 var i: i64 = 0 224 while i < n { 225 let c: i64 = row[i] as i64 226 if c == 124 { field = field + 1; if field > k { i = n } } 227 if c != 124 { if field == k { if c >= 48 && c <= 57 { v = v * 10 + (c - 48); seen = 1 } } } 228 if i < n { i = i + 1 } 229 } 230 if seen == 0 { return 0 - 1 } 231 return v 232} 233 234func main(argc: i64, argv: *i64) -> i64 { 235 if argc < 2 { 236 std_putln("usage: nx_deploy_leash register <name> <owner> <purpose> <pid> <renew_ttl_ms> <stop_path> | walk | status" as *u8) 237 sys_exit(4) 238 return 4 239 } 240 let a1: i64 = argv[1] 241 let verb: *u8 = a1 as *u8 242 if std_streq(verb, "register" as *u8) == 1 { 243 if argc < 8 { std_putln("register needs <name> <owner> <purpose> <pid> <renew_ttl_ms> <stop_path>" as *u8); sys_exit(4); return 4 } 244 let b2: i64 = argv[2] 245 let b3: i64 = argv[3] 246 let b4: i64 = argv[4] 247 let b5: i64 = argv[5] 248 let b6: i64 = argv[6] 249 let b7: i64 = argv[7] 250 let p5: *u8 = b5 as *u8 251 let p6: *u8 = b6 as *u8 252 dl_register(b2 as *u8, b3 as *u8, b4 as *u8, std_atoi(p5), std_atoi(p6), b7 as *u8) 253 std_putln("LEASH registered (clock started; consumers: nx_watch beat leash <name> on every use)" as *u8) 254 sys_exit(0) 255 return 0 256 } 257 if std_streq(verb, "walk" as *u8) == 1 { 258 let w: i64 = dl_walk(1) 259 sys_exit(w) 260 return w 261 } 262 if std_streq(verb, "status" as *u8) == 1 { 263 let s: i64 = dl_walk(0) 264 sys_exit(s) 265 return s 266 } 267 std_putln("unknown verb (register|walk|status)" as *u8) 268 sys_exit(4) 269 return 4 270}