code wiki / _hdl_build / nx_minecov.nx
nx_minecov.nx source
↩ module page · 325 lines · 14518 B
1// nx_minecov.nx -- MINER CLASS-COVERAGE CENSUS (miner-sota F969/MS06, 2026-07-23).
2// The operator's "features and bugs and capabilities and harnesses and workflows and agents" clause,
3// MECHANIZED: a data-driven class table (knowledge/status/minecov_classes.conf, hot-read, rule-11
4// tunable) declares every artifact class we want brought inside; the census VERIFIES each row by
5// actually READING its source (journal lines, or a seg-store plane loaded through the ALLOWLIST-
6// RESOLVED loader) and reports TWO gauges: coverage (a reader exists AND evidence exists) and mined
7// (that reader actually mines patterns rather than merely listing/deriving). A class can never be
8// "covered" by declaration alone -- no evidence, no credit; and no reader, no credit. The GAP list
9// IS the build queue. Composes nx_sovjson_lib (sj_*). Read-only. No hw writes (Rule 26).
10// census <classconf> [loader] -> JSON per-class rows + coverage_permil/mined_permil + gaps
11// selftest <scratch-prefix> -> gate T1..T8 (unique per-run scratch)
12// conf cols: id TAB class TAB kind(jrnl|plane|none) TAB source TAB reader(- = none) TAB mined(0|1) TAB note
13// license_tier: ORIGINAL
14import "nx_sovjson_lib.nx"
15import "nx_syscalls.nx"
16import "nx_gate_verdict.nx"
17import "nx_tool_run.nx"
18
19const MC_CONF: i64 = 65536
20const MC_CAP: i64 = 4194304
21const MC_OUT: i64 = 65536
22const MC_PATH: i64 = 512
23const MC_ROWS: i64 = 64
24const MC_MODE_644: i64 = 420
25const MC_PERMIL: i64 = 1000
26const MC_ALLOW_BUF: i64 = 131072
27const MC_NOTE_MAX: i64 = 160
28
29func mc_read(path: *u8, buf: *u8, cap: i64) -> i64 {
30 let fd: i64 = sys_openat_rd(path)
31 if fd < 0 { return -1 }
32 var n: i64 = 0
33 var go: i64 = 1
34 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 } }
35 sys_close(fd)
36 return n
37}
38func mc_find(q: *u8, n: i64, lit: *u8) -> i64 {
39 let ll: i64 = sj_vlen(lit)
40 if ll == 0 { return 0 }
41 var i: i64 = 0
42 while i + ll <= n {
43 var k: i64 = 0
44 var ok: i64 = 1
45 while k < ll { if q[i+k] != lit[k] { ok = 0; k = ll } else { k = k + 1 } }
46 if ok == 1 { return 1 }
47 i = i + 1
48 }
49 return 0
50}
51// count non-empty, non-comment lines (the honest row count for journals AND plane dumps)
52func mc_count_lines(q: *u8, n: i64) -> i64 {
53 var c: i64 = 0
54 var i: i64 = 0
55 while i < n {
56 let le: i64 = sj_le(q, i, n)
57 if le > i { if q[i] != (35 as u8) { c = c + 1 } }
58 i = le + 1
59 }
60 return c
61}
62// ⚠rule-15: this allowlist resolver is now the THIRD inline copy (nx_actlog al_allow_path,
63// nx_claude_harvest ch_allow_path). Extraction onto nx_sovjson_lib is filed to the local-maker
64// dedup queue (dedupq-) per the engine-shift doctrine -- NOT hand-migrated mid-round.
65// DELEGATES to the shared base (rule-15 extraction 2026-07-23) -- was the 3rd of 7 inline copies
66func mc_allow_path(name: *u8, outp: *u8) -> i64 { return sj_allow_path(name, outp) }
67func mc_key(d: *u8, o: i64, name: *u8) -> i64 {
68 d[o] = 34 as u8
69 var p: i64 = o + 1
70 p = sj_cat(d, p, name)
71 d[p] = 34 as u8
72 p = p + 1
73 d[p] = 58 as u8
74 p = p + 1
75 return p
76}
77func mc_qspan(d: *u8, o: i64, q: *u8, s: i64, e: i64, maxb: i64) -> i64 {
78 var p: i64 = o
79 d[p] = 34 as u8; p = p + 1
80 p = sj_cat_esc(d, p, q, s, e, maxb)
81 d[p] = 34 as u8; p = p + 1
82 return p
83}
84// evaluate one class source -> rows seen. tcx[0]=truncated tcx[1]=kind_ok
85func mc_source_rows(cq: *u8, ks: i64, ke: i64, src: *u8, lp: *u8, lok: i64, tcx: *i64) -> i64 {
86 tcx[0] = 0
87 tcx[1] = 1
88 if sj_lit_eq(cq, ks, ke, "jrnl" as *u8) == 1 {
89 let b: *u8 = sys_mmap(MC_CAP)
90 let n: i64 = mc_read(src, b, MC_CAP - 8)
91 if n <= 0 { return 0 }
92 if n >= MC_CAP - 8 { tcx[0] = 1 }
93 return mc_count_lines(b, n)
94 }
95 if sj_lit_eq(cq, ks, ke, "plane" as *u8) == 1 {
96 if lok == 0 { tcx[1] = 0; return 0 }
97 let av: *i64 = sys_mmap(64) as *i64
98 av[0] = lp as i64
99 av[1] = src as i64
100 av[2] = "load" as *u8 as i64
101 av[3] = 0
102 let cout: *u8 = sys_mmap(MC_CAP)
103 let cl: *i64 = sys_mmap(16) as *i64
104 let ex: i64 = tr_run_capture(lp, av, cout, MC_CAP - 8, cl)
105 if ex != 0 { return 0 }
106 if cl[0] >= MC_CAP - 8 { tcx[0] = 1 }
107 return mc_count_lines(cout, cl[0])
108 }
109 if sj_lit_eq(cq, ks, ke, "none" as *u8) == 1 { return 0 }
110 tcx[1] = 0
111 return 0
112}
113// the census. returns emitted bytes, or -1 when the class table is missing/empty (fail closed).
114func mc_census(conf: *u8, loader: *u8, d: *u8) -> i64 {
115 let cb: *u8 = sys_mmap(MC_CONF)
116 let cn: i64 = mc_read(conf, cb, MC_CONF - 8)
117 if cn <= 0 { return -1 }
118 let lp: *u8 = sys_mmap(MC_PATH)
119 let lok: i64 = mc_allow_path(loader, lp)
120 let sp: *i64 = sys_mmap(16) as *i64
121 let srcb: *u8 = sys_mmap(MC_PATH)
122 let tcx: *i64 = sys_mmap(16) as *i64
123 var p: i64 = 0
124 d[p] = 123 as u8; p = p + 1
125 p = mc_key(d, p, "v" as *u8); p = sj_catn(d, p, 1); d[p] = 44 as u8; p = p + 1
126 p = mc_key(d, p, "tool" as *u8)
127 d[p] = 34 as u8; p = p + 1
128 p = sj_cat(d, p, "nx_minecov" as *u8)
129 d[p] = 34 as u8; p = p + 1
130 d[p] = 44 as u8; p = p + 1
131 p = mc_key(d, p, "averb" as *u8)
132 d[p] = 34 as u8; p = p + 1
133 p = sj_cat(d, p, "census" as *u8)
134 d[p] = 34 as u8; p = p + 1
135 d[p] = 44 as u8; p = p + 1
136 p = mc_key(d, p, "conf" as *u8)
137 p = mc_qspan(d, p, conf, 0, sj_vlen(conf), MC_NOTE_MAX)
138 d[p] = 44 as u8; p = p + 1
139 p = mc_key(d, p, "loader_resolved" as *u8); p = sj_catn(d, p, lok); d[p] = 44 as u8; p = p + 1
140 p = mc_key(d, p, "classes_rows" as *u8)
141 d[p] = 91 as u8; p = p + 1
142 var classes: i64 = 0
143 var covered: i64 = 0
144 var minedn: i64 = 0
145 var kunk: i64 = 0
146 var shown: i64 = 0
147 var rcapped: i64 = 0
148 var efirst: i64 = 1
149 var i: i64 = 0
150 while i < cn {
151 let le: i64 = sj_le(cb, i, cn)
152 var ok: i64 = 0
153 if le > i { if cb[i] != (35 as u8) { if sj_col(cb, i, le, 5, sp) == 1 { ok = 1 } } }
154 if ok == 1 {
155 classes = classes + 1
156 sj_col(cb, i, le, 3, sp)
157 var k: i64 = 0
158 while sp[0]+k < sp[1] { if k < MC_PATH - 2 { srcb[k] = cb[sp[0]+k] } k = k + 1 }
159 srcb[k] = 0 as u8
160 let kst: *i64 = sys_mmap(16) as *i64
161 sj_col(cb, i, le, 2, kst)
162 let rows: i64 = mc_source_rows(cb, kst[0], kst[1], srcb, lp, lok, tcx)
163 if tcx[1] == 0 { kunk = kunk + 1 }
164 sj_col(cb, i, le, 4, sp)
165 var hasreader: i64 = 1
166 if sj_lit_eq(cb, sp[0], sp[1], "-" as *u8) == 1 { hasreader = 0 }
167 let rs: i64 = sp[0]
168 let re: i64 = sp[1]
169 var cov: i64 = 0
170 if hasreader == 1 { if rows > 0 { cov = 1 } }
171 let mst: *i64 = sys_mmap(16) as *i64
172 sj_col(cb, i, le, 5, mst)
173 let mdecl: i64 = sj_atoi_span(cb, mst[0], mst[1])
174 var mnd: i64 = 0
175 if cov == 1 { if mdecl == 1 { mnd = 1 } }
176 covered = covered + cov
177 minedn = minedn + mnd
178 if shown >= MC_ROWS { rcapped = 1 } else {
179 if efirst == 0 { d[p] = 44 as u8; p = p + 1 }
180 efirst = 0
181 d[p] = 123 as u8; p = p + 1
182 p = mc_key(d, p, "id" as *u8)
183 sj_col(cb, i, le, 0, sp)
184 p = mc_qspan(d, p, cb, sp[0], sp[1], MC_NOTE_MAX)
185 d[p] = 44 as u8; p = p + 1
186 p = mc_key(d, p, "covered" as *u8); p = sj_catn(d, p, cov); d[p] = 44 as u8; p = p + 1
187 p = mc_key(d, p, "mined" as *u8); p = sj_catn(d, p, mnd); d[p] = 44 as u8; p = p + 1
188 p = mc_key(d, p, "rows" as *u8); p = sj_catn(d, p, rows); d[p] = 44 as u8; p = p + 1
189 p = mc_key(d, p, "truncated" as *u8); p = sj_catn(d, p, tcx[0]); d[p] = 44 as u8; p = p + 1
190 p = mc_key(d, p, "kind_ok" as *u8); p = sj_catn(d, p, tcx[1]); d[p] = 44 as u8; p = p + 1
191 p = mc_key(d, p, "class" as *u8)
192 sj_col(cb, i, le, 1, sp)
193 p = mc_qspan(d, p, cb, sp[0], sp[1], MC_NOTE_MAX)
194 d[p] = 44 as u8; p = p + 1
195 p = mc_key(d, p, "reader" as *u8)
196 p = mc_qspan(d, p, cb, rs, re, MC_NOTE_MAX)
197 d[p] = 125 as u8; p = p + 1
198 shown = shown + 1
199 }
200 }
201 i = le + 1
202 }
203 d[p] = 93 as u8; p = p + 1
204 d[p] = 44 as u8; p = p + 1
205 var cperm: i64 = 0 - 1
206 var mperm: i64 = 0 - 1
207 if classes > 0 { cperm = covered * MC_PERMIL / classes; mperm = minedn * MC_PERMIL / classes }
208 p = mc_key(d, p, "classes" as *u8); p = sj_catn(d, p, classes); d[p] = 44 as u8; p = p + 1
209 p = mc_key(d, p, "covered" as *u8); p = sj_catn(d, p, covered); d[p] = 44 as u8; p = p + 1
210 p = mc_key(d, p, "mined" as *u8); p = sj_catn(d, p, minedn); d[p] = 44 as u8; p = p + 1
211 p = mc_key(d, p, "coverage_permil" as *u8); p = sj_catn(d, p, cperm); d[p] = 44 as u8; p = p + 1
212 p = mc_key(d, p, "mined_permil" as *u8); p = sj_catn(d, p, mperm); d[p] = 44 as u8; p = p + 1
213 p = mc_key(d, p, "kind_unknown" as *u8); p = sj_catn(d, p, kunk); d[p] = 44 as u8; p = p + 1
214 p = mc_key(d, p, "rows_capped" as *u8); p = sj_catn(d, p, rcapped)
215 d[p] = 125 as u8; p = p + 1
216 d[p] = 10 as u8; p = p + 1
217 return p
218}
219func mc_selftest(prefix: *u8) -> i64 {
220 let ctr: *i64 = gv_ctr()
221 gv_head("nx_minecov selftest -- class-coverage census teeth (evidence-or-no-credit)" as *u8)
222 let now: i64 = sys_now_realtime_sec()
223 let j1: *u8 = sys_mmap(MC_PATH)
224 var o: i64 = sj_cat(j1, 0, prefix)
225 o = sj_catn(j1, o, now)
226 o = sj_cat(j1, o, ".j1" as *u8)
227 j1[o] = 0 as u8
228 let miss: *u8 = sys_mmap(MC_PATH)
229 o = sj_cat(miss, 0, prefix)
230 o = sj_catn(miss, o, now)
231 o = sj_cat(miss, o, ".absent" as *u8)
232 miss[o] = 0 as u8
233 let cf: *u8 = sys_mmap(MC_PATH)
234 o = sj_cat(cf, 0, prefix)
235 o = sj_catn(cf, o, now)
236 o = sj_cat(cf, o, ".conf" as *u8)
237 cf[o] = 0 as u8
238 // j1 = 3 evidence lines
239 let jfd: i64 = sys_openat_append(j1, MC_MODE_644)
240 let lb: *u8 = sys_mmap(MC_PATH)
241 var lo: i64 = sj_cat(lb, 0, "e1\ne2\ne3\n" as *u8)
242 sys_write(jfd, lb, lo)
243 sys_close(jfd)
244 // fixture class table: F1 both / F2 reader-no-evidence / F3 evidence-no-reader / F4 bad kind / F5 covered-not-mined
245 let cfd: i64 = sys_openat_wr(cf, MC_MODE_644)
246 lo = sj_cat(lb, 0, "# fixture\n" as *u8)
247 sys_write(cfd, lb, lo)
248 lo = sj_cat(lb, 0, "F1\talpha\tjrnl\t" as *u8)
249 lo = sj_cat(lb, lo, j1)
250 lo = sj_cat(lb, lo, "\treader:x\t1\tboth\n" as *u8)
251 sys_write(cfd, lb, lo)
252 lo = sj_cat(lb, 0, "F2\tbeta\tjrnl\t" as *u8)
253 lo = sj_cat(lb, lo, miss)
254 lo = sj_cat(lb, lo, "\treader:y\t1\tdeclared reader no evidence\n" as *u8)
255 sys_write(cfd, lb, lo)
256 lo = sj_cat(lb, 0, "F3\tgamma\tjrnl\t" as *u8)
257 lo = sj_cat(lb, lo, j1)
258 lo = sj_cat(lb, lo, "\t-\t0\tevidence no reader\n" as *u8)
259 sys_write(cfd, lb, lo)
260 lo = sj_cat(lb, 0, "F4\tdelta\tbogus\t" as *u8)
261 lo = sj_cat(lb, lo, j1)
262 lo = sj_cat(lb, lo, "\treader:z\t1\tunknown kind\n" as *u8)
263 sys_write(cfd, lb, lo)
264 lo = sj_cat(lb, 0, "F5\teps\tjrnl\t" as *u8)
265 lo = sj_cat(lb, lo, j1)
266 lo = sj_cat(lb, lo, "\treader:w\t0\tcovered not mined\n" as *u8)
267 sys_write(cfd, lb, lo)
268 sys_close(cfd)
269 let d: *u8 = sys_mmap(MC_OUT)
270 // T1 missing class table fails closed
271 let r1: i64 = mc_census(miss, "nx_store_put" as *u8, d)
272 var ok1: i64 = 0
273 if r1 == (0 - 1) { ok1 = 1 }
274 gv_check("T1 missing class table refused (-1) fail closed" as *u8, ok1, ctr)
275 let dl: i64 = mc_census(cf, "nx_store_put" as *u8, d)
276 var ok2: i64 = 0
277 if dl > 0 { if mc_find(d, dl, "\"classes\":5" as *u8) == 1 { ok2 = 1 } }
278 gv_check("T2 counts exactly the 5 declared classes (comment skipped)" as *u8, ok2, ctr)
279 var ok3: i64 = 0
280 if mc_find(d, dl, "\"id\":\"F2\",\"covered\":0,\"mined\":0,\"rows\":0" as *u8) == 1 { ok3 = 1 }
281 gv_check("T3 declared reader with NO evidence earns no credit" as *u8, ok3, ctr)
282 var ok4: i64 = 0
283 if mc_find(d, dl, "\"id\":\"F3\",\"covered\":0,\"mined\":0,\"rows\":3" as *u8) == 1 { ok4 = 1 }
284 gv_check("T4 evidence with NO reader is a GAP not silent coverage" as *u8, ok4, ctr)
285 var ok5: i64 = 0
286 if mc_find(d, dl, "\"id\":\"F1\",\"covered\":1,\"mined\":1,\"rows\":3" as *u8) == 1 { ok5 = 1 }
287 gv_check("T5 reader plus evidence counts covered and mined" as *u8, ok5, ctr)
288 var ok6: i64 = 0
289 if mc_find(d, dl, "\"coverage_permil\":400" as *u8) == 1 { ok6 = 1 }
290 gv_check("T6 coverage_permil exact 400 (2 of 5)" as *u8, ok6, ctr)
291 var ok7: i64 = 0
292 if mc_find(d, dl, "\"mined_permil\":200" as *u8) == 1 { if mc_find(d, dl, "\"id\":\"F5\",\"covered\":1,\"mined\":0" as *u8) == 1 { ok7 = 1 } }
293 gv_check("T7 mined is DISTINCT from covered (200 permil; F5 read but not mined)" as *u8, ok7, ctr)
294 var ok8: i64 = 0
295 if mc_find(d, dl, "\"id\":\"F4\",\"covered\":0,\"mined\":0,\"rows\":0,\"truncated\":0,\"kind_ok\":0" as *u8) == 1 { if mc_find(d, dl, "\"kind_unknown\":1" as *u8) == 1 { ok8 = 1 } }
296 gv_check("T8 unknown source kind flagged, never fabricated as covered" as *u8, ok8, ctr)
297 let rc: i64 = gv_verdict("MINECOV-GATE" as *u8, ctr, "class-coverage census: evidence-or-no-credit, reader-or-no-credit, mined distinct from covered" as *u8)
298 return rc
299}
300
301func main(argc: i64, argv: *i64) -> i64 {
302 if argc < 3 { sj_puts("usage: nx_minecov {census <classconf> [loader] | selftest <scratch-prefix>}\n" as *u8); sys_exit(2); return 2 }
303 let verb: *u8 = argv[1] as *u8
304 let vl: i64 = sj_vlen(verb)
305 if sj_lit_eq(verb, 0, vl, "selftest" as *u8) == 1 {
306 let rc: i64 = mc_selftest(argv[2] as *u8)
307 sys_exit(rc)
308 return rc
309 }
310 if sj_lit_eq(verb, 0, vl, "census" as *u8) == 1 {
311 let loader: *u8 = sys_mmap(128)
312 var lo2: i64 = 0
313 if argc >= 4 { lo2 = sj_cat(loader, 0, argv[3] as *u8) } else { lo2 = sj_cat(loader, 0, "nx_store_put" as *u8) }
314 loader[lo2] = 0 as u8
315 let d: *u8 = sys_mmap(MC_OUT)
316 let dl: i64 = mc_census(argv[2] as *u8, loader, d)
317 if dl < 0 { sj_puts("REFUSED class table missing or empty\n" as *u8); sys_exit(3); return 3 }
318 sys_write(1, d, dl)
319 sys_exit(0)
320 return 0
321 }
322 sj_puts("unknown verb\n" as *u8)
323 sys_exit(2)
324 return 2
325}