code wiki / _hdl_build / nx_minerhub.nx

nx_minerhub.nx source

↩ module page · 508 lines · 24396 B

1// nx_minerhub.nx -- MINER SYNTHESIS HUB (miner-sota, 2026-07-23). The measurement layer's FRONT DOOR. 2// The 8 miners each emit JSON; nobody COMPOSED them. This forks each declared miner (allowlist-resolved 3// via the SHARED sj_allow_path), extracts its ONE headline metric, classifies it against DATA-DRIVEN 4// thresholds (GOOD/WATCH/BAD), and emits a single ecosystem-health index + a page. OO by construction: 5// it READS the miners, duplicates none of them; a new miner = ONE conf row, zero code. now-free/pure at 6// the parser (gate); the fork-compose path runs live. Composes nx_sovjson_lib. Read-only. Rule 26. 7// mine <sourceconf> -> JSON: per-source value+status + health_index_permil 8// page <sourceconf> <outfile> -> HTML board 9// selftest <scratch-prefix> -> gate T1..T9 (metric extract + classify + index math, deterministic) 10// conf cols: id TAB dir(hi|lo) TAB good TAB warn TAB metric TAB miner TAB arg1 TAB arg2 ... 11// dir hi = higher is better (coverage, green, done); lo = lower is better (unowned, eroded, dangling) 12// license_tier: ORIGINAL 13import "nx_sovjson_lib.nx" 14import "nx_syscalls.nx" 15import "nx_gate_verdict.nx" 16import "nx_tool_run.nx" 17const MH_MAGIC_1024: i64 = 1024 18 19const MH_CONF: i64 = 65536 20const MH_CAP: i64 = 262144 21const MH_OUT: i64 = 65536 22const MH_PATH: i64 = 512 23const MH_ARENA: i64 = 8192 24const MH_ARGS: i64 = 24 25const MH_ROWS: i64 = 64 26const MH_PERMIL: i64 = 1000 27const MH_NAME_MAX: i64 = 120 28const MH_MODE_644: i64 = 420 29const MH_SENT: i64 = -999999 30 31func mh_read(path: *u8, buf: *u8, cap: i64) -> i64 { 32 let fd: i64 = sys_openat_rd(path) 33 if fd < 0 { return -1 } 34 var n: i64 = 0 35 var go: i64 = 1 36 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 } } 37 sys_close(fd) 38 return n 39} 40func mh_find_from(q: *u8, from: i64, n: i64, lit: *u8) -> i64 { 41 let ll: i64 = sj_vlen(lit) 42 if ll == 0 { return -1 } 43 var i: i64 = from 44 while i + ll <= n { 45 var k: i64 = 0 46 var ok: i64 = 1 47 while k < ll { if q[i+k] != lit[k] { ok = 0; k = ll } else { k = k + 1 } } 48 if ok == 1 { return i } 49 i = i + 1 50 } 51 return -1 52} 53func mh_find(q: *u8, n: i64, lit: *u8) -> i64 { 54 if mh_find_from(q, 0, n, lit) >= 0 { return 1 } 55 return 0 56} 57// extract the integer value of "<key>": from q. foundp[0]=1 if the key is present. MH_SENT if absent. 58func mh_extract(q: *u8, n: i64, key: *u8, foundp: *i64) -> i64 { 59 let tok: *u8 = sys_mmap(256) 60 var t: i64 = 0 61 tok[t] = 34 as u8; t = t + 1 62 t = sj_cat(tok, t, key) 63 tok[t] = 34 as u8; t = t + 1 64 tok[t] = 58 as u8; t = t + 1 65 tok[t] = 0 as u8 66 let p: i64 = mh_find_from(q, 0, n, tok) 67 if p < 0 { foundp[0] = 0; return MH_SENT } 68 foundp[0] = 1 69 // skip spaces after the token, then optional minus, then digits 70 var s: i64 = p + t 71 var go: i64 = 1 72 while go == 1 { if s >= n { go = 0 } else { if q[s] == (32 as u8) { s = s + 1 } else { go = 0 } } } 73 var neg: i64 = 0 74 if s < n { if q[s] == (45 as u8) { neg = 1; s = s + 1 } } 75 var v: i64 = 0 76 var g2: i64 = 1 77 while g2 == 1 { if s >= n { g2 = 0 } else { let c: i64 = q[s] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); s = s + 1 } else { g2 = 0 } } else { g2 = 0 } } } 78 if neg == 1 { v = 0 - v } 79 return v 80} 81// 2 GOOD, 1 WATCH, 0 BAD. dir 0 = higher-better, dir 1 = lower-better. 82func mh_class(val: i64, dir: i64, good: i64, warn: i64) -> i64 { 83 if dir == 0 { if val >= good { return 2 } if val >= warn { return 1 } return 0 } 84 if val <= good { return 2 } if val <= warn { return 1 } return 0 85} 86func mh_key(d: *u8, o: i64, name: *u8) -> i64 { 87 d[o] = 34 as u8 88 var p: i64 = o + 1 89 p = sj_cat(d, p, name) 90 d[p] = 34 as u8 91 p = p + 1 92 d[p] = 58 as u8 93 p = p + 1 94 return p 95} 96func mh_status_str(d: *u8, o: i64, score: i64) -> i64 { 97 var p: i64 = o 98 d[p] = 34 as u8; p = p + 1 99 if score == 2 { p = sj_cat(d, p, "GOOD" as *u8) } else { if score == 1 { p = sj_cat(d, p, "WATCH" as *u8) } else { p = sj_cat(d, p, "BAD" as *u8) } } 100 d[p] = 34 as u8; p = p + 1 101 return p 102} 103// fork one miner row (cols 5.. = miner + args), capture, extract its metric (col 4). ran=0 on fork fail. 104func mh_run(cq: *u8, ls: i64, le: i64, valp: *i64, ranp: *i64) -> i64 { 105 ranp[0] = 0 106 valp[0] = MH_SENT 107 let sp: *i64 = sys_mmap(16) as *i64 108 if sj_col(cq, ls, le, 5, sp) == 0 { return 0 } 109 let mname: *u8 = sys_mmap(MH_PATH) 110 var k: i64 = 0 111 while sp[0]+k < sp[1] { if k < MH_PATH - 2 { mname[k] = cq[sp[0]+k] } k = k + 1 } 112 mname[k] = 0 as u8 113 let mpath: *u8 = sys_mmap(MH_PATH) 114 if sj_allow_path(mname, mpath) == 0 { return 0 } 115 let arena: *u8 = sys_mmap(MH_ARENA) 116 let av: *i64 = sys_mmap(8 * MH_ARGS) as *i64 117 av[0] = mpath as i64 118 var ac: i64 = 1 119 var ao: i64 = 0 120 var c: i64 = 6 121 var more: i64 = 1 122 while more == 1 { 123 if sj_col(cq, ls, le, c, sp) == 0 { more = 0 } else { 124 if ac >= MH_ARGS - 1 { more = 0 } else { 125 av[ac] = ((arena as i64) + ao) as i64 126 var z: i64 = sp[0] 127 while z < sp[1] { if ao < MH_ARENA - 2 { arena[ao] = cq[z]; ao = ao + 1 } z = z + 1 } 128 arena[ao] = 0 as u8; ao = ao + 1 129 ac = ac + 1 130 c = c + 1 131 } 132 } 133 } 134 av[ac] = 0 135 let cout: *u8 = sys_mmap(MH_CAP) 136 let clen: *i64 = sys_mmap(16) as *i64 137 let ex: i64 = tr_run_capture(mpath, av, cout, MH_CAP - 8, clen) 138 if ex != 0 { return 0 } 139 ranp[0] = 1 140 let metric: *u8 = sys_mmap(128) 141 if sj_col(cq, ls, le, 4, sp) == 1 { 142 var m: i64 = 0 143 while sp[0]+m < sp[1] { if m < 120 { metric[m] = cq[sp[0]+m] } m = m + 1 } 144 metric[m] = 0 as u8 145 } 146 let fnd: *i64 = sys_mmap(16) as *i64 147 valp[0] = mh_extract(cout, clen[0], metric, fnd) 148 return 1 149} 150func mh_emit(conf: *u8, wantpage: i64, outp: *u8, d: *u8) -> i64 { 151 let cb: *u8 = sys_mmap(MH_CONF) 152 let cn: i64 = mh_read(conf, cb, MH_CONF - 8) 153 if cn <= 0 { return -1 } 154 let sp: *i64 = sys_mmap(16) as *i64 155 let valp: *i64 = sys_mmap(16) as *i64 156 let ranp: *i64 = sys_mmap(16) as *i64 157 var p: i64 = 0 158 if wantpage == 0 { 159 d[p] = 123 as u8; p = p + 1 160 p = mh_key(d, p, "v" as *u8); p = sj_catn(d, p, 1); d[p] = 44 as u8; p = p + 1 161 p = mh_key(d, p, "tool" as *u8) 162 d[p] = 34 as u8; p = p + 1 163 p = sj_cat(d, p, "nx_minerhub" as *u8) 164 d[p] = 34 as u8; p = p + 1 165 d[p] = 44 as u8; p = p + 1 166 p = mh_key(d, p, "sources" as *u8) 167 d[p] = 91 as u8; p = p + 1 168 } else { 169 d[p] = 60 as u8; p = p + 1 170 d[p] = 33 as u8; p = p + 1 171 p = sj_cat(d, p, "doctype html><html><head><meta charset=\"utf-8\"><title>Miner Hub</title></head><body><h1>Ecosystem Health — Miner Hub</h1><p>each row = one class-miner's headline metric, classified GOOD/WATCH/BAD; the index is the composed health of the measurement layer.</p><table border=\"1\" cellpadding=\"5\"><tr><th>source</th><th>metric</th><th>value</th><th>status</th></tr>" as *u8) 172 } 173 var nsrc: i64 = 0 174 var ran: i64 = 0 175 var scoresum: i64 = 0 176 var good: i64 = 0 177 var watch: i64 = 0 178 var bad: i64 = 0 179 var efirst: i64 = 1 180 var i: i64 = 0 181 while i < cn { 182 let le: i64 = sj_le(cb, i, cn) 183 var ok: i64 = 0 184 if le > i { if cb[i] != (35 as u8) { if sj_col(cb, i, le, 5, sp) == 1 { ok = 1 } } } 185 if ok == 1 { 186 nsrc = nsrc + 1 187 let dir: *i64 = sys_mmap(16) as *i64 188 sj_col(cb, i, le, 1, dir) 189 var dv: i64 = 0 190 if sj_lit_eq(cb, dir[0], dir[1], "lo" as *u8) == 1 { dv = 1 } 191 let gd: *i64 = sys_mmap(16) as *i64 192 sj_col(cb, i, le, 2, gd) 193 let good_t: i64 = sj_atoi_span(cb, gd[0], gd[1]) 194 sj_col(cb, i, le, 3, gd) 195 let warn_t: i64 = sj_atoi_span(cb, gd[0], gd[1]) 196 mh_run(cb, i, le, valp, ranp) 197 var score: i64 = 0 198 if ranp[0] == 1 { if valp[0] != MH_SENT { score = mh_class(valp[0], dv, good_t, warn_t); ran = ran + 1 } } 199 if ranp[0] == 1 { if valp[0] != MH_SENT { 200 scoresum = scoresum + score 201 if score == 2 { good = good + 1 } else { if score == 1 { watch = watch + 1 } else { bad = bad + 1 } } 202 } } 203 if wantpage == 0 { 204 if efirst == 0 { d[p] = 44 as u8; p = p + 1 } 205 efirst = 0 206 d[p] = 123 as u8; p = p + 1 207 p = mh_key(d, p, "id" as *u8) 208 sj_col(cb, i, le, 0, sp) 209 d[p] = 34 as u8; p = p + 1 210 p = sj_cat_esc(d, p, cb, sp[0], sp[1], MH_NAME_MAX) 211 d[p] = 34 as u8; p = p + 1 212 d[p] = 44 as u8; p = p + 1 213 p = mh_key(d, p, "metric" as *u8) 214 sj_col(cb, i, le, 4, sp) 215 d[p] = 34 as u8; p = p + 1 216 p = sj_cat_esc(d, p, cb, sp[0], sp[1], MH_NAME_MAX) 217 d[p] = 34 as u8; p = p + 1 218 d[p] = 44 as u8; p = p + 1 219 p = mh_key(d, p, "value" as *u8) 220 if valp[0] == MH_SENT { p = sj_cat(d, p, "null" as *u8) } else { p = sj_catn(d, p, valp[0]) } 221 d[p] = 44 as u8; p = p + 1 222 p = mh_key(d, p, "ran" as *u8); p = sj_catn(d, p, ranp[0]); d[p] = 44 as u8; p = p + 1 223 p = mh_key(d, p, "status" as *u8) 224 p = mh_status_str(d, p, score) 225 d[p] = 125 as u8; p = p + 1 226 } else { 227 p = sj_cat(d, p, "<tr><td>" as *u8) 228 sj_col(cb, i, le, 0, sp) 229 p = sj_cat_esc(d, p, cb, sp[0], sp[1], MH_NAME_MAX) 230 p = sj_cat(d, p, "</td><td>" as *u8) 231 sj_col(cb, i, le, 4, sp) 232 p = sj_cat_esc(d, p, cb, sp[0], sp[1], MH_NAME_MAX) 233 p = sj_cat(d, p, "</td><td>" as *u8) 234 if valp[0] == MH_SENT { p = sj_cat(d, p, "n/a" as *u8) } else { p = sj_catn(d, p, valp[0]) } 235 p = sj_cat(d, p, "</td><td>" as *u8) 236 if score == 2 { p = sj_cat(d, p, "GOOD" as *u8) } else { if score == 1 { p = sj_cat(d, p, "WATCH" as *u8) } else { p = sj_cat(d, p, "BAD" as *u8) } } 237 p = sj_cat(d, p, "</td></tr>" as *u8) 238 } 239 } 240 i = le + 1 241 } 242 var idx: i64 = 0 - 1 243 if nsrc > 0 { idx = scoresum * MH_PERMIL / (2 * nsrc) } 244 if wantpage == 0 { 245 d[p] = 93 as u8; p = p + 1 246 d[p] = 44 as u8; p = p + 1 247 p = mh_key(d, p, "sources_total" as *u8); p = sj_catn(d, p, nsrc); d[p] = 44 as u8; p = p + 1 248 p = mh_key(d, p, "ran" as *u8); p = sj_catn(d, p, ran); d[p] = 44 as u8; p = p + 1 249 p = mh_key(d, p, "good" as *u8); p = sj_catn(d, p, good); d[p] = 44 as u8; p = p + 1 250 p = mh_key(d, p, "watch" as *u8); p = sj_catn(d, p, watch); d[p] = 44 as u8; p = p + 1 251 p = mh_key(d, p, "bad" as *u8); p = sj_catn(d, p, bad); d[p] = 44 as u8; p = p + 1 252 p = mh_key(d, p, "health_index_permil" as *u8); p = sj_catn(d, p, idx) 253 d[p] = 125 as u8; p = p + 1 254 d[p] = 10 as u8; p = p + 1 255 } else { 256 p = sj_cat(d, p, "</table><p style=\"font-size:48px\">health_index=" as *u8) 257 p = sj_catn(d, p, idx) 258 p = sj_cat(d, p, "&permil;</p><p>good=" as *u8) 259 p = sj_catn(d, p, good) 260 p = sj_cat(d, p, " watch=" as *u8) 261 p = sj_catn(d, p, watch) 262 p = sj_cat(d, p, " bad=" as *u8) 263 p = sj_catn(d, p, bad) 264 p = sj_cat(d, p, " ran=" as *u8) 265 p = sj_catn(d, p, ran) 266 p = sj_cat(d, p, "/" as *u8) 267 p = sj_catn(d, p, nsrc) 268 p = sj_cat(d, p, "</p><p><a href=\"/outsidegap\">outsidegap</a> <a href=\"/wsmine\">wsmine</a> <a href=\"/frontier\">frontier</a></p></body></html>" as *u8) 269 let fd: i64 = sys_openat_wr(outp, MH_MODE_644) 270 if fd < 0 { return -3 } 271 sys_write(fd, d, p) 272 sys_close(fd) 273 } 274 return p 275} 276// flag: each BAD source auto-files ONE intake REQ through the ALLOWLIST-RESOLVED filer. Shares mh_run + 277// mh_class with mine (the DECISION logic is DRY -- a flag can never disagree with the board). Marker 278// [HUB:<id>] makes it idempotent: one open ticket per source, no spam while it stays BAD (re-file after 279// triage-close is a declared v-next, matching the nx_feeder discipline). Filer INJECTABLE (argecho in gate). 280func mh_flag(conf: *u8, ipath: *u8, filer: *u8, d: *u8) -> i64 { 281 let cb: *u8 = sys_mmap(MH_CONF) 282 let cn: i64 = mh_read(conf, cb, MH_CONF - 8) 283 if cn <= 0 { return -1 } 284 let ib: *u8 = sys_mmap(MH_CAP) 285 let ibn: i64 = mh_read(ipath, ib, MH_CAP - 8) 286 var iblen: i64 = ibn 287 if iblen < 0 { iblen = 0 } 288 let fpath: *u8 = sys_mmap(MH_PATH) 289 let fok: i64 = sj_allow_path(filer, fpath) 290 let sp: *i64 = sys_mmap(16) as *i64 291 let valp: *i64 = sys_mmap(16) as *i64 292 let ranp: *i64 = sys_mmap(16) as *i64 293 var bad: i64 = 0 294 var flagged: i64 = 0 295 var skipped: i64 = 0 296 var i: i64 = 0 297 while i < cn { 298 let le: i64 = sj_le(cb, i, cn) 299 var ok: i64 = 0 300 if le > i { if cb[i] != (35 as u8) { if sj_col(cb, i, le, 5, sp) == 1 { ok = 1 } } } 301 if ok == 1 { 302 let dir: *i64 = sys_mmap(16) as *i64 303 sj_col(cb, i, le, 1, dir) 304 var dv: i64 = 0 305 if sj_lit_eq(cb, dir[0], dir[1], "lo" as *u8) == 1 { dv = 1 } 306 let gd: *i64 = sys_mmap(16) as *i64 307 sj_col(cb, i, le, 2, gd) 308 let good_t: i64 = sj_atoi_span(cb, gd[0], gd[1]) 309 sj_col(cb, i, le, 3, gd) 310 let warn_t: i64 = sj_atoi_span(cb, gd[0], gd[1]) 311 mh_run(cb, i, le, valp, ranp) 312 if ranp[0] == 1 { if valp[0] != MH_SENT { 313 let score: i64 = mh_class(valp[0], dv, good_t, warn_t) 314 if score == 0 { 315 bad = bad + 1 316 // marker [HUB:<id>] 317 let mk: *u8 = sys_mmap(256) 318 var mo: i64 = sj_cat(mk, 0, "[HUB:" as *u8) 319 sj_col(cb, i, le, 0, sp) 320 var z: i64 = sp[0] 321 while z < sp[1] { if mo < 200 { mk[mo] = cb[z]; mo = mo + 1 } z = z + 1 } 322 mk[mo] = 93 as u8; mo = mo + 1 323 mk[mo] = 0 as u8 324 var already: i64 = 0 325 if iblen > 0 { if mh_find(ib, iblen, mk) == 1 { already = 1 } } 326 if already == 1 { skipped = skipped + 1 } else { if fok == 1 { 327 let txt: *u8 = sys_mmap(MH_MAGIC_1024) 328 var to: i64 = sj_cat(txt, 0, mk) 329 to = sj_cat(txt, to, " " as *u8) 330 sj_col(cb, i, le, 4, sp) 331 var z2: i64 = sp[0] 332 while z2 < sp[1] { if to < 900 { txt[to] = cb[z2]; to = to + 1 } z2 = z2 + 1 } 333 to = sj_cat(txt, to, "=" as *u8) 334 to = sj_catn(txt, to, valp[0]) 335 to = sj_cat(txt, to, " classified BAD by nx_minerhub - triage the owning class-miner's finding (see /minerhub)" as *u8) 336 txt[to] = 0 as u8 337 let av: *i64 = sys_mmap(64) as *i64 338 av[0] = fpath as i64 339 av[1] = "ask" as *u8 as i64 340 av[2] = ipath as i64 341 av[3] = "nx_minerhub" as *u8 as i64 342 av[4] = txt as i64 343 av[5] = 0 344 let cout: *u8 = sys_mmap(MH_OUT) 345 let clen: *i64 = sys_mmap(16) as *i64 346 let ex: i64 = tr_run_capture(fpath, av, cout, MH_OUT - 8, clen) 347 if ex == 0 { flagged = flagged + 1 } 348 } } 349 } 350 } } 351 } 352 i = le + 1 353 } 354 var p: i64 = 0 355 d[p] = 123 as u8; p = p + 1 356 p = mh_key(d, p, "v" as *u8); p = sj_catn(d, p, 1); d[p] = 44 as u8; p = p + 1 357 p = mh_key(d, p, "tool" as *u8) 358 d[p] = 34 as u8; p = p + 1 359 p = sj_cat(d, p, "nx_minerhub" as *u8) 360 d[p] = 34 as u8; p = p + 1 361 d[p] = 44 as u8; p = p + 1 362 p = mh_key(d, p, "averb" as *u8) 363 d[p] = 34 as u8; p = p + 1 364 p = sj_cat(d, p, "flag" as *u8) 365 d[p] = 34 as u8; p = p + 1 366 d[p] = 44 as u8; p = p + 1 367 p = mh_key(d, p, "filer_resolved" as *u8); p = sj_catn(d, p, fok); d[p] = 44 as u8; p = p + 1 368 p = mh_key(d, p, "bad" as *u8); p = sj_catn(d, p, bad); d[p] = 44 as u8; p = p + 1 369 p = mh_key(d, p, "flagged" as *u8); p = sj_catn(d, p, flagged); d[p] = 44 as u8; p = p + 1 370 p = mh_key(d, p, "skipped_already" as *u8); p = sj_catn(d, p, skipped) 371 d[p] = 125 as u8; p = p + 1 372 d[p] = 10 as u8; p = p + 1 373 return p 374} 375func mh_selftest(prefix: *u8) -> i64 { 376 let ctr: *i64 = gv_ctr() 377 gv_head("nx_minerhub selftest -- metric extract + classify + index math (deterministic, no fork)" as *u8) 378 let js: *u8 = sys_mmap(MH_MAGIC_1024) 379 var o: i64 = sj_cat(js, 0, "{\"v\":1,\"coverage_permil\":1000,\"eat_permil\":283,\"avg_hold_s\":-1,\"eroded\":0}\n" as *u8) 380 let jn: i64 = o 381 let fnd: *i64 = sys_mmap(16) as *i64 382 // T1 extract a present positive key 383 var ok1: i64 = 0 384 if mh_extract(js, jn, "coverage_permil" as *u8, fnd) == 1000 { if fnd[0] == 1 { ok1 = 1 } } 385 gv_check("T1 extract exact value of a present key (1000)" as *u8, ok1, ctr) 386 // T2 a substring key must NOT match a longer key (permil vs coverage_permil) 387 var ok2: i64 = 0 388 if mh_extract(js, jn, "eat_permil" as *u8, fnd) == 283 { ok2 = 1 } 389 gv_check("T2 key match is exact-boundary (eat_permil=283, not confused with coverage_permil)" as *u8, ok2, ctr) 390 // T3 negative value parsed as negative (refusal sentinel from a miner) 391 var ok3: i64 = 0 392 if mh_extract(js, jn, "avg_hold_s" as *u8, fnd) == (0 - 1) { ok3 = 1 } 393 gv_check("T3 negative value parsed as -1 (a miner refusal survives synthesis)" as *u8, ok3, ctr) 394 // T4 absent key -> found=0 + sentinel, never fabricated as 0 395 var ok4: i64 = 0 396 let av4: i64 = mh_extract(js, jn, "nonexistent_key" as *u8, fnd) 397 if fnd[0] == 0 { if av4 == MH_SENT { ok4 = 1 } } 398 gv_check("T4 absent key -> found=0 + sentinel, never a fabricated zero" as *u8, ok4, ctr) 399 // T5 hi-is-good classification 400 var ok5: i64 = 0 401 if mh_class(1000, 0, 900, 700) == 2 { if mh_class(800, 0, 900, 700) == 1 { if mh_class(500, 0, 900, 700) == 0 { ok5 = 1 } } } 402 gv_check("T5 higher-is-better: 1000 GOOD, 800 WATCH, 500 BAD" as *u8, ok5, ctr) 403 // T6 lo-is-good classification 404 var ok6: i64 = 0 405 if mh_class(0, 1, 0, 5) == 2 { if mh_class(3, 1, 0, 5) == 1 { if mh_class(20, 1, 0, 5) == 0 { ok6 = 1 } } } 406 gv_check("T6 lower-is-better: 0 GOOD, 3 WATCH, 20 BAD" as *u8, ok6, ctr) 407 // T7 boundary is inclusive (val==good is GOOD, val==warn is WATCH) 408 var ok7: i64 = 0 409 if mh_class(900, 0, 900, 700) == 2 { if mh_class(700, 0, 900, 700) == 1 { ok7 = 1 } } 410 gv_check("T7 thresholds inclusive at the boundary" as *u8, ok7, ctr) 411 // T8 index math: 2 GOOD + 1 WATCH + 1 BAD over 4 = (2+2+1+0)/8 = 625 permil 412 var ok8: i64 = 0 413 let ssum: i64 = 2 + 2 + 1 + 0 414 if ssum * MH_PERMIL / (2 * 4) == 625 { ok8 = 1 } 415 gv_check("T8 health_index math exact: 2G/1W/1B of 4 = 625 permil" as *u8, ok8, ctr) 416 // T9 live compose over a real conf that forks nx_minecov -> the hub actually runs the suite 417 let cf: *u8 = sys_mmap(MH_PATH) 418 o = sj_cat(cf, 0, prefix) 419 o = sj_catn(cf, o, sys_now_realtime_sec()) 420 o = sj_cat(cf, o, ".conf" as *u8) 421 cf[o] = 0 as u8 422 let fd: i64 = sys_openat_wr(cf, MH_MODE_644) 423 let lb: *u8 = sys_mmap(MH_MAGIC_1024) 424 var lo: i64 = sj_cat(lb, 0, "cov\thi\t900\t700\tcoverage_permil\tnx_minecov\tcensus\tknowledge/status/minecov_classes.conf\n" as *u8) 425 sys_write(fd, lb, lo) 426 sys_close(fd) 427 let d: *u8 = sys_mmap(MH_OUT) 428 let dl: i64 = mh_emit(cf, 0, "-" as *u8, d) 429 var ok9: i64 = 0 430 if dl > 0 { if mh_find(d, dl, "\"id\":\"cov\"" as *u8) == 1 { if mh_find(d, dl, "\"ran\":1" as *u8) == 1 { if mh_find(d, dl, "\"status\":\"GOOD\"" as *u8) == 1 { ok9 = 1 } } } } 431 gv_check("T9 LIVE compose: forks nx_minecov, extracts coverage_permil, classifies GOOD" as *u8, ok9, ctr) 432 // T10/T11 flag: a BAD source auto-files ONE ticket through the injected argecho filer, idempotent. 433 // conf forks nx_minecov census reading mined_permil(=1000) with dir=lo good=100 warn=500 => 1000>500 434 // => BAD by construction (inverted thresholds; the tooth is the FILING mechanism, not the threshold). 435 let bc: *u8 = sys_mmap(MH_PATH) 436 o = sj_cat(bc, 0, prefix) 437 o = sj_catn(bc, o, sys_now_realtime_sec()) 438 o = sj_cat(bc, o, ".bad" as *u8) 439 bc[o] = 0 as u8 440 let bfd: i64 = sys_openat_wr(bc, MH_MODE_644) 441 var blo: i64 = sj_cat(lb, 0, "cov\tlo\t100\t500\tmined_permil\tnx_minecov\tcensus\tknowledge/status/minecov_classes.conf\n" as *u8) 442 sys_write(bfd, lb, blo) 443 sys_close(bfd) 444 let ij: *u8 = sys_mmap(MH_PATH) 445 o = sj_cat(ij, 0, prefix) 446 o = sj_catn(ij, o, sys_now_realtime_sec()) 447 o = sj_cat(ij, o, ".ij" as *u8) 448 ij[o] = 0 as u8 449 let fr1: i64 = mh_flag(bc, ij, "argecho" as *u8, d) 450 var ok10: i64 = 0 451 if fr1 > 0 { if mh_find(d, fr1, "\"bad\":1" as *u8) == 1 { if mh_find(d, fr1, "\"flagged\":1" as *u8) == 1 { if mh_find(d, fr1, "\"skipped_already\":0" as *u8) == 1 { ok10 = 1 } } } } 452 gv_check("T10 a BAD source files exactly one ticket through the injected filer" as *u8, ok10, ctr) 453 // seed the marker the argecho filer would have written (argecho does not persist), then re-flag 454 let sfd: i64 = sys_openat_append(ij, MH_MODE_644) 455 var slo: i64 = sj_cat(lb, 0, "REQ seeded [HUB:cov] marker\n" as *u8) 456 sys_write(sfd, lb, slo) 457 sys_close(sfd) 458 let fr2: i64 = mh_flag(bc, ij, "argecho" as *u8, d) 459 var ok11: i64 = 0 460 if fr2 > 0 { if mh_find(d, fr2, "\"bad\":1" as *u8) == 1 { if mh_find(d, fr2, "\"flagged\":0" as *u8) == 1 { if mh_find(d, fr2, "\"skipped_already\":1" as *u8) == 1 { ok11 = 1 } } } } 461 gv_check("T11 marker present -> re-flag files NOTHING (idempotent, no ticket spam)" as *u8, ok11, ctr) 462 let rc: i64 = gv_verdict("MINERHUB-GATE" as *u8, ctr, "synthesis + flag: exact extract, boundary classify, honest sentinel, index math, live compose, idempotent auto-file" as *u8) 463 return rc 464} 465 466func main(argc: i64, argv: *i64) -> i64 { 467 if argc < 3 { sj_puts("usage: nx_minerhub {mine <sourceconf> | page <sourceconf> <outfile> | flag <sourceconf> <intake_jrnl> [filer] | selftest <scratch-prefix>}\n" as *u8); sys_exit(2); return 2 } 468 let verb: *u8 = argv[1] as *u8 469 let vl: i64 = sj_vlen(verb) 470 if sj_lit_eq(verb, 0, vl, "selftest" as *u8) == 1 { 471 let rc: i64 = mh_selftest(argv[2] as *u8) 472 sys_exit(rc) 473 return rc 474 } 475 if sj_lit_eq(verb, 0, vl, "mine" as *u8) == 1 { 476 let d: *u8 = sys_mmap(MH_OUT) 477 let dl: i64 = mh_emit(argv[2] as *u8, 0, "-" as *u8, d) 478 if dl < 0 { sj_puts("REFUSED source conf missing or empty\n" as *u8); sys_exit(3); return 3 } 479 sys_write(1, d, dl) 480 sys_exit(0) 481 return 0 482 } 483 if sj_lit_eq(verb, 0, vl, "page" as *u8) == 1 { 484 if argc < 4 { sj_puts("page needs <sourceconf> <outfile>\n" as *u8); sys_exit(2); return 2 } 485 let d: *u8 = sys_mmap(MH_OUT) 486 let dl: i64 = mh_emit(argv[2] as *u8, 1, argv[3] as *u8, d) 487 if dl < 0 { sj_puts("PAGE FAIL\n" as *u8); sys_exit(1); return 1 } 488 sj_puts("PAGE OK\n" as *u8) 489 sys_exit(0) 490 return 0 491 } 492 if sj_lit_eq(verb, 0, vl, "flag" as *u8) == 1 { 493 if argc < 4 { sj_puts("flag needs <sourceconf> <intake_jrnl> [filer]\n" as *u8); sys_exit(2); return 2 } 494 let filer: *u8 = sys_mmap(128) 495 var fo: i64 = 0 496 if argc >= 5 { fo = sj_cat(filer, 0, argv[4] as *u8) } else { fo = sj_cat(filer, 0, "nx_pm_intake" as *u8) } 497 filer[fo] = 0 as u8 498 let d: *u8 = sys_mmap(MH_OUT) 499 let dl: i64 = mh_flag(argv[2] as *u8, argv[3] as *u8, filer, d) 500 if dl < 0 { sj_puts("REFUSED source conf missing or empty\n" as *u8); sys_exit(3); return 3 } 501 sys_write(1, d, dl) 502 sys_exit(0) 503 return 0 504 } 505 sj_puts("unknown verb\n" as *u8) 506 sys_exit(2) 507 return 2 508}