code wiki / _hdl_build / nx_ale_exec.nx
nx_ale_exec.nx source
↩ module page · 483 lines · 21480 B
1// nx_ale_exec.nx -- sovereign ALE agent-core EXECUTE/dispatch organ (rung ALE-R2b).
2// THE execute step the whole ALE-R2 agent-core routes through: it CONSUMES the ALE-R2a ordered
3// plan and the task spec and DISPATCHES each step IN ORDER over a sandbox working dir to produce a
4// REAL artifact file -- never re-planning, never opening the reference path. PURE function of:
5// argv[1] = PLAN path (ALE-R2a plan: "step|<n>|<verb>|<arg>" lines, ordered from 1)
6// argv[2] = TASK path (ALE-format task spec: "contract|field|value" lines)
7// argv[3] = SANDBOX dir (the working dir; staged files + the artifact land here)
8// CONTRACT (data-driven; the step shape comes from ale_exec.spec / ale_plan.spec):
9// REQUIRED task fields = materials_dir, input_stage, artifact_path. If ANY is absent the
10// executor REFUSES: exit non-zero, produces NO artifact.
11// The plan is walked TOP-TO-BOTHOM and consumed STRICTLY in order via a 3-state machine:
12// step 1 must be stage_input -> copies materials_dir/input_stage VERBATIM into sandbox/input_stage
13// step 2 must be run_organ -> applies the instruction's named DETERMINISTIC transform over the
14// staged bytes (extract_kv_to_units: each "kv|k|v" -> "unit|k|v")
15// step 3 must be write_artifact -> writes the transform output VERBATIM to sandbox/artifact_path
16// Any out-of-order verb, an unknown transform token, or a plan MISSING write_artifact => REFUSE
17// (exit non-zero, NO artifact). The executor reads ONLY argv[1..3] + materials_dir/input_stage;
18// it NEVER opens the reference path -> the artifact is independent of reference presence (no
19// leakage, enforced end-to-end). No clock, no rand -> two runs on the same (plan,task,fresh
20// sandbox) yield a BYTE-IDENTICAL artifact (DETERMINISTIC).
21// Landmines respected: nested ifs (no &&/||), flat exprs, <=6 args/func, no empty-string literal,
22// strings via Write, openat_wr fresh path. Helpers mirror the ALE-R2a/R1a line-grammar (ae_*).
23// license_tier: ORIGINAL
24import "nx_syscalls.nx"
25const K_MAGIC_262144: i64 = 262144
26const K_MAGIC_8192: i64 = 8192
27const K_MAGIC_16384: i64 = 16384
28
29// read whole file at path into buf (cap), return byte count (0 on open-fail)
30func ae_read(path: *u8, buf: *u8, cap: i64) -> i64 {
31 let fd: i64 = sys_openat_rd(path)
32 if fd < 0 { return 0 }
33 var n: i64 = 0
34 var go: i64 = 1
35 while go == 1 {
36 let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - 1 - n)
37 if r <= 0 { go = 0 } else { n = n + r }
38 if n >= cap - 1 { go = 0 }
39 }
40 sys_close(fd)
41 return n
42}
43
44// length of a C string
45func ae_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
46
47// does buf[pos..] match pat (len pl)? 1/0
48func ae_match(buf: *u8, n: i64, pos: i64, pat: *u8, pl: i64) -> i64 {
49 if pos + pl > n { return 0 }
50 var k: i64 = 0
51 while k < pl {
52 if buf[pos + k] != pat[k] { return 0 }
53 k = k + 1
54 }
55 return 1
56}
57
58// is pos a line start? (pos==0 or previous byte is newline)
59func ae_is_bol(buf: *u8, pos: i64) -> i64 {
60 if pos == 0 { return 1 }
61 if buf[pos - 1] == (10 as u8) { return 1 }
62 return 0
63}
64
65// find a line beginning with prefix; return its start index, or -1
66func ae_find_line(buf: *u8, n: i64, prefix: *u8) -> i64 {
67 let pl: i64 = ae_len(prefix)
68 var i: i64 = 0
69 while i < n {
70 if ae_is_bol(buf, i) == 1 {
71 if ae_match(buf, n, i, prefix, pl) == 1 { return i }
72 }
73 i = i + 1
74 }
75 return 0 - 1
76}
77
78// Extract the VALUE of the field whose line starts with prefix: copy bytes from after the prefix
79// up to (not including) the end-of-line newline into out, NUL-terminate, return value length.
80// Returns -1 if the field line is absent (the GROUNDING check). cap bounds the copy.
81func ae_field_val(buf: *u8, n: i64, prefix: *u8, out: *u8, cap: i64) -> i64 {
82 let start: i64 = ae_find_line(buf, n, prefix)
83 if start < 0 { return 0 - 1 }
84 let pl: i64 = ae_len(prefix)
85 var p: i64 = start + pl
86 var k: i64 = 0
87 var go: i64 = 1
88 while go == 1 {
89 if p >= n { go = 0 } else {
90 if buf[p] == (10 as u8) { go = 0 } else {
91 if k < cap - 1 { out[k] = buf[p]; k = k + 1 }
92 p = p + 1
93 }
94 }
95 }
96 out[k] = 0 as u8
97 return k
98}
99
100// join a + "/" + b into out (NUL-terminated). a,b are NUL-terminated. returns length.
101func ae_join(a: *u8, b: *u8, out: *u8) -> i64 {
102 var k: i64 = 0
103 var i: i64 = 0
104 while a[i] != (0 as u8) { out[k] = a[i]; k = k + 1; i = i + 1 }
105 out[k] = 47 as u8; k = k + 1 // '/'
106 var j: i64 = 0
107 while b[j] != (0 as u8) { out[k] = b[j]; k = k + 1; j = j + 1 }
108 out[k] = 0 as u8
109 return k
110}
111
112// write n bytes from buf to a fresh file at path (mode 0644). 1 on success, 0 on open-fail.
113func ae_write_file(path: *u8, buf: *u8, n: i64) -> i64 {
114 let fd: i64 = sys_openat_wr(path, 0x1a4)
115 if fd < 0 { return 0 }
116 if n > 0 { sys_write(fd, buf, n) }
117 sys_close(fd)
118 return 1
119}
120
121// the run_organ TRANSFORM extract_kv_to_units: for each staged line "kv|<rest>", emit
122// "unit|<rest>\n" into out (in input order). Non-"kv|" lines (comments/blanks) are skipped.
123// Returns the produced byte count. PURE function of the staged bytes (no clock/rand).
124func ae_transform_kv(inb: *u8, n: i64, out: *u8) -> i64 {
125 var o: i64 = 0
126 var i: i64 = 0
127 while i < n {
128 if ae_is_bol(inb, i) == 1 {
129 if ae_match(inb, n, i, "kv|" as *u8, 3) == 1 {
130 // emit "unit|" then the bytes after "kv|" up to and including the newline
131 out[o] = 117 as u8; o = o + 1 // u
132 out[o] = 110 as u8; o = o + 1 // n
133 out[o] = 105 as u8; o = o + 1 // i
134 out[o] = 116 as u8; o = o + 1 // t
135 out[o] = 124 as u8; o = o + 1 // |
136 var p: i64 = i + 3
137 var go: i64 = 1
138 while go == 1 {
139 if p >= n { out[o] = 10 as u8; o = o + 1; go = 0 } else {
140 if inb[p] == (10 as u8) { out[o] = 10 as u8; o = o + 1; p = p + 1; go = 0 } else {
141 out[o] = inb[p]; o = o + 1; p = p + 1
142 }
143 }
144 }
145 }
146 }
147 i = i + 1
148 }
149 return o
150}
151
152// the run_organ TRANSFORM copy_verbatim (ALE-R3a): the IDENTITY transform -- emit the staged
153// bytes UNCHANGED as the deliverable (artifact == staged input, byte-for-byte). PURE function of
154// the staged bytes: no clock, no rand, no synthesis. Returns the produced byte count (== n).
155func ae_transform_copy(inb: *u8, n: i64, out: *u8) -> i64 {
156 var i: i64 = 0
157 while i < n { out[i] = inb[i]; i = i + 1 }
158 return n
159}
160
161// the run_organ TRANSFORM count_lines (ALE-R4 seed-task DATA/CLI domain skill): count the staged
162// input's newline-terminated lines and emit a SINGLE grading unit "unit|line_count|<N>\n". PURE
163// function of the staged bytes (no clock/rand): N = number of '\n' bytes. A DISTINCT skill
164// (aggregation/counting) beyond kv-extraction/identity-copy -- grows the agent's vocabulary so the
165// harness can measure a counting task end-to-end. Returns the produced byte count.
166func ae_transform_count(inb: *u8, n: i64, out: *u8) -> i64 {
167 var lines: i64 = 0
168 var i: i64 = 0
169 while i < n { if inb[i] == (10 as u8) { lines = lines + 1 } i = i + 1 }
170 var o: i64 = 0
171 let pre: *u8 = "unit|line_count|" as *u8
172 var j: i64 = 0
173 while pre[j] != (0 as u8) { out[o] = pre[j]; o = o + 1; j = j + 1 }
174 var m: i64 = lines
175 let t: *u8 = sys_mmap(28)
176 var k: i64 = 0
177 if m == 0 { t[0] = 48 as u8; k = 1 }
178 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
179 var p: i64 = 0
180 while p < k { out[o] = t[k - 1 - p]; o = o + 1; p = p + 1 }
181 out[o] = 10 as u8; o = o + 1
182 return o
183}
184
185// find a line in buf (len n) beginning with pat (len pl) at a BOL; return its index, or -1.
186func ae_plan_find(buf: *u8, n: i64, pat: *u8, pl: i64) -> i64 {
187 var i: i64 = 0
188 while i < n {
189 if ae_is_bol(buf, i) == 1 {
190 if ae_match(buf, n, i, pat, pl) == 1 { return i }
191 }
192 i = i + 1
193 }
194 return 0 - 1
195}
196
197// read the verb of the plan step whose number is num into vbuf (cap); also copy its <arg> into
198// abuf (cap). A plan line is "step|<num>|<verb>|<arg>". Returns 1 if the step line was found, else 0.
199func ae_plan_step(buf: *u8, n: i64, num: i64, vbuf: *u8, abuf: *u8, cap: i64) -> i64 {
200 // build prefix "step|<num>|"
201 let pb: *u8 = sys_mmap(64)
202 pb[0] = 115 as u8; pb[1] = 116 as u8; pb[2] = 101 as u8; pb[3] = 112 as u8; pb[4] = 124 as u8
203 var m: i64 = num
204 let t: *u8 = sys_mmap(28)
205 var k: i64 = 0
206 if m == 0 { t[0] = 48; k = 1 }
207 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
208 var w: i64 = 5
209 var j: i64 = 0
210 while j < k { pb[w] = t[k - 1 - j]; w = w + 1; j = j + 1 }
211 pb[w] = 124 as u8; w = w + 1; pb[w] = 0 as u8
212 let pl: i64 = w
213 let start: i64 = ae_plan_find(buf, n, pb, pl)
214 if start < 0 { return 0 }
215 // from start, skip the prefix (pl bytes) -> verb starts; copy verb to next '|'
216 var q: i64 = start + pl
217 var vk: i64 = 0
218 var g1: i64 = 1
219 while g1 == 1 {
220 if q >= n { g1 = 0 } else {
221 if buf[q] == (124 as u8) { g1 = 0 } else {
222 if vk < cap - 1 { vbuf[vk] = buf[q]; vk = vk + 1 }
223 q = q + 1
224 }
225 }
226 }
227 vbuf[vk] = 0 as u8
228 // after the verb's '|' -> arg starts; copy arg to newline/EOF
229 if q < n { q = q + 1 }
230 var ak: i64 = 0
231 var g2: i64 = 1
232 while g2 == 1 {
233 if q >= n { g2 = 0 } else {
234 if buf[q] == (10 as u8) { g2 = 0 } else {
235 if ak < cap - 1 { abuf[ak] = buf[q]; ak = ak + 1 }
236 q = q + 1
237 }
238 }
239 }
240 abuf[ak] = 0 as u8
241 return 1
242}
243
244// equal NUL-terminated strings? 1/0
245func ae_streq(a: *u8, b: *u8) -> i64 {
246 var i: i64 = 0
247 while a[i] != (0 as u8) {
248 if a[i] != b[i] { return 0 }
249 i = i + 1
250 }
251 if b[i] != (0 as u8) { return 0 }
252 return 1
253}
254
255// does s start with prefix p (both NUL-terminated)? 1/0 (transform-token dispatch)
256func ae_starts(s: *u8, p: *u8) -> i64 {
257 var i: i64 = 0
258 while p[i] != (0 as u8) {
259 if s[i] != p[i] { return 0 }
260 i = i + 1
261 }
262 return 1
263}
264
265// the run_organ TRANSFORM sum_values (ALE-R5 RSI-loop: the capability BUILT to close the
266// data/sum-values-001 GAP the flywheel detected): sum the staged input's integer lines and emit a
267// SINGLE grading unit "unit|sum|<TOTAL>\n". PURE function of the staged bytes (no clock/rand): each
268// maximal digit-run terminated by newline/EOF is one integer; TOTAL = their sum. A distinct
269// arithmetic-aggregation skill. Returns the produced byte count.
270func ae_transform_sum(inb: *u8, n: i64, out: *u8) -> i64 {
271 var total: i64 = 0
272 var cur: i64 = 0
273 var indig: i64 = 0
274 var i: i64 = 0
275 while i < n {
276 let c: i64 = inb[i] as i64
277 if c >= 48 { if c <= 57 { cur = cur * 10 + (c - 48); indig = 1 } }
278 if c == 10 { if indig == 1 { total = total + cur } cur = 0; indig = 0 }
279 i = i + 1
280 }
281 if indig == 1 { total = total + cur }
282 var o: i64 = 0
283 let pre: *u8 = "unit|sum|" as *u8
284 var j: i64 = 0
285 while pre[j] != (0 as u8) { out[o] = pre[j]; o = o + 1; j = j + 1 }
286 var m: i64 = total
287 let t: *u8 = sys_mmap(28)
288 var k: i64 = 0
289 if m == 0 { t[0] = 48 as u8; k = 1 }
290 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
291 var p: i64 = 0
292 while p < k { out[o] = t[k - 1 - p]; o = o + 1; p = p + 1 }
293 out[o] = 10 as u8; o = o + 1
294 return o
295}
296
297// parse helpers for the PARAMETERIZED reducer.
298func ae_rd_skipword(s: *u8, i: i64) -> i64 { var p: i64 = i; var g: i64 = 1; while g == 1 { if s[p] == (0 as u8) { g = 0 } else { if s[p] == (32 as u8) { g = 0 } else { p = p + 1 } } } return p }
299func ae_rd_skipsp(s: *u8, i: i64) -> i64 { var p: i64 = i; while s[p] == (32 as u8) { p = p + 1 } return p }
300func ae_rd_atoi(s: *u8, i: i64) -> i64 { var p: i64 = i; var neg: i64 = 0; if s[p] == (45 as u8) { neg = 1; p = p + 1 } var v: i64 = 0; var g: i64 = 1; while g == 1 { if s[p] >= (48 as u8) { if s[p] <= (57 as u8) { v = v * 10 + ((s[p] as i64) - 48); p = p + 1 } else { g = 0 } } else { g = 0 } } if neg == 1 { return 0 - v } return v }
301
302// the run_organ TRANSFORM reduce_op (PARAMETERIZED -- the evolutionary member's GENE TARGET): the
303// instruction "reduce_op <op> <init>" carries the genes (op in {add,mul,max,min}, init an integer).
304// acc=init; for each staged integer line v: add->acc+v mul->acc*v max->max min->min. Emits
305// "unit|reduced|<acc>". A GENERAL reducer: sum is (add,0), PRODUCT is (mul,1) -- genes nx_evolve
306// DISCOVERS (tier-1 search can't supply parameters; tier-2 evolution searches them). license_tier: ORIGINAL
307func ae_transform_reduce(inb: *u8, n: i64, out: *u8, args: *u8) -> i64 {
308 var p: i64 = ae_rd_skipword(args, 0)
309 p = ae_rd_skipsp(args, p)
310 let op_at: i64 = p
311 p = ae_rd_skipword(args, p)
312 var op: i64 = 0
313 if args[op_at] == (109 as u8) {
314 if args[op_at+1] == (117 as u8) { op = 1 }
315 if args[op_at+1] == (97 as u8) { op = 2 }
316 if args[op_at+1] == (105 as u8) { op = 3 }
317 }
318 p = ae_rd_skipsp(args, p)
319 let init: i64 = ae_rd_atoi(args, p)
320 var acc: i64 = init
321 var i: i64 = 0
322 var cur: i64 = 0
323 var indig: i64 = 0
324 while i < n {
325 let c: i64 = inb[i] as i64
326 if c >= 48 { if c <= 57 { cur = cur * 10 + (c - 48); indig = 1 } }
327 if c == 10 { if indig == 1 { if op == 0 { acc = acc + cur } if op == 1 { acc = acc * cur } if op == 2 { if cur > acc { acc = cur } } if op == 3 { if cur < acc { acc = cur } } } cur = 0; indig = 0 }
328 i = i + 1
329 }
330 if indig == 1 { if op == 0 { acc = acc + cur } if op == 1 { acc = acc * cur } if op == 2 { if cur > acc { acc = cur } } if op == 3 { if cur < acc { acc = cur } } }
331 var o: i64 = 0
332 let pre: *u8 = "unit|reduced|" as *u8
333 var j: i64 = 0
334 while pre[j] != (0 as u8) { out[o] = pre[j]; o = o + 1; j = j + 1 }
335 var m: i64 = acc
336 if m < 0 { out[o] = 45 as u8; o = o + 1; m = 0 - m }
337 let t: *u8 = sys_mmap(28)
338 var k: i64 = 0
339 if m == 0 { t[0] = 48 as u8; k = 1 }
340 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
341 var q: i64 = 0
342 while q < k { out[o] = t[k - 1 - q]; o = o + 1; q = q + 1 }
343 out[o] = 10 as u8; o = o + 1
344 return o
345}
346
347// ---- ALE-R3a: the run_organ TRANSFORM VOCABULARY as a DATA TABLE ----
348// The dispatch is data-driven: a parallel-array table of (token, transform-id) rows. Adding a
349// transform means adding ONE token-row here + one ae_transform_* fn -- the dispatch loop never
350// grows a per-transform if-chain. transform-id values are abstract handles (1,2,...); the run_organ
351// branch invokes the selected fn by id. Mirrors ale_exec.spec's `transform|<token>|...` rows.
352// ae_vocab_build fills caller arrays toks[] (token *u8) + ids[] (transform-id i64) and returns the
353// row count. cap bounds the row count.
354func ae_vocab_build(toks: *i64, ids: *i64, cap: i64) -> i64 {
355 var c: i64 = 0
356 if c < cap { toks[c] = "extract_kv_to_units" as *u8 as i64; ids[c] = 1; c = c + 1 }
357 if c < cap { toks[c] = "copy_verbatim" as *u8 as i64; ids[c] = 2; c = c + 1 }
358 if c < cap { toks[c] = "count_lines" as *u8 as i64; ids[c] = 3; c = c + 1 }
359 if c < cap { toks[c] = "sum_values" as *u8 as i64; ids[c] = 4; c = c + 1 }
360 if c < cap { toks[c] = "reduce_op" as *u8 as i64; ids[c] = 5; c = c + 1 }
361 return c
362}
363
364// data-driven dispatch: return the transform-id whose token is a PREFIX of instruction s, or 0 if
365// no vocabulary token matches (unknown token -> the caller REFUSES). Walks the table in order.
366func ae_vocab_lookup(s: *u8, toks: *i64, ids: *i64, cnt: i64) -> i64 {
367 var i: i64 = 0
368 while i < cnt {
369 let tk: *u8 = toks[i] as *u8
370 if ae_starts(s, tk) == 1 { return ids[i] }
371 i = i + 1
372 }
373 return 0
374}
375
376func main(argc: i64, argv: *i64) -> i64 {
377 if argc < 4 { sys_exit(2); return 2 }
378 let planp: *u8 = argv[1] as *u8
379 let taskp: *u8 = argv[2] as *u8
380 let sandbox: *u8 = argv[3] as *u8
381
382 let pbuf: *u8 = sys_mmap(K_MAGIC_262144)
383 let tbuf: *u8 = sys_mmap(K_MAGIC_262144)
384 let pn: i64 = ae_read(planp, pbuf, K_MAGIC_262144)
385 let tn: i64 = ae_read(taskp, tbuf, K_MAGIC_262144)
386 if pn <= 0 { sys_exit(3); return 3 }
387 if tn <= 0 { sys_exit(3); return 3 }
388
389 // REQUIRED task fields; -1 => absent => REFUSE.
390 let v_mat: *u8 = sys_mmap(K_MAGIC_8192)
391 let v_in: *u8 = sys_mmap(K_MAGIC_8192)
392 let v_art: *u8 = sys_mmap(K_MAGIC_8192)
393 let lm: i64 = ae_field_val(tbuf, tn, "task|materials_dir|" as *u8, v_mat, K_MAGIC_8192)
394 let lin: i64 = ae_field_val(tbuf, tn, "task|input_stage|" as *u8, v_in, K_MAGIC_8192)
395 let lar: i64 = ae_field_val(tbuf, tn, "task|artifact_path|" as *u8, v_art, K_MAGIC_8192)
396 var bad: i64 = 0
397 if lm < 0 { bad = 1 }
398 if lin < 0 { bad = 1 }
399 if lar < 0 { bad = 1 }
400 if bad == 1 { sys_exit(1); return 1 }
401
402 // The plan MUST contain a write_artifact step or we refuse (no terminal deliverable).
403 let has_wa: i64 = ae_plan_find(pbuf, pn, "step|3|write_artifact|" as *u8, 22)
404 if has_wa < 0 { sys_exit(4); return 4 }
405
406 // 3-state machine over plan steps 1,2,3 -- consumed STRICTLY in order.
407 let vb: *u8 = sys_mmap(K_MAGIC_8192)
408 let ab: *u8 = sys_mmap(K_MAGIC_8192)
409 let content: *u8 = sys_mmap(K_MAGIC_262144)
410 var contn: i64 = 0
411 var staged: i64 = 0
412 var transformed: i64 = 0
413 var written: i64 = 0
414 var step: i64 = 1
415 var run: i64 = 1
416
417 // ALE-R3a: build the run_organ transform-vocabulary table ONCE (token -> transform-id). The
418 // run_organ branch dispatches DATA-DRIVEN off this table; no per-transform if-chain.
419 let vtoks: *i64 = sys_mmap(256) as *i64
420 let vids: *i64 = sys_mmap(256) as *i64
421 let vcnt: i64 = ae_vocab_build(vtoks, vids, 16)
422 while run == 1 {
423 let found: i64 = ae_plan_step(pbuf, pn, step, vb, ab, K_MAGIC_8192)
424 if found == 0 { run = 0 } else {
425 // dispatch the verb of THIS step. order law: stage_input before run_organ before write_artifact.
426 if ae_streq(vb, "stage_input" as *u8) == 1 {
427 if step != 1 { sys_exit(5); return 5 }
428 // copy materials_dir/input_stage -> sandbox/input_stage (verbatim bytes)
429 let srcp: *u8 = sys_mmap(K_MAGIC_16384)
430 ae_join(v_mat, v_in, srcp)
431 let dstp: *u8 = sys_mmap(K_MAGIC_16384)
432 ae_join(sandbox, v_in, dstp)
433 let mbuf: *u8 = sys_mmap(K_MAGIC_262144)
434 let mn: i64 = ae_read(srcp, mbuf, K_MAGIC_262144)
435 if mn <= 0 { sys_exit(6); return 6 }
436 let okw: i64 = ae_write_file(dstp, mbuf, mn)
437 if okw == 0 { sys_exit(7); return 7 }
438 staged = 1
439 } else {
440 if ae_streq(vb, "run_organ" as *u8) == 1 {
441 if staged != 1 { sys_exit(8); return 8 }
442 if step != 2 { sys_exit(8); return 8 }
443 // DATA-DRIVEN dispatch: look the instruction's leading token up in the vocabulary
444 // table (ab = plan step-2 arg) -> abstract transform-id. id 0 = unknown -> REFUSE.
445 let tid: i64 = ae_vocab_lookup(ab, vtoks, vids, vcnt)
446 if tid == 0 { sys_exit(10); return 10 }
447 // read the STAGED file (not the source) once; the selected transform consumes it.
448 let stagedp: *u8 = sys_mmap(K_MAGIC_16384)
449 ae_join(sandbox, v_in, stagedp)
450 let sbuf: *u8 = sys_mmap(K_MAGIC_262144)
451 let sn: i64 = ae_read(stagedp, sbuf, K_MAGIC_262144)
452 if sn <= 0 { sys_exit(9); return 9 }
453 // invoke the transform by its abstract id (composition dispatch, not a token if-chain).
454 if tid == 1 { contn = ae_transform_kv(sbuf, sn, content) }
455 if tid == 2 { contn = ae_transform_copy(sbuf, sn, content) }
456 if tid == 3 { contn = ae_transform_count(sbuf, sn, content) }
457 if tid == 4 { contn = ae_transform_sum(sbuf, sn, content) }
458 if tid == 5 { contn = ae_transform_reduce(sbuf, sn, content, ab) }
459 transformed = 1
460 } else {
461 if ae_streq(vb, "write_artifact" as *u8) == 1 {
462 if transformed != 1 { sys_exit(11); return 11 }
463 if step != 3 { sys_exit(11); return 11 }
464 let artp: *u8 = sys_mmap(K_MAGIC_16384)
465 ae_join(sandbox, v_art, artp)
466 if contn <= 0 { sys_exit(12); return 12 }
467 let okw2: i64 = ae_write_file(artp, content, contn)
468 if okw2 == 0 { sys_exit(13); return 13 }
469 written = 1
470 } else {
471 // unknown verb -> REFUSE
472 sys_exit(14); return 14
473 }
474 }
475 }
476 step = step + 1
477 }
478 }
479
480 if written != 1 { sys_exit(15); return 15 }
481 sys_exit(0)
482 return 0
483}