code wiki / (root) / nx_goalmap_lib.nx

nx_goalmap_lib.nx source

↩ module page · 1303 lines · 64769 B

1// nx_goalmap_lib.nx -- THE GOAL MAPPER (seat-system, 2026-09-05). Operator: "build our mapping setup to 2// exceed yours so we dont need to reinvest heavy tokens and instead the nishi ecosystem can do the lifts." 3// MEASURED the day it was built: two Claude workflows spent 5.7M tokens and 1,272 tool calls to map ONE 4// operator goal onto the boards. This lib does that lift from DATA, deterministically, with no language 5// model in the path: goal WORDS -> per domain, the rung| rows whose title / done-rule / symbol carry them 6// (score = DISTINCT words matched, published as a COUNT and never thresholded -- the capsearch law: a ruler 7// that scores a novel thing highest cannot be thresholded, publish the list), each rung's STATUS derived 8// from the matrix (a present symbol = PRESENT, an _ABSENT_:<sym> watch = OPEN, neither = UNMAPPED) and from 9// the operator's own plane (knowledge/store/accept-: a REJECT whose targets name <dom>:<sym> = PRESENT-REJECTED, 10// an ACCEPT = ACCEPTED), the log| ledger size and last epoch per rung, the matrix WATCH rows the words match 11// (gaps, with SOURCE / BUILT / PROMOTED probed by open at the three roots), and a dependency ORDER over the 12// matched rungs (Kahn over the deps column; ties by score then file order; a cycle is ANNOUNCED, never hidden). 13// Output is ONE capped JSON digest (GM_OUTCAP declared in the output, clipped=1 when the budget bound it) so a 14// seat reads the decision surface, not the boards. COMPOSES nx_sovjson_lib (emit + spans) and 15// nx_store_seed_lib (plane load sized from the plane -- never a partial board). Every read declares its true 16// size beside the window it took. A duplicate rung id is REFUSED BY NAME (the ranker's closure hides a rung 17// behind one; measured 'rung|GE50|' x2 on gameengine.plan on 2026-09-05). No hw writes (Rule 26). 18// gm_run(base, domains-csv, words, nwords, out) -> bytes written, or -3 NO-DOMAIN-READABLE, -4 DUPLICATE-RUNG-ID 19// base = path prefix for a fixture tree ("" in production = the nishihost cwd). 20import "nx_syscalls.nx" 21import "nx_sovjson_lib.nx" 22import "nx_store_seed_lib.nx" 23import "nx_gauge_lib.nx" // the ONE gauge-heartbeat ruler: the census stamps its own freshness so the emitter judges it with the same classifier 24 25const GM_CAP: i64 = 1048576 26const GM_OUTCAP: i64 = 16384 // v1.1 (2026-09-05): 8192 clipped 3 of 4 real domains on the first real run; a goal map over four boards is read ONCE, so 16 KB is still a ~17x lift over the 270 KB of agent maps it replaces 27const GM_RF: i64 = 16 28const GM_MF: i64 = 12 29const GM_PATHB: i64 = 512 30const GM_WORDB: i64 = 64 31const GM_NL: i64 = 10 32const GM_PIPE: i64 = 124 33const GM_COMMA: i64 = 44 34const GM_COLON: i64 = 58 35const GM_TAB: i64 = 9 36const GM_SLASH: i64 = 47 37const GM_DOT: i64 = 46 38const GM_HASH_BYTE: i64 = 35 39const GM_SEEK_SET: i64 = 0 40const GM_SEEK_END: i64 = 2 41const GM_SPAN: i64 = 16 42const GM_SPAN6: i64 = 48 43const GM_ID_ESC: i64 = 24 44const GM_SYM_ESC: i64 = 48 45const GM_LABEL_ESC: i64 = 64 46const GM_DEPS_ESC: i64 = 40 47const GM_TAIL_RESERVE: i64 = 200 48const GM_ROW_RESERVE: i64 = 260 49const GM_MAXVERD: i64 = 8 50const GM_R_NODOM: i64 = 0 - 3 51const GM_R_DUP: i64 = 0 - 4 52const GM_ST_UNMAPPED: i64 = 0 53const GM_ST_OPEN: i64 = 1 54const GM_ST_PRESENT: i64 = 2 55const GM_ST_REJECTED: i64 = 3 56const GM_ST_ACCEPTED: i64 = 4 57const GM_ABSENT_LEN: i64 = 9 58const GM_RUNG_PFX_LEN: i64 = 5 59const GM_LOG_PFX_LEN: i64 = 4 60const GM_LC_A: i64 = 65 61const GM_LC_Z: i64 = 90 62const GM_LC_D: i64 = 32 63// v1.2 (2026-09-05, debt 1788626163): the promoted binary SIGSEGV'd on an 8-board query. Every ROW emit was 64// budgeted by gm_room, but the per-domain SCAFFOLDING (the header numbers, the array openers and closers) was 65// not, so once the row budget was spent each further domain kept growing the digest past GM_OUTCAP and over 66// the edge of the caller's 16 KB buffer into the page holding the query words; a corrupted word pointer is 67// non-canonical, and x86-64 reports that fault at address 0 -- which is what the crash guard printed. 68// The array caps were guessed too (GM_MAXRUNG, GM_MAXMAT, GM_MAXDOM, GM_MAXWORDS): sizes are now DERIVED -- 69// rung and matrix records from a count over the file just read, the words array from argc in the CLI, the 70// output buffer from the domain count (gm_outbuf). ONE declared reserve remains, the per-domain scaffold, 71// and nx_goalmap_gate MEASURES it against a real emit instead of trusting this number. 72const GM_DOM_RESERVE: i64 = 400 73 74// ---- derived sizes (v1.2) ---- 75// non-empty comma tokens in a domains csv = the number of domain objects gm_run will emit 76func gm_ndom(domcsv: *u8) -> i64 { 77 var n: i64 = 0 78 var i: i64 = 0 79 var tok: i64 = 0 80 while domcsv[i] != (0 as u8) { 81 if domcsv[i] == (GM_COMMA as u8) { if tok == 1 { n = n + 1 } tok = 0 } else { tok = 1 } 82 i = i + 1 83 } 84 if tok == 1 { n = n + 1 } 85 return n 86} 87// the output buffer a caller must hand gm_run: the row budget, one scaffold reserve per domain, the tail 88func gm_outbuf(domcsv: *u8) -> i64 { return GM_OUTCAP + gm_ndom(domcsv) * GM_DOM_RESERVE + GM_TAIL_RESERVE } 89// lines of q[0..n) that start with pfx = the record count to allocate (a count, never a cap) 90func gm_count_pfx(q: *u8, n: i64, pfx: *u8) -> i64 { 91 let pl: i64 = sj_vlen(pfx) 92 var cnt: i64 = 0 93 var p: i64 = 0 94 while p < n { 95 let le: i64 = sj_le(q, p, n) 96 if le - p >= pl { if sj_lit_eq(q, p, p + pl, pfx) == 1 { cnt = cnt + 1 } } 97 p = le + 1 98 } 99 return cnt 100} 101// lines of q[0..n) = the matrix record count to allocate 102func gm_count_lines(q: *u8, n: i64) -> i64 { 103 var cnt: i64 = 0 104 var p: i64 = 0 105 while p < n { let le: i64 = sj_le(q, p, n); cnt = cnt + 1; p = le + 1 } 106 return cnt 107} 108 109// ---- byte helpers ---- 110func gm_lc(c: i64) -> i64 { if c >= GM_LC_A { if c <= GM_LC_Z { return c + GM_LC_D } } return c } 111 112func gm_span_eq(q: *u8, s1: i64, e1: i64, s2: i64, e2: i64) -> i64 { 113 if e1 - s1 != e2 - s2 { return 0 } 114 var i: i64 = 0 115 while s1 + i < e1 { if q[s1 + i] != q[s2 + i] { return 0 } i = i + 1 } 116 return 1 117} 118 119// case-insensitive: does the zero-terminated word occur inside q[s..e) 120func gm_has_ci(q: *u8, s: i64, e: i64, w: *u8) -> i64 { 121 let wl: i64 = sj_vlen(w) 122 if wl == 0 { return 0 } 123 var i: i64 = s 124 while i + wl <= e { 125 var k: i64 = 0 126 var ok: i64 = 1 127 while k < wl { 128 if ok == 1 { if gm_lc(q[i + k] as i64) != gm_lc(w[k] as i64) { ok = 0 } } 129 k = k + 1 130 } 131 if ok == 1 { return 1 } 132 i = i + 1 133 } 134 return 0 135} 136 137// position of lit inside q[s..e), or -1 138func gm_find(q: *u8, s: i64, e: i64, lit: *u8) -> i64 { 139 let ll: i64 = sj_vlen(lit) 140 if ll == 0 { return 0 - 1 } 141 var i: i64 = s 142 while i + ll <= e { 143 var k: i64 = 0 144 var ok: i64 = 1 145 while k < ll { if ok == 1 { if q[i + k] != lit[k] { ok = 0 } } k = k + 1 } 146 if ok == 1 { return i } 147 i = i + 1 148 } 149 return 0 - 1 150} 151 152// does q[s..e) contain the bytes n[ns..ne) 153func gm_span_has_span(q: *u8, s: i64, e: i64, n: *u8, ns: i64, ne: i64) -> i64 { 154 let ll: i64 = ne - ns 155 if ll <= 0 { return 0 } 156 var i: i64 = s 157 while i + ll <= e { 158 var k: i64 = 0 159 var ok: i64 = 1 160 while k < ll { if ok == 1 { if q[i + k] != n[ns + k] { ok = 0 } } k = k + 1 } 161 if ok == 1 { return 1 } 162 i = i + 1 163 } 164 return 0 165} 166 167// pipe-separated column c of the line q[ls..le) -> out[0]=start out[1]=end 168func gm_pcol(q: *u8, ls: i64, le: i64, c: i64, out: *i64) -> i64 { 169 var col: i64 = 0 170 var p: i64 = ls 171 while col < c { 172 var s: i64 = 1 173 while s == 1 { if p >= le { return 0 } if q[p] == (GM_PIPE as u8) { s = 0 } else { p = p + 1 } } 174 p = p + 1 175 col = col + 1 176 } 177 var e: i64 = p 178 var s2: i64 = 1 179 while s2 == 1 { if e >= le { s2 = 0 } else { if q[e] == (GM_PIPE as u8) { s2 = 0 } else { e = e + 1 } } } 180 out[0] = p 181 out[1] = e 182 return 1 183} 184 185// HEAD window of a file (rung rows live at the top of a plan); sizep[0] = TRUE size, return = bytes read, -1 unreadable 186func gm_read(path: *u8, buf: *u8, cap: i64, sizep: *i64) -> i64 { 187 sizep[0] = 0 188 let fd: i64 = sys_openat_rd(path) 189 if fd < 0 { return 0 - 1 } 190 var size: i64 = sys_lseek(fd, 0, GM_SEEK_END) 191 if size < 0 { size = 0 } 192 sizep[0] = size 193 sys_lseek(fd, 0, GM_SEEK_SET) 194 var n: i64 = 0 195 var go: i64 = 1 196 while go == 1 { 197 let r: i64 = sys_read(fd, ((buf as i64) + n) as *u8, cap - n) 198 if r <= 0 { go = 0 } else { n = n + r } 199 if n >= cap { go = 0 } 200 } 201 sys_close(fd) 202 return n 203} 204 205func gm_probe(path: *u8) -> i64 { 206 let fd: i64 = sys_openat_rd(path) 207 if fd < 0 { return 0 } 208 sys_close(fd) 209 return 1 210} 211 212// path = base + rel + span(q[s..e)) + suffix, zero-terminated into pb 213func gm_path(pb: *u8, base: *u8, rel: *u8, q: *u8, s: i64, e: i64, suffix: *u8) -> i64 { 214 var o: i64 = 0 215 o = sj_cat(pb, o, base) 216 o = sj_cat(pb, o, rel) 217 var i: i64 = s 218 while i < e { if o < GM_PATHB - 2 { pb[o] = q[i]; o = o + 1 } i = i + 1 } 219 o = sj_cat(pb, o, suffix) 220 pb[o] = 0 as u8 221 return o 222} 223 224// ---- rung records: GM_RF i64 per rung ---- 225// 0 ls 1 le 2 id_s 3 id_e 4 title_s 5 title_e 6 sym_s 7 sym_e 8 done_s 9 done_e 10 deps_s 11 deps_e 226// 12 score 13 status 14 log_rows 15 last_epoch 227func gm_rec(rec: *i64, i: i64, f: i64) -> i64 { return rec[i * GM_RF + f] } 228func gm_set(rec: *i64, i: i64, f: i64, v: i64) -> i64 { rec[i * GM_RF + f] = v; return 0 } 229 230func gm_setcol(q: *u8, rec: *i64, i: i64, ls: i64, le: i64, col: i64, fs: i64, sp: *i64) -> i64 { 231 if gm_pcol(q, ls, le, col, sp) == 1 { gm_set(rec, i, fs, sp[0]); gm_set(rec, i, fs + 1, sp[1]) } else { gm_set(rec, i, fs, ls); gm_set(rec, i, fs + 1, ls) } 232 return 0 233} 234 235// returns count, or -1 on a duplicate id (dup[0..1] = span of the SECOND occurrence); floor[0]=1 when GM_MAXRUNG bound the census 236func gm_parse_rungs(q: *u8, n: i64, rec: *i64, cap: i64, dup: *i64, floor: *i64) -> i64 { 237 var cnt: i64 = 0 238 var p: i64 = 0 239 let sp: *i64 = sys_mmap(GM_SPAN) as *i64 240 floor[0] = 0 241 while p < n { 242 let le: i64 = sj_le(q, p, n) 243 var isr: i64 = 0 244 if le - p >= GM_RUNG_PFX_LEN { if sj_lit_eq(q, p, p + GM_RUNG_PFX_LEN, "rung|" as *u8) == 1 { isr = 1 } } 245 if isr == 1 { 246 // cap = the count gm_count_pfx took over this same buffer, so the floor can only fire if the two scans disagree 247 if cnt >= cap { floor[0] = 1 } else { 248 gm_set(rec, cnt, 0, p); gm_set(rec, cnt, 1, le) 249 gm_setcol(q, rec, cnt, p, le, 1, 2, sp) 250 gm_setcol(q, rec, cnt, p, le, 2, 4, sp) 251 gm_setcol(q, rec, cnt, p, le, 3, 6, sp) 252 // v1.1: a rung whose own symbol column carries the watch prefix (rung|GE26|...|_ABSENT_:ws_gt_reproduce|...) 253 // names the SAME symbol as its matrix watch -- normalise the span here so the matrix status join and 254 // the accept- needle both see the core symbol (measured UNMAPPED on the first real run) 255 if gm_rec(rec, cnt, 7) - gm_rec(rec, cnt, 6) > GM_ABSENT_LEN { if sj_lit_eq(q, gm_rec(rec, cnt, 6), gm_rec(rec, cnt, 6) + GM_ABSENT_LEN, "_ABSENT_:" as *u8) == 1 { gm_set(rec, cnt, 6, gm_rec(rec, cnt, 6) + GM_ABSENT_LEN) } } 256 gm_setcol(q, rec, cnt, p, le, 4, 8, sp) 257 gm_setcol(q, rec, cnt, p, le, 7, 10, sp) 258 gm_set(rec, cnt, 12, 0); gm_set(rec, cnt, 13, GM_ST_UNMAPPED); gm_set(rec, cnt, 14, 0); gm_set(rec, cnt, 15, 0) 259 var j: i64 = 0 260 while j < cnt { 261 if gm_span_eq(q, gm_rec(rec, j, 2), gm_rec(rec, j, 3), gm_rec(rec, cnt, 2), gm_rec(rec, cnt, 3)) == 1 { 262 dup[0] = gm_rec(rec, cnt, 2); dup[1] = gm_rec(rec, cnt, 3) 263 return 0 - 1 264 } 265 j = j + 1 266 } 267 cnt = cnt + 1 268 } 269 } 270 p = le + 1 271 } 272 return cnt 273} 274 275// log|epoch|rung|kind|text -> per-rung ledger count + last epoch 276func gm_log_stats(q: *u8, n: i64, rec: *i64, nr: i64) -> i64 { 277 var p: i64 = 0 278 let sp: *i64 = sys_mmap(GM_SPAN) as *i64 279 let se: *i64 = sys_mmap(GM_SPAN) as *i64 280 var rows: i64 = 0 281 while p < n { 282 let le: i64 = sj_le(q, p, n) 283 var isl: i64 = 0 284 if le - p >= GM_LOG_PFX_LEN { if sj_lit_eq(q, p, p + GM_LOG_PFX_LEN, "log|" as *u8) == 1 { isl = 1 } } 285 if isl == 1 { 286 if gm_pcol(q, p, le, 2, sp) == 1 { 287 var ep: i64 = 0 288 if gm_pcol(q, p, le, 1, se) == 1 { ep = sj_atoi_span(q, se[0], se[1]) } 289 var i: i64 = 0 290 while i < nr { 291 if gm_span_eq(q, gm_rec(rec, i, 2), gm_rec(rec, i, 3), sp[0], sp[1]) == 1 { 292 gm_set(rec, i, 14, gm_rec(rec, i, 14) + 1) 293 if ep > gm_rec(rec, i, 15) { gm_set(rec, i, 15, ep) } 294 } 295 i = i + 1 296 } 297 rows = rows + 1 298 } 299 } 300 p = le + 1 301 } 302 return rows 303} 304 305// a query word that repeats an EARLIER query word is not a second word (T4: 'webgpu webgpu cast' scores 2, not 3) 306func gm_str_eq(a: *u8, b: *u8) -> i64 { 307 var i: i64 = 0 308 while a[i] != (0 as u8) { if gm_lc(a[i] as i64) != gm_lc(b[i] as i64) { return 0 } i = i + 1 } 309 if b[i] != (0 as u8) { return 0 } 310 return 1 311} 312func gm_word_dup(words: *i64, w: i64) -> i64 { 313 var j: i64 = 0 314 while j < w { if gm_str_eq(words[j] as *u8, words[w] as *u8) == 1 { return 1 } j = j + 1 } 315 return 0 316} 317 318// score = DISTINCT words found in title, done-rule or symbol (a repeated query word counts once) 319func gm_score(q: *u8, rec: *i64, i: i64, words: *i64, nw: i64) -> i64 { 320 var sc: i64 = 0 321 var w: i64 = 0 322 while w < nw { 323 let wp: *u8 = words[w] as *u8 324 var hit: i64 = 0 325 if gm_word_dup(words, w) == 0 { 326 if gm_has_ci(q, gm_rec(rec, i, 4), gm_rec(rec, i, 5), wp) == 1 { hit = 1 } 327 if hit == 0 { if gm_has_ci(q, gm_rec(rec, i, 8), gm_rec(rec, i, 9), wp) == 1 { hit = 1 } } 328 if hit == 0 { if gm_has_ci(q, gm_rec(rec, i, 6), gm_rec(rec, i, 7), wp) == 1 { hit = 1 } } 329 } 330 sc = sc + hit 331 w = w + 1 332 } 333 return sc 334} 335 336// ---- matrix records: GM_MF i64 per row ---- 337// 0 ls 1 le 2 label_s 3 label_e 4 organ_s 5 organ_e 6 sym_s 7 sym_e 8 absent 9 core_s 10 core_e 11 matched 338func gm_mrec(m: *i64, i: i64, f: i64) -> i64 { return m[i * GM_MF + f] } 339func gm_mset(m: *i64, i: i64, f: i64, v: i64) -> i64 { m[i * GM_MF + f] = v; return 0 } 340 341func gm_parse_matrix(q: *u8, n: i64, m: *i64, cap: i64, floor: *i64) -> i64 { 342 var cnt: i64 = 0 343 var p: i64 = 0 344 let sp: *i64 = sys_mmap(GM_SPAN) as *i64 345 floor[0] = 0 346 while p < n { 347 let le: i64 = sj_le(q, p, n) 348 var ok: i64 = 0 349 if le > p { if q[p] != (GM_HASH_BYTE as u8) { if gm_pcol(q, p, le, 2, sp) == 1 { ok = 1 } } } 350 if ok == 1 { 351 // cap = the line count gm_count_lines took over this same buffer; every row is a line, so the floor cannot fire 352 if cnt >= cap { floor[0] = 1 } else { 353 gm_mset(m, cnt, 0, p); gm_mset(m, cnt, 1, le) 354 gm_pcol(q, p, le, 0, sp); gm_mset(m, cnt, 2, sp[0]); gm_mset(m, cnt, 3, sp[1]) 355 gm_pcol(q, p, le, 1, sp); gm_mset(m, cnt, 4, sp[0]); gm_mset(m, cnt, 5, sp[1]) 356 gm_pcol(q, p, le, 2, sp); gm_mset(m, cnt, 6, sp[0]); gm_mset(m, cnt, 7, sp[1]) 357 var ab: i64 = 0 358 if sp[1] - sp[0] >= GM_ABSENT_LEN { if sj_lit_eq(q, sp[0], sp[0] + GM_ABSENT_LEN, "_ABSENT_:" as *u8) == 1 { ab = 1 } } 359 gm_mset(m, cnt, 8, ab) 360 if ab == 1 { gm_mset(m, cnt, 9, sp[0] + GM_ABSENT_LEN) } else { gm_mset(m, cnt, 9, sp[0]) } 361 gm_mset(m, cnt, 10, sp[1]) 362 gm_mset(m, cnt, 11, 0) 363 cnt = cnt + 1 364 } 365 } 366 p = le + 1 367 } 368 return cnt 369} 370 371// status from the matrix: a present row whose symbol equals the rung symbol = PRESENT; an _ABSENT_ watch = OPEN 372func gm_status_matrix(q: *u8, rec: *i64, i: i64, mq: *u8, m: *i64, nm: i64) -> i64 { 373 var st: i64 = GM_ST_UNMAPPED 374 var k: i64 = 0 375 let ss: i64 = gm_rec(rec, i, 6) 376 let se: i64 = gm_rec(rec, i, 7) 377 if se <= ss { return st } 378 while k < nm { 379 let cs: i64 = gm_mrec(m, k, 9) 380 let ce: i64 = gm_mrec(m, k, 10) 381 if ce - cs == se - ss { 382 var eq: i64 = 1 383 var t: i64 = 0 384 while t < ce - cs { if mq[cs + t] != q[ss + t] { eq = 0 } t = t + 1 } 385 if eq == 1 { if gm_mrec(m, k, 8) == 1 { if st == GM_ST_UNMAPPED { st = GM_ST_OPEN } } else { st = GM_ST_PRESENT } } 386 } 387 k = k + 1 388 } 389 return st 390} 391 392// operator plane: rows id TAB subject TAB verdict TAB date TAB actor TAB words TAB targets; targets carry <dom>:<sym> 393func gm_status_accept(q: *u8, rec: *i64, i: i64, dom: *u8, ab: *u8, an: i64, st0: i64) -> i64 { 394 var st: i64 = st0 395 if an <= 0 { return st } 396 let nb: *u8 = sys_mmap(GM_PATHB) 397 var o: i64 = 0 398 o = sj_cat(nb, o, dom) 399 nb[o] = GM_COLON as u8; o = o + 1 400 let ss: i64 = gm_rec(rec, i, 6) 401 let se: i64 = gm_rec(rec, i, 7) 402 var t: i64 = ss 403 while t < se { if o < GM_PATHB - 2 { nb[o] = q[t]; o = o + 1 } t = t + 1 } 404 let sp: *i64 = sys_mmap(GM_SPAN) as *i64 405 let tv: *i64 = sys_mmap(GM_SPAN) as *i64 406 var p: i64 = 0 407 while p < an { 408 let le: i64 = sj_le(ab, p, an) 409 if sj_col(ab, p, le, 6, sp) == 1 { 410 if gm_span_has_span(ab, sp[0], sp[1], nb, 0, o) == 1 { 411 if sj_col(ab, p, le, 2, tv) == 1 { 412 if sj_lit_eq(ab, tv[0], tv[1], "REJECT" as *u8) == 1 { st = GM_ST_REJECTED } 413 if sj_lit_eq(ab, tv[0], tv[1], "ACCEPT" as *u8) == 1 { st = GM_ST_ACCEPTED } 414 } 415 } 416 } 417 p = le + 1 418 } 419 return st 420} 421 422func gm_st_lit(c: i64) -> *u8 { 423 if c == GM_ST_OPEN { return "OPEN" as *u8 } 424 if c == GM_ST_PRESENT { return "PRESENT" as *u8 } 425 if c == GM_ST_REJECTED { return "PRESENT-REJECTED" as *u8 } 426 if c == GM_ST_ACCEPTED { return "ACCEPTED" as *u8 } 427 return "UNMAPPED" as *u8 428} 429 430// does rung i depend (deps column, comma list) on any MATCHED rung not yet emitted 431func gm_blocked(q: *u8, rec: *i64, i: i64, mi: *i64, nm: i64, em: *i64) -> i64 { 432 let ds: i64 = gm_rec(rec, i, 10) 433 let de: i64 = gm_rec(rec, i, 11) 434 var ts: i64 = ds 435 var t: i64 = ds 436 var blocked: i64 = 0 437 while t <= de { 438 var endtok: i64 = 0 439 if t == de { endtok = 1 } else { if q[t] == (GM_COMMA as u8) { endtok = 1 } } 440 if endtok == 1 { 441 if t > ts { 442 var k: i64 = 0 443 while k < nm { 444 if em[k] == 0 { 445 let r: i64 = mi[k] 446 if r != i { if gm_span_eq(q, gm_rec(rec, r, 2), gm_rec(rec, r, 3), ts, t) == 1 { blocked = 1 } } 447 } 448 k = k + 1 449 } 450 } 451 ts = t + 1 452 } 453 t = t + 1 454 } 455 return blocked 456} 457 458// Kahn-like order over matched rungs: repeatedly emit the unblocked rung with the highest score (file order on ties). 459// order[] receives matched-list indices; returns count; cycle[0]=1 when the remainder was emitted in file order. 460func gm_order(q: *u8, rec: *i64, mi: *i64, nm: i64, order: *i64, cycle: *i64) -> i64 { 461 let em: *i64 = sys_mmap(nm * 8 + 8) as *i64 // v1.2: sized from the matched count, never from a cap 462 var k: i64 = 0 463 while k < nm { em[k] = 0; k = k + 1 } 464 var done: i64 = 0 465 cycle[0] = 0 466 var progress: i64 = 1 467 while done < nm { 468 if progress == 0 { 469 cycle[0] = 1 470 var z: i64 = 0 471 while z < nm { if em[z] == 0 { order[done] = z; em[z] = 1; done = done + 1 } z = z + 1 } 472 } else { 473 var best: i64 = 0 - 1 474 var bs: i64 = 0 - 1 475 var c: i64 = 0 476 while c < nm { 477 if em[c] == 0 { 478 if gm_blocked(q, rec, mi[c], mi, nm, em) == 0 { 479 let sc: i64 = gm_rec(rec, mi[c], 12) 480 if sc > bs { bs = sc; best = c } 481 } 482 } 483 c = c + 1 484 } 485 if best < 0 { progress = 0 } else { order[done] = best; em[best] = 1; done = done + 1 } 486 } 487 } 488 return done 489} 490 491// basename of an organ path without its .nx extension, into pb (zero-terminated) 492func gm_basename(pb: *u8, q: *u8, s: i64, e: i64) -> i64 { 493 var bs: i64 = s 494 var t: i64 = s 495 while t < e { if q[t] == (GM_SLASH as u8) { bs = t + 1 } t = t + 1 } 496 var be: i64 = e 497 if e - bs > 3 { if q[e - 3] == (GM_DOT as u8) { if q[e - 2] == (110 as u8) { if q[e - 1] == (120 as u8) { be = e - 3 } } } } 498 var o: i64 = 0 499 t = bs 500 while t < be { if o < GM_WORDB - 2 { pb[o] = q[t]; o = o + 1 } t = t + 1 } 501 pb[o] = 0 as u8 502 return o 503} 504 505func gm_room(o: i64, need: i64) -> i64 { if o + need + GM_TAIL_RESERVE <= GM_OUTCAP { return 1 } return 0 } 506 507// ---- the run ---- 508// ==== EC38 RECORD GAPS (2026-09-06): the estate mines its OWN RECORD for compare-worthy work no board carries ==== 509// Operator standing order (verbatim on ecosystem.plan EC38): mine the logs and transcripts and memory and everything for 510// anything that should be on a /compare domain but was missed on being flagged, so that callouts are never the mechanism 511// of the 1-2-3 step program. The DECLARED source set is knowledge/recordgaps.conf (source|<kind>|<path>, plane|<prefix>). 512// BOARDED is derived from the files this mapper already reads, for every domain in <plans>/regen.list: each <dom>.matrix 513// row's organ basename and symbol, each <dom>.plan rung symbol, each <dom>.gates row's organ. Candidates: 514// ORGAN a tool the estate actually RAN (the freq JSON `nx_actlog freq <journal> <topn>` writes) that no board 515// carries; frames without the nx_ prefix (harness Bash/PowerShell/Edit/Read) are COUNTED as skipped 516// DIRECTIVE an nx_ organ or an _ABSENT_:symbol named inside a <dom>.plan log|..|queue| row that no board carries -- 517// a seat's callout is ONE INPUT CLASS among the sources, never the mechanism 518// SYMBOL / DEFECT declared classes NOT read in v1 (debt rows, symbols in prose): printed with a zero count and 519// status UNIMPLEMENTED, never silently absent 520// The candidate plane (default knowledge/store/comparegaps-) is REWRITTEN WHOLE by sts_seed on every run, so the verb 521// is idempotent; rows kind|name|board|source|evidence. The partition organ+directive+symbol+defect is printed AND summed. 522const GR_MAXNAMES: i64 = 65536 // name-set slots; when reached the census prints floor=1 (a FLOOR, never a total) 523const GR_NAMEB: i64 = 2097152 // name arena bytes 524const GR_MAXCAND: i64 = 32768 // candidate slots; floor printed when reached 525const GR_EVB: i64 = 4194304 // candidate board+evidence arena bytes 526const GR_OUTB: i64 = 1048576 // the JSON the verb prints (rows inline are capped at GR_SHOWN_CAP; the plane is whole) 527const GR_SHOWN_CAP: i64 = 200 528const GR_KIND_ORGAN: i64 = 0 529const GR_KIND_DIRECTIVE: i64 = 1 530const GR_KIND_SYMBOL: i64 = 2 531const GR_KIND_DEFECT: i64 = 3 532const GR_KINDS: i64 = 4 533const GR_PLANE_DEFAULT: *u8 = "knowledge/store/comparegaps-" 534const GR_CONF_DEFAULT: *u8 = "knowledge/recordgaps.conf" 535const GR_UNDERSCORE: i64 = 95 536const GR_LOW_A: i64 = 97 537const GR_LOW_Z: i64 = 122 538const GR_D0: i64 = 48 539const GR_D9: i64 = 57 540const GR_QUOTE: i64 = 34 541const GR_ABSENT_PFX: i64 = 9 // len("_ABSENT_:") 542const GR_MCP_PFX: i64 = 12 // len("mcp__nishi__") 543const GR_NXPFX: i64 = 3 // len("nx_") 544const GR_ROW_RESERVE_LOCAL: i64 = 1200 545const GM_RBRACE_BYTE: i64 = 125 546const GR_ROWS_SFX: *u8 = ".rows" // the RENDER FEED beside the conf: the same bytes the plane received, truncate-written by the same run, read by the compare emitter with a plain file read (the emitter never links the seg store) 547const GR_STAMP_SFX: *u8 = ".stamp" // the gauge heartbeat beside the conf (nx_gauge_lib shape): gauge = candidates total, axes = sources READ of sources DECLARED -- BLIND until every declared source has a reader, by construction; derived from the conf path so a fixture run can never forge the production heartbeat 548const GR_CADENCE_DEFAULT: i64 = 86400 // the record beat's declared cadence; a conf row cadence|<secs> overrides it 549const GR_MODE_RW: i64 = 420 550// source kinds (conf column 1) -> slot in the sources table; a kind this reader does not know is counted UNKNOWN 551const GR_S_INVOKED: i64 = 0 552const GR_S_JOURNAL: i64 = 1 553const GR_S_PLANS: i64 = 2 554const GR_S_GATES: i64 = 3 555const GR_S_DEBT: i64 = 4 556const GR_S_MEMORY: i64 = 5 557const GR_S_TRANSCRIPTS: i64 = 6 558const GR_S_N: i64 = 7 559func gr_is_ident(c: i64) -> i64 { 560 if c == GR_UNDERSCORE { return 1 } 561 if c >= GR_LOW_A { if c <= GR_LOW_Z { return 1 } } 562 if c >= GR_D0 { if c <= GR_D9 { return 1 } } 563 return 0 564} 565// name set over an arena: nb bytes, no[] offsets, nl[] lengths, nn count. find -> index or -1 566func gr_name_find(nb: *u8, no: *i64, nl: *i64, nn: i64, s: *u8, ss: i64, se: i64) -> i64 { 567 let len: i64 = se - ss 568 var i: i64 = 0 569 while i < nn { 570 if nl[i] == len { 571 var j: i64 = 0 572 var same: i64 = 1 573 while j < len { if nb[no[i] + j] != s[ss + j] { same = 0 } j = j + 1 } 574 if same == 1 { return i } 575 } 576 i = i + 1 577 } 578 return 0 - 1 579} 580// add s[ss..se) when new; returns 1 added, 0 present or empty; floor[0]=1 when the set is full (never silent) 581func gr_name_add(nb: *u8, no: *i64, nl: *i64, nnp: *i64, bp: *i64, s: *u8, ss: i64, se: i64, floor: *i64) -> i64 { 582 if se <= ss { return 0 } 583 if gr_name_find(nb, no, nl, nnp[0], s, ss, se) >= 0 { return 0 } 584 if nnp[0] >= GR_MAXNAMES { floor[0] = 1; return 0 } 585 if bp[0] + (se - ss) + 1 >= GR_NAMEB { floor[0] = 1; return 0 } 586 let start: i64 = bp[0] 587 var j: i64 = ss 588 while j < se { nb[bp[0]] = s[j]; bp[0] = bp[0] + 1; j = j + 1 } 589 no[nnp[0]] = start 590 nl[nnp[0]] = se - ss 591 nnp[0] = nnp[0] + 1 592 return 1 593} 594// the organ NAME inside a path-shaped span: after the last '/', minus one of .sov.elf / .elf / .nx, minus mcp__nishi__ 595func gr_organ_span(q: *u8, s: i64, e: i64, out: *i64) -> i64 { 596 var a: i64 = s 597 var i: i64 = s 598 while i < e { if q[i] == (GM_SLASH as u8) { a = i + 1 } i = i + 1 } 599 var b: i64 = e 600 if b - a > 8 { if sj_lit_eq(q, b - 8, b, ".sov.elf" as *u8) == 1 { b = b - 8 } } 601 if b - a > 4 { if sj_lit_eq(q, b - 4, b, ".elf" as *u8) == 1 { b = b - 4 } } 602 if b - a > 3 { if sj_lit_eq(q, b - 3, b, ".nx" as *u8) == 1 { b = b - 3 } } 603 if b - a > GR_MCP_PFX { if sj_lit_eq(q, a, a + GR_MCP_PFX, "mcp__nishi__" as *u8) == 1 { a = a + GR_MCP_PFX } } 604 out[0] = a 605 out[1] = b 606 return b - a 607} 608func gr_has_nxpfx(q: *u8, s: i64, e: i64) -> i64 { 609 if e - s <= GR_NXPFX { return 0 } 610 return sj_lit_eq(q, s, s + GR_NXPFX, "nx_" as *u8) 611} 612// names a <dom>.matrix carries: column 1 organ basename, column 2 symbol (minus _ABSENT_:) 613func gr_names_from_matrix(q: *u8, n: i64, nb: *u8, no: *i64, nl: *i64, nnp: *i64, bp: *i64, floor: *i64) -> i64 { 614 let sp: *i64 = sys_mmap(GM_SPAN) as *i64 615 let os: *i64 = sys_mmap(GM_SPAN) as *i64 616 var added: i64 = 0 617 var p: i64 = 0 618 while p < n { 619 let le: i64 = sj_le(q, p, n) 620 if le > p { if q[p] != (GM_HASH_BYTE as u8) { 621 if gm_pcol(q, p, le, 1, sp) == 1 { if gr_organ_span(q, sp[0], sp[1], os) > 0 { added = added + gr_name_add(nb, no, nl, nnp, bp, q, os[0], os[1], floor) } } 622 if gm_pcol(q, p, le, 2, sp) == 1 { 623 var ss: i64 = sp[0] 624 if sp[1] - sp[0] > GR_ABSENT_PFX { if sj_lit_eq(q, sp[0], sp[0] + GR_ABSENT_PFX, "_ABSENT_:" as *u8) == 1 { ss = sp[0] + GR_ABSENT_PFX } } 625 added = added + gr_name_add(nb, no, nl, nnp, bp, q, ss, sp[1], floor) 626 } 627 } } 628 p = le + 1 629 } 630 return added 631} 632// names a <dom>.plan carries: every rung row's symbol (column 3) 633func gr_names_from_plan(q: *u8, n: i64, nb: *u8, no: *i64, nl: *i64, nnp: *i64, bp: *i64, floor: *i64) -> i64 { 634 let sp: *i64 = sys_mmap(GM_SPAN) as *i64 635 var added: i64 = 0 636 var p: i64 = 0 637 while p < n { 638 let le: i64 = sj_le(q, p, n) 639 if le > p { if le - p > GM_RUNG_PFX_LEN { if sj_lit_eq(q, p, p + GM_RUNG_PFX_LEN, "rung|" as *u8) == 1 { 640 if gm_pcol(q, p, le, 3, sp) == 1 { added = added + gr_name_add(nb, no, nl, nnp, bp, q, sp[0], sp[1], floor) } 641 } } } 642 p = le + 1 643 } 644 return added 645} 646// names a <dom>.gates carries: column 0 organ (an elf path) 647func gr_names_from_gates(q: *u8, n: i64, nb: *u8, no: *i64, nl: *i64, nnp: *i64, bp: *i64, floor: *i64) -> i64 { 648 let sp: *i64 = sys_mmap(GM_SPAN) as *i64 649 let os: *i64 = sys_mmap(GM_SPAN) as *i64 650 var added: i64 = 0 651 var p: i64 = 0 652 while p < n { 653 let le: i64 = sj_le(q, p, n) 654 if le > p { if q[p] != (GM_HASH_BYTE as u8) { 655 if gm_pcol(q, p, le, 0, sp) == 1 { if gr_organ_span(q, sp[0], sp[1], os) > 0 { added = added + gr_name_add(nb, no, nl, nnp, bp, q, os[0], os[1], floor) } } 656 } } 657 p = le + 1 658 } 659 return added 660} 661// candidate table: kind[], name span in the name arena (cn offsets/lengths via a SECOND name set), board+evidence in ev arena 662func gr_cand_add(kind: *i64, cno: *i64, cnl: *i64, cb: *u8, cbp: *i64, ncp: *i64, evo: *i64, evl: *i64, eb: *u8, ebp: *i64, k: i64, q: *u8, ns: i64, ne: i64, ev: *u8, evn: i64, floor: *i64) -> i64 { 663 if gr_name_find(cb, cno, cnl, ncp[0], q, ns, ne) >= 0 { return 0 } 664 if ncp[0] >= GR_MAXCAND { floor[0] = 1; return 0 } 665 if ebp[0] + evn + 1 >= GR_EVB { floor[0] = 1; return 0 } 666 let before: i64 = ncp[0] 667 let dummy: *i64 = sys_mmap(GM_SPAN) as *i64 668 dummy[0] = 0 669 if gr_name_add(cb, cno, cnl, ncp, cbp, q, ns, ne, dummy) == 0 { return 0 } 670 if dummy[0] == 1 { floor[0] = 1 } 671 kind[before] = k 672 evo[before] = ebp[0] 673 evl[before] = evn 674 var j: i64 = 0 675 while j < evn { eb[ebp[0]] = ev[j]; ebp[0] = ebp[0] + 1; j = j + 1 } 676 return 1 677} 678func gr_atoi(b: *u8, s: i64, e: i64) -> i64 { var v: i64 = 0; var i: i64 = s; while i < e { let c: i64 = b[i] as i64; if c >= GR_D0 { if c <= GR_D9 { v = v * (10 as i64) + (c - GR_D0) } } i = i + 1 } return v } 679// the conf: source|kind|path rows into paths[GR_S_N] (each a zero-terminated copy), plane|prefix, cadence|secs; returns rows read 680func gr_conf_load(conf: *u8, paths: *i64, plane: *u8, declared: *i64, unknown: *i64, cad: *i64) -> i64 { 681 let buf: *u8 = sys_mmap(GM_CAP) 682 let szp: *i64 = sys_mmap(GM_SPAN) as *i64 683 let n: i64 = gm_read(conf, buf, GM_CAP, szp) 684 if n <= 0 { return 0 - 1 } 685 let sp: *i64 = sys_mmap(GM_SPAN) as *i64 686 let vp: *i64 = sys_mmap(GM_SPAN) as *i64 687 var rows: i64 = 0 688 var p: i64 = 0 689 while p < n { 690 let le: i64 = sj_le(buf, p, n) 691 if le > p { if buf[p] != (GM_HASH_BYTE as u8) { 692 if gm_pcol(buf, p, le, 0, sp) == 1 { 693 if sj_lit_eq(buf, sp[0], sp[1], "source" as *u8) == 1 { 694 rows = rows + 1 695 var slot: i64 = 0 - 1 696 if gm_pcol(buf, p, le, 1, sp) == 1 { 697 if sj_lit_eq(buf, sp[0], sp[1], "invoked" as *u8) == 1 { slot = GR_S_INVOKED } 698 if sj_lit_eq(buf, sp[0], sp[1], "journal" as *u8) == 1 { slot = GR_S_JOURNAL } 699 if sj_lit_eq(buf, sp[0], sp[1], "plans" as *u8) == 1 { slot = GR_S_PLANS } 700 if sj_lit_eq(buf, sp[0], sp[1], "gates" as *u8) == 1 { slot = GR_S_GATES } 701 if sj_lit_eq(buf, sp[0], sp[1], "debt" as *u8) == 1 { slot = GR_S_DEBT } 702 if sj_lit_eq(buf, sp[0], sp[1], "memory" as *u8) == 1 { slot = GR_S_MEMORY } 703 if sj_lit_eq(buf, sp[0], sp[1], "transcripts" as *u8) == 1 { slot = GR_S_TRANSCRIPTS } 704 } 705 if slot < 0 { unknown[0] = unknown[0] + 1 } else { 706 declared[slot] = 1 707 if gm_pcol(buf, p, le, 2, vp) == 1 { 708 let dst: *u8 = paths[slot] as *u8 709 var o: i64 = 0 710 var i: i64 = vp[0] 711 while i < vp[1] { if o < GM_PATHB - 2 { dst[o] = buf[i]; o = o + 1 } i = i + 1 } 712 dst[o] = 0 as u8 713 } 714 } 715 } 716 if sj_lit_eq(buf, sp[0], sp[1], "plane" as *u8) == 1 { 717 rows = rows + 1 718 if gm_pcol(buf, p, le, 1, vp) == 1 { 719 var o2: i64 = 0 720 var i2: i64 = vp[0] 721 while i2 < vp[1] { if o2 < GM_PATHB - 2 { plane[o2] = buf[i2]; o2 = o2 + 1 } i2 = i2 + 1 } 722 plane[o2] = 0 as u8 723 } 724 } 725 if sj_lit_eq(buf, sp[0], sp[1], "cadence" as *u8) == 1 { 726 rows = rows + 1 727 if gm_pcol(buf, p, le, 1, vp) == 1 { let cv: i64 = gr_atoi(buf, vp[0], vp[1]); if cv > 0 { cad[0] = cv } } 728 } 729 } 730 } } 731 p = le + 1 732 } 733 return rows 734} 735// the invoked population: every "tv":"<tool>:<verb>" ... "count":<n> in the freq JSON. stats: 0 distinct 1 harness_skipped 736func gr_scan_invoked(fq: *u8, fn: i64, nb: *u8, no: *i64, nl: *i64, nn: i64, kind: *i64, cno: *i64, cnl: *i64, cb: *u8, cbp: *i64, ncp: *i64, evo: *i64, evl: *i64, eb: *u8, ebp: *i64, stats: *i64, floor: *i64) -> i64 { 737 let os: *i64 = sys_mmap(GM_SPAN) as *i64 738 let ev: *u8 = sys_mmap(GM_PATHB) 739 var added: i64 = 0 740 var i: i64 = 0 741 while i + 6 <= fn { 742 if sj_lit_eq(fq, i, i + 6, "\"tv\":\"" as *u8) == 1 { 743 let s: i64 = i + 6 744 var e: i64 = s 745 var scan: i64 = 1 746 while scan == 1 { if e >= fn { scan = 0 } else { if fq[e] == (GR_QUOTE as u8) { scan = 0 } else { e = e + 1 } } } 747 // the tool is everything before the LAST colon of the tv string 748 var colon: i64 = 0 - 1 749 var m: i64 = s 750 while m < e { if fq[m] == (GM_COLON as u8) { colon = m } m = m + 1 } 751 var te: i64 = e 752 if colon >= 0 { te = colon } 753 stats[0] = stats[0] + 1 754 // the count right after: "count":<digits> 755 var cnt: i64 = 0 756 var c: i64 = e 757 var found: i64 = 0 758 var look: i64 = 1 759 while look == 1 { 760 if c + 8 > fn { look = 0 } else { 761 if sj_lit_eq(fq, c, c + 8, "\"count\":" as *u8) == 1 { 762 var d: i64 = c + 8 763 var dig: i64 = 1 764 while dig == 1 { if d >= fn { dig = 0 } else { let ch: i64 = fq[d] as i64; if ch >= GR_D0 { if ch <= GR_D9 { cnt = cnt * (10 as i64) + (ch - GR_D0); d = d + 1 } else { dig = 0 } } else { dig = 0 } } } 765 found = 1 766 look = 0 767 } else { if fq[c] == (GM_RBRACE_BYTE as u8) { look = 0 } else { c = c + 1 } } 768 } 769 } 770 if gr_organ_span(fq, s, te, os) > 0 { 771 if gr_has_nxpfx(fq, os[0], os[1]) == 0 { stats[1] = stats[1] + 1 } else { 772 if gr_name_find(nb, no, nl, nn, fq, os[0], os[1]) < 0 { 773 var eo: i64 = sj_cat(ev, 0, "UNASSIGNED|invoked|count=" as *u8) 774 eo = sj_catn(ev, eo, cnt) 775 added = added + gr_cand_add(kind, cno, cnl, cb, cbp, ncp, evo, evl, eb, ebp, GR_KIND_ORGAN, fq, os[0], os[1], ev, eo, floor) 776 } 777 } 778 } 779 i = e 780 } else { i = i + 1 } 781 } 782 return added 783} 784// directives: every log|ts|rung|queue|text row of one plan; nx_ organs and _ABSENT_:symbols in the text not boarded 785func gr_scan_plan_queue(q: *u8, n: i64, dom: *u8, ds: i64, de: i64, nb: *u8, no: *i64, nl: *i64, nn: i64, kind: *i64, cno: *i64, cnl: *i64, cb: *u8, cbp: *i64, ncp: *i64, evo: *i64, evl: *i64, eb: *u8, ebp: *i64, stats: *i64, floor: *i64) -> i64 { 786 let sp: *i64 = sys_mmap(GM_SPAN) as *i64 787 let rp: *i64 = sys_mmap(GM_SPAN) as *i64 788 let ev: *u8 = sys_mmap(GM_PATHB) 789 var added: i64 = 0 790 var p: i64 = 0 791 while p < n { 792 let le: i64 = sj_le(q, p, n) 793 if le > p { if le - p > GM_LOG_PFX_LEN { if sj_lit_eq(q, p, p + GM_LOG_PFX_LEN, "log|" as *u8) == 1 { 794 if gm_pcol(q, p, le, 3, sp) == 1 { if sj_lit_eq(q, sp[0], sp[1], "queue" as *u8) == 1 { 795 stats[2] = stats[2] + 1 796 gm_pcol(q, p, le, 2, rp) 797 if gm_pcol(q, p, le, 4, sp) == 1 { 798 var i: i64 = sp[0] 799 while i < sp[1] { 800 var ts: i64 = 0 - 1 801 if i + GR_ABSENT_PFX < sp[1] { if sj_lit_eq(q, i, i + GR_ABSENT_PFX, "_ABSENT_:" as *u8) == 1 { ts = i + GR_ABSENT_PFX } } 802 if ts < 0 { if i + GR_NXPFX < sp[1] { if sj_lit_eq(q, i, i + GR_NXPFX, "nx_" as *u8) == 1 { 803 var boundary: i64 = 1 804 if i > sp[0] { if gr_is_ident(q[i - 1] as i64) == 1 { boundary = 0 } } 805 if boundary == 1 { ts = i } 806 } } } 807 if ts >= 0 { 808 var te: i64 = ts 809 // a FLAG ends the scan, never a sentinel in the cursor: the first cut wrote sp[1]+1 into te to exit and 810 // every token then "ended" at the column end (measured: one directive named the whole 48-byte window) 811 var tscan: i64 = 1 812 while tscan == 1 { if te >= sp[1] { tscan = 0 } else { if gr_is_ident(q[te] as i64) == 1 { te = te + 1 } else { tscan = 0 } } } 813 if te > ts { 814 if gr_name_find(nb, no, nl, nn, q, ts, te) < 0 { 815 var eo: i64 = 0 816 var dd: i64 = ds 817 while dd < de { ev[eo] = dom[dd]; eo = eo + 1; dd = dd + 1 } 818 eo = sj_cat(ev, eo, "|plan-queue|rung=" as *u8) 819 var rr: i64 = rp[0] 820 while rr < rp[1] { if eo < GM_PATHB - 2 { ev[eo] = q[rr]; eo = eo + 1 } rr = rr + 1 } 821 added = added + gr_cand_add(kind, cno, cnl, cb, cbp, ncp, evo, evl, eb, ebp, GR_KIND_DIRECTIVE, q, ts, te, ev, eo, floor) 822 } 823 i = te 824 } else { i = i + 1 } 825 } else { i = i + 1 } 826 } 827 } 828 } } 829 } } } 830 p = le + 1 831 } 832 return added 833} 834func gr_kind_name(k: i64) -> *u8 { 835 if k == GR_KIND_ORGAN { return "organ" as *u8 } 836 if k == GR_KIND_DIRECTIVE { return "directive" as *u8 } 837 if k == GR_KIND_SYMBOL { return "symbol" as *u8 } 838 return "defect" as *u8 839} 840func gr_src_name(s: i64) -> *u8 { 841 if s == GR_S_INVOKED { return "invoked" as *u8 } 842 if s == GR_S_JOURNAL { return "journal" as *u8 } 843 if s == GR_S_PLANS { return "plans" as *u8 } 844 if s == GR_S_GATES { return "gates" as *u8 } 845 if s == GR_S_DEBT { return "debt" as *u8 } 846 if s == GR_S_MEMORY { return "memory" as *u8 } 847 return "transcripts" as *u8 848} 849// THE VERB. out must hold GR_OUTB. Returns bytes written to out, or -1 when the conf is unreadable, -3 when no domain 850// list is readable (an unobservable census writes no plane and says so). 851func gm_record_gaps(conf: *u8, out: *u8) -> i64 { 852 let paths: *i64 = sys_mmap(GR_S_N * 8) as *i64 853 var s: i64 = 0 854 while s < GR_S_N { let pb: *u8 = sys_mmap(GM_PATHB); pb[0] = 0 as u8; paths[s] = pb as i64; s = s + 1 } 855 let plane: *u8 = sys_mmap(GM_PATHB) 856 sj_cat(plane, 0, GR_PLANE_DEFAULT) 857 let declared: *i64 = sys_mmap(GR_S_N * 8) as *i64 858 let unknown: *i64 = sys_mmap(GM_SPAN) as *i64 859 unknown[0] = 0 860 let cadp: *i64 = sys_mmap(GM_SPAN) as *i64 861 cadp[0] = GR_CADENCE_DEFAULT 862 let crows: i64 = gr_conf_load(conf, paths, plane, declared, unknown, cadp) 863 if crows < 0 { return 0 - 1 } 864 // the boarded set 865 let nb: *u8 = sys_mmap(GR_NAMEB) 866 let no: *i64 = sys_mmap(GR_MAXNAMES * 8) as *i64 867 let nl: *i64 = sys_mmap(GR_MAXNAMES * 8) as *i64 868 let nnp: *i64 = sys_mmap(GM_SPAN) as *i64 869 let bp: *i64 = sys_mmap(GM_SPAN) as *i64 870 let floor: *i64 = sys_mmap(GM_SPAN) as *i64 871 nnp[0] = 0; bp[0] = 0; floor[0] = 0 872 let stats: *i64 = sys_mmap(GM_SPAN6) as *i64 873 var z: i64 = 0 874 while z < 6 { stats[z] = 0; z = z + 1 } 875 let plans: *u8 = paths[GR_S_PLANS] as *u8 876 let gates: *u8 = paths[GR_S_GATES] as *u8 877 let pb2: *u8 = sys_mmap(GM_PATHB) 878 let doms: *u8 = sys_mmap(GM_CAP) 879 let dszp: *i64 = sys_mmap(GM_SPAN) as *i64 880 var dn: i64 = 0 881 if plans[0] != (0 as u8) { gm_path(pb2, "" as *u8, plans, plans, 0, 0, "regen.list" as *u8); dn = gm_read(pb2, doms, GM_CAP, dszp) } 882 if dn <= 0 { return 0 - 3 } 883 let fbuf: *u8 = sys_mmap(GM_CAP) 884 let fszp: *i64 = sys_mmap(GM_SPAN) as *i64 885 var ndom: i64 = 0 886 var p: i64 = 0 887 while p < dn { 888 let le: i64 = sj_le(doms, p, dn) 889 if le > p { if doms[p] != (GM_HASH_BYTE as u8) { 890 ndom = ndom + 1 891 gm_path(pb2, "" as *u8, plans, doms, p, le, ".matrix" as *u8) 892 var fn: i64 = gm_read(pb2, fbuf, GM_CAP, fszp) 893 if fn > 0 { stats[3] = stats[3] + 1; gr_names_from_matrix(fbuf, fn, nb, no, nl, nnp, bp, floor) } 894 gm_path(pb2, "" as *u8, plans, doms, p, le, ".plan" as *u8) 895 fn = gm_read(pb2, fbuf, GM_CAP, fszp) 896 if fn > 0 { stats[4] = stats[4] + 1; gr_names_from_plan(fbuf, fn, nb, no, nl, nnp, bp, floor) } 897 if gates[0] != (0 as u8) { 898 gm_path(pb2, "" as *u8, gates, doms, p, le, ".gates" as *u8) 899 fn = gm_read(pb2, fbuf, GM_CAP, fszp) 900 if fn > 0 { stats[5] = stats[5] + 1; gr_names_from_gates(fbuf, fn, nb, no, nl, nnp, bp, floor) } 901 } 902 } } 903 p = le + 1 904 } 905 let boarded: i64 = nnp[0] 906 // candidates 907 let kind: *i64 = sys_mmap(GR_MAXCAND * 8) as *i64 908 let cno: *i64 = sys_mmap(GR_MAXCAND * 8) as *i64 909 let cnl: *i64 = sys_mmap(GR_MAXCAND * 8) as *i64 910 let cb: *u8 = sys_mmap(GR_NAMEB) 911 let cbp: *i64 = sys_mmap(GM_SPAN) as *i64 912 let ncp: *i64 = sys_mmap(GM_SPAN) as *i64 913 let evo: *i64 = sys_mmap(GR_MAXCAND * 8) as *i64 914 let evl: *i64 = sys_mmap(GR_MAXCAND * 8) as *i64 915 let eb: *u8 = sys_mmap(GR_EVB) 916 let ebp: *i64 = sys_mmap(GM_SPAN) as *i64 917 cbp[0] = 0; ncp[0] = 0; ebp[0] = 0 918 let cfloor: *i64 = sys_mmap(GM_SPAN) as *i64 919 cfloor[0] = 0 920 let istats: *i64 = sys_mmap(GM_SPAN6) as *i64 921 istats[0] = 0; istats[1] = 0; istats[2] = 0 922 var invoked_read: i64 = 0 923 let fpath: *u8 = paths[GR_S_INVOKED] as *u8 924 if fpath[0] != (0 as u8) { 925 let fq: *u8 = sys_mmap(GM_CAP) 926 let fqn: i64 = gm_read(fpath, fq, GM_CAP, fszp) 927 if fqn > 0 { invoked_read = 1; gr_scan_invoked(fq, fqn, nb, no, nl, boarded, kind, cno, cnl, cb, cbp, ncp, evo, evl, eb, ebp, istats, cfloor) } 928 } 929 p = 0 930 while p < dn { 931 let le: i64 = sj_le(doms, p, dn) 932 if le > p { if doms[p] != (GM_HASH_BYTE as u8) { 933 gm_path(pb2, "" as *u8, plans, doms, p, le, ".plan" as *u8) 934 let fn2: i64 = gm_read(pb2, fbuf, GM_CAP, fszp) 935 if fn2 > 0 { gr_scan_plan_queue(fbuf, fn2, doms, p, le, nb, no, nl, boarded, kind, cno, cnl, cb, cbp, ncp, evo, evl, eb, ebp, istats, cfloor) } 936 } } 937 p = le + 1 938 } 939 // partition 940 let per: *i64 = sys_mmap(GR_KINDS * 8) as *i64 941 var k: i64 = 0 942 while k < GR_KINDS { per[k] = 0; k = k + 1 } 943 var c: i64 = 0 944 while c < ncp[0] { per[kind[c]] = per[kind[c]] + 1; c = c + 1 } 945 var psum: i64 = 0 946 k = 0 947 while k < GR_KINDS { psum = psum + per[k]; k = k + 1 } 948 // the plane, rewritten whole: kind|name|board|source|evidence per row 949 let pbuf: *u8 = sys_mmap(GR_EVB) 950 var po: i64 = 0 951 c = 0 952 while c < ncp[0] { 953 po = sj_cat(pbuf, po, gr_kind_name(kind[c])) 954 pbuf[po] = GM_PIPE as u8; po = po + 1 955 var j: i64 = 0 956 while j < cnl[c] { pbuf[po] = cb[cno[c] + j]; po = po + 1; j = j + 1 } 957 pbuf[po] = GM_PIPE as u8; po = po + 1 958 j = 0 959 while j < evl[c] { pbuf[po] = eb[evo[c] + j]; po = po + 1; j = j + 1 } 960 pbuf[po] = GM_NL as u8; po = po + 1 961 c = c + 1 962 } 963 var prows: i64 = 0 964 if plane[0] != (0 as u8) { prows = sts_seed(plane, pbuf, po) } 965 // the RENDER FEED and the HEARTBEAT, both DERIVED from the conf path (a fixture run stamps its own fixture, never 966 // production): the feed is the plane's own bytes under a header; the stamp's axes are sources READ of sources DECLARED 967 var known: i64 = 0 968 if invoked_read == 1 { known = known + 1 } 969 if stats[4] > 0 { known = known + 1 } 970 if stats[5] > 0 { known = known + 1 } 971 if declared[GR_S_JOURNAL] == 1 { known = known + 1 } 972 var decl: i64 = 0 973 s = 0 974 while s < GR_S_N { if declared[s] == 1 { decl = decl + 1 } s = s + 1 } 975 let now: i64 = sys_now_realtime_sec() 976 let rpath: *u8 = sys_mmap(GM_PATHB) 977 var rpo: i64 = sj_cat(rpath, 0, conf); rpo = sj_cat(rpath, rpo, GR_ROWS_SFX); rpath[rpo] = 0 as u8 978 let spath: *u8 = sys_mmap(GM_PATHB) 979 var spo: i64 = sj_cat(spath, 0, conf); spo = sj_cat(spath, spo, GR_STAMP_SFX); spath[spo] = 0 as u8 980 var rows_wrote: i64 = 0 - 1 981 sys_unlinkat(rpath) 982 let rfd: i64 = sys_openat_wr(rpath, GR_MODE_RW) 983 if rfd >= 0 { 984 let hb: *u8 = sys_mmap(GM_PATHB) 985 var ho: i64 = sj_cat(hb, 0, "# comparegaps rows ts=" as *u8); ho = sj_catn(hb, ho, now) 986 ho = sj_cat(hb, ho, " total=" as *u8); ho = sj_catn(hb, ho, ncp[0]) 987 ho = sj_cat(hb, ho, " organ=" as *u8); ho = sj_catn(hb, ho, per[GR_KIND_ORGAN]) 988 ho = sj_cat(hb, ho, " directive=" as *u8); ho = sj_catn(hb, ho, per[GR_KIND_DIRECTIVE]) 989 ho = sj_cat(hb, ho, " sources_read=" as *u8); ho = sj_catn(hb, ho, known) 990 ho = sj_cat(hb, ho, " sources_declared=" as *u8); ho = sj_catn(hb, ho, decl) 991 hb[ho] = GM_NL as u8; ho = ho + 1 992 rows_wrote = sys_write(rfd, hb, ho) + sys_write(rfd, pbuf, po) 993 sys_close(rfd) 994 } 995 let stamp_wrote: i64 = ga_stamp_write(spath, now, ncp[0], known, decl, cadp[0]) 996 // the JSON 997 var o: i64 = 0 998 o = sj_cat(out, o, "{\"organ\":\"nx_goalmap\",\"verb\":\"record\",\"conf\":\"" as *u8) 999 o = sj_cat_esc(out, o, conf, 0, sj_vlen(conf), GM_PATHB) 1000 o = sj_cat(out, o, "\",\"conf_rows\":" as *u8); o = sj_catn(out, o, crows) 1001 o = sj_cat(out, o, ",\"conf_unknown_kinds\":" as *u8); o = sj_catn(out, o, unknown[0]) 1002 o = sj_cat(out, o, ",\"sources\":{" as *u8) 1003 s = 0 1004 while s < GR_S_N { 1005 if s > 0 { o = sj_cat(out, o, "," as *u8) } 1006 o = sj_cat(out, o, "\"" as *u8); o = sj_cat(out, o, gr_src_name(s)); o = sj_cat(out, o, "\":\"" as *u8) 1007 var st: *u8 = "UNDECLARED" as *u8 1008 if declared[s] == 1 { 1009 st = "UNIMPLEMENTED" as *u8 1010 if s == GR_S_INVOKED { st = "ABSENT" as *u8; if invoked_read == 1 { st = "READ" as *u8 } } 1011 if s == GR_S_PLANS { st = "READ" as *u8 } 1012 if s == GR_S_GATES { st = "READ" as *u8 } 1013 if s == GR_S_JOURNAL { st = "REFRESHED-BY-CLI" as *u8 } 1014 } 1015 o = sj_cat(out, o, st); o = sj_cat(out, o, "\"" as *u8) 1016 s = s + 1 1017 } 1018 o = sj_cat(out, o, "},\"domains\":" as *u8); o = sj_catn(out, o, ndom) 1019 o = sj_cat(out, o, ",\"matrices_read\":" as *u8); o = sj_catn(out, o, stats[3]) 1020 o = sj_cat(out, o, ",\"plans_read\":" as *u8); o = sj_catn(out, o, stats[4]) 1021 o = sj_cat(out, o, ",\"gates_read\":" as *u8); o = sj_catn(out, o, stats[5]) 1022 o = sj_cat(out, o, ",\"boarded_names\":" as *u8); o = sj_catn(out, o, boarded) 1023 o = sj_cat(out, o, ",\"boarded_floor\":" as *u8); o = sj_catn(out, o, floor[0]) 1024 o = sj_cat(out, o, ",\"invoked_distinct\":" as *u8); o = sj_catn(out, o, istats[0]) 1025 o = sj_cat(out, o, ",\"harness_skipped\":" as *u8); o = sj_catn(out, o, istats[1]) 1026 o = sj_cat(out, o, ",\"queue_rows\":" as *u8); o = sj_catn(out, o, istats[2]) 1027 o = sj_cat(out, o, ",\"candidates\":{" as *u8) 1028 k = 0 1029 while k < GR_KINDS { 1030 if k > 0 { o = sj_cat(out, o, "," as *u8) } 1031 o = sj_cat(out, o, "\"" as *u8); o = sj_cat(out, o, gr_kind_name(k)); o = sj_cat(out, o, "\":" as *u8); o = sj_catn(out, o, per[k]) 1032 k = k + 1 1033 } 1034 o = sj_cat(out, o, ",\"total\":" as *u8); o = sj_catn(out, o, ncp[0]) 1035 var ps: i64 = 0 1036 if psum == ncp[0] { ps = 1 } 1037 o = sj_cat(out, o, ",\"partition_sums\":" as *u8); o = sj_catn(out, o, ps) 1038 o = sj_cat(out, o, ",\"symbol_status\":\"UNIMPLEMENTED\",\"defect_status\":\"UNIMPLEMENTED\",\"candidates_floor\":" as *u8); o = sj_catn(out, o, cfloor[0]) 1039 o = sj_cat(out, o, "},\"rows\":[" as *u8) 1040 var shown: i64 = 0 1041 c = 0 1042 while c < ncp[0] { 1043 if shown < GR_SHOWN_CAP { if o + GR_ROW_RESERVE_LOCAL < GR_OUTB { 1044 if shown > 0 { o = sj_cat(out, o, "," as *u8) } 1045 o = sj_cat(out, o, "{\"kind\":\"" as *u8); o = sj_cat(out, o, gr_kind_name(kind[c])) 1046 o = sj_cat(out, o, "\",\"name\":\"" as *u8); o = sj_cat_esc(out, o, cb, cno[c], cno[c] + cnl[c], GM_SYM_ESC) 1047 o = sj_cat(out, o, "\",\"board_source_evidence\":\"" as *u8); o = sj_cat_esc(out, o, eb, evo[c], evo[c] + evl[c], GM_PATHB) 1048 o = sj_cat(out, o, "\"}" as *u8) 1049 shown = shown + 1 1050 } } 1051 c = c + 1 1052 } 1053 o = sj_cat(out, o, "],\"rows_shown\":" as *u8); o = sj_catn(out, o, shown) 1054 o = sj_cat(out, o, ",\"rows_of\":" as *u8); o = sj_catn(out, o, ncp[0]) 1055 o = sj_cat(out, o, ",\"plane\":\"" as *u8); o = sj_cat_esc(out, o, plane, 0, sj_vlen(plane), GM_PATHB) 1056 o = sj_cat(out, o, "\",\"plane_rows\":" as *u8); o = sj_catn(out, o, prows) 1057 o = sj_cat(out, o, ",\"rows_artifact\":\"" as *u8); o = sj_cat_esc(out, o, rpath, 0, rpo, GM_PATHB) 1058 o = sj_cat(out, o, "\",\"rows_artifact_wrote\":" as *u8); o = sj_catn(out, o, rows_wrote) 1059 o = sj_cat(out, o, ",\"stamp\":\"" as *u8); o = sj_cat_esc(out, o, spath, 0, spo, GM_PATHB) 1060 o = sj_cat(out, o, "\",\"stamp_wrote\":" as *u8); o = sj_catn(out, o, stamp_wrote) 1061 o = sj_cat(out, o, ",\"stamp_axes_known\":" as *u8); o = sj_catn(out, o, known) 1062 o = sj_cat(out, o, ",\"stamp_axes_total\":" as *u8); o = sj_catn(out, o, decl) 1063 o = sj_cat(out, o, ",\"cadence_s\":" as *u8); o = sj_catn(out, o, cadp[0]) 1064 o = sj_cat(out, o, "}" as *u8) 1065 out[o] = GM_NL as u8; o = o + 1 1066 return o 1067} 1068 1069func gm_run(base: *u8, domcsv: *u8, words: *i64, nw: i64, out: *u8) -> i64 { 1070 var o: i64 = 0 1071 var clipped: i64 = 0 1072 o = sj_cat(out, o, "{\"organ\":\"nx_goalmap\",\"budget_bytes\":" as *u8) 1073 o = sj_catn(out, o, GM_OUTCAP) 1074 o = sj_cat(out, o, ",\"read_cap\":" as *u8) 1075 o = sj_catn(out, o, GM_CAP) 1076 o = sj_cat(out, o, ",\"words\":[" as *u8) 1077 var w: i64 = 0 1078 while w < nw { 1079 if w > 0 { o = sj_cat(out, o, "," as *u8) } 1080 let wp: *u8 = words[w] as *u8 1081 o = sj_cat(out, o, "\"" as *u8) 1082 o = sj_cat_esc(out, o, wp, 0, sj_vlen(wp), GM_WORDB) 1083 o = sj_cat(out, o, "\"" as *u8) 1084 w = w + 1 1085 } 1086 o = sj_cat(out, o, "],\"domains\":[" as *u8) 1087 // the operator plane, loaded ONCE, sized from the plane 1088 let ap: *u8 = sys_mmap(GM_PATHB) 1089 gm_path(ap, base, "knowledge/store/accept-" as *u8, ap, 0, 0, "" as *u8) 1090 let alp: *i64 = sys_mmap(GM_SPAN) as *i64 1091 alp[0] = 0 1092 let ab: *u8 = sts_load_fit(ap, alp) 1093 var an: i64 = 0 1094 if (ab as i64) != 0 { an = alp[0] } 1095 let plan: *u8 = sys_mmap(GM_CAP) 1096 let mat: *u8 = sys_mmap(GM_CAP) 1097 // v1.2: rec, mi, order and mrec are allocated PER DOMAIN below, sized from a count over the file just read 1098 let dup: *i64 = sys_mmap(GM_SPAN) as *i64 1099 let fl: *i64 = sys_mmap(GM_SPAN) as *i64 1100 let mfl: *i64 = sys_mmap(GM_SPAN) as *i64 1101 let cyc: *i64 = sys_mmap(GM_SPAN) as *i64 1102 let szp: *i64 = sys_mmap(GM_SPAN) as *i64 1103 let msz: *i64 = sys_mmap(GM_SPAN) as *i64 1104 let pb: *u8 = sys_mmap(GM_PATHB) 1105 let bn: *u8 = sys_mmap(GM_WORDB) 1106 let dom: *u8 = sys_mmap(GM_WORDB) 1107 var readable: i64 = 0 1108 var ndom: i64 = 0 1109 var dp: i64 = 0 1110 let dl: i64 = sj_vlen(domcsv) 1111 while dp <= dl { 1112 if ndom >= gm_ndom(domcsv) { dp = dl + 1 } else { // v1.2: the bound is the token count itself, never a cap 1113 // next domain token 1114 var de: i64 = dp 1115 var s: i64 = 1 1116 while s == 1 { if de >= dl { s = 0 } else { if domcsv[de] == (GM_COMMA as u8) { s = 0 } else { de = de + 1 } } } 1117 if de > dp { 1118 var t: i64 = 0 1119 while dp + t < de { if t < GM_WORDB - 2 { dom[t] = domcsv[dp + t] } t = t + 1 } 1120 if t > GM_WORDB - 2 { t = GM_WORDB - 2 } 1121 dom[t] = 0 as u8 1122 if ndom > 0 { o = sj_cat(out, o, "," as *u8) } 1123 ndom = ndom + 1 1124 o = sj_cat(out, o, "{\"dom\":\"" as *u8) 1125 o = sj_cat_esc(out, o, dom, 0, t, GM_WORDB) 1126 o = sj_cat(out, o, "\"" as *u8) 1127 gm_path(pb, base, "buildroot/knowledge/compare/" as *u8, dom, 0, t, ".plan" as *u8) 1128 let pn: i64 = gm_read(pb, plan, GM_CAP, szp) 1129 o = sj_cat(out, o, ",\"plan_bytes\":" as *u8); o = sj_catn(out, o, szp[0]) 1130 o = sj_cat(out, o, ",\"plan_read\":" as *u8); o = sj_catn(out, o, pn) 1131 if pn < 0 { 1132 o = sj_cat(out, o, ",\"readable\":0}" as *u8) 1133 } else { 1134 readable = readable + 1 1135 var trunc: i64 = 0 1136 if szp[0] > pn { trunc = 1 } 1137 o = sj_cat(out, o, ",\"readable\":1,\"truncated\":" as *u8); o = sj_catn(out, o, trunc) 1138 // v1.2: records sized from a count over the buffer just read (+1 so an empty plan still owns a slot) 1139 let rcap: i64 = gm_count_pfx(plan, pn, "rung|" as *u8) + 1 1140 let rec: *i64 = sys_mmap(rcap * GM_RF * 8) as *i64 1141 let mi: *i64 = sys_mmap(rcap * 8) as *i64 1142 let order: *i64 = sys_mmap(rcap * 8) as *i64 1143 let nr: i64 = gm_parse_rungs(plan, pn, rec, rcap, dup, fl) 1144 if nr < 0 { 1145 o = sj_cat(out, o, ",\"refused\":\"duplicate-rung-id\",\"id\":\"" as *u8) 1146 o = sj_cat_esc(out, o, plan, dup[0], dup[1], GM_ID_ESC) 1147 o = sj_cat(out, o, "\"}]}" as *u8) 1148 out[o] = GM_NL as u8; o = o + 1 1149 out[o] = 0 as u8 1150 return GM_R_DUP 1151 } 1152 gm_log_stats(plan, pn, rec, nr) 1153 gm_path(pb, base, "buildroot/knowledge/compare/" as *u8, dom, 0, t, ".matrix" as *u8) 1154 let mn: i64 = gm_read(pb, mat, GM_CAP, msz) 1155 var nm: i64 = 0 1156 let mcap: i64 = gm_count_lines(mat, mn) + 1 1157 let mrec: *i64 = sys_mmap(mcap * GM_MF * 8) as *i64 1158 if mn > 0 { nm = gm_parse_matrix(mat, mn, mrec, mcap, mfl) } 1159 o = sj_cat(out, o, ",\"matrix_bytes\":" as *u8); o = sj_catn(out, o, msz[0]) 1160 o = sj_cat(out, o, ",\"matrix_rows\":" as *u8); o = sj_catn(out, o, nm) 1161 // score + status 1162 var matched: i64 = 0 1163 var i: i64 = 0 1164 while i < nr { 1165 let sc: i64 = gm_score(plan, rec, i, words, nw) 1166 gm_set(rec, i, 12, sc) 1167 if sc > 0 { 1168 var st: i64 = gm_status_matrix(plan, rec, i, mat, mrec, nm) 1169 st = gm_status_accept(plan, rec, i, dom, ab, an, st) 1170 gm_set(rec, i, 13, st) 1171 mi[matched] = i 1172 matched = matched + 1 1173 } 1174 i = i + 1 1175 } 1176 o = sj_cat(out, o, ",\"rungs_total\":" as *u8); o = sj_catn(out, o, nr) 1177 o = sj_cat(out, o, ",\"rungs_floor\":" as *u8); o = sj_catn(out, o, fl[0]) 1178 o = sj_cat(out, o, ",\"rungs_matched\":" as *u8); o = sj_catn(out, o, matched) 1179 let no: i64 = gm_order(plan, rec, mi, matched, order, cyc) 1180 o = sj_cat(out, o, ",\"cycle\":" as *u8); o = sj_catn(out, o, cyc[0]) 1181 o = sj_cat(out, o, ",\"order\":[" as *u8) 1182 var e2: i64 = 0 1183 var k: i64 = 0 1184 while k < no { 1185 if gm_room(o, GM_ID_ESC + 4) == 1 { 1186 let r: i64 = mi[order[k]] 1187 if e2 > 0 { o = sj_cat(out, o, "," as *u8) } 1188 o = sj_cat(out, o, "\"" as *u8) 1189 o = sj_cat_esc(out, o, plan, gm_rec(rec, r, 2), gm_rec(rec, r, 3), GM_ID_ESC) 1190 o = sj_cat(out, o, "\"" as *u8) 1191 e2 = e2 + 1 1192 } else { clipped = 1 } 1193 k = k + 1 1194 } 1195 o = sj_cat(out, o, "],\"rungs\":[" as *u8) 1196 var e3: i64 = 0 1197 k = 0 1198 while k < no { 1199 if gm_room(o, GM_ROW_RESERVE) == 1 { 1200 let r: i64 = mi[order[k]] 1201 if e3 > 0 { o = sj_cat(out, o, "," as *u8) } 1202 o = sj_cat(out, o, "{\"id\":\"" as *u8) 1203 o = sj_cat_esc(out, o, plan, gm_rec(rec, r, 2), gm_rec(rec, r, 3), GM_ID_ESC) 1204 o = sj_cat(out, o, "\",\"score\":" as *u8); o = sj_catn(out, o, gm_rec(rec, r, 12)) 1205 o = sj_cat(out, o, ",\"status\":\"" as *u8); o = sj_cat(out, o, gm_st_lit(gm_rec(rec, r, 13))) 1206 o = sj_cat(out, o, "\",\"symbol\":\"" as *u8) 1207 o = sj_cat_esc(out, o, plan, gm_rec(rec, r, 6), gm_rec(rec, r, 7), GM_SYM_ESC) 1208 o = sj_cat(out, o, "\",\"deps\":\"" as *u8) 1209 o = sj_cat_esc(out, o, plan, gm_rec(rec, r, 10), gm_rec(rec, r, 11), GM_DEPS_ESC) 1210 o = sj_cat(out, o, "\",\"log_rows\":" as *u8); o = sj_catn(out, o, gm_rec(rec, r, 14)) 1211 o = sj_cat(out, o, ",\"last_epoch\":" as *u8); o = sj_catn(out, o, gm_rec(rec, r, 15)) 1212 o = sj_cat(out, o, "}" as *u8) 1213 e3 = e3 + 1 1214 } else { clipped = 1 } 1215 k = k + 1 1216 } 1217 // gaps: matrix WATCH rows the words match, with the three roots probed 1218 o = sj_cat(out, o, "],\"gaps\":[" as *u8) 1219 var e4: i64 = 0 1220 var g: i64 = 0 1221 var gaps_total: i64 = 0 1222 while g < nm { 1223 if gm_mrec(mrec, g, 8) == 1 { 1224 var hit: i64 = 0 1225 var ww: i64 = 0 1226 while ww < nw { 1227 let wp2: *u8 = words[ww] as *u8 1228 if gm_word_dup(words, ww) == 0 { 1229 if gm_has_ci(mat, gm_mrec(mrec, g, 2), gm_mrec(mrec, g, 3), wp2) == 1 { hit = hit + 1 } else { if gm_has_ci(mat, gm_mrec(mrec, g, 9), gm_mrec(mrec, g, 10), wp2) == 1 { hit = hit + 1 } } 1230 } 1231 ww = ww + 1 1232 } 1233 if hit > 0 { 1234 gaps_total = gaps_total + 1 1235 if gm_room(o, GM_ROW_RESERVE) == 1 { 1236 if e4 > 0 { o = sj_cat(out, o, "," as *u8) } 1237 o = sj_cat(out, o, "{\"label\":\"" as *u8) 1238 o = sj_cat_esc(out, o, mat, gm_mrec(mrec, g, 2), gm_mrec(mrec, g, 3), GM_LABEL_ESC) 1239 o = sj_cat(out, o, "\",\"organ\":\"" as *u8) 1240 o = sj_cat_esc(out, o, mat, gm_mrec(mrec, g, 4), gm_mrec(mrec, g, 5), GM_LABEL_ESC) 1241 o = sj_cat(out, o, "\",\"symbol\":\"" as *u8) 1242 o = sj_cat_esc(out, o, mat, gm_mrec(mrec, g, 9), gm_mrec(mrec, g, 10), GM_SYM_ESC) 1243 o = sj_cat(out, o, "\",\"score\":" as *u8); o = sj_catn(out, o, hit) 1244 gm_path(pb, base, "buildroot/" as *u8, mat, gm_mrec(mrec, g, 4), gm_mrec(mrec, g, 5), "" as *u8) 1245 o = sj_cat(out, o, ",\"src\":" as *u8); o = sj_catn(out, o, gm_probe(pb)) 1246 gm_basename(bn, mat, gm_mrec(mrec, g, 4), gm_mrec(mrec, g, 5)) 1247 gm_path(pb, base, "buildroot/_build/" as *u8, bn, 0, sj_vlen(bn), ".sov.elf" as *u8) 1248 o = sj_cat(out, o, ",\"built\":" as *u8); o = sj_catn(out, o, gm_probe(pb)) 1249 gm_path(pb, base, "" as *u8, bn, 0, sj_vlen(bn), ".elf" as *u8) 1250 o = sj_cat(out, o, ",\"promoted\":" as *u8); o = sj_catn(out, o, gm_probe(pb)) 1251 o = sj_cat(out, o, "}" as *u8) 1252 e4 = e4 + 1 1253 } else { clipped = 1 } 1254 } 1255 } 1256 g = g + 1 1257 } 1258 o = sj_cat(out, o, "],\"gaps_total\":" as *u8); o = sj_catn(out, o, gaps_total) 1259 // operator verdicts naming this domain 1260 o = sj_cat(out, o, ",\"verdicts\":[" as *u8) 1261 var e5: i64 = 0 1262 var vp: i64 = 0 1263 let vs: *i64 = sys_mmap(GM_SPAN) as *i64 1264 let vv: *i64 = sys_mmap(GM_SPAN) as *i64 1265 let vi: *i64 = sys_mmap(GM_SPAN) as *i64 1266 let dn: *u8 = sys_mmap(GM_WORDB) 1267 var dno: i64 = sj_cat(dn, 0, dom) 1268 dn[dno] = GM_COLON as u8; dno = dno + 1; dn[dno] = 0 as u8 1269 while vp < an { 1270 let vle: i64 = sj_le(ab, vp, an) 1271 if sj_col(ab, vp, vle, 6, vs) == 1 { 1272 if gm_find(ab, vs[0], vs[1], dn) >= 0 { 1273 if e5 < GM_MAXVERD { if gm_room(o, GM_ROW_RESERVE) == 1 { 1274 if e5 > 0 { o = sj_cat(out, o, "," as *u8) } 1275 sj_col(ab, vp, vle, 0, vi) 1276 sj_col(ab, vp, vle, 2, vv) 1277 o = sj_cat(out, o, "{\"id\":\"" as *u8) 1278 o = sj_cat_esc(out, o, ab, vi[0], vi[1], GM_LABEL_ESC) 1279 o = sj_cat(out, o, "\",\"verdict\":\"" as *u8) 1280 o = sj_cat_esc(out, o, ab, vv[0], vv[1], GM_ID_ESC) 1281 o = sj_cat(out, o, "\"}" as *u8) 1282 e5 = e5 + 1 1283 } else { clipped = 1 } } 1284 } 1285 } 1286 vp = vle + 1 1287 } 1288 o = sj_cat(out, o, "]}" as *u8) 1289 } 1290 } 1291 dp = de + 1 1292 } 1293 } 1294 o = sj_cat(out, o, "],\"accept_bytes\":" as *u8); o = sj_catn(out, o, an) 1295 o = sj_cat(out, o, ",\"domains_readable\":" as *u8); o = sj_catn(out, o, readable) 1296 o = sj_cat(out, o, ",\"clipped\":" as *u8); o = sj_catn(out, o, clipped) 1297 o = sj_cat(out, o, ",\"out_bytes\":" as *u8); o = sj_catn(out, o, o + 12) 1298 o = sj_cat(out, o, "}" as *u8) 1299 out[o] = GM_NL as u8; o = o + 1 1300 out[o] = 0 as u8 1301 if readable == 0 { return GM_R_NODOM } 1302 return o 1303}