nx_treatment_lib.nx source
↩ module page · 372 lines · 16158 B
1// nx_treatment_lib.nx -- THE ONE TREATMENT RULER (ecosystem EC49, 2026-09-16): every capability gets the three-step
2// treatment -- a PRIMITIVE reachable on the MCP and API surfaces, a WORKFLOW that composes it, an AGENT beat that
3// runs it -- and a board declares that treatment per rung as DATA the ranker judges.
4//
5// WHY. Operator 2026-09-16: "make sure its mandatory that they get mcp and api and composable primitives and
6// workflows and agent treatment in our 1 2 3 step process". A rule a seat must remember is adopted at advice
7// rates; a ruler in the ranker is adopted at 100 percent, the same way the bar-age and ladder rulers were placed.
8//
9// ROW (7 fields, on <domain>.plan):
10// treat|<rung>|mcp=<row>|api=<route>|prim=<lib>|wf=<planid>|agent=<row>
11// mcp the tool_allowlist.conf row (the MCP surface) the rung's organ answers to; verified against the allowlist
12// api the API route the row is reached through (the MCP surface IS the API: /api/tools/call name=<row>, /mcp);
13// verified as: declared AND its mcp row verified, since the route is the registered row
14// prim the composable primitive (the lib the organ composes) -- the caller verifies the source exists
15// wf the plan_run plan id whose rows compose the primitive (knowledge/store/plan-<id>-) -- caller verifies
16// agent the beat that runs it: a clockjobs-/clocksched- row name or a gateroster.conf row; verified against both
17// a value of - is MISSING; a declared value the check cannot find is ABSENT; a value the check cannot judge is
18// DECLARED (the caller passed no evidence for that field) -- three negatives, never one word.
19// VERDICT per row: COMPLETE (five fields PRESENT) | PARTIAL (any field MISSING or ABSENT, named) | FIELDS (a
20// malformed row). Per board: TREATED (every treat row COMPLETE) | PARTIAL (a declared row unmet: the hard fail,
21// like a stale bar) | NO-TREATMENT (no treat rows: LABELED, the board opts in by declaring its first). Rungs with
22// no treat row are counted UNDECLARED and named, never refused: opting in is per rung.
23// license_tier: ORIGINAL No hw writes (Rule 26).
24import "nx_syscalls.nx"
25
26const TRT_I64: i64 = 8
27const TRT_STRIDE: i64 = 24
28const TRT_RUNG_O: i64 = 0
29const TRT_RUNG_L: i64 = 1
30const TRT_MCP_O: i64 = 2
31const TRT_MCP_L: i64 = 3
32const TRT_API_O: i64 = 4
33const TRT_API_L: i64 = 5
34const TRT_PRIM_O: i64 = 6
35const TRT_PRIM_L: i64 = 7
36const TRT_WF_O: i64 = 8
37const TRT_WF_L: i64 = 9
38const TRT_AGENT_O: i64 = 10
39const TRT_AGENT_L: i64 = 11
40const TRT_ST_MCP: i64 = 12
41const TRT_ST_API: i64 = 13
42const TRT_ST_PRIM: i64 = 14
43const TRT_ST_WF: i64 = 15
44const TRT_ST_AGENT: i64 = 16
45const TRT_VERDICT: i64 = 17
46const TRT_NF: i64 = 18
47const TRT_LINE: i64 = 19
48const TRT_TAG: *u8 = "treat"
49const TRT_NF_ROW: i64 = 7
50const TRT_F_RUNG: i64 = 1
51const TRT_F_MCP: i64 = 2
52const TRT_F_API: i64 = 3
53const TRT_F_PRIM: i64 = 4
54const TRT_F_WF: i64 = 5
55const TRT_F_AGENT: i64 = 6
56const TRT_MIN_ROW: i64 = 30 // "treat|r|mcp=|api=|prim=|wf=|agent=" plus a newline: the shortest well-formed row
57// field states
58const TRT_F_MISSING: i64 = 0
59const TRT_F_PRESENT: i64 = 1
60const TRT_F_DECLARED: i64 = 2
61const TRT_F_ABSENT: i64 = 3
62// row verdicts
63const TRT_V_COMPLETE: i64 = 0
64const TRT_V_PARTIAL: i64 = 1
65const TRT_V_FIELDS: i64 = 2
66// board exits
67const TRT_EXIT_TREATED: i64 = 0
68const TRT_EXIT_PARTIAL: i64 = 1
69const TRT_EXIT_NONE: i64 = 3
70// census slots
71const TRT_C_ROWS: i64 = 0
72const TRT_C_COMPLETE: i64 = 1
73const TRT_C_PARTIAL: i64 = 2
74const TRT_C_FIELDS: i64 = 3
75const TRT_C_RUNGS: i64 = 4
76const TRT_C_UNDECLARED: i64 = 5
77const TRT_C_SLOTS: i64 = 8
78const TRT_CH_PIPE: i64 = 124
79const TRT_CH_NL: i64 = 10
80const TRT_CH_TAB: i64 = 9
81const TRT_CH_DASH: i64 = 45
82const TRT_CH_EQ: i64 = 61
83const TRT_CH_HASH: i64 = 35
84const TRT_CH_SEMI: i64 = 59
85const TRT_CH_COMMA: i64 = 44
86const TRT_RUNG_TAG: *u8 = "rung"
87const TRT_GREEN: *u8 = "GREEN"
88
89func trt_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
90func trt_cap(bytes: i64) -> i64 { return bytes / TRT_MIN_ROW + 1 }
91
92func trt_line_end(buf: *u8, n: i64, p: i64) -> i64 {
93 var e: i64 = p
94 var go: i64 = 1
95 while go == 1 {
96 if e >= n { go = 0 } else {
97 if buf[e] == (TRT_CH_NL as u8) { go = 0 } else { if buf[e] == (0 as u8) { go = 0 } else { e = e + 1 } }
98 }
99 }
100 return e
101}
102func trt_field(buf: *u8, p: i64, e: i64, k: i64, off: *i64) -> i64 {
103 var i: i64 = p
104 var f: i64 = 0
105 var s: i64 = p
106 while i < e {
107 if buf[i] == (TRT_CH_PIPE as u8) {
108 if f == k { off[0] = s; return i - s }
109 f = f + 1
110 s = i + 1
111 }
112 i = i + 1
113 }
114 if f == k { off[0] = s; return e - s }
115 return 0 - 1
116}
117func trt_nfields(buf: *u8, p: i64, e: i64) -> i64 {
118 if e <= p { return 0 }
119 var c: i64 = 1
120 var i: i64 = p
121 while i < e { if buf[i] == (TRT_CH_PIPE as u8) { c = c + 1 } i = i + 1 }
122 return c
123}
124func trt_span_is(buf: *u8, off: i64, len: i64, lit: *u8) -> i64 {
125 if len < 0 { return 0 }
126 if trt_slen(lit) != len { return 0 }
127 var i: i64 = 0
128 while i < len { if buf[off + i] != lit[i] { return 0 } i = i + 1 }
129 return 1
130}
131// the value after "<key>=" in the span; returns the value length and its offset in off[0]; -1 when the key does not match
132func trt_kv(buf: *u8, off0: i64, len: i64, key: *u8, off: *i64) -> i64 {
133 let kl: i64 = trt_slen(key)
134 if len < kl + 1 { return 0 - 1 }
135 var i: i64 = 0
136 while i < kl { if buf[off0 + i] != key[i] { return 0 - 1 } i = i + 1 }
137 if buf[off0 + kl] != (TRT_CH_EQ as u8) { return 0 - 1 }
138 off[0] = off0 + kl + 1
139 return len - kl - 1
140}
141func trt_value_state(buf: *u8, off: i64, len: i64) -> i64 {
142 if len <= 0 { return TRT_F_MISSING }
143 if len == 1 { if buf[off] == (TRT_CH_DASH as u8) { return TRT_F_MISSING } }
144 return TRT_F_DECLARED
145}
146// parse one keyed field into the table; a key mismatch marks the row FIELDS
147func trt_take(buf: *u8, p: i64, e: i64, k: i64, key: *u8, tab: *i64, b: i64, oslot: i64, lslot: i64, sslot: i64, off: *i64) -> i64 {
148 let fl: i64 = trt_field(buf, p, e, k, off)
149 if fl < 0 { tab[b + oslot] = p; tab[b + lslot] = 0; tab[b + sslot] = TRT_F_MISSING; return 0 }
150 let foff: i64 = off[0]
151 let vl: i64 = trt_kv(buf, foff, fl, key, off)
152 if vl < 0 { tab[b + oslot] = foff; tab[b + lslot] = fl; tab[b + sslot] = TRT_F_MISSING; return 0 }
153 tab[b + oslot] = off[0]; tab[b + lslot] = vl
154 tab[b + sslot] = trt_value_state(buf, off[0], vl)
155 return 1
156}
157
158// parse every treat row of buf into tab (stride TRT_STRIDE, capacity cap rows). Returns the row count.
159func trt_scan(buf: *u8, n: i64, tab: *i64, cap: i64) -> i64 {
160 let off: *i64 = sys_mmap(TRT_I64) as *i64
161 var rows: i64 = 0
162 var line: i64 = 0
163 var p: i64 = 0
164 while p < n {
165 let e: i64 = trt_line_end(buf, n, p)
166 line = line + 1
167 let l0: i64 = trt_field(buf, p, e, 0, off)
168 if trt_span_is(buf, off[0], l0, TRT_TAG) == 1 { if rows < cap {
169 let b: i64 = rows * TRT_STRIDE
170 var s: i64 = 0
171 while s < TRT_STRIDE { tab[b + s] = 0; s = s + 1 }
172 tab[b + TRT_LINE] = line
173 let nf: i64 = trt_nfields(buf, p, e)
174 tab[b + TRT_NF] = nf
175 let rl: i64 = trt_field(buf, p, e, TRT_F_RUNG, off)
176 if rl < 0 { tab[b + TRT_RUNG_O] = p; tab[b + TRT_RUNG_L] = 0 } else { tab[b + TRT_RUNG_O] = off[0]; tab[b + TRT_RUNG_L] = rl }
177 var keys_ok: i64 = 1
178 if trt_take(buf, p, e, TRT_F_MCP, "mcp" as *u8, tab, b, TRT_MCP_O, TRT_MCP_L, TRT_ST_MCP, off) == 0 { keys_ok = 0 }
179 if trt_take(buf, p, e, TRT_F_API, "api" as *u8, tab, b, TRT_API_O, TRT_API_L, TRT_ST_API, off) == 0 { keys_ok = 0 }
180 if trt_take(buf, p, e, TRT_F_PRIM, "prim" as *u8, tab, b, TRT_PRIM_O, TRT_PRIM_L, TRT_ST_PRIM, off) == 0 { keys_ok = 0 }
181 if trt_take(buf, p, e, TRT_F_WF, "wf" as *u8, tab, b, TRT_WF_O, TRT_WF_L, TRT_ST_WF, off) == 0 { keys_ok = 0 }
182 if trt_take(buf, p, e, TRT_F_AGENT, "agent" as *u8, tab, b, TRT_AGENT_O, TRT_AGENT_L, TRT_ST_AGENT, off) == 0 { keys_ok = 0 }
183 var v: i64 = TRT_V_PARTIAL
184 if nf != TRT_NF_ROW { v = TRT_V_FIELDS }
185 if keys_ok == 0 { v = TRT_V_FIELDS }
186 if rl <= 0 { v = TRT_V_FIELDS }
187 tab[b + TRT_VERDICT] = v
188 rows = rows + 1
189 } }
190 p = e + 1
191 }
192 return rows
193}
194
195// does a line of text start with the name followed by a TAB, a NL or the end? (allowlist, clock plane, roster rows)
196func trt_text_has_row(text: *u8, tn: i64, buf: *u8, noff: i64, nlen: i64) -> i64 {
197 if nlen <= 0 { return 0 }
198 var p: i64 = 0
199 while p < tn {
200 let e: i64 = trt_line_end(text, tn, p)
201 if e - p >= nlen { if text[p] != (TRT_CH_HASH as u8) { if text[p] != (TRT_CH_SEMI as u8) {
202 var same: i64 = 1
203 var i: i64 = 0
204 while i < nlen { if text[p + i] != buf[noff + i] { same = 0; i = nlen } else { i = i + 1 } }
205 if same == 1 {
206 if e - p == nlen { return 1 }
207 let c: i64 = text[p + nlen] as i64
208 if c == TRT_CH_TAB { return 1 }
209 }
210 } } }
211 p = e + 1
212 }
213 return 0
214}
215// the allowlist row must also be GREEN: the tool_allowlist.conf row is name TAB elf TAB GREEN [TAB args]
216func trt_allow_has(allow: *u8, an: i64, buf: *u8, noff: i64, nlen: i64) -> i64 {
217 if nlen <= 0 { return 0 }
218 var p: i64 = 0
219 while p < an {
220 let e: i64 = trt_line_end(allow, an, p)
221 if e - p > nlen { if allow[p + nlen] == (TRT_CH_TAB as u8) {
222 var same: i64 = 1
223 var i: i64 = 0
224 while i < nlen { if allow[p + i] != buf[noff + i] { same = 0; i = nlen } else { i = i + 1 } }
225 if same == 1 {
226 // GREEN anywhere after the name on this line
227 var q: i64 = p + nlen
228 let gl: i64 = trt_slen(TRT_GREEN)
229 while q + gl <= e {
230 var m: i64 = 1
231 var j: i64 = 0
232 while j < gl { if allow[q + j] != TRT_GREEN[j] { m = 0; j = gl } else { j = j + 1 } }
233 if m == 1 { return 1 }
234 q = q + 1
235 }
236 return 0
237 }
238 } }
239 p = e + 1
240 }
241 return 0
242}
243
244// judge one row. allow/roster/clock are text buffers (a NULL pointer with n=0 means NO EVIDENCE: DECLARED stays
245// DECLARED). prim_ok / wf_ok are the caller's filesystem answers: 1 found, 0 not found, -1 not checked.
246func trt_judge_row(tab: *i64, r: i64, buf: *u8, allow: *u8, an: i64, roster: *u8, rn: i64, clock: *u8, cn: i64, prim_ok: i64, wf_ok: i64) -> i64 {
247 let b: i64 = r * TRT_STRIDE
248 if tab[b + TRT_VERDICT] == TRT_V_FIELDS { return TRT_V_FIELDS }
249 // mcp
250 if tab[b + TRT_ST_MCP] == TRT_F_DECLARED { if an > 0 {
251 if trt_allow_has(allow, an, buf, tab[b + TRT_MCP_O], tab[b + TRT_MCP_L]) == 1 { tab[b + TRT_ST_MCP] = TRT_F_PRESENT } else { tab[b + TRT_ST_MCP] = TRT_F_ABSENT }
252 } }
253 // api: the route is the registered row
254 if tab[b + TRT_ST_API] == TRT_F_DECLARED {
255 if tab[b + TRT_ST_MCP] == TRT_F_PRESENT { tab[b + TRT_ST_API] = TRT_F_PRESENT } else { if tab[b + TRT_ST_MCP] == TRT_F_ABSENT { tab[b + TRT_ST_API] = TRT_F_ABSENT } }
256 }
257 // prim
258 if tab[b + TRT_ST_PRIM] == TRT_F_DECLARED { if prim_ok == 1 { tab[b + TRT_ST_PRIM] = TRT_F_PRESENT } else { if prim_ok == 0 { tab[b + TRT_ST_PRIM] = TRT_F_ABSENT } } }
259 // wf
260 if tab[b + TRT_ST_WF] == TRT_F_DECLARED { if wf_ok == 1 { tab[b + TRT_ST_WF] = TRT_F_PRESENT } else { if wf_ok == 0 { tab[b + TRT_ST_WF] = TRT_F_ABSENT } } }
261 // agent: a clock row OR a roster row
262 if tab[b + TRT_ST_AGENT] == TRT_F_DECLARED { if cn + rn > 0 {
263 var hit: i64 = 0
264 if cn > 0 { if trt_text_has_row(clock, cn, buf, tab[b + TRT_AGENT_O], tab[b + TRT_AGENT_L]) == 1 { hit = 1 } }
265 if hit == 0 { if rn > 0 { if trt_text_has_row(roster, rn, buf, tab[b + TRT_AGENT_O], tab[b + TRT_AGENT_L]) == 1 { hit = 1 } } }
266 if hit == 1 { tab[b + TRT_ST_AGENT] = TRT_F_PRESENT } else { tab[b + TRT_ST_AGENT] = TRT_F_ABSENT }
267 } }
268 var v: i64 = TRT_V_COMPLETE
269 var k: i64 = TRT_ST_MCP
270 while k <= TRT_ST_AGENT { if tab[b + k] != TRT_F_PRESENT { v = TRT_V_PARTIAL } k = k + 1 }
271 tab[b + TRT_VERDICT] = v
272 return v
273}
274
275// the treat row for a rung id (NUL-terminated), or -1
276func trt_find(tab: *i64, rows: i64, buf: *u8, rid: *u8) -> i64 {
277 let n: i64 = trt_slen(rid)
278 var r: i64 = 0
279 while r < rows {
280 let b: i64 = r * TRT_STRIDE
281 if tab[b + TRT_RUNG_L] == n {
282 var same: i64 = 1
283 var i: i64 = 0
284 while i < n { if buf[tab[b + TRT_RUNG_O] + i] != rid[i] { same = 0; i = n } else { i = i + 1 } }
285 if same == 1 { return r }
286 }
287 r = r + 1
288 }
289 return 0 - 1
290}
291
292// census: rows by verdict, rungs, and rungs with no treat row (UNDECLARED, named by the caller)
293func trt_census(tab: *i64, rows: i64, plan: *u8, pn: i64, c: *i64) -> i64 {
294 var s: i64 = 0
295 while s < TRT_C_SLOTS { c[s] = 0; s = s + 1 }
296 c[TRT_C_ROWS] = rows
297 var r: i64 = 0
298 while r < rows {
299 let v: i64 = tab[r * TRT_STRIDE + TRT_VERDICT]
300 if v == TRT_V_COMPLETE { c[TRT_C_COMPLETE] = c[TRT_C_COMPLETE] + 1 }
301 if v == TRT_V_PARTIAL { c[TRT_C_PARTIAL] = c[TRT_C_PARTIAL] + 1 }
302 if v == TRT_V_FIELDS { c[TRT_C_FIELDS] = c[TRT_C_FIELDS] + 1 }
303 r = r + 1
304 }
305 let off: *i64 = sys_mmap(TRT_I64) as *i64
306 let idbuf: *u8 = sys_mmap(pn + 1)
307 var p: i64 = 0
308 while p < pn {
309 let e: i64 = trt_line_end(plan, pn, p)
310 let l0: i64 = trt_field(plan, p, e, 0, off)
311 if trt_span_is(plan, off[0], l0, TRT_RUNG_TAG) == 1 {
312 c[TRT_C_RUNGS] = c[TRT_C_RUNGS] + 1
313 let il: i64 = trt_field(plan, p, e, 1, off)
314 var i: i64 = 0
315 while i < il { idbuf[i] = plan[off[0] + i]; i = i + 1 }
316 idbuf[il] = 0 as u8
317 if trt_find(tab, rows, plan, idbuf) < 0 { c[TRT_C_UNDECLARED] = c[TRT_C_UNDECLARED] + 1 }
318 }
319 p = e + 1
320 }
321 return rows
322}
323func trt_partition_sum(c: *i64) -> i64 { return c[TRT_C_COMPLETE] + c[TRT_C_PARTIAL] + c[TRT_C_FIELDS] }
324func trt_verdict(c: *i64) -> i64 {
325 if c[TRT_C_ROWS] <= 0 { return TRT_EXIT_NONE }
326 if c[TRT_C_PARTIAL] + c[TRT_C_FIELDS] > 0 { return TRT_EXIT_PARTIAL }
327 return TRT_EXIT_TREATED
328}
329func trt_state_name(s: i64) -> *u8 {
330 if s == TRT_F_PRESENT { return "present" as *u8 }
331 if s == TRT_F_DECLARED { return "declared" as *u8 }
332 if s == TRT_F_ABSENT { return "absent" as *u8 }
333 return "missing" as *u8
334}
335func trt_verdict_name(v: i64) -> *u8 {
336 if v == TRT_V_COMPLETE { return "COMPLETE" as *u8 }
337 if v == TRT_V_PARTIAL { return "PARTIAL" as *u8 }
338 return "FIELDS" as *u8
339}
340func trt_exit_name(v: i64) -> *u8 {
341 if v == TRT_EXIT_TREATED { return "TREATED" as *u8 }
342 if v == TRT_EXIT_PARTIAL { return "PARTIAL" as *u8 }
343 return "NO-TREATMENT" as *u8
344}
345// "mcp,api,wf" -- the fields of row r that are not PRESENT, comma-joined into dst at o; returns the new o
346func trt_missing(tab: *i64, r: i64, dst: *u8, o: i64) -> i64 {
347 let b: i64 = r * TRT_STRIDE
348 var oo: i64 = o
349 var first: i64 = 1
350 var k: i64 = 0
351 while k < 5 {
352 let st: i64 = tab[b + TRT_ST_MCP + k]
353 if st != TRT_F_PRESENT {
354 if first == 0 { dst[oo] = TRT_CH_COMMA as u8; oo = oo + 1 }
355 first = 0
356 var name: *u8 = "mcp" as *u8
357 if k == 1 { name = "api" as *u8 }
358 if k == 2 { name = "prim" as *u8 }
359 if k == 3 { name = "wf" as *u8 }
360 if k == 4 { name = "agent" as *u8 }
361 var i: i64 = 0
362 while name[i] != (0 as u8) { dst[oo] = name[i]; oo = oo + 1; i = i + 1 }
363 dst[oo] = 58 as u8; oo = oo + 1
364 let sn: *u8 = trt_state_name(st)
365 i = 0
366 while sn[i] != (0 as u8) { dst[oo] = sn[i]; oo = oo + 1; i = i + 1 }
367 }
368 k = k + 1
369 }
370 dst[oo] = 0 as u8
371 return oo
372}