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}