code wiki / _hdl_build / nx_sovjson_lib.nx
nx_sovjson_lib.nx source
↩ module page · 102 lines · 5072 B
1// nx_sovjson_lib.nx -- SHARED sovereign-JSON emitter + seg-store span helpers.
2// OO BASE COMPONENT for the token-efficiency subsystem: nx_clawf_route composes it now;
3// nx_seat (st_*) and the TS03 dispatcher migrate onto it next (filed). Consolidates the ~10
4// helpers each organ was re-implementing INLINE (DRY, rule-15) -- one canonical copy the atlas
5// can see as a hub. Functionality preserved BY CONSTRUCTION: byte-identical helper semantics,
6// proven by each consumer's gate. license_tier: ORIGINAL No hw writes (Rule 26).
7import "nx_syscalls.nx"
8
9func sj_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
10func sj_werr(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(2, s, n); return 0 }
11func sj_vlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
12func sj_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o] = s[i]; o = o + 1; i = i + 1 } return o }
13func sj_catn(d: *u8, o: i64, v: i64) -> i64 { let t: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { d[o] = 45 as u8; o = o + 1; m = 0 - m } var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } var i: i64 = 0; while i < k { d[o] = t[k-1-i]; o = o + 1; i = i + 1 } return o }
14func sj_cat_esc(d: *u8, o: i64, q: *u8, s: i64, e: i64, maxn: i64) -> i64 {
15 var i: i64 = s
16 var w: i64 = 0
17 while i < e {
18 if w >= maxn { i = e } else {
19 var c: i64 = q[i] as i64
20 if c == 34 { c = 39 }
21 if c == 92 { c = 47 }
22 if c < 32 { c = 32 }
23 d[o] = c as u8
24 o = o + 1
25 w = w + 1
26 i = i + 1
27 }
28 }
29 return o
30}
31func sj_le(q: *u8, i: i64, n: i64) -> i64 { var e: i64 = i; var s: i64 = 1; while s == 1 { if e >= n { s = 0 } else { if q[e] == (10 as u8) { s = 0 } else { e = e + 1 } } } return e }
32func sj_col(q: *u8, ls: i64, le: i64, c: i64, out: *i64) -> i64 {
33 var col: i64 = 0
34 var p: i64 = ls
35 while col < c {
36 var s: i64 = 1
37 while s == 1 { if p >= le { return 0 } if q[p] == (9 as u8) { s = 0 } else { p = p + 1 } }
38 p = p + 1
39 col = col + 1
40 }
41 var e: i64 = p
42 var s2: i64 = 1
43 while s2 == 1 { if e >= le { s2 = 0 } else { if q[e] == (9 as u8) { s2 = 0 } else { e = e + 1 } } }
44 out[0] = p
45 out[1] = e
46 return 1
47}
48func sj_lit_eq(q: *u8, s: i64, e: i64, lit: *u8) -> i64 {
49 var i: i64 = 0
50 while s + i < e { if lit[i] == (0 as u8) { return 0 } if q[s+i] != lit[i] { return 0 } i = i + 1 }
51 if lit[i] != (0 as u8) { return 0 }
52 return 1
53}
54func sj_atoi_span(q: *u8, s: i64, e: i64) -> i64 { var v: i64 = 0; var i: i64 = s; while i < e { let c: i64 = q[i] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } i = i + 1 } return v }
55func sj_atoi_z(s: *u8) -> i64 { var v: i64 = 0; var i: i64 = 0; while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } i = i + 1 } return v }
56// sj_allow_path: resolve a tool NAME to its absolute ELF via the NAS tool_allowlist.conf (col0 -> col1).
57// SHARED because SEVEN organs (nx_actlog harden, nx_claude_harvest propose, nx_minecov/nx_debtmine/
58// nx_registrymine/nx_workflowmine/nx_featuremine loaders) each need to fork a SIBLING organ, and the
59// allowlist row is the ONLY sanctioned resolver -- never a name-derived path (the execve-127 lesson).
60// Extracted 2026-07-23 at rule-15's threshold instead of leaving 7 inline copies. Returns 1 + writes a
61// NUL-terminated path, else 0 (fail-closed: an unresolvable name must never become a runnable path).
62const SJ_ALLOW_BUF: i64 = 131072
63func sj_allow_path(name: *u8, outp: *u8) -> i64 {
64 let cb: *u8 = sys_mmap(SJ_ALLOW_BUF)
65 let fd: i64 = sys_openat_rd("tool_allowlist.conf" as *u8)
66 if fd < 0 { return 0 }
67 var cn: i64 = 0
68 var go: i64 = 1
69 while go == 1 { let r: i64 = sys_read(fd, ((cb as i64)+cn) as *u8, SJ_ALLOW_BUF - 8 - cn); if r <= 0 { go = 0 } else { cn = cn + r } if cn >= SJ_ALLOW_BUF - 8 { go = 0 } }
70 sys_close(fd)
71 if cn <= 0 { return 0 }
72 let sp: *i64 = sys_mmap(16) as *i64
73 var i: i64 = 0
74 while i < cn {
75 let le: i64 = sj_le(cb, i, cn)
76 if sj_col(cb, i, le, 0, sp) == 1 {
77 if sj_lit_eq(cb, sp[0], sp[1], name) == 1 {
78 if sj_col(cb, i, le, 1, sp) == 1 {
79 var k: i64 = 0
80 while sp[0]+k < sp[1] { outp[k] = cb[sp[0]+k]; k = k + 1 }
81 outp[k] = 0 as u8
82 return 1
83 }
84 }
85 }
86 i = le + 1
87 }
88 return 0
89}
90func sj_span_has(q: *u8, s: i64, e: i64, lit: *u8) -> i64 {
91 let ll: i64 = sj_vlen(lit)
92 if ll == 0 { return 0 }
93 var i: i64 = s
94 while i + ll <= e {
95 var j: i64 = 0
96 var ok: i64 = 1
97 while j < ll { if q[i+j] != lit[j] { ok = 0; j = ll } else { j = j + 1 } }
98 if ok == 1 { return 1 }
99 i = i + 1
100 }
101 return 0
102}