code wiki / _hdl_build / nx_registrymine.nx
nx_registrymine.nx source
↩ module page · 1063 lines · 52793 B
1// nx_registrymine.nx -- REGISTRY-PLANE MINER (miner-sota MS06d, 2026-07-23) closing the census's last
2// two uncovered classes in ONE organ: MC07 capabilities (bigrock-) and MC11 residual-catalog (minergap-).
3// Both share the canonical registry row shape, so this is deliberately GENERIC (raci-, commontask-,
4// work- fit it too) rather than two near-identical organs -- rule-15 applied BEFORE the duplication.
5// It answers the question a registry cannot answer about itself: WHO OWNS WHAT, and what is ORPHANED.
6// UNOWNED = owner is "-" or empty (a capability nobody is accountable for -- the real find)
7// UNSCOPED = scope is "-" or empty (a row that cannot be routed to a lane)
8// plus per-owner load (total + open), status distribution, severity distribution, owned_permil.
9// Source is a seg-store plane via the ALLOWLIST-RESOLVED loader, or a FILE when loader is "-"
10// (deterministic gate fixtures). Composes nx_sovjson_lib (sj_*). Read-only. No hw writes (Rule 26).
11// mine <source> [loader|-] [minsup] -> JSON: totals, by_owner ranked, by_status, sev, gaps
12// selftest <scratch-prefix> -> gate T1..T8
13// row cols: id TAB title TAB sev TAB status TAB owner TAB scope TAB note
14// license_tier: ORIGINAL
15import "nx_sovjson_lib.nx"
16import "nx_syscalls.nx"
17import "nx_gate_verdict.nx"
18import "nx_tool_run.nx"
19const RM_MAGIC_4088: i64 = 4088
20
21const RM_CAP: i64 = 1048576
22const RM_OUT: i64 = 65536
23const RM_PATH: i64 = 512
24const RM_SLOTS: i64 = 256
25const RM_TOPN: i64 = 20
26const RM_ALLOW: i64 = 131072
27const RM_PERMIL: i64 = 1000
28const RM_SEVN: i64 = 12
29const RM_NAME_MAX: i64 = 120
30const RM_MODE_644: i64 = 420
31
32func rm_read(path: *u8, buf: *u8, cap: i64) -> i64 {
33 let fd: i64 = sys_openat_rd(path)
34 if fd < 0 { return -1 }
35 var n: i64 = 0
36 var go: i64 = 1
37 while go == 1 { let r: i64 = sys_read(fd, ((buf as i64)+n) as *u8, cap-n); if r <= 0 { go = 0 } else { n = n + r } if n >= cap { go = 0 } }
38 sys_close(fd)
39 return n
40}
41func rm_find(q: *u8, n: i64, lit: *u8) -> i64 {
42 let ll: i64 = sj_vlen(lit)
43 if ll == 0 { return 0 }
44 var i: i64 = 0
45 while i + ll <= n {
46 var k: i64 = 0
47 var ok: i64 = 1
48 while k < ll { if q[i+k] != lit[k] { ok = 0; k = ll } else { k = k + 1 } }
49 if ok == 1 { return 1 }
50 i = i + 1
51 }
52 return 0
53}
54// DELEGATES to the shared base (rule-15 extraction 2026-07-23)
55func rm_allow_path(name: *u8, outp: *u8) -> i64 { return sj_allow_path(name, outp) }
56func rm_key(d: *u8, o: i64, name: *u8) -> i64 {
57 d[o] = 34 as u8
58 var p: i64 = o + 1
59 p = sj_cat(d, p, name)
60 d[p] = 34 as u8
61 p = p + 1
62 d[p] = 58 as u8
63 p = p + 1
64 return p
65}
66// a field is ABSENT when it is empty or a bare "-"
67func rm_absent(q: *u8, s: i64, e: i64) -> i64 {
68 if e <= s { return 1 }
69 if e - s == 1 { if q[s] == (45 as u8) { return 1 } }
70 return 0
71}
72// A COVERAGE METRIC THAT COUNTS A PLACEHOLDER AS COVERAGE OVERSTATES ITSELF (2026-08-15).
73// rm_absent recognises only an EMPTY field or a bare '-', so the literal owner "unassigned" and a
74// numeric owner left behind by a mis-split row BOTH read as real ownership. MEASURED on
75// knowledge/store/frontier-: owned_permil reported 1000 while 16 rows were owned by the string
76// "unassigned" and 20 by "2". The 2026 governance bar is the percentage of services WITH OWNERS, so
77// overstating it flatters exactly the number that is supposed to be uncomfortable -- and with only the
78// top 20 of 74 owners emitted, a reader cannot recompute the honest figure downstream. The RULER has
79// to do it.
80// * AN ALL-DIGIT OWNER IS NOT A PERSON, IT IS A COLUMN THAT SLIPPED.
81// ADDITIVE BY CONSTRUCTION (rule 19): unowned, owned_permil and the by_owner table are UNCHANGED.
82// This adds a stricter SECOND reading beside the first, so the GAP between them is the visible thing
83// rather than a silently corrected number.
84func rm_placeholder(q: *u8, s: i64, e: i64) -> i64 {
85 if e <= s { return 0 }
86 if sj_lit_eq(q, s, e, "unassigned" as *u8) == 1 { return 1 }
87 if sj_lit_eq(q, s, e, "unowned" as *u8) == 1 { return 1 }
88 if sj_lit_eq(q, s, e, "none" as *u8) == 1 { return 1 }
89 if sj_lit_eq(q, s, e, "TBD" as *u8) == 1 { return 1 }
90 if sj_lit_eq(q, s, e, "tbd" as *u8) == 1 { return 1 }
91 var i: i64 = s
92 var alldig: i64 = 1
93 while i < e {
94 let c: i64 = q[i] as i64
95 if c < 48 { alldig = 0; i = e } else { if c > 57 { alldig = 0; i = e } else { i = i + 1 } }
96 }
97 if alldig == 1 { return 1 }
98 return 0
99}
100// intern a span into a parallel table; returns index or -1 when full
101func rm_intern(q: *u8, cs: i64, ce: i64, ss: *i64, se: *i64, np: *i64) -> i64 {
102 var k: i64 = 0
103 while k < np[0] {
104 if ce - cs == se[k] - ss[k] {
105 var m: i64 = 0
106 var eq: i64 = 1
107 while m < ce - cs { if q[cs+m] != q[ss[k]+m] { eq = 0; m = ce - cs } else { m = m + 1 } }
108 if eq == 1 { return k }
109 }
110 k = k + 1
111 }
112 if np[0] >= RM_SLOTS { return -1 }
113 ss[np[0]] = cs
114 se[np[0]] = ce
115 np[0] = np[0] + 1
116 return np[0] - 1
117}
118func rm_load(src: *u8, loader: *u8, buf: *u8, lcx: *i64) -> i64 {
119 lcx[0] = 0
120 if sj_lit_eq(loader, 0, sj_vlen(loader), "-" as *u8) == 1 {
121 let n: i64 = rm_read(src, buf, RM_CAP - 8)
122 if n <= 0 { return -1 }
123 return n
124 }
125 let lp: *u8 = sys_mmap(RM_PATH)
126 if rm_allow_path(loader, lp) == 0 { return -2 }
127 lcx[0] = 1
128 let av: *i64 = sys_mmap(64) as *i64
129 av[0] = lp as i64
130 av[1] = src as i64
131 av[2] = "load" as *u8 as i64
132 av[3] = 0
133 let cl: *i64 = sys_mmap(16) as *i64
134 let ex: i64 = tr_run_capture(lp, av, buf, RM_CAP - 8, cl)
135 if ex != 0 { return -3 }
136 if cl[0] <= 0 { return -1 }
137 return cl[0]
138}
139func rm_mine_json(src: *u8, loader: *u8, minsup: i64, d: *u8) -> i64 {
140 let q: *u8 = sys_mmap(RM_CAP)
141 let lcx: *i64 = sys_mmap(16) as *i64
142 let n: i64 = rm_load(src, loader, q, lcx)
143 if n < 0 { return n }
144 let ows: *i64 = sys_mmap(8 * RM_SLOTS) as *i64
145 let owe: *i64 = sys_mmap(8 * RM_SLOTS) as *i64
146 let owc: *i64 = sys_mmap(8 * RM_SLOTS) as *i64
147 let owo: *i64 = sys_mmap(8 * RM_SLOTS) as *i64
148 let nown: *i64 = sys_mmap(16) as *i64
149 let sts: *i64 = sys_mmap(8 * RM_SLOTS) as *i64
150 let ste: *i64 = sys_mmap(8 * RM_SLOTS) as *i64
151 let stc: *i64 = sys_mmap(8 * RM_SLOTS) as *i64
152 let nsts: *i64 = sys_mmap(16) as *i64
153 let sevc: *i64 = sys_mmap(8 * RM_SEVN) as *i64
154 let done: *i64 = sys_mmap(8 * RM_SLOTS) as *i64
155 let sp: *i64 = sys_mmap(16) as *i64
156 var rows: i64 = 0
157 var malformed: i64 = 0
158 var unowned: i64 = 0
159 var placeheld: i64 = 0
160 var unscoped: i64 = 0
161 var capped: i64 = 0
162 var i: i64 = 0
163 while i < n {
164 let le: i64 = sj_le(q, i, n)
165 var ok: i64 = 0
166 var cmt: i64 = 0
167 if le > i { if q[i] == (35 as u8) { cmt = 1 } }
168 if le > i { if cmt == 0 { if sj_col(q, i, le, 4, sp) == 1 { ok = 1 } } }
169 if ok == 0 { if le > i { if cmt == 0 { malformed = malformed + 1 } } } else {
170 rows = rows + 1
171 // owner (col 4)
172 let os: i64 = sp[0]
173 let oe: i64 = sp[1]
174 if rm_absent(q, os, oe) == 1 { unowned = unowned + 1 } else {
175 // counted BESIDE the owner, never instead of it: the row still interns under its
176 // literal owner so by_owner keeps naming the placeholder, which is what makes it fixable.
177 if rm_placeholder(q, os, oe) == 1 { placeheld = placeheld + 1 }
178 let oi: i64 = rm_intern(q, os, oe, ows, owe, nown)
179 if oi < 0 { capped = 1 } else { owc[oi] = owc[oi] + 1 }
180 }
181 // status (col 3)
182 var isopen: i64 = 0
183 if sj_col(q, i, le, 3, sp) == 1 {
184 if sj_lit_eq(q, sp[0], sp[1], "O" as *u8) == 1 { isopen = 1 }
185 if sj_lit_eq(q, sp[0], sp[1], "open" as *u8) == 1 { isopen = 1 }
186 let si: i64 = rm_intern(q, sp[0], sp[1], sts, ste, nsts)
187 if si < 0 { capped = 1 } else { stc[si] = stc[si] + 1 }
188 }
189 if isopen == 1 { if rm_absent(q, os, oe) == 0 {
190 let oi2: i64 = rm_intern(q, os, oe, ows, owe, nown)
191 if oi2 >= 0 { owo[oi2] = owo[oi2] + 1 }
192 } }
193 // scope (col 5)
194 if sj_col(q, i, le, 5, sp) == 1 {
195 if rm_absent(q, sp[0], sp[1]) == 1 { unscoped = unscoped + 1 }
196 } else { unscoped = unscoped + 1 }
197 // severity (col 2)
198 if sj_col(q, i, le, 2, sp) == 1 {
199 let sv: i64 = sj_atoi_span(q, sp[0], sp[1])
200 if sv >= 0 { if sv < RM_SEVN { sevc[sv] = sevc[sv] + 1 } }
201 }
202 }
203 i = le + 1
204 }
205 var p: i64 = 0
206 d[p] = 123 as u8; p = p + 1
207 p = rm_key(d, p, "v" as *u8); p = sj_catn(d, p, 1); d[p] = 44 as u8; p = p + 1
208 p = rm_key(d, p, "tool" as *u8)
209 d[p] = 34 as u8; p = p + 1
210 p = sj_cat(d, p, "nx_registrymine" as *u8)
211 d[p] = 34 as u8; p = p + 1
212 d[p] = 44 as u8; p = p + 1
213 p = rm_key(d, p, "averb" as *u8)
214 d[p] = 34 as u8; p = p + 1
215 p = sj_cat(d, p, "mine" as *u8)
216 d[p] = 34 as u8; p = p + 1
217 d[p] = 44 as u8; p = p + 1
218 p = rm_key(d, p, "source" as *u8)
219 d[p] = 34 as u8; p = p + 1
220 p = sj_cat_esc(d, p, src, 0, sj_vlen(src), RM_NAME_MAX)
221 d[p] = 34 as u8; p = p + 1
222 d[p] = 44 as u8; p = p + 1
223 p = rm_key(d, p, "loader_resolved" as *u8); p = sj_catn(d, p, lcx[0]); d[p] = 44 as u8; p = p + 1
224 p = rm_key(d, p, "rows" as *u8); p = sj_catn(d, p, rows); d[p] = 44 as u8; p = p + 1
225 p = rm_key(d, p, "malformed" as *u8); p = sj_catn(d, p, malformed); d[p] = 44 as u8; p = p + 1
226 p = rm_key(d, p, "owners" as *u8); p = sj_catn(d, p, nown[0]); d[p] = 44 as u8; p = p + 1
227 p = rm_key(d, p, "unowned" as *u8); p = sj_catn(d, p, unowned); d[p] = 44 as u8; p = p + 1
228 p = rm_key(d, p, "unscoped" as *u8); p = sj_catn(d, p, unscoped); d[p] = 44 as u8; p = p + 1
229 var op: i64 = 0 - 1
230 if rows > 0 { op = (rows - unowned) * RM_PERMIL / rows }
231 p = rm_key(d, p, "owned_permil" as *u8); p = sj_catn(d, p, op); d[p] = 44 as u8; p = p + 1
232 // THE STRICT READING, EMITTED BESIDE THE NOMINAL ONE. owned_permil answers "has an owner field";
233 // owned_permil_strict answers "has an owner a human could actually be held to". Publishing both is
234 // the point -- the DIFFERENCE is the worklist, and a single blended number would hide it.
235 p = rm_key(d, p, "placeholder_owned" as *u8); p = sj_catn(d, p, placeheld); d[p] = 44 as u8; p = p + 1
236 var ops: i64 = 0 - 1
237 if rows > 0 { ops = (rows - unowned - placeheld) * RM_PERMIL / rows }
238 p = rm_key(d, p, "owned_permil_strict" as *u8); p = sj_catn(d, p, ops); d[p] = 44 as u8; p = p + 1
239 // by_owner ranked by total desc
240 p = rm_key(d, p, "by_owner" as *u8)
241 d[p] = 91 as u8; p = p + 1
242 var shown: i64 = 0
243 var below: i64 = 0
244 var efirst: i64 = 1
245 var pass: i64 = 0
246 while pass < nown[0] {
247 var mi: i64 = 0 - 1
248 var mx: i64 = 0 - 1
249 var k: i64 = 0
250 while k < nown[0] {
251 if done[k] == 0 { if owc[k] > mx { mx = owc[k]; mi = k } }
252 k = k + 1
253 }
254 if mi >= 0 {
255 done[mi] = 1
256 if mx < minsup { below = below + 1 } else {
257 if shown < RM_TOPN {
258 if efirst == 0 { d[p] = 44 as u8; p = p + 1 }
259 efirst = 0
260 d[p] = 123 as u8; p = p + 1
261 p = rm_key(d, p, "owner" as *u8)
262 d[p] = 34 as u8; p = p + 1
263 p = sj_cat_esc(d, p, q, ows[mi], owe[mi], RM_NAME_MAX)
264 d[p] = 34 as u8; p = p + 1
265 d[p] = 44 as u8; p = p + 1
266 p = rm_key(d, p, "rows" as *u8); p = sj_catn(d, p, owc[mi]); d[p] = 44 as u8; p = p + 1
267 p = rm_key(d, p, "open" as *u8); p = sj_catn(d, p, owo[mi])
268 d[p] = 125 as u8; p = p + 1
269 shown = shown + 1
270 }
271 }
272 }
273 pass = pass + 1
274 }
275 d[p] = 93 as u8; p = p + 1
276 d[p] = 44 as u8; p = p + 1
277 p = rm_key(d, p, "owners_shown" as *u8); p = sj_catn(d, p, shown); d[p] = 44 as u8; p = p + 1
278 p = rm_key(d, p, "owners_below_minsup" as *u8); p = sj_catn(d, p, below); d[p] = 44 as u8; p = p + 1
279 // by_status (declaration order)
280 p = rm_key(d, p, "by_status" as *u8)
281 d[p] = 91 as u8; p = p + 1
282 var si2: i64 = 0
283 var sfirst: i64 = 1
284 while si2 < nsts[0] {
285 if sfirst == 0 { d[p] = 44 as u8; p = p + 1 }
286 sfirst = 0
287 d[p] = 123 as u8; p = p + 1
288 p = rm_key(d, p, "status" as *u8)
289 d[p] = 34 as u8; p = p + 1
290 p = sj_cat_esc(d, p, q, sts[si2], ste[si2], RM_NAME_MAX)
291 d[p] = 34 as u8; p = p + 1
292 d[p] = 44 as u8; p = p + 1
293 p = rm_key(d, p, "rows" as *u8); p = sj_catn(d, p, stc[si2])
294 d[p] = 125 as u8; p = p + 1
295 si2 = si2 + 1
296 }
297 d[p] = 93 as u8; p = p + 1
298 d[p] = 44 as u8; p = p + 1
299 p = rm_key(d, p, "sev" as *u8)
300 d[p] = 91 as u8; p = p + 1
301 var sv2: i64 = 0
302 var vfirst: i64 = 1
303 while sv2 < RM_SEVN {
304 if sevc[sv2] > 0 {
305 if vfirst == 0 { d[p] = 44 as u8; p = p + 1 }
306 vfirst = 0
307 d[p] = 123 as u8; p = p + 1
308 p = rm_key(d, p, "sev" as *u8); p = sj_catn(d, p, sv2); d[p] = 44 as u8; p = p + 1
309 p = rm_key(d, p, "rows" as *u8); p = sj_catn(d, p, sevc[sv2])
310 d[p] = 125 as u8; p = p + 1
311 }
312 sv2 = sv2 + 1
313 }
314 d[p] = 93 as u8; p = p + 1
315 d[p] = 44 as u8; p = p + 1
316 p = rm_key(d, p, "slots_capped" as *u8); p = sj_catn(d, p, capped)
317 d[p] = 125 as u8; p = p + 1
318 d[p] = 10 as u8; p = p + 1
319 return p
320}
321func rm_selftest(prefix: *u8) -> i64 {
322 let ctr: *i64 = gv_ctr()
323 gv_head("nx_registrymine selftest -- ownership-gap teeth (a dash owner is UNOWNED, not an owner)" as *u8)
324 let fx: *u8 = sys_mmap(RM_PATH)
325 var o: i64 = sj_cat(fx, 0, prefix)
326 o = sj_catn(fx, o, sys_now_realtime_sec())
327 o = sj_cat(fx, o, ".rm" as *u8)
328 fx[o] = 0 as u8
329 let miss: *u8 = sys_mmap(RM_PATH)
330 o = sj_cat(miss, 0, fx)
331 o = sj_cat(miss, o, ".absent" as *u8)
332 miss[o] = 0 as u8
333 // 6 rows: pm owns 3 (2 open), hr owns 1 open, 1 dash-owner, 1 empty-owner; 2 unscoped; 1 malformed
334 let fd: i64 = sys_openat_wr(fx, RM_MODE_644)
335 let lb: *u8 = sys_mmap(RM_MAGIC_4088)
336 var lo: i64 = sj_cat(lb, 0, "# fixture\n" as *u8)
337 lo = sj_cat(lb, lo, "R1\tcap one\t8\tO\tpm\tlaneA\tnote\n" as *u8)
338 lo = sj_cat(lb, lo, "R2\tcap two\t5\tO\tpm\tlaneA\tnote\n" as *u8)
339 lo = sj_cat(lb, lo, "R3\tcap three\t5\tD\tpm\tlaneB\tnote\n" as *u8)
340 lo = sj_cat(lb, lo, "R4\tcap four\t8\tO\thr\t-\tnote\n" as *u8)
341 lo = sj_cat(lb, lo, "R5\tcap five\t3\tO\t-\tlaneC\tnobody owns this\n" as *u8)
342 lo = sj_cat(lb, lo, "R6\tcap six\t3\tD\t\t\tempty owner and scope\n" as *u8)
343 lo = sj_cat(lb, lo, "junkrow\n" as *u8)
344 sys_write(fd, lb, lo)
345 sys_close(fd)
346 let d: *u8 = sys_mmap(RM_OUT)
347 let r1: i64 = rm_mine_json(miss, "-" as *u8, 1, d)
348 var ok1: i64 = 0
349 if r1 < 0 { ok1 = 1 }
350 gv_check("T1 missing source refused fail closed" as *u8, ok1, ctr)
351 let dl: i64 = rm_mine_json(fx, "-" as *u8, 1, d)
352 var ok2: i64 = 0
353 if dl > 0 { if rm_find(d, dl, "\"rows\":6,\"malformed\":1" as *u8) == 1 { ok2 = 1 } }
354 gv_check("T2 exact rows 6 with the junk row counted malformed (comment skipped)" as *u8, ok2, ctr)
355 var ok3: i64 = 0
356 if rm_find(d, dl, "\"unowned\":2" as *u8) == 1 { if rm_find(d, dl, "\"owners\":2" as *u8) == 1 { ok3 = 1 } }
357 gv_check("T3 BOTH a dash owner and an empty owner count UNOWNED, neither becomes an owner" as *u8, ok3, ctr)
358 var ok4: i64 = 0
359 if rm_find(d, dl, "\"owner\":\"pm\",\"rows\":3,\"open\":2" as *u8) == 1 { ok4 = 1 }
360 gv_check("T4 per-owner load exact: pm 3 rows of which 2 open" as *u8, ok4, ctr)
361 var ok5: i64 = 0
362 if rm_find(d, dl, "\"status\":\"O\",\"rows\":4" as *u8) == 1 { if rm_find(d, dl, "\"status\":\"D\",\"rows\":2" as *u8) == 1 { ok5 = 1 } }
363 gv_check("T5 status distribution exact 4 open 2 done" as *u8, ok5, ctr)
364 var ok6: i64 = 0
365 if rm_find(d, dl, "\"owned_permil\":666" as *u8) == 1 { ok6 = 1 }
366 gv_check("T6 owned_permil exact 666 (4 owned of 6)" as *u8, ok6, ctr)
367 var ok7: i64 = 0
368 if rm_find(d, dl, "\"unscoped\":2" as *u8) == 1 { ok7 = 1 }
369 gv_check("T7 unscoped exact 2 (dash scope AND empty scope)" as *u8, ok7, ctr)
370 let dl8: i64 = rm_mine_json(fx, "-" as *u8, 2, d)
371 var ok8: i64 = 0
372 if dl8 > 0 { if rm_find(d, dl8, "\"owner\":\"hr\"" as *u8) == 0 { if rm_find(d, dl8, "\"owners_below_minsup\":1" as *u8) == 1 { ok8 = 1 } } }
373 gv_check("T8 minsup 2 suppresses the single-row owner and DECLARES it" as *u8, ok8, ctr)
374 let rc: i64 = gv_verdict("REGISTRYMINE-GATE" as *u8, ctr, "registry mining: unowned and unscoped surfaced, per-owner load exact, suppression declared" as *u8)
375 return rc
376}
377
378// ================= DM3 (devmgmt rung): rm_lostset -- THE EXEC-PROVEN LOST-SET MINER =================
379// The question a registry CANNOT answer about itself, and the reason nx_toolreg_reconcile could not:
380// its POPULATION IS THE REGISTRY FILE, so a row deleted by a clobber is not "drift" -- it is absent
381// from the question. Measured 2026-08-19: `nx_toolreg_reconcile check` reported drift=0 while 20 rows
382// were gone. This miner INVERTS THE JOIN: the population is EXECUTION EVIDENCE from the session
383// record, and the registry is only the TEST applied to it.
384//
385// EXEC-PROVEN = a tool_result record carrying the server's own "mcpMeta" -> "_meta" -> "exit_code":
386// the organ provably forked, so a GREEN row existed at call time. The anchor is deliberately spelled
387// with UNESCAPED quotes. In JSONL every quote inside a string VALUE is backslash-escaped, so this
388// literal can only ever match STRUCTURE and never prose that discusses it -- which is what stops the
389// miner matching its own source text when this very session is mined later. (neg-control tooth.)
390// The same property is why tool names are read ONLY from inside a "type":"tool_use" object: the
391// harness also ships `deferred_tools_delta` attachments that LIST tool names as structural JSON, and
392// a bare-prefix scan counts every listed-but-never-called tool as evidence. Measured, real, guarded.
393//
394// BUCKETS ARE A PARTITION OVER TOOLS WITH IN-WINDOW PAIRED RESULTS, AND THE SUM IS PRINTED:
395// row_green + row_notgreen + lost == exec_tools
396// DENIED-ONLY and UNKNOWN-ONLY are their OWN buckets, never folded into either side: a refusal is cap
397// coverage, and an unrecognised result is "I could not look", not "it is broken".
398//
399// SCOPE / HORIZON -- part of the claim, not a footnote. exec_meta exists ONLY in the client-side
400// session transcripts. The NAS capture frames (nx_claude_harvest ch_frames) carry the tool NAME but a
401// CONSTANT verb and outcome column, so they cannot answer this question: checked in the source, not
402// assumed. nx_job_run FORKS an elf directly and bypasses the row check, so a job-run-only tool is not
403// evidence that a row ever existed and is deliberately NOT counted.
404//
405// lostset <transcripts-dir> <tool_allowlist.conf> [since-iso]
406// license_tier: ORIGINAL Read-only. No hw writes (Rule 26).
407const RM_LS_SLASH: i64 = 47 // ASCII '/'
408const RM_LS_DOT: i64 = 46 // ASCII '.'
409const RM_LS_QUOTE: i64 = 34 // ASCII '"'
410const RM_LS_NL: i64 = 10 // ASCII newline (a bare-newline string literal is lexer-ambiguous)
411const RM_LS_CH_M: i64 = 109 // ASCII 'm' -- first byte after the quote of "mcpMeta"
412const RM_LS_CH_T: i64 = 116 // ASCII 't' -- first byte after the quote of "type"/"tool_use_id"/"timestamp"
413const RM_LS_DT_DIR: i64 = 4 // linux dirent d_type DT_DIR
414const RM_LS_DT_UNKNOWN: i64 = 0 // linux dirent d_type DT_UNKNOWN -- probed, never assumed
415const RM_LS_DIRBUF: i64 = 65536 // getdents64 batch -- LOOPED until 0; ONE CALL IS NOT A LISTING
416const RM_LS_PATH: i64 = 1024 // one path cell (longest measured transcript path ~130 B)
417const RM_LS_MAXDIRS: i64 = 8192 // directory stack; overflow REFUSES loudly
418const RM_LS_MAXFILES: i64 = 32768 // transcript table (899 measured 2026-08-20); overflow REFUSES loudly
419const RM_LS_MAXTOOLS: i64 = 8192 // distinct tool names (1,187 registered); overflow REFUSES loudly
420const RM_LS_NAMECELL: i64 = 128 // one interned tool-name cell
421const RM_LS_TSCELL: i64 = 32 // one ISO-8601 cell ("2026-08-19T21:59:59.999Z" = 24 measured)
422const RM_LS_IDSLOTS: i64 = 262144 // per-file tool_use-id map slots, power of two (open addressing)
423const RM_LS_GIDSLOTS: i64 = 1048576 // global counted-result id set slots, power of two
424const RM_LS_GIDMAX: i64 = 524288 // counted results (32,122 in-window measured); overflow REFUSES loudly
425const RM_LS_IDCELL: i64 = 48 // one tool_use id cell ("toolu_" + 24 = 30 measured)
426const RM_LS_SCAN: i64 = 512 // bounded forward scan inside ONE tool_use object, newline-stopped
427const RM_LS_DENYSCAN: i64 = 4096 // bounded refusal-marker scan; a MISS falls to UNKNOWN, never to OK
428const RM_LS_OUT: i64 = 4194304 // report buffer (full worklist, never a top-N)
429const RM_LS_HASH_MUL: i64 = 131 // odd multiplier, classic polynomial string hash
430const RM_LS_HASH_MOD: i64 = 1000000007 // large prime modulus keeps the accumulator inside i64
431const RM_LS_CX: i64 = 16 // caller-visible counter slots
432const RM_LS_CX_LOST: i64 = 0
433const RM_LS_CX_EXECT: i64 = 1
434const RM_LS_CX_CAPS: i64 = 2
435
436func rm_ls_cell(base: *u8, idx: i64, cell: i64) -> *u8 { return ((base as i64) + idx * cell) as *u8 }
437
438// prefix match of `lit` at position i, never past `endlim`
439func rm_ls_at(q: *u8, i: i64, endlim: i64, lit: *u8) -> i64 {
440 let ll: i64 = sj_vlen(lit)
441 if i + ll > endlim { return 0 }
442 var k: i64 = 0
443 var ok: i64 = 1
444 while k < ll { if q[i+k] != lit[k] { ok = 0; k = ll } else { k = k + 1 } }
445 return ok
446}
447// bounded find that ALSO stops at a newline: a JSONL record never spans one, so a scan that crosses a
448// newline is reading the NEXT record's fields and would silently attribute them to this one.
449func rm_ls_find_nl(q: *u8, from: i64, endlim: i64, lit: *u8) -> i64 {
450 let ll: i64 = sj_vlen(lit)
451 if ll == 0 { return 0 - 1 }
452 var i: i64 = from
453 var hit: i64 = 0 - 1
454 var go: i64 = 1
455 while go == 1 {
456 if i + ll > endlim { go = 0 } else {
457 if (q[i] as i64) == RM_LS_NL { go = 0 } else {
458 if rm_ls_at(q, i, endlim, lit) == 1 { hit = i; go = 0 } else { i = i + 1 }
459 }
460 }
461 }
462 return hit
463}
464func rm_ls_ends(name: *u8, sfx: *u8) -> i64 {
465 let n: i64 = sj_vlen(name)
466 let s: i64 = sj_vlen(sfx)
467 if s > n { return 0 }
468 var k: i64 = 0
469 var ok: i64 = 1
470 while k < s { if name[n-s+k] != sfx[k] { ok = 0; k = s } else { k = k + 1 } }
471 return ok
472}
473func rm_ls_hash(q: *u8, s: i64, e: i64) -> i64 {
474 var h: i64 = 0
475 var i: i64 = s
476 while i < e { h = (h * RM_LS_HASH_MUL + (q[i] as i64)) % RM_LS_HASH_MOD; i = i + 1 }
477 return h
478}
479// per-file id map: returns the slot holding this key, or the first EMPTY slot for it. -1 = table full.
480func rm_ls_probe(q: *u8, s: i64, e: i64, off: *i64, ln: *i64, gn: *i64, gen: i64) -> i64 {
481 let ky: i64 = e - s
482 var slot: i64 = rm_ls_hash(q, s, e) % RM_LS_IDSLOTS
483 var tries: i64 = 0
484 var res: i64 = 0 - 1
485 while tries < RM_LS_IDSLOTS {
486 if gn[slot] != gen { res = slot; tries = RM_LS_IDSLOTS } else {
487 var eq: i64 = 0
488 if ln[slot] == ky {
489 eq = 1
490 var m: i64 = 0
491 while m < ky { if q[off[slot]+m] != q[s+m] { eq = 0; m = ky } else { m = m + 1 } }
492 }
493 if eq == 1 { res = slot; tries = RM_LS_IDSLOTS } else {
494 slot = (slot + 1) % RM_LS_IDSLOTS
495 tries = tries + 1
496 }
497 }
498 }
499 return res
500}
501// GLOBAL dedupe set over counted results. A resumed session REPLAYS earlier records into a new
502// transcript, so the same tool_use id is present in several files: counting per file would inflate
503// every number in the report. Keys are COPIED -- the per-file mapping is unmapped before the report.
504// returns 1 NEW, 0 ALREADY-SEEN, -2 CAPPED (announced, never silent), -1 unusable key.
505func rm_ls_gid_add(q: *u8, s: i64, e: i64, ar: *u8, gsl: *i64, ng: *i64) -> i64 {
506 let ky: i64 = e - s
507 if ky <= 0 { return 0 - 1 }
508 if ky >= RM_LS_IDCELL { return 0 - 1 }
509 var slot: i64 = rm_ls_hash(q, s, e) % RM_LS_GIDSLOTS
510 var tries: i64 = 0
511 var out: i64 = 0 - 2
512 while tries < RM_LS_GIDSLOTS {
513 let v: i64 = gsl[slot]
514 if v == 0 {
515 if ng[0] >= RM_LS_GIDMAX { out = 0 - 2; tries = RM_LS_GIDSLOTS } else {
516 let base: i64 = ng[0] * RM_LS_IDCELL
517 var j: i64 = 0
518 while j < ky { ar[base+j] = q[s+j]; j = j + 1 }
519 ar[base+ky] = 0 as u8
520 gsl[slot] = ng[0] + 1
521 ng[0] = ng[0] + 1
522 out = 1
523 tries = RM_LS_GIDSLOTS
524 }
525 } else {
526 let b2: i64 = (v - 1) * RM_LS_IDCELL
527 var eq: i64 = 1
528 var m: i64 = 0
529 while m < ky { if ar[b2+m] != q[s+m] { eq = 0; m = ky } else { m = m + 1 } }
530 if eq == 1 { if ar[b2+ky] != (0 as u8) { eq = 0 } }
531 if eq == 1 { out = 0; tries = RM_LS_GIDSLOTS } else {
532 slot = (slot + 1) % RM_LS_GIDSLOTS
533 tries = tries + 1
534 }
535 }
536 }
537 return out
538}
539// intern a tool NAME (mcp__nishi__ prefix already stripped) into the global table. COPIES the bytes.
540// -1 unusable, -2 CAPPED.
541func rm_ls_tintern(q: *u8, s: i64, e: i64, ar: *u8, toff: *i64, tlen: *i64, nt: *i64) -> i64 {
542 let ln: i64 = e - s
543 if ln <= 0 { return 0 - 1 }
544 if ln >= RM_LS_NAMECELL { return 0 - 1 }
545 var k: i64 = 0
546 while k < nt[0] {
547 if tlen[k] == ln {
548 var m: i64 = 0
549 var eq: i64 = 1
550 while m < ln { if ar[toff[k]+m] != q[s+m] { eq = 0; m = ln } else { m = m + 1 } }
551 if eq == 1 { return k }
552 }
553 k = k + 1
554 }
555 if nt[0] >= RM_LS_MAXTOOLS { return 0 - 2 }
556 let base: i64 = nt[0] * RM_LS_NAMECELL
557 var j: i64 = 0
558 while j < ln { ar[base+j] = q[s+j]; j = j + 1 }
559 ar[base+ln] = 0 as u8
560 toff[nt[0]] = base
561 tlen[nt[0]] = ln
562 nt[0] = nt[0] + 1
563 return nt[0] - 1
564}
565// ISO-8601 UTC sorts lexicographically, so the window test needs NO calendar arithmetic and therefore
566// no epoch constants -- one fewer duplicate ruler beside ch_iso_epoch. Empty `since` = all time.
567func rm_ls_ts_ge(q: *u8, s: i64, e: i64, since: *u8) -> i64 {
568 let sl: i64 = sj_vlen(since)
569 if sl == 0 { return 1 }
570 if s < 0 { return 0 }
571 var i: i64 = 0
572 var res: i64 = 1
573 while i < sl {
574 if s + i >= e { res = 0; i = sl } else {
575 let a: i64 = q[s+i] as i64
576 let b: i64 = since[i] as i64
577 if a > b { res = 1; i = sl } else { if a < b { res = 0; i = sl } else { i = i + 1 } }
578 }
579 }
580 return res
581}
582// 0 = NO ROW, 1 = ROW PRESENT BUT NOT GREEN, 2 = ROW GREEN. A present-not-green row is its own state:
583// it is NOT lost, and calling it lost would send the next reader to register a row that already exists.
584func rm_ls_rowstate(cb: *u8, cn: i64, ar: *u8, off: i64, ln: i64, sp: *i64) -> i64 {
585 var i: i64 = 0
586 var best: i64 = 0
587 while i < cn {
588 let le: i64 = sj_le(cb, i, cn)
589 if sj_col(cb, i, le, 0, sp) == 1 {
590 if sp[1] - sp[0] == ln {
591 var m: i64 = 0
592 var eq: i64 = 1
593 while m < ln { if cb[sp[0]+m] != ar[off+m] { eq = 0; m = ln } else { m = m + 1 } }
594 if eq == 1 {
595 var st: i64 = 1
596 if sj_col(cb, i, le, 2, sp) == 1 { if sj_lit_eq(cb, sp[0], sp[1], "GREEN" as *u8) == 1 { st = 2 } }
597 if st > best { best = st }
598 }
599 }
600 }
601 i = le + 1
602 }
603 return best
604}
605func rm_ls_isdir(path: *u8, pbuf: *u8) -> i64 {
606 let fd: i64 = sys_openat_rd(path)
607 if fd < 0 { return 0 }
608 let r: i64 = sys_getdents64(fd, pbuf, RM_LS_DIRBUF)
609 sys_close(fd)
610 if r < 0 { return 0 }
611 return 1
612}
613// RECURSIVE transcript walk. wcx[0]=dirs wcx[1]=files wcx[2]=dirs_capped wcx[3]=files_capped
614// wcx[4]=other_entries. A walk that silently stops is a population that silently shrank, so both caps
615// SET A FLAG the report prints and the caller turns into a refusal.
616func rm_ls_walk(root: *u8, parena: *u8, wcx: *i64) -> i64 {
617 let stk: *u8 = sys_mmap(RM_LS_MAXDIRS * RM_LS_PATH)
618 let dbuf: *u8 = sys_mmap(RM_LS_DIRBUF)
619 let pbuf: *u8 = sys_mmap(RM_LS_DIRBUF)
620 let cur: *u8 = sys_mmap(RM_LS_PATH)
621 let fp: *u8 = sys_mmap(RM_LS_PATH)
622 let sfx: *u8 = ".jsonl" as *u8
623 let dotl: *u8 = "." as *u8
624 let dotdot: *u8 = ".." as *u8
625 let c0: *u8 = rm_ls_cell(stk, 0, RM_LS_PATH)
626 var z: i64 = sj_cat(c0, 0, root)
627 c0[z] = 0 as u8
628 var sn: i64 = 1
629 var nf: i64 = 0
630 while sn > 0 {
631 sn = sn - 1
632 let dcell: *u8 = rm_ls_cell(stk, sn, RM_LS_PATH)
633 var dl: i64 = sj_cat(cur, 0, dcell)
634 cur[dl] = 0 as u8
635 let fd: i64 = sys_openat_rd(cur)
636 if fd < 0 { wcx[4] = wcx[4] + 1 } else {
637 wcx[0] = wcx[0] + 1
638 var go: i64 = 1
639 while go == 1 {
640 let nr: i64 = sys_getdents64(fd, dbuf, RM_LS_DIRBUF)
641 if nr <= 0 { go = 0 } else {
642 var off: i64 = 0
643 while off < nr {
644 let rec: *u8 = ((dbuf as i64) + off) as *u8
645 let nm: *u8 = dirent_name(rec)
646 let dt: i64 = dirent_type(rec)
647 var skip: i64 = 0
648 if sj_vlen(nm) == 1 { if nm[0] == (RM_LS_DOT as u8) { skip = 1 } }
649 if sj_vlen(nm) == 2 { if nm[0] == (RM_LS_DOT as u8) { if nm[1] == (RM_LS_DOT as u8) { skip = 1 } } }
650 if skip == 0 {
651 var fo: i64 = sj_cat(fp, 0, cur)
652 if fo > 0 { if fp[fo-1] != (RM_LS_SLASH as u8) { fp[fo] = RM_LS_SLASH as u8; fo = fo + 1 } }
653 fo = sj_cat(fp, fo, nm)
654 fp[fo] = 0 as u8
655 if rm_ls_ends(nm, sfx) == 1 {
656 if nf >= RM_LS_MAXFILES { wcx[3] = 1 } else {
657 let fc: *u8 = rm_ls_cell(parena, nf, RM_LS_PATH)
658 var q2: i64 = sj_cat(fc, 0, fp)
659 fc[q2] = 0 as u8
660 nf = nf + 1
661 }
662 } else {
663 var isd: i64 = 0
664 if dt == RM_LS_DT_DIR { isd = 1 }
665 if dt == RM_LS_DT_UNKNOWN { isd = rm_ls_isdir(fp, pbuf) }
666 if isd == 1 {
667 if sn >= RM_LS_MAXDIRS { wcx[2] = 1 } else {
668 let sc: *u8 = rm_ls_cell(stk, sn, RM_LS_PATH)
669 var q3: i64 = sj_cat(sc, 0, fp)
670 sc[q3] = 0 as u8
671 sn = sn + 1
672 }
673 } else { wcx[4] = wcx[4] + 1 }
674 }
675 }
676 off = off + dirent_reclen(rec)
677 }
678 }
679 }
680 sys_close(fd)
681 }
682 }
683 wcx[1] = nf
684 sys_munmap(stk, RM_LS_MAXDIRS * RM_LS_PATH)
685 sys_munmap(dbuf, RM_LS_DIRBUF)
686 sys_munmap(pbuf, RM_LS_DIRBUF)
687 return nf
688}
689func rm_ls_row(d: *u8, p: i64, tag: *u8, ar: *u8, off: i64, ln: i64) -> i64 {
690 var o: i64 = sj_cat(d, p, tag)
691 d[o] = 32 as u8
692 o = o + 1
693 var k: i64 = 0
694 while k < ln { d[o] = ar[off+k]; o = o + 1; k = k + 1 }
695 return o
696}
697// cx[RM_LS_CX_LOST]=lost cx[RM_LS_CX_EXECT]=exec_tools cx[RM_LS_CX_CAPS]=any cap hit (1 = REFUSE)
698// returns report bytes, or -1 no transcripts read, -2 registry unreadable, -4 root unreadable.
699func rm_lostset(tdir: *u8, conf: *u8, since: *u8, d: *u8, cx: *i64) -> i64 {
700 var ci: i64 = 0
701 while ci < RM_LS_CX { cx[ci] = 0; ci = ci + 1 }
702 let clen: *i64 = sys_mmap(16) as *i64
703 let cb: *u8 = sys_map_file(conf, clen)
704 if (cb as i64) == 0 { return 0 - 2 }
705 let cn: i64 = clen[0]
706 let parena: *u8 = sys_mmap(RM_LS_MAXFILES * RM_LS_PATH)
707 let wcx: *i64 = sys_mmap(8 * RM_LS_CX) as *i64
708 let nfiles: i64 = rm_ls_walk(tdir, parena, wcx)
709 if wcx[0] == 0 { return 0 - 4 }
710 // ---- global tables (allocated ONCE, never inside the per-file loop) ----
711 let tar: *u8 = sys_mmap(RM_LS_MAXTOOLS * RM_LS_NAMECELL)
712 let toff: *i64 = sys_mmap(8 * RM_LS_MAXTOOLS) as *i64
713 let tlen: *i64 = sys_mmap(8 * RM_LS_MAXTOOLS) as *i64
714 let texe: *i64 = sys_mmap(8 * RM_LS_MAXTOOLS) as *i64
715 let tden: *i64 = sys_mmap(8 * RM_LS_MAXTOOLS) as *i64
716 let tunk: *i64 = sys_mmap(8 * RM_LS_MAXTOOLS) as *i64
717 let tlast: *u8 = sys_mmap(RM_LS_MAXTOOLS * RM_LS_TSCELL)
718 let nt: *i64 = sys_mmap(16) as *i64
719 let gar: *u8 = sys_mmap(RM_LS_GIDMAX * RM_LS_IDCELL)
720 let gsl: *i64 = sys_mmap(8 * RM_LS_GIDSLOTS) as *i64
721 let ng: *i64 = sys_mmap(16) as *i64
722 let ioff: *i64 = sys_mmap(8 * RM_LS_IDSLOTS) as *i64
723 let iln: *i64 = sys_mmap(8 * RM_LS_IDSLOTS) as *i64
724 let ign: *i64 = sys_mmap(8 * RM_LS_IDSLOTS) as *i64
725 let inm: *i64 = sys_mmap(8 * RM_LS_IDSLOTS) as *i64
726 let flen: *i64 = sys_mmap(16) as *i64
727 let sp: *i64 = sys_mmap(16) as *i64
728 let pfx: *u8 = "mcp__nishi__" as *u8
729 let pfxl: i64 = sj_vlen(pfx)
730 let LIT_TU: *u8 = "\"type\":\"tool_use\"" as *u8
731 let LIT_ID: *u8 = "\"id\":\"" as *u8
732 let LIT_NM: *u8 = "\"name\":\"" as *u8
733 let LIT_TR: *u8 = "\"tool_use_id\":\"" as *u8
734 let LIT_TS: *u8 = "\"timestamp\":\"" as *u8
735 let LIT_MT: *u8 = "\"mcpMeta\":{\"_meta\":{\"exit_code\":" as *u8
736 let LIT_D1: *u8 = "capability denied" as *u8
737 let LIT_D2: *u8 = "not on GREEN execution allowlist" as *u8
738 let LIT_D3: *u8 = "No such tool available" as *u8
739 var scanned: i64 = 0
740 var unreadable: i64 = 0
741 var tbytes: i64 = 0
742 var recs: i64 = 0
743 var caps: i64 = 0
744 var tu_cap: i64 = 0
745 var tu_noid: i64 = 0
746 var mixed: i64 = 0
747 var paired: i64 = 0
748 var counted: i64 = 0
749 var dupes: i64 = 0
750 var outwin: i64 = 0
751 var c_exec: i64 = 0
752 var c_den: i64 = 0
753 var c_unk: i64 = 0
754 var gen: i64 = 0
755 var fi: i64 = 0
756 while fi < nfiles {
757 let path: *u8 = rm_ls_cell(parena, fi, RM_LS_PATH)
758 let q: *u8 = sys_map_file(path, flen)
759 if (q as i64) == 0 { unreadable = unreadable + 1 } else {
760 let n: i64 = flen[0]
761 scanned = scanned + 1
762 tbytes = tbytes + n
763 gen = gen + 1
764 var ls: i64 = 0
765 var r_ts: i64 = 0 - 1
766 var r_ids: i64 = 0 - 1
767 var r_ide: i64 = 0 - 1
768 var r_meta: i64 = 0
769 var r_use: i64 = 0
770 var i: i64 = 0
771 var go: i64 = 1
772 while go == 1 {
773 var atend: i64 = 0
774 if i >= n { atend = 1 }
775 var eol: i64 = 0
776 if atend == 0 { if (q[i] as i64) == RM_LS_NL { eol = 1 } }
777 if atend == 1 { eol = 1 }
778 if eol == 1 {
779 if i > ls {
780 recs = recs + 1
781 if r_ids >= 0 {
782 if r_use > 0 { mixed = mixed + 1 } else {
783 let sl: i64 = rm_ls_probe(q, r_ids, r_ide, ioff, iln, ign, gen)
784 var nmi: i64 = 0 - 1
785 if sl >= 0 { if ign[sl] == gen { nmi = inm[sl] } }
786 if nmi >= 0 {
787 paired = paired + 1
788 if rm_ls_ts_ge(q, r_ts, i, since) == 0 { outwin = outwin + 1 } else {
789 let nw: i64 = rm_ls_gid_add(q, r_ids, r_ide, gar, gsl, ng)
790 if nw == (0 - 2) { caps = 1 } else {
791 if nw == 0 { dupes = dupes + 1 } else {
792 counted = counted + 1
793 if r_meta == 1 {
794 c_exec = c_exec + 1
795 texe[nmi] = texe[nmi] + 1
796 if r_ts >= 0 {
797 let tc: *u8 = rm_ls_cell(tlast, nmi, RM_LS_TSCELL)
798 if rm_ls_ts_ge(q, r_ts, i, tc) == 1 {
799 var k2: i64 = 0
800 while k2 < RM_LS_TSCELL - 1 {
801 if r_ts + k2 >= i { tc[k2] = 0 as u8; k2 = RM_LS_TSCELL - 1 } else {
802 if (q[r_ts+k2] as i64) == RM_LS_QUOTE { tc[k2] = 0 as u8; k2 = RM_LS_TSCELL - 1 } else {
803 tc[k2] = q[r_ts+k2]; k2 = k2 + 1
804 }
805 }
806 }
807 tc[RM_LS_TSCELL - 1] = 0 as u8
808 }
809 }
810 } else {
811 var dend: i64 = r_ide + RM_LS_DENYSCAN
812 if dend > i { dend = i }
813 var den: i64 = 0
814 if rm_ls_find_nl(q, r_ide, dend, LIT_D1) >= 0 { den = 1 }
815 if rm_ls_find_nl(q, r_ide, dend, LIT_D2) >= 0 { den = 1 }
816 if rm_ls_find_nl(q, r_ide, dend, LIT_D3) >= 0 { den = 1 }
817 if den == 1 { c_den = c_den + 1; tden[nmi] = tden[nmi] + 1 } else { c_unk = c_unk + 1; tunk[nmi] = tunk[nmi] + 1 }
818 }
819 }
820 }
821 }
822 }
823 }
824 }
825 }
826 r_ts = 0 - 1
827 r_ids = 0 - 1
828 r_ide = 0 - 1
829 r_meta = 0
830 r_use = 0
831 ls = i + 1
832 if atend == 1 { go = 0 } else { i = i + 1 }
833 } else {
834 var adv: i64 = 1
835 if (q[i] as i64) == RM_LS_QUOTE {
836 var c1: i64 = 0 - 1
837 if i + 1 < n { c1 = q[i+1] as i64 }
838 if c1 == RM_LS_CH_T {
839 if rm_ls_at(q, i, n, LIT_TU) == 1 {
840 r_use = r_use + 1
841 var send: i64 = i + RM_LS_SCAN
842 if send > n { send = n }
843 let ip: i64 = rm_ls_find_nl(q, i, send, LIT_ID)
844 let np2: i64 = rm_ls_find_nl(q, i, send, LIT_NM)
845 if ip < 0 { tu_noid = tu_noid + 1 } else {
846 if np2 < 0 { tu_noid = tu_noid + 1 } else {
847 var ivs: i64 = ip + sj_vlen(LIT_ID)
848 var ive: i64 = ivs
849 var g2: i64 = 1
850 while g2 == 1 { if ive >= send { g2 = 0 } else { if (q[ive] as i64) == RM_LS_QUOTE { g2 = 0 } else { ive = ive + 1 } } }
851 var nvs: i64 = np2 + sj_vlen(LIT_NM)
852 var nve: i64 = nvs
853 var g3: i64 = 1
854 while g3 == 1 { if nve >= send { g3 = 0 } else { if (q[nve] as i64) == RM_LS_QUOTE { g3 = 0 } else { nve = nve + 1 } } }
855 if rm_ls_at(q, nvs, nve, pfx) == 1 {
856 let ti: i64 = rm_ls_tintern(q, nvs + pfxl, nve, tar, toff, tlen, nt)
857 if ti == (0 - 2) { caps = 1 } else {
858 if ti >= 0 {
859 tu_cap = tu_cap + 1
860 let sl2: i64 = rm_ls_probe(q, ivs, ive, ioff, iln, ign, gen)
861 if sl2 >= 0 { ioff[sl2] = ivs; iln[sl2] = ive - ivs; ign[sl2] = gen; inm[sl2] = ti }
862 }
863 }
864 }
865 }
866 }
867 adv = sj_vlen(LIT_TU)
868 } else {
869 if rm_ls_at(q, i, n, LIT_TR) == 1 {
870 if r_ids < 0 {
871 var vs: i64 = i + sj_vlen(LIT_TR)
872 var ve: i64 = vs
873 var g4: i64 = 1
874 while g4 == 1 { if ve >= n { g4 = 0 } else { if (q[ve] as i64) == RM_LS_QUOTE { g4 = 0 } else { if (q[ve] as i64) == RM_LS_NL { g4 = 0 } else { ve = ve + 1 } } } }
875 r_ids = vs
876 r_ide = ve
877 }
878 adv = sj_vlen(LIT_TR)
879 } else {
880 if rm_ls_at(q, i, n, LIT_TS) == 1 {
881 if r_ts < 0 { r_ts = i + sj_vlen(LIT_TS) }
882 adv = sj_vlen(LIT_TS)
883 }
884 }
885 }
886 } else {
887 if c1 == RM_LS_CH_M {
888 if rm_ls_at(q, i, n, LIT_MT) == 1 { r_meta = 1; adv = sj_vlen(LIT_MT) }
889 }
890 }
891 }
892 i = i + adv
893 }
894 }
895 sys_munmap(q, n)
896 }
897 fi = fi + 1
898 }
899 if wcx[2] == 1 { caps = 1 }
900 if wcx[3] == 1 { caps = 1 }
901 // ---- the JOIN: execution evidence is the POPULATION, the registry is only the TEST ----
902 var exect: i64 = 0
903 var rgreen: i64 = 0
904 var rnot: i64 = 0
905 var lost: i64 = 0
906 var denonly: i64 = 0
907 var unkonly: i64 = 0
908 let rst: *i64 = sys_mmap(8 * RM_LS_MAXTOOLS) as *i64
909 var t: i64 = 0
910 while t < nt[0] {
911 rst[t] = rm_ls_rowstate(cb, cn, tar, toff[t], tlen[t], sp)
912 if texe[t] > 0 {
913 exect = exect + 1
914 if rst[t] == 2 { rgreen = rgreen + 1 } else { if rst[t] == 1 { rnot = rnot + 1 } else { lost = lost + 1 } }
915 } else {
916 if tden[t] > 0 { denonly = denonly + 1 } else { if tunk[t] > 0 { unkonly = unkonly + 1 } }
917 }
918 t = t + 1
919 }
920 var p: i64 = 0
921 p = sj_cat(d, p, "# NX-LOSTSET v=1 tool=nx_registrymine averb=lostset\n" as *u8)
922 p = sj_cat(d, p, "# ROOT " as *u8); p = sj_cat(d, p, tdir)
923 p = sj_cat(d, p, " REGISTRY " as *u8); p = sj_cat(d, p, conf)
924 p = sj_cat(d, p, " registry_bytes=" as *u8); p = sj_catn(d, p, cn)
925 p = sj_cat(d, p, " SINCE " as *u8)
926 if sj_vlen(since) == 0 { p = sj_cat(d, p, "(all-time)" as *u8) } else { p = sj_cat(d, p, since) }
927 d[p] = RM_LS_NL as u8; p = p + 1
928 p = sj_cat(d, p, "# ENVELOPE dirs=" as *u8); p = sj_catn(d, p, wcx[0])
929 p = sj_cat(d, p, " files_found=" as *u8); p = sj_catn(d, p, nfiles)
930 p = sj_cat(d, p, " files_scanned=" as *u8); p = sj_catn(d, p, scanned)
931 p = sj_cat(d, p, " files_unreadable=" as *u8); p = sj_catn(d, p, unreadable)
932 p = sj_cat(d, p, " bytes=" as *u8); p = sj_catn(d, p, tbytes)
933 p = sj_cat(d, p, " records=" as *u8); p = sj_catn(d, p, recs)
934 p = sj_cat(d, p, " nonwalkable_entries=" as *u8); p = sj_catn(d, p, wcx[4])
935 d[p] = RM_LS_NL as u8; p = p + 1
936 p = sj_cat(d, p, "# CALLS tooluse_nishi=" as *u8); p = sj_catn(d, p, tu_cap)
937 p = sj_cat(d, p, " tooluse_unparsed=" as *u8); p = sj_catn(d, p, tu_noid)
938 p = sj_cat(d, p, " mixed_records=" as *u8); p = sj_catn(d, p, mixed)
939 p = sj_cat(d, p, " results_paired=" as *u8); p = sj_catn(d, p, paired)
940 p = sj_cat(d, p, " results_out_of_window=" as *u8); p = sj_catn(d, p, outwin)
941 p = sj_cat(d, p, " results_duplicate=" as *u8); p = sj_catn(d, p, dupes)
942 p = sj_cat(d, p, " results_counted=" as *u8); p = sj_catn(d, p, counted)
943 d[p] = RM_LS_NL as u8; p = p + 1
944 p = sj_cat(d, p, "# CLASS exec=" as *u8); p = sj_catn(d, p, c_exec)
945 p = sj_cat(d, p, " denied=" as *u8); p = sj_catn(d, p, c_den)
946 p = sj_cat(d, p, " unknown=" as *u8); p = sj_catn(d, p, c_unk)
947 p = sj_cat(d, p, " sum=" as *u8); p = sj_catn(d, p, c_exec + c_den + c_unk)
948 p = sj_cat(d, p, " calls_sum_ok=" as *u8)
949 if c_exec + c_den + c_unk == counted { p = sj_catn(d, p, 1) } else { p = sj_catn(d, p, 0) }
950 d[p] = RM_LS_NL as u8; p = p + 1
951 // ---- the WORKLIST: every row, never a top-N. A count without a worklist is not actionable, and a
952 // worklist without the reason is one step short -- so each row carries its own evidence.
953 var t2: i64 = 0
954 while t2 < nt[0] {
955 if texe[t2] > 0 {
956 var tag: *u8 = "OK-ROW" as *u8
957 if rst[t2] == 1 { tag = "ROW-NOT-GREEN" as *u8 }
958 if rst[t2] == 0 { tag = "LOST" as *u8 }
959 p = rm_ls_row(d, p, tag, tar, toff[t2], tlen[t2])
960 p = sj_cat(d, p, " exec=" as *u8); p = sj_catn(d, p, texe[t2])
961 p = sj_cat(d, p, " denied=" as *u8); p = sj_catn(d, p, tden[t2])
962 p = sj_cat(d, p, " unknown=" as *u8); p = sj_catn(d, p, tunk[t2])
963 p = sj_cat(d, p, " last=" as *u8)
964 let tc2: *u8 = rm_ls_cell(tlast, t2, RM_LS_TSCELL)
965 if tc2[0] == (0 as u8) { p = sj_cat(d, p, "-" as *u8) } else { p = sj_cat(d, p, tc2) }
966 if rst[t2] == 0 { p = sj_cat(d, p, " REMEDY /api/tools/register name=&elf=&confirm=yes" as *u8) }
967 d[p] = RM_LS_NL as u8; p = p + 1
968 } else {
969 if tden[t2] > 0 {
970 p = rm_ls_row(d, p, "DENIED-ONLY" as *u8, tar, toff[t2], tlen[t2])
971 p = sj_cat(d, p, " denied=" as *u8); p = sj_catn(d, p, tden[t2])
972 p = sj_cat(d, p, " row=" as *u8); p = sj_catn(d, p, rst[t2])
973 p = sj_cat(d, p, " NOTE a refusal is cap coverage, not clobber fallout" as *u8)
974 d[p] = RM_LS_NL as u8; p = p + 1
975 } else {
976 if tunk[t2] > 0 {
977 p = rm_ls_row(d, p, "UNKNOWN-ONLY" as *u8, tar, toff[t2], tlen[t2])
978 p = sj_cat(d, p, " unknown=" as *u8); p = sj_catn(d, p, tunk[t2])
979 p = sj_cat(d, p, " row=" as *u8); p = sj_catn(d, p, rst[t2])
980 p = sj_cat(d, p, " NOTE abstain, not acquit" as *u8)
981 d[p] = RM_LS_NL as u8; p = p + 1
982 }
983 }
984 }
985 t2 = t2 + 1
986 }
987 p = sj_cat(d, p, "# PARTITION exec_tools=" as *u8); p = sj_catn(d, p, exect)
988 p = sj_cat(d, p, " row_green=" as *u8); p = sj_catn(d, p, rgreen)
989 p = sj_cat(d, p, " row_notgreen=" as *u8); p = sj_catn(d, p, rnot)
990 p = sj_cat(d, p, " lost=" as *u8); p = sj_catn(d, p, lost)
991 p = sj_cat(d, p, " sum=" as *u8); p = sj_catn(d, p, rgreen + rnot + lost)
992 p = sj_cat(d, p, " sum_ok=" as *u8)
993 if rgreen + rnot + lost == exect { p = sj_catn(d, p, 1) } else { p = sj_catn(d, p, 0) }
994 d[p] = RM_LS_NL as u8; p = p + 1
995 p = sj_cat(d, p, "# SIDE denied_only_tools=" as *u8); p = sj_catn(d, p, denonly)
996 p = sj_cat(d, p, " unknown_only_tools=" as *u8); p = sj_catn(d, p, unkonly)
997 p = sj_cat(d, p, " tools_seen=" as *u8); p = sj_catn(d, p, nt[0])
998 p = sj_cat(d, p, " ids_interned=" as *u8); p = sj_catn(d, p, ng[0])
999 d[p] = RM_LS_NL as u8; p = p + 1
1000 p = sj_cat(d, p, "# CAPS dirs_capped=" as *u8); p = sj_catn(d, p, wcx[2])
1001 p = sj_cat(d, p, " files_capped=" as *u8); p = sj_catn(d, p, wcx[3])
1002 p = sj_cat(d, p, " any_cap_hit=" as *u8); p = sj_catn(d, p, caps)
1003 p = sj_cat(d, p, " floor_not_total=" as *u8); p = sj_catn(d, p, caps)
1004 d[p] = RM_LS_NL as u8; p = p + 1
1005 p = sj_cat(d, p, "LOSTSET lost=" as *u8); p = sj_catn(d, p, lost)
1006 p = sj_cat(d, p, " exec_tools=" as *u8); p = sj_catn(d, p, exect)
1007 p = sj_cat(d, p, " files_scanned=" as *u8); p = sj_catn(d, p, scanned)
1008 p = sj_cat(d, p, " sum_ok=" as *u8)
1009 if rgreen + rnot + lost == exect { p = sj_catn(d, p, 1) } else { p = sj_catn(d, p, 0) }
1010 d[p] = RM_LS_NL as u8; p = p + 1
1011 cx[RM_LS_CX_LOST] = lost
1012 cx[RM_LS_CX_EXECT] = exect
1013 cx[RM_LS_CX_CAPS] = caps
1014 if scanned == 0 { return 0 - 1 }
1015 return p
1016}
1017
1018func main(argc: i64, argv: *i64) -> i64 {
1019 if argc < 3 { sj_puts("usage: nx_registrymine {mine <source> [loader|-] [minsup] | lostset <transcripts-dir> <tool_allowlist.conf> [since-iso] | selftest <scratch-prefix>}\n" as *u8); sys_exit(2); return 2 }
1020 let verb: *u8 = argv[1] as *u8
1021 let vl: i64 = sj_vlen(verb)
1022 if sj_lit_eq(verb, 0, vl, "selftest" as *u8) == 1 {
1023 let rc: i64 = rm_selftest(argv[2] as *u8)
1024 sys_exit(rc)
1025 return rc
1026 }
1027 if sj_lit_eq(verb, 0, vl, "lostset" as *u8) == 1 {
1028 if argc < 4 { sj_puts("usage: nx_registrymine lostset <transcripts-dir> <tool_allowlist.conf> [since-iso]\n" as *u8); sys_exit(2); return 2 }
1029 let since: *u8 = sys_mmap(RM_LS_TSCELL * 2)
1030 var so: i64 = 0
1031 if argc >= 5 { so = sj_cat(since, 0, argv[4] as *u8) }
1032 since[so] = 0 as u8
1033 let d: *u8 = sys_mmap(RM_LS_OUT)
1034 let cx: *i64 = sys_mmap(8 * RM_LS_CX) as *i64
1035 let dl: i64 = rm_lostset(argv[2] as *u8, argv[3] as *u8, since, d, cx)
1036 if dl == (0 - 2) { sj_puts("REFUSED registry unreadable -- pass the tool_allowlist.conf path; ABSENCE OF THE TEST IS NOT ABSENCE OF THE ROW\n" as *u8); sys_exit(3); return 3 }
1037 if dl == (0 - 4) { sj_puts("REFUSED transcripts root unreadable -- an unwalkable root is UNPROVEN, never zero lost\n" as *u8); sys_exit(3); return 3 }
1038 if dl < 0 { sj_puts("REFUSED no transcript scanned -- a zero-subject run cannot acquit a registry\n" as *u8); sys_exit(3); return 3 }
1039 sys_write(1, d, dl)
1040 if cx[RM_LS_CX_CAPS] == 1 { sj_puts("REFUSED a table filled: this report is a FLOOR, not a total\n" as *u8); sys_exit(3); return 3 }
1041 sys_exit(0)
1042 return 0
1043 }
1044 if sj_lit_eq(verb, 0, vl, "mine" as *u8) == 1 {
1045 let loader: *u8 = sys_mmap(128)
1046 var lo: i64 = 0
1047 if argc >= 4 { lo = sj_cat(loader, 0, argv[3] as *u8) } else { lo = sj_cat(loader, 0, "nx_store_put" as *u8) }
1048 loader[lo] = 0 as u8
1049 var minsup: i64 = 1
1050 if argc >= 5 { let mz: i64 = sj_atoi_z(argv[4] as *u8); if mz > 0 { minsup = mz } }
1051 let d: *u8 = sys_mmap(RM_OUT)
1052 let dl: i64 = rm_mine_json(argv[2] as *u8, loader, minsup, d)
1053 if dl == (0 - 2) { sj_puts("REFUSED loader not in the allowlist\n" as *u8); sys_exit(3); return 3 }
1054 if dl == (0 - 3) { sj_puts("REFUSED loader exited nonzero\n" as *u8); sys_exit(3); return 3 }
1055 if dl < 0 { sj_puts("REFUSED source missing or empty\n" as *u8); sys_exit(3); return 3 }
1056 sys_write(1, d, dl)
1057 sys_exit(0)
1058 return 0
1059 }
1060 sj_puts("unknown verb\n" as *u8)
1061 sys_exit(2)
1062 return 2
1063}