code wiki / (root) / nx_swarm_place.nx

nx_swarm_place.nx source

↩ module page · 333 lines · 14011 B

1// nx_swarm_place.nx -- SWARM FABRIC placement brain (SF-R2): given the fleet snapshot (NODE rows 2// from nx_swarm_beat) pick the best node for a chunky job. The 2025/26 radar's #1+#2 gaps 3// (energy-aware 98 + load-aware 65) in one organ. GREENFIELD: pure integer cost model over the 4// beacon's live truth; freshness is a HARD gate (you cannot place on stale truth -- inherits the 5// beat store's liveness liar-killers); battery politeness EXCLUDES (never cook a phone/laptop); 6// thermal sheds (heavy penalty, still schedulable in an emergency); unknown (-1) sensors are 7// NEUTRAL (honest-absent must not punish a node that cannot report). 8// 9// nx_swarm_place pick <snap> <window_sec> [conf] rank + pick; prints per-node verdicts + winner 10// nx_swarm_place [gate] self-gate (8 tests incl liar-killers) 11// 12// CONF (rule 11, data-driven -- knowledge/swarm/place.conf ships the live lever; bootstrap 13// defaults compiled as the last tier of the config hierarchy): lines "key value": 14// w_load 600 · w_mem 400 · shed_temp_mc 85000 · batt_floor_pct 20 15// SCORE (0..1000): base = (w_load*load_headroom + w_mem*mem_headroom)/(w_load+w_mem); 16// load_headroom = 1000-lpc clamped; mem_headroom = (100-mem_used_pct)*10 clamped; 17// temp_mc >= shed → base/10. EXCLUDED: stale/forged ts · batt < floor · malformed row. 18// Ties: first-in-snap wins (deterministic). license_tier: ORIGINAL expect_exit:0 19import "nx_syscalls.nx" 20import "nx_framed_append.nx" 21import "nx_swarm_lib.nx" 22const SP_MAGIC_85000: i64 = 85000 23const SP_MAGIC_1024: i64 = 1024 24const SP_MAGIC_3600: i64 = 3600 25const SP_MAGIC_90000: i64 = 90000 26const SP_MAGIC_40000: i64 = 40000 27const SP_MAGIC_7200000000: i64 = 7200000000 28 29const SP_SNAP_CAP: i64 = 65536 30const SP_CONF_CAP: i64 = 4096 31 32func sp_puts(s: *u8) -> i64 { sys_write(1, s, fa_len(s)); return 0 } 33 34func sp_eq(a: *u8, b: *u8) -> i64 { 35 var i: i64 = 0 36 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } 37 if b[i] != (0 as u8) { return 0 } 38 return 1 39} 40 41// does buf[p..] start with key (nul-terminated)? returns index AFTER key, or -1. 42func sp_starts(buf: *u8, n: i64, p: i64, key: *u8) -> i64 { 43 var k: i64 = 0 44 while key[k] != (0 as u8) { 45 if p + k >= n { return 0 - 1 } 46 if buf[p + k] != key[k] { return 0 - 1 } 47 k = k + 1 48 } 49 return p + k 50} 51 52// conf loader: c[0]=w_load c[1]=w_mem c[2]=shed_temp_mc c[3]=batt_floor_pct. 53// Missing file / missing keys keep the compiled bootstrap defaults (config-hierarchy last tier). 54func sp_conf_load(path: *u8, c: *i64) -> i64 { 55 c[0] = 600 56 c[1] = 400 57 c[2] = SP_MAGIC_85000 58 c[3] = 20 59 if (path as i64) == 0 { return 0 } 60 let buf: *u8 = sys_mmap(SP_CONF_CAP) 61 let n: i64 = sb_read(path, buf, SP_CONF_CAP) 62 if n <= 0 { return 0 } 63 let vout: *i64 = sys_mmap(16) as *i64 64 let pend: *i64 = sys_mmap(16) as *i64 65 var i: i64 = 0 66 while i < n { 67 var e: i64 = i 68 var g: i64 = 1 69 while g == 1 { if e >= n { g = 0 } else { if (buf[e] as i64) == 10 { g = 0 } else { e = e + 1 } } } 70 var at: i64 = sp_starts(buf, e, i, "w_load " as *u8) 71 if at >= 0 { if sb_pint(buf, e, at, vout, pend) == 1 { c[0] = vout[0] } } 72 at = sp_starts(buf, e, i, "w_mem " as *u8) 73 if at >= 0 { if sb_pint(buf, e, at, vout, pend) == 1 { c[1] = vout[0] } } 74 at = sp_starts(buf, e, i, "shed_temp_mc " as *u8) 75 if at >= 0 { if sb_pint(buf, e, at, vout, pend) == 1 { c[2] = vout[0] } } 76 at = sp_starts(buf, e, i, "batt_floor_pct " as *u8) 77 if at >= 0 { if sb_pint(buf, e, at, vout, pend) == 1 { c[3] = vout[0] } } 78 i = e + 1 79 } 80 return 0 81} 82 83// score one parsed row. >=0 score / -1 EXCLUDED (why[0]: 1=stale 2=battery). 84// f = cpu,load,ncpu,lpc,memu,mema,memt,conns,ts,temp,batt (sb_fields layout) 85func sp_score(f: *i64, now: i64, window_sec: i64, c: *i64, why: *i64) -> i64 { 86 why[0] = 0 87 if sb_fresh(f[8], now, window_sec) == 0 { why[0] = 1; return 0 - 1 } 88 let batt: i64 = f[10] 89 if batt >= 0 { if batt < c[3] { why[0] = 2; return 0 - 1 } } 90 var load_head: i64 = 1000 - f[3] 91 if load_head < 0 { load_head = 0 } 92 if load_head > 1000 { load_head = 1000 } 93 var mem_head: i64 = (100 - f[4]) * 10 94 if mem_head < 0 { mem_head = 0 } 95 if mem_head > 1000 { mem_head = 1000 } 96 var denom: i64 = c[0] + c[1] 97 if denom < 1 { denom = 1 } 98 var base: i64 = (c[0] * load_head + c[1] * mem_head) / denom 99 let temp: i64 = f[9] 100 if temp >= 0 { if temp >= c[2] { base = base / 10 } } 101 return base 102} 103 104// pick over a snapshot. Prints per-node verdicts + winner line. Returns 0 winner / 3 none. 105// wname/wcap: out-buffer for the winner name (for the gate); pass 0 to skip. 106func sp_pick(snap: *u8, window_sec: i64, confpath: *u8, wname: *u8, wcap: i64) -> i64 { 107 let c: *i64 = sys_mmap(64) as *i64 108 sp_conf_load(confpath, c) 109 let buf: *u8 = sys_mmap(SP_SNAP_CAP) 110 let n: i64 = sb_read(snap, buf, SP_SNAP_CAP) 111 let now: i64 = sys_now_us() 112 let f: *i64 = sys_mmap(128) as *i64 113 let why: *i64 = sys_mmap(16) as *i64 114 let nso: *i64 = sys_mmap(16) as *i64 115 let nlo: *i64 = sys_mmap(16) as *i64 116 let tso: *i64 = sys_mmap(16) as *i64 117 let t: *u8 = sys_mmap(SP_MAGIC_1024) 118 var best: i64 = 0 - 1 119 var bns: i64 = 0 120 var bnl: i64 = 0 121 var i: i64 = 0 122 while i < n { 123 var e: i64 = i 124 var g: i64 = 1 125 while g == 1 { if e >= n { g = 0 } else { if (buf[e] as i64) == 10 { g = 0 } else { e = e + 1 } } } 126 if e > i { 127 let line: *u8 = (buf as i64 + i) as *u8 128 let ln: i64 = e - i 129 var to: i64 = 0 130 if sb_fields(line, ln, f) == 1 { 131 sb_validate(line, ln, nso, nlo, tso) 132 let sc: i64 = sp_score(f, now, window_sec, c, why) 133 if sc >= 0 { 134 to = fa_cat(t, 0, "CANDIDATE score=" as *u8) 135 to = fa_catn(t, to, sc) 136 } else { 137 if why[0] == 1 { to = fa_cat(t, 0, "EXCLUDED-stale" as *u8) } else { to = fa_cat(t, 0, "EXCLUDED-battery" as *u8) } 138 } 139 to = fa_cat(t, to, " " as *u8) 140 sys_write(1, t, to) 141 sys_write(1, line, ln) 142 sp_puts("\n" as *u8) 143 if sc > best { 144 best = sc 145 bns = i + nso[0] 146 bnl = nlo[0] 147 } 148 } else { 149 to = fa_cat(t, 0, "EXCLUDED-badrow " as *u8) 150 sys_write(1, t, to) 151 sys_write(1, line, ln) 152 sp_puts("\n" as *u8) 153 } 154 } 155 i = e + 1 156 } 157 if best < 0 { 158 sp_puts("SWARMPLACE NO-PLACEMENT (no fresh eligible node)\n" as *u8) 159 return 3 160 } 161 var to2: i64 = 0 162 to2 = fa_cat(t, to2, "SWARMPLACE winner=" as *u8) 163 var k: i64 = 0 164 while k < bnl { t[to2] = buf[bns + k]; to2 = to2 + 1; k = k + 1 } 165 to2 = fa_cat(t, to2, " score=" as *u8) 166 to2 = fa_catn(t, to2, best) 167 to2 = fa_cat(t, to2, "\n" as *u8) 168 sys_write(1, t, to2) 169 if (wname as i64) != 0 { 170 var k2: i64 = 0 171 while k2 < bnl { if k2 < wcap - 1 { wname[k2] = buf[bns + k2] } k2 = k2 + 1 } 172 var wl: i64 = bnl 173 if wl > wcap - 1 { wl = wcap - 1 } 174 wname[wl] = 0 as u8 175 } 176 return 0 177} 178 179// gate helpers ------------------------------------------------------------ 180func sp_mkrow(dst: *u8, name: *u8, lpc: i64, memu: i64, ts: i64, temp: i64, batt: i64) -> i64 { 181 var o: i64 = 0 182 o = fa_cat(dst, o, "NODE " as *u8) 183 o = fa_cat(dst, o, name) 184 o = fa_cat(dst, o, " 50 " as *u8) 185 o = fa_catn(dst, o, lpc) 186 o = fa_cat(dst, o, " 1 " as *u8) 187 o = fa_catn(dst, o, lpc) 188 o = fa_cat(dst, o, " " as *u8) 189 o = fa_catn(dst, o, memu) 190 o = fa_cat(dst, o, " 1000 2000 0 " as *u8) 191 o = fa_catn(dst, o, ts) 192 o = fa_cat(dst, o, " " as *u8) 193 o = fa_catn(dst, o, temp) 194 o = fa_cat(dst, o, " " as *u8) 195 o = fa_catn(dst, o, batt) 196 o = fa_cat(dst, o, "\n" as *u8) 197 return o 198} 199 200func sp_wfile(path: *u8, buf: *u8, n: i64) -> i64 { 201 let fd: i64 = sys_openat_wr(path, 0x1a4) 202 if fd < 0 { return 0 - 1 } 203 let wr: i64 = fa_write_all(fd, buf, n) 204 sys_close(fd) 205 if wr != n { return 0 - 1 } 206 return 0 207} 208 209func sp_gate() -> i64 { 210 var pass: i64 = 0 211 var total: i64 = 0 212 let now: i64 = sys_now_us() 213 let snap: *u8 = sys_mmap(256) 214 var so: i64 = 0 215 so = fa_cat(snap, so, "/tmp/swp_gate_" as *u8) 216 so = fa_catn(snap, so, now) 217 so = fa_cat(snap, so, ".snap" as *u8) 218 snap[so] = 0 as u8 219 let conf: *u8 = sys_mmap(256) 220 var co: i64 = 0 221 co = fa_cat(conf, co, "/tmp/swp_gate_" as *u8) 222 co = fa_catn(conf, co, now) 223 co = fa_cat(conf, co, ".conf" as *u8) 224 conf[co] = 0 as u8 225 let body: *u8 = sys_mmap(SP_SNAP_CAP) 226 let w: *u8 = sys_mmap(64) 227 228 // T1 idle beats loaded (both fresh, sensors unknown) 229 total = total + 1 230 var o: i64 = 0 231 o = o + sp_mkrow((body as i64 + o) as *u8, "loaded" as *u8, 900, 50, now, 0 - 1, 0 - 1) 232 o = o + sp_mkrow((body as i64 + o) as *u8, "idle" as *u8, 100, 50, now, 0 - 1, 0 - 1) 233 sp_wfile(snap, body, o) 234 var r: i64 = sp_pick(snap, SP_MAGIC_3600, 0 as *u8, w, 64) 235 if r == 0 { if sp_eq(w, "idle" as *u8) == 1 { pass = pass + 1; sp_puts("T1 idle-beats-loaded OK\n" as *u8) } } 236 237 // T2 LIAR-KILLER thermal shed: hot-idle loses to cool-busier 238 total = total + 1 239 o = 0 240 o = o + sp_mkrow((body as i64 + o) as *u8, "hot" as *u8, 100, 50, now, SP_MAGIC_90000, 0 - 1) 241 o = o + sp_mkrow((body as i64 + o) as *u8, "cool" as *u8, 400, 50, now, SP_MAGIC_40000, 0 - 1) 242 sp_wfile(snap, body, o) 243 r = sp_pick(snap, SP_MAGIC_3600, 0 as *u8, w, 64) 244 if r == 0 { if sp_eq(w, "cool" as *u8) == 1 { pass = pass + 1; sp_puts("T2 thermal-shed OK\n" as *u8) } } 245 246 // T3 LIAR-KILLER battery floor: low-battery node EXCLUDED even if otherwise best 247 total = total + 1 248 o = 0 249 o = o + sp_mkrow((body as i64 + o) as *u8, "lowbatt" as *u8, 100, 10, now, 0 - 1, 10) 250 o = o + sp_mkrow((body as i64 + o) as *u8, "plugged" as *u8, 800, 90, now, 0 - 1, 95) 251 sp_wfile(snap, body, o) 252 r = sp_pick(snap, SP_MAGIC_3600, 0 as *u8, w, 64) 253 if r == 0 { if sp_eq(w, "plugged" as *u8) == 1 { pass = pass + 1; sp_puts("T3 battery-floor-excludes OK\n" as *u8) } } 254 255 // T4 LIAR-KILLER stale never placed: ancient perfect node loses to fresh busy one 256 total = total + 1 257 o = 0 258 o = o + sp_mkrow((body as i64 + o) as *u8, "ancient" as *u8, 0, 0, now - SP_MAGIC_7200000000, 0 - 1, 0 - 1) 259 o = o + sp_mkrow((body as i64 + o) as *u8, "alive" as *u8, 800, 80, now, 0 - 1, 0 - 1) 260 sp_wfile(snap, body, o) 261 r = sp_pick(snap, SP_MAGIC_3600, 0 as *u8, w, 64) 262 if r == 0 { if sp_eq(w, "alive" as *u8) == 1 { pass = pass + 1; sp_puts("T4 stale-never-placed OK\n" as *u8) } } 263 264 // T5 honest-absent neutral: unknown sensors still placeable 265 total = total + 1 266 o = 0 267 o = o + sp_mkrow((body as i64 + o) as *u8, "solo" as *u8, 500, 50, now, 0 - 1, 0 - 1) 268 sp_wfile(snap, body, o) 269 r = sp_pick(snap, SP_MAGIC_3600, 0 as *u8, w, 64) 270 if r == 0 { if sp_eq(w, "solo" as *u8) == 1 { pass = pass + 1; sp_puts("T5 honest-absent-neutral OK\n" as *u8) } } 271 272 // T6 conf-driven flip (data-driven weights, rule 11): same snap, two confs, two winners 273 total = total + 1 274 o = 0 275 o = o + sp_mkrow((body as i64 + o) as *u8, "cpuish" as *u8, 200, 80, now, 0 - 1, 0 - 1) 276 o = o + sp_mkrow((body as i64 + o) as *u8, "memish" as *u8, 400, 20, now, 0 - 1, 0 - 1) 277 sp_wfile(snap, body, o) 278 var cb: i64 = 0 279 cb = fa_cat(body, cb, "w_load 1000\nw_mem 0\n" as *u8) 280 sp_wfile(conf, body, cb) 281 r = sp_pick(snap, SP_MAGIC_3600, conf, w, 64) 282 var flip1: i64 = 0 283 if r == 0 { if sp_eq(w, "cpuish" as *u8) == 1 { flip1 = 1 } } 284 cb = 0 285 cb = fa_cat(body, cb, "w_load 0\nw_mem 1000\n" as *u8) 286 sp_wfile(conf, body, cb) 287 r = sp_pick(snap, SP_MAGIC_3600, conf, w, 64) 288 if flip1 == 1 { if r == 0 { if sp_eq(w, "memish" as *u8) == 1 { pass = pass + 1; sp_puts("T6 conf-weight-flip OK\n" as *u8) } } } 289 290 // T7 determinism: same inputs twice -> same winner 291 total = total + 1 292 r = sp_pick(snap, SP_MAGIC_3600, conf, w, 64) 293 var w1ok: i64 = 0 294 if r == 0 { if sp_eq(w, "memish" as *u8) == 1 { w1ok = 1 } } 295 r = sp_pick(snap, SP_MAGIC_3600, conf, w, 64) 296 if w1ok == 1 { if r == 0 { if sp_eq(w, "memish" as *u8) == 1 { pass = pass + 1; sp_puts("T7 deterministic OK\n" as *u8) } } } 297 298 // T8 NEG: empty snap -> NO-PLACEMENT (never fabricate a winner) 299 total = total + 1 300 sp_wfile(snap, body, 0) 301 r = sp_pick(snap, SP_MAGIC_3600, 0 as *u8, w, 64) 302 if r == 3 { pass = pass + 1; sp_puts("T8 empty-no-placement OK\n" as *u8) } 303 304 let t: *u8 = sys_mmap(128) 305 var to: i64 = 0 306 to = fa_cat(t, to, "SWARMPLACEGATE " as *u8) 307 to = fa_catn(t, to, pass) 308 to = fa_cat(t, to, "/" as *u8) 309 to = fa_catn(t, to, total) 310 if pass == total { to = fa_cat(t, to, " verdict=GREEN\n" as *u8) } else { to = fa_cat(t, to, " verdict=RED\n" as *u8) } 311 sys_write(1, t, to) 312 if pass == total { return 0 } 313 return 1 314} 315 316func main(argc: i64, argv: *i64) -> i64 { 317 if argc >= 2 { 318 let verb: *u8 = argv[1] as *u8 319 if sp_eq(verb, "pick" as *u8) == 1 { 320 if argc < 4 { sp_puts("usage: nx_swarm_place pick <snap> <window_sec> [conf]\n" as *u8); return 2 } 321 let snap: *u8 = argv[2] as *u8 322 if sb_path_ok(snap) == 0 { sp_puts("SWARMPLACE pick REFUSED (path law)\n" as *u8); return 3 } 323 let vout: *i64 = sys_mmap(16) as *i64 324 let pend: *i64 = sys_mmap(16) as *i64 325 let ws: *u8 = argv[3] as *u8 326 if sb_pint(ws, fa_len(ws), 0, vout, pend) == 0 { return 2 } 327 var conf: *u8 = 0 as *u8 328 if argc >= 5 { conf = argv[4] as *u8 } 329 return sp_pick(snap, vout[0], conf, 0 as *u8, 0) 330 } 331 } 332 return sp_gate() 333}