code wiki / _hdl_build / nx_plan_run.nx

nx_plan_run.nx source

↩ module page · 286 lines · 11564 B

1// nx_plan_run.nx -- WORKFLOWS-AS-DATA: the sovereign plan executor (operator 2026-07-18: "i still 2// see scratchpadding not via nishi... get what you are doing outside of it in mcp and api and 3// workflow"). Kills the session-side shell-script orchestration class: a PLAN is rows in a plane 4// (seeded via the MCP-live nx_store_put), and ONE cap-gated tools/call executes the whole sequence 5// SERVER-SIDE, recording per-step results to a results plane (provenance in the plane, as always). 6// nx_plan_run <planid> [allowlist] [planprefix] [resultsprefix] 7// plan rows : knowledge/store/plan-<id>- seq<TAB>tool<TAB>arg... (executed in seq order) 8// results rows: knowledge/store/planrun-<id>- seq<TAB>tool<TAB>rc<TAB>output-snippet 9// SECURITY = the tools-plane model, no escalation: each step's tool MUST be a GREEN row in 10// tool_allowlist.conf; a row's PINNED args override plan args (fixed-arg pinning, caller args 11// ignored); unknown tool -> REFUSED fail-closed; a failing step STOPS the plan (later steps never 12// run) with the failure recorded. nx_plan_run itself is cap-gated on the tools plane. 13// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 14import "nx_store_seed_lib.nx" 15import "nx_seg_store.nx" 16import "nx_deploy_lib.nx" 17import "nx_syscalls.nx" 18 19const PR_CAP: i64 = 1048576 20const PR_NL: i64 = 10 21const PR_TAB: i64 = 9 22const PR_SP: i64 = 32 23const PR_MAXCOL: i64 = 16 24const PR_PAIR: i64 = 2 25const PR_SPB: i64 = 256 26const PR_MAXSTEP: i64 = 64 27const PR_MAXARG: i64 = 12 28const PR_ARENA: i64 = 65536 29const PR_PFXCAP: i64 = 256 30// ★200 -> 2000 (2026-07-30, ws=neuro). A 200-byte snippet is SMALLER THAN THE SUMMARY MANY ORGANS PRINT, 31// so the results plane silently reported only a tool's header and dropped its actual finding: nx_meshprofile 32// emits a DELIBERATE SHORTLIST (top-12 radius jumps, the whole point of the organ) and the plane carried only 33// the DIAG line, making the step unreadable while still recording rc=0. A results row that cannot hold the 34// result is a green light with the answer cut off. BOUNDED BY CONSTRUCTION, not by hope: res is mmap'd at 35// PR_CAP (1 MiB) and steps are capped at PR_MAXSTEP (64), so the worst case is 64*~2050 = ~131 KB, an eighth 36// of the arena. Raise PR_CAP first if PR_MAXSTEP ever grows. 37const PR_SNIP: i64 = 2000 38const PR_OUTCAP: i64 = 65536 39const PR_STDERR: i64 = 2 40const PR_EXIT_USAGE: i64 = 2 41const PR_EXIT_IO: i64 = 1 42const PR_EXIT_REFUSED: i64 = 4 43const PR_EXIT_STEPFAIL: i64 = 5 44const PR_ZERO: i64 = 48 45const PR_NINE: i64 = 57 46const PR_B10: i64 = 10 47 48func pr_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 49func pr_werr(s: *u8) -> i64 { sys_write(PR_STDERR, s, pr_slen(s)); return 0 } 50func pr_cols(q: *u8, ls: i64, le: i64, sp: *i64) -> i64 { 51 var c: i64 = 0 52 var p: i64 = ls 53 while c < PR_MAXCOL { 54 var e: i64 = p 55 var s: i64 = 1 56 while s == 1 { if e >= le { s = 0 } else { if q[e] == (PR_TAB as u8) { s = 0 } else { e = e + 1 } } } 57 sp[c*PR_PAIR] = p 58 sp[c*PR_PAIR+1] = e 59 c = c + 1 60 if e >= le { return c } 61 p = e + 1 62 } 63 return c 64} 65func pr_slice_int(q: *u8, a: i64, b: i64) -> i64 { 66 var v: i64 = 0 67 var i: i64 = a 68 while i < b { let c: i64 = q[i]; if c >= PR_ZERO { if c <= PR_NINE { v = v * PR_B10 + (c - PR_ZERO) } } i = i + 1 } 69 return v 70} 71func pr_slice_eq(q: *u8, a: i64, b: i64, r: *u8, c: i64, d: i64) -> i64 { 72 if b - a != d - c { return 0 } 73 var i: i64 = 0 74 while a + i < b { if q[a+i] != r[c+i] { return 0 } i = i + 1 } 75 return 1 76} 77// copy slice into arena as a NUL-terminated C-string; returns its address, bumps off 78func pr_cstr(arena: *u8, off: *i64, q: *u8, a: i64, b: i64) -> i64 { 79 let base: i64 = off[0] 80 var i: i64 = a 81 var o: i64 = base 82 while i < b { arena[o] = q[i]; o = o + 1; i = i + 1 } 83 arena[o] = 0 as u8 84 off[0] = o + 1 85 return (arena as i64) + base 86} 87// find tool (slice) in allowlist buf; fill elfp[0]=elf cstr addr; pinned args into av[0..], returns nargs (-1 not found) 88func pr_find_tool(al: *u8, n: i64, q: *u8, ta: i64, tb: i64, arena: *u8, off: *i64, elfp: *i64, av: *i64) -> i64 { 89 let sp: *i64 = sys_mmap(PR_SPB) as *i64 90 var i: i64 = 0 91 while i < n { 92 var le: i64 = i 93 var s: i64 = 1 94 while s == 1 { if le >= n { s = 0 } else { if al[le] == (PR_NL as u8) { s = 0 } else { le = le + 1 } } } 95 if le > i { 96 let nc: i64 = pr_cols(al, i, le, sp) 97 if nc >= 3 { 98 if pr_slice_eq(al, sp[0], sp[1], q, ta, tb) == 1 { 99 elfp[0] = pr_cstr(arena, off, al, sp[2], sp[3]) 100 var na: i64 = 0 101 if nc >= 4 { 102 // pinned args col: split on spaces 103 var p: i64 = sp[6] 104 let pe: i64 = sp[7] 105 while p < pe { 106 var e2: i64 = p 107 var s2: i64 = 1 108 while s2 == 1 { if e2 >= pe { s2 = 0 } else { if al[e2] == (PR_SP as u8) { s2 = 0 } else { e2 = e2 + 1 } } } 109 if e2 > p { if na < PR_MAXARG { av[na] = pr_cstr(arena, off, al, p, e2); na = na + 1 } } 110 p = e2 + 1 111 } 112 } 113 return na 114 } 115 } 116 } 117 i = le + 1 118 } 119 return 0 - 1 120} 121// sanitize outfile content into a snippet: tabs/newlines -> spaces, cap PR_SNIP 122func pr_snip(dst: *u8, o: i64, src: *u8, n: i64) -> i64 { 123 var m: i64 = n 124 if m > PR_SNIP { m = PR_SNIP } 125 var oo: i64 = o 126 var i: i64 = 0 127 while i < m { 128 var c: i64 = src[i] 129 if c == PR_TAB { c = PR_SP } 130 if c == PR_NL { c = PR_SP } 131 if c < PR_SP { c = PR_SP } 132 dst[oo] = c as u8 133 oo = oo + 1 134 i = i + 1 135 } 136 return oo 137} 138 139func main(argc: i64, argv: *i64) -> i64 { 140 if argc < 2 { pr_werr("usage: nx_plan_run <planid> [allowlist] [planprefix] [resultsprefix]\n" as *u8); sys_exit(PR_EXIT_USAGE); return PR_EXIT_USAGE } 141 let planid: *u8 = argv[1] as *u8 142 var alpath: *u8 = "tool_allowlist.conf" as *u8 143 if argc > 2 { alpath = argv[2] as *u8 } 144 let ppfx: *u8 = sys_mmap(PR_PFXCAP) 145 let rpfx: *u8 = sys_mmap(PR_PFXCAP) 146 if argc > 3 { 147 let p3: *u8 = argv[3] as *u8 148 var i0: i64 = 0 149 while p3[i0] != (0 as u8) { ppfx[i0] = p3[i0]; i0 = i0 + 1 } 150 ppfx[i0] = 0 as u8 151 } else { 152 var o1: i64 = ss_cat(ppfx, 0, "knowledge/store/plan-" as *u8) 153 o1 = ss_cat(ppfx, o1, planid) 154 o1 = ss_cat(ppfx, o1, "-" as *u8) 155 ppfx[o1] = 0 as u8 156 } 157 if argc > 4 { 158 let p4: *u8 = argv[4] as *u8 159 var i1: i64 = 0 160 while p4[i1] != (0 as u8) { rpfx[i1] = p4[i1]; i1 = i1 + 1 } 161 rpfx[i1] = 0 as u8 162 } else { 163 var o2: i64 = ss_cat(rpfx, 0, "knowledge/store/planrun-" as *u8) 164 o2 = ss_cat(rpfx, o2, planid) 165 o2 = ss_cat(rpfx, o2, "-" as *u8) 166 rpfx[o2] = 0 as u8 167 } 168 169 let plan: *u8 = sys_mmap(PR_CAP) 170 let pn: i64 = sts_load(ppfx, plan, PR_CAP) 171 if pn <= 0 { pr_werr("plan plane EMPTY / unseeded (fail-closed)\n" as *u8); sys_exit(PR_EXIT_IO); return PR_EXIT_IO } 172 let al: *u8 = sys_mmap(PR_CAP) 173 let an: i64 = dp_read(alpath, al, PR_CAP - 4) 174 if an <= 0 { pr_werr("allowlist unreadable (fail-closed)\n" as *u8); sys_exit(PR_EXIT_IO); return PR_EXIT_IO } 175 176 // collect step line spans + seqs 177 let lss: *i64 = sys_mmap(PR_MAXSTEP*8) as *i64 178 let les: *i64 = sys_mmap(PR_MAXSTEP*8) as *i64 179 let sqs: *i64 = sys_mmap(PR_MAXSTEP*8) as *i64 180 let sp: *i64 = sys_mmap(PR_SPB) as *i64 181 var nstep: i64 = 0 182 var i: i64 = 0 183 while i < pn { 184 var le: i64 = i 185 var s: i64 = 1 186 while s == 1 { if le >= pn { s = 0 } else { if plan[le] == (PR_NL as u8) { s = 0 } else { le = le + 1 } } } 187 if le > i { if nstep < PR_MAXSTEP { 188 let nc: i64 = pr_cols(plan, i, le, sp) 189 if nc >= 2 { 190 lss[nstep] = i 191 les[nstep] = le 192 sqs[nstep] = pr_slice_int(plan, sp[0], sp[1]) 193 nstep = nstep + 1 194 } 195 } } 196 i = le + 1 197 } 198 // insertion sort by seq 199 var a: i64 = 1 200 while a < nstep { 201 var b: i64 = a 202 while b > 0 { 203 if sqs[b-1] > sqs[b] { 204 let t0: i64 = sqs[b-1] 205 sqs[b-1] = sqs[b] 206 sqs[b] = t0 207 let t1: i64 = lss[b-1] 208 lss[b-1] = lss[b] 209 lss[b] = t1 210 let t2: i64 = les[b-1] 211 les[b-1] = les[b] 212 les[b] = t2 213 b = b - 1 214 } else { b = 0 } 215 } 216 a = a + 1 217 } 218 219 let arena: *u8 = sys_mmap(PR_ARENA) 220 let aoff: *i64 = sys_mmap(16) as *i64 221 let res: *u8 = sys_mmap(PR_CAP) 222 let outbuf: *u8 = sys_mmap(PR_OUTCAP) 223 let elfp: *i64 = sys_mmap(16) as *i64 224 let av: *i64 = sys_mmap((PR_MAXARG+2)*8) as *i64 225 let outfile: *u8 = "/tmp/nx_plan_step.out" as *u8 226 var ro: i64 = 0 227 var k: i64 = 0 228 var failed: i64 = 0 229 while k < nstep { 230 if failed == 0 { 231 aoff[0] = 0 232 let nc2: i64 = pr_cols(plan, lss[k], les[k], sp) 233 // resolve tool (col1) in allowlist 234 var na: i64 = pr_find_tool(al, an, plan, sp[2], sp[3], arena, aoff, elfp, av) 235 if na < 0 { 236 ro = ss_catn(res, ro, sqs[k]) 237 res[ro] = PR_TAB as u8 238 ro = ro + 1 239 var rr: i64 = ro 240 rr = pr_snip(res, rr, "REFUSED-unknown-tool" as *u8, 20) 241 ro = rr 242 res[ro] = PR_NL as u8 243 ro = ro + 1 244 failed = PR_EXIT_REFUSED 245 } else { 246 if na == 0 { 247 // no pinned args -> plan cols 2.. are the argv 248 var c: i64 = 2 249 while c < nc2 { 250 if na < PR_MAXARG { av[na] = pr_cstr(arena, aoff, plan, sp[c*PR_PAIR], sp[c*PR_PAIR+1]); na = na + 1 } 251 c = c + 1 252 } 253 } 254 let rc: i64 = dep_run_capture(elfp[0] as *u8, av, na, outfile) 255 let on: i64 = dp_read(outfile, outbuf, PR_OUTCAP - 4) 256 ro = ss_catn(res, ro, sqs[k]) 257 res[ro] = PR_TAB as u8 258 ro = ro + 1 259 ro = ss_cat(res, ro, "rc=" as *u8) 260 ro = ss_catn(res, ro, rc) 261 res[ro] = PR_TAB as u8 262 ro = ro + 1 263 var on2: i64 = on 264 if on2 < 0 { on2 = 0 } 265 ro = pr_snip(res, ro, outbuf, on2) 266 res[ro] = PR_NL as u8 267 ro = ro + 1 268 if rc != 0 { failed = PR_EXIT_STEPFAIL } 269 } 270 } 271 k = k + 1 272 } 273 if sts_seed(rpfx, res, ro) < 0 { pr_werr("results commit error\n" as *u8); sys_exit(PR_EXIT_IO); return PR_EXIT_IO } 274 let msg: *u8 = sys_mmap(PR_PFXCAP) 275 var mo: i64 = ss_cat(msg, 0, "PLAN " as *u8) 276 mo = ss_cat(msg, mo, planid) 277 mo = ss_cat(msg, mo, " steps=" as *u8) 278 mo = ss_catn(msg, mo, nstep) 279 if failed != 0 { mo = ss_cat(msg, mo, " FAILED (stopped fail-closed, results recorded)" as *u8) } else { mo = ss_cat(msg, mo, " ok" as *u8) } 280 msg[mo] = PR_NL as u8 281 mo = mo + 1 282 sys_write(1, msg, mo) 283 if failed != 0 { sys_exit(failed); return failed } 284 sys_exit(0) 285 return 0 286}