code wiki / _hdl_build / nx_schema_backfill.nx
nx_schema_backfill.nx source
↩ module page · 322 lines · 16274 B
1// nx_schema_backfill.nx -- CAPABILITY DISCOVERABILITY HARVESTER (seq1282). Every tool_allowlist.conf row
2// lacking a knowledge/tool_schemas.conf row gets one AUTO-DERIVED from its source's own first header line
3// (the tree-wide `// <stem>.nx -- <desc>` convention; the codewiki maker beat writes missing headers daily,
4// so RE-RUNNING harvests newly documented organs). The register API keeps NEW tools discoverable by
5// construction (seq722 fix) -- this organ only drains history. HONEST: no source / no `-- ` header / desc
6// too short => SKIPPED + COUNTED, never guessed (blank beats bad). Append-if-absent via the API's own
7// ma_schema_has_name tri-state (UNKNOWN refuses the WHOLE run -- a truncated read can never duplicate).
8// nx_schema_backfill (JSON report: scanned/had_schema/filled/skipped_no_source/skipped_no_header)
9// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
10import "nx_mgmt_api.nx"
11import "nx_toolsafety_lib.nx"
12import "nx_syscalls.nx"
13
14// sized: allowlist read matches md_allow_has_name's 256KiB envelope; refuse-on-full keeps the census honest
15const SB_ALCAP: i64 = 1 << 18
16// sized: only the FIRST source line is read; header docs are one-liners
17const SB_HDRCAP: i64 = 4096
18// sized: schema titles are one-line prose; hard cap keeps rows lean
19const SB_TITLECAP: i64 = 300
20// derived: shortest honest capability description in curated rows is ~20 bytes; below = not a title, skip
21const SB_MINDESC: i64 = 20
22// sized: tool names are sanitized [a-zA-Z0-9_] <= 120 by the register API
23const SB_NAMECAP: i64 = 128
24// sized: elf paths in the allowlist are absolute NAS paths well under this
25const SB_PATHCAP: i64 = 512
26
27func sbw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
28
29func sb_ends(s: *u8, sl: i64, suf: *u8, fl: i64) -> i64 {
30 if sl < fl { return 0 }
31 var i: i64 = 0
32 while i < fl { if s[sl-fl+i] != suf[i] { return 0 } i = i + 1 }
33 return 1
34}
35
36// ---- SAFETY FLAGS: DERIVED, NOT ASSERTED (2026-08-06) ----------------------------------------
37// MEASURED BEFORE CHANGING ANYTHING: of the 389 rows this organ has auto-derived into
38// tool_schemas.conf, **389 carry the identical quad `0 1 0 1`** -- zero exceptions. Against ~852
39// total rows that is ~46% of the registry's safety metadata being ONE HARDCODED CONSTANT that was
40// never looked up. nx_prim_query serves it downstream as `safety:{read_only,destructive,
41// idempotent,open_world}`, so a consumer cannot tell a measured 0 from a constant 0.
42// ★★A CONSTANT WEARING THE SHAPE OF A MEASUREMENT IS WORSE THAN A BLANK: a blank invites a
43// lookup, a fabricated value ends the enquiry. This organ's own header says "blank beats bad" and
44// it honours that for the DESCRIPTION -- then guessed the most security-relevant field.
45// (In fairness the old constant erred CONSERVATIVE -- claiming destructive+open_world over-warns
46// rather than under-warns -- so this was an INFORMATION defect, not an unsafe one.)
47//
48// WHAT IS AND IS NOT DERIVABLE. read_only / destructive / open_world fall out of a static scan of
49// the organ's own source for the syscalls it actually reaches for. `idempotent` does NOT -- nothing
50// in the source declares it -- so it stays 0, the conservative direction (a caller will not blindly
51// re-run something marked non-idempotent). ★DERIVE WHAT IS DERIVABLE, DECLARE THE REST UNDECLARED,
52// AND SAY WHICH IS WHICH IN THE ROW ITSELF.
53// SB_SRCCAP and the private sb_has substring scanner were DELETED 2026-08-25, not merely bypassed:
54// a dead copy of a ruler beside the shared one is the duplicate-ruler defect waiting to be re-called.
55
56func sb_wflag(fd: i64, v: i64) -> i64 {
57 if v == 1 { ma_write_str(fd, "1" as *u8) } else { ma_write_str(fd, "0" as *u8) }
58 return 0
59}
60
61// box[0]=read_only box[1]=destructive box[2]=idempotent box[3]=open_world box[4]=derived(1/0)
62func sb_derive_flags(path: *u8, box: *i64) -> i64 {
63 box[0] = 0
64 box[1] = 1
65 box[2] = 0
66 box[3] = 1
67 box[4] = 0
68 // COMPOSED, NOT RE-IMPLEMENTED (2026-08-25). The single-file scan that used to live here is gone.
69 // It was not wrong about what it looked at -- it was looking at the wrong SUBJECT. An organ that
70 // writes through an imported helper reaches the write syscall in the LIB, so scanning only the
71 // organ's own source published readOnly=1 for a writer: wrong in the UNSAFE direction, and stamped
72 // with a provenance note confident enough that nx_tools_api's overlay deliberately left it alone.
73 // MEASURED by nx_schemadrift over the whole population this organ had already written.
74 // A MEASUREMENT OF THE WRONG SUBJECT IS STILL A MEASUREMENT, AND THAT IS EXACTLY WHY NOTHING
75 // DOWNSTREAM COULD TELL IT FROM A GOOD ONE.
76 // ts_quad is the ONE ruler now (nx_toolsafety_lib), shared with nx_toolflags and the drift control,
77 // so the three cannot disagree: there is only one of it. It also removes the 256 KiB source cap --
78 // the old scan returned NOT-DERIVED for any source past it -- because sys_read_file sizes from the
79 // file and cannot short-read.
80 let quad: *i64 = sys_mmap(64) as *i64
81 let deep: *i64 = sys_mmap(64) as *i64
82 let own: *i64 = sys_mmap(64) as *i64
83 // ABSTAIN, DO NOT ASSERT. An inconclusive walk (unreadable subject, unreadable marker table, or a
84 // budget hit) leaves the CAUTIOUS DEFAULT set above and box[4]=0, which makes sb_append stamp the
85 // row NOT DERIVABLE. A DERIVER THAT FAILS TOWARD PERMISSIVE IS WORSE THAN ONE THAT DECLINES.
86 if ts_quad(path, quad, deep, own) == 0 { return 0 }
87 box[0] = quad[0]
88 box[1] = quad[1]
89 box[2] = quad[2]
90 box[3] = quad[3]
91 box[4] = 1
92 return 1
93}
94
95// append one schema row -- SAME invariants as the API path (trailing-nl self-heal; caller scrubbed title)
96func sb_append(nm: *u8, ti: *u8, box: *i64) -> i64 {
97 let sf: i64 = sys_openat_append("knowledge/tool_schemas.conf" as *u8, 420)
98 if sf < 0 { return 0 }
99 ma_ensure_trailing_nl("knowledge/tool_schemas.conf" as *u8, sf)
100 ma_write_str(sf, nm)
101 ma_write_str(sf, "\t" as *u8)
102 ma_write_str(sf, ti)
103 ma_write_str(sf, "\t" as *u8)
104 sb_wflag(sf, box[0])
105 ma_write_str(sf, "\t" as *u8)
106 sb_wflag(sf, box[1])
107 ma_write_str(sf, "\t" as *u8)
108 sb_wflag(sf, box[2])
109 ma_write_str(sf, "\t" as *u8)
110 sb_wflag(sf, box[3])
111 ma_write_str(sf, "\t" as *u8)
112 ma_write_str(sf, nm)
113 if box[4] == 1 {
114 ma_write_str(sf, " output (auto-derived by nx_schema_backfill; safety flags DERIVED FROM THE TRANSITIVE IMPORT CLOSURE by nx_toolsafety_lib -- a write reached through an imported helper counts, idempotent UNDECLARED)\n" as *u8)
115 } else {
116 ma_write_str(sf, " output (auto-derived by nx_schema_backfill; safety flags NOT DERIVABLE -- conservative default, treat as UNKNOWN)\n" as *u8)
117 }
118 sys_close(sf)
119 return 1
120}
121
122// read the FIRST line of path; copy the text after the first `-- ` into ti (scrubbed, trimmed, capped).
123// returns title length; 0 = header convention absent or desc too short; -1 = file unreadable.
124func sb_title_from_header(path: *u8, ti: *u8) -> i64 {
125 let fd: i64 = sys_openat_rd(path)
126 if fd < 0 { return 0 - 1 }
127 let hb: *u8 = sys_mmap(SB_HDRCAP)
128 let hn: i64 = sys_read(fd, hb, SB_HDRCAP - 1)
129 sys_close(fd)
130 if hn <= 2 { return 0 }
131 // The header is NOT always line 1: many organs open with their `import` lines and put the
132 // `// <stem>.nx -- <desc>` block AFTER them (measured: nx_gamebench_gate, nx_media_extract_gate
133 // were reported as UNDOCUMENTED purely because this parser only looked at line 1 -- the organs were
134 // documented all along). Scan the header window for the FIRST `//` line carrying `-- `; that is the
135 // convention's actual shape. Declared limitation: a `//` line containing `-- ` above the real header
136 // would win, so the rule is first-match and the emitted title is always verbatim source text.
137 var ls: i64 = 0
138 var ds: i64 = 0
139 var le: i64 = 0
140 var scan: i64 = 1
141 while scan == 1 {
142 if ls >= hn { scan = 0 } else {
143 le = ls
144 var sc: i64 = 1
145 while sc == 1 { if le >= hn { sc = 0 } else { if hb[le] == (10 as u8) { sc = 0 } else { le = le + 1 } } }
146 var iscmt: i64 = 0
147 if le - ls >= 8 { if hb[ls] == (47 as u8) { if hb[ls+1] == (47 as u8) { iscmt = 1 } } }
148 if iscmt == 1 {
149 var p: i64 = ls + 2
150 var s2: i64 = 1
151 while s2 == 1 {
152 if p + 3 > le { s2 = 0 } else {
153 if hb[p] == (45 as u8) { if hb[p+1] == (45 as u8) { if hb[p+2] == (32 as u8) { ds = p + 3; s2 = 0 } } }
154 if ds == 0 { p = p + 1 }
155 }
156 }
157 }
158 if ds > 0 { scan = 0 } else { ls = le + 1 }
159 }
160 }
161 if ds == 0 { return 0 }
162 var o: i64 = 0
163 var q: i64 = ds
164 while q < le {
165 var c: i64 = hb[q] as i64
166 if c < 32 { c = 32 }
167 if c == 9 { c = 32 }
168 if o < SB_TITLECAP - 1 { ti[o] = c as u8; o = o + 1 }
169 q = q + 1
170 }
171 var tc: i64 = 1
172 while tc == 1 { if o > 0 { if ti[o-1] == (32 as u8) { o = o - 1 } else { tc = 0 } } else { tc = 0 } }
173 ti[o] = 0 as u8
174 if o < SB_MINDESC { return 0 }
175 return o
176}
177
178func main() -> i64 {
179 let al: *u8 = sys_mmap(SB_ALCAP)
180 let fd: i64 = sys_openat_rd("tool_allowlist.conf" as *u8)
181 if fd < 0 { sbw("{\"organ\":\"nx_schema_backfill\",\"refused\":\"tool_allowlist.conf unreadable\"}\n" as *u8); sys_exit(2); return 2 }
182 let n: i64 = sys_read(fd, al, SB_ALCAP - 1)
183 sys_close(fd)
184 if n <= 0 { sbw("{\"organ\":\"nx_schema_backfill\",\"refused\":\"tool_allowlist.conf empty\"}\n" as *u8); sys_exit(2); return 2 }
185 if n >= SB_ALCAP - 1 { sbw("{\"organ\":\"nx_schema_backfill\",\"refused\":\"allowlist read filled the buffer (possible truncation) -- refusing a partial census\"}\n" as *u8); sys_exit(2); return 2 }
186 al[n] = 0 as u8
187 var scanned: i64 = 0
188 var had: i64 = 0
189 var filled: i64 = 0
190 var nosrc: i64 = 0
191 var nohdr: i64 = 0
192 var derived: i64 = 0
193 let nm: *u8 = sys_mmap(SB_NAMECAP)
194 let elf: *u8 = sys_mmap(SB_PATHCAP)
195 let ti: *u8 = sys_mmap(SB_TITLECAP)
196 let pth: *u8 = sys_mmap(SB_PATHCAP)
197 let fbox: *i64 = sys_mmap(64) as *i64
198 var i: i64 = 0
199 while i < n {
200 var le: i64 = i
201 var sc: i64 = 1
202 while sc == 1 { if le >= n { sc = 0 } else { if al[le] == (10 as u8) { sc = 0 } else { le = le + 1 } } }
203 var ok: i64 = 1
204 if le <= i { ok = 0 }
205 if ok == 1 { if al[i] == (35 as u8) { ok = 0 } }
206 if ok == 1 {
207 var nmn: i64 = 0
208 var p: i64 = i
209 var s2: i64 = 1
210 while s2 == 1 {
211 if p >= le { s2 = 0; ok = 0 } else {
212 if al[p] == (9 as u8) { s2 = 0 } else {
213 if nmn < SB_NAMECAP - 1 { nm[nmn] = al[p]; nmn = nmn + 1 }
214 p = p + 1
215 }
216 }
217 }
218 nm[nmn] = 0 as u8
219 var en: i64 = 0
220 if ok == 1 {
221 p = p + 1
222 var s3: i64 = 1
223 while s3 == 1 {
224 if p >= le { s3 = 0 } else {
225 if al[p] == (9 as u8) { s3 = 0 } else {
226 if en < SB_PATHCAP - 1 { elf[en] = al[p]; en = en + 1 }
227 p = p + 1
228 }
229 }
230 }
231 }
232 elf[en] = 0 as u8
233 if nmn == 0 { ok = 0 }
234 if en == 0 { ok = 0 }
235 if ok == 1 {
236 scanned = scanned + 1
237 let hs: i64 = ma_schema_has_name(nm)
238 if hs == 1 { had = had + 1 }
239 if hs < 0 {
240 sbw("{\"organ\":\"nx_schema_backfill\",\"refused\":\"tool_schemas.conf unreadable or possibly truncated -- refusing to append blind\"}\n" as *u8)
241 sys_exit(3)
242 return 3
243 }
244 if hs == 0 {
245 var bs: i64 = 0
246 var k: i64 = 0
247 while elf[k] != (0 as u8) { if elf[k] == (47 as u8) { bs = k + 1 } k = k + 1 }
248 var stl: i64 = k - bs
249 let base: *u8 = ((elf as i64) + bs) as *u8
250 if sb_ends(base, stl, ".sov.elf.new" as *u8, 12) == 1 { stl = stl - 12 } else {
251 if sb_ends(base, stl, ".elf.new" as *u8, 8) == 1 { stl = stl - 8 } else {
252 if sb_ends(base, stl, ".sov.elf" as *u8, 8) == 1 { stl = stl - 8 } else {
253 if sb_ends(base, stl, ".elf" as *u8, 4) == 1 { stl = stl - 4 } else {
254 if sb_ends(base, stl, ".new" as *u8, 4) == 1 { stl = stl - 4 }
255 }
256 }
257 }
258 }
259 var r1: i64 = 0 - 1
260 var r2: i64 = 0 - 1
261 var tin: i64 = 0
262 if stl > 0 {
263 var o2: i64 = sd_cat(pth, 0, "buildroot/runtime/_hdl_build/" as *u8)
264 var c2: i64 = 0
265 while c2 < stl { pth[o2] = base[c2]; o2 = o2 + 1; c2 = c2 + 1 }
266 o2 = sd_cat(pth, o2, ".nx" as *u8)
267 pth[o2] = 0 as u8
268 r1 = sb_title_from_header(pth, ti)
269 if r1 > 0 { tin = r1 } else {
270 o2 = sd_cat(pth, 0, "buildroot/runtime/" as *u8)
271 c2 = 0
272 while c2 < stl { pth[o2] = base[c2]; o2 = o2 + 1; c2 = c2 + 1 }
273 o2 = sd_cat(pth, o2, ".nx" as *u8)
274 pth[o2] = 0 as u8
275 r2 = sb_title_from_header(pth, ti)
276 if r2 > 0 { tin = r2 }
277 }
278 }
279 if tin > 0 {
280 // pth still holds the source path that actually yielded the title, so the
281 // flags are derived from the SAME file the description came from.
282 sb_derive_flags(pth, fbox)
283 if sb_append(nm, ti, fbox) == 1 {
284 filled = filled + 1
285 if fbox[4] == 1 { derived = derived + 1 }
286 }
287 } else {
288 var nof: i64 = 1
289 if r1 >= 0 { nof = 0 }
290 if r2 >= 0 { nof = 0 }
291 // a COUNT is not a work item: name every skip on stderr so the residual is
292 // actionable (write the header, re-run, watch the number fall) instead of
293 // being an unfalsifiable "2 left" that nobody can pick up.
294 sys_write(2, "SKIP " as *u8, 5)
295 if nof == 1 { sys_write(2, "no-source " as *u8, 12) } else { sys_write(2, "no-header " as *u8, 12) }
296 sys_write(2, nm, nmn)
297 sys_write(2, "\n" as *u8, 1)
298 if nof == 1 { nosrc = nosrc + 1 } else { nohdr = nohdr + 1 }
299 }
300 }
301 }
302 }
303 i = le + 1
304 }
305 let out: *u8 = sys_mmap(SB_HDRCAP)
306 var o3: i64 = sd_cat(out, 0, "{\"organ\":\"nx_schema_backfill\",\"scanned\":" as *u8)
307 o3 = sd_catn(out, o3, scanned)
308 o3 = sd_cat(out, o3, ",\"had_schema\":" as *u8)
309 o3 = sd_catn(out, o3, had)
310 o3 = sd_cat(out, o3, ",\"flags_static_derived\":" as *u8)
311 o3 = sd_catn(out, o3, derived)
312 o3 = sd_cat(out, o3, ",\"filled\":" as *u8)
313 o3 = sd_catn(out, o3, filled)
314 o3 = sd_cat(out, o3, ",\"skipped_no_source\":" as *u8)
315 o3 = sd_catn(out, o3, nosrc)
316 o3 = sd_cat(out, o3, ",\"skipped_no_header\":" as *u8)
317 o3 = sd_catn(out, o3, nohdr)
318 o3 = sd_cat(out, o3, ",\"note\":\"idempotent; re-run after maker-beat header writes; run nx_toolreg_reconcile to publish\"}\n" as *u8)
319 out[o3] = 0 as u8
320 sbw(out)
321 return 0
322}