code wiki / _hdl_build / nx_ws_ingest.nx

nx_ws_ingest.nx source

↩ module page · 307 lines · 15992 B

1// nx_ws_ingest.nx -- THE MISSING INTEGRATION KEYSTONE (WMS derive-from-SSOT R1, for real). 2// 3// The operator's "we shouldn't have lots of separate systems" bug, named and fixed: the machine 4// registry (knowledge/store/ws-, read by nx_ws_board) only ever tracked the assignment-queue ids 5// (via nx_workstream_popqueue) and the PM/old WMS streams. The 426 durable project-*.md arcs -- 6// genealogy, login, media, reader, brand, APM, doctor, ... -- were NEVER ingested, so the board 7// could not see them. nx_ws_manifest_emit only rewrites a MARKDOWN list; it has zero ws_put. This 8// organ is the half that was missing: it SCANS every project-*.md and ws_put's each into the 9// registry so the board ENUMERATES every arc -> one source of truth, not three. 10// 11// REUSE / lineage: the dir walk is wme_scan (nx_ws_index_lib) -- names[] + REAL mtimes[]. The 12// one-snapshot(ss_open)/one-writer(ss_begin)/one-commit(ss_commit) batch discipline + idempotent 13// byte-compare skip is the proven nx_workstream_popqueue path (256-segment-cap safe at >1000 14// records; re-runs add ZERO segments). last_touched = the file mtime, so the board computes HONEST 15// recency (ALIVE/STALLED) from real data instead of age=-1 phantom labels. State is data-derived: 16// ACTIVE iff the file was touched within WSI_FRESH_SEC (genuinely in-flight), else FLOATING 17// (indexed dormant history -- honest, never a faked DONE/ACTIVE). empire = best-effort keyword 18// routing, unknown -> E-MISC (the documented catch-all, mirrors the popqueue doctrine); refined 19// later from gate markers. memory_link = the project-*.md basename (so the arc is openable). 20// 21// Sovereign: imports only nx_workstream_store + nx_seg_store + nx_framed_append + nx_ws_index_lib 22// + nx_syscalls (no gcc). Additive-only: modifies no existing organ. license_tier: ORIGINAL 23import "nx_workstream_store.nx" 24import "nx_seg_store.nx" 25import "nx_framed_append.nx" 26import "nx_ws_index_lib.nx" 27import "nx_syscalls.nx" 28const WSI_MAGIC_1048576: i64 = 1048576 29const WSI_MAGIC_1024: i64 = 1024 30 31const WSI_CAP: i64 = 8192 // max project-*.md records (426 today; ample headroom) 32const WSI_FRESH_SEC: i64 = 432000 // 5 days: a file touched within this window -> state ACTIVE 33 34// 1 if NUL-term `pre` is a prefix of NUL-term `s`. 35func wsi_has_prefix(s: *u8, pre: *u8) -> i64 { 36 var i: i64 = 0 37 while pre[i] != (0 as u8) { if s[i] != pre[i] { return 0 } i = i + 1 } 38 return 1 39} 40 41// 1 iff NUL-term `a` byte-equals NUL-term `b`. 42func wsi_id_eq(a: *u8, b: *u8) -> i64 { 43 var k: i64 = 0 44 while a[k] != (0 as u8) { if a[k] != b[k] { return 0 } k = k + 1 } 45 if b[k] != (0 as u8) { return 0 } 46 return 1 47} 48 49// copy NUL-term `s` into `out` (incl terminator); returns length. 50func wsi_setstr(out: *u8, s: *u8) -> i64 { 51 var i: i64 = 0 52 while s[i] != (0 as u8) { out[i] = s[i]; i = i + 1 } 53 out[i] = 0 as u8 54 return i 55} 56 57// strip "project-" prefix and the ".md" suffix from a filename -> a clean stream id. returns len. 58func wsi_id_from_name(name: *u8, out: *u8) -> i64 { 59 let n: i64 = wme_len(name) 60 var start: i64 = 0 61 if wsi_has_prefix(name, "project-" as *u8) == 1 { start = 8 } 62 var end: i64 = n 63 if n >= 3 { end = n - 3 } 64 var o: i64 = 0 65 var i: i64 = start 66 while i < end { out[o] = name[i]; o = o + 1; i = i + 1 } 67 out[o] = 0 as u8 68 return o 69} 70 71// 1 if NUL-term `pat` occurs as a substring of NUL-term `s` (keyword empire routing). 72func wsi_contains(s: *u8, pat: *u8) -> i64 { 73 let sl: i64 = wme_len(s) 74 if wme_find(s, sl, pat) >= 0 { return 1 } 75 return 0 76} 77 78// data-driven keyword -> empire routing for a project-*.md id. Strongest/most-specific signals 79// first; unknown -> E-MISC. Every target is a real member of ws:empires so the registry audit 80// (ws_audit_complete) stays clean. 81func wsi_empire_for(id: *u8, out: *u8) -> i64 { 82 if wsi_contains(id, "genealog" as *u8) == 1 { wsi_setstr(out, "E-CORE" as *u8); return 0 } 83 if wsi_contains(id, "lineage" as *u8) == 1 { wsi_setstr(out, "E-CORE" as *u8); return 0 } 84 if wsi_contains(id, "genesis" as *u8) == 1 { wsi_setstr(out, "E-CORE" as *u8); return 0 } 85 if wsi_contains(id, "omniforge" as *u8) == 1 { wsi_setstr(out, "E-CORE" as *u8); return 0 } 86 if wsi_contains(id, "silicon" as *u8) == 1 { wsi_setstr(out, "E-CORE" as *u8); return 0 } 87 if wsi_contains(id, "compiler" as *u8) == 1 { wsi_setstr(out, "E-CORE" as *u8); return 0 } 88 if wsi_contains(id, "nishilang" as *u8) == 1 { wsi_setstr(out, "E-CORE" as *u8); return 0 } 89 if wsi_contains(id, "kernel" as *u8) == 1 { wsi_setstr(out, "E-CORE" as *u8); return 0 } 90 if wsi_contains(id, "doctor" as *u8) == 1 { wsi_setstr(out, "E-CORE" as *u8); return 0 } 91 if wsi_contains(id, "robot" as *u8) == 1 { wsi_setstr(out, "E-CORE" as *u8); return 0 } 92 if wsi_contains(id, "pcb" as *u8) == 1 { wsi_setstr(out, "E-CORE" as *u8); return 0 } 93 if wsi_contains(id, "nishios" as *u8) == 1 { wsi_setstr(out, "E-NISHIOS" as *u8); return 0 } 94 if wsi_contains(id, "login" as *u8) == 1 { wsi_setstr(out, "E-WEB" as *u8); return 0 } 95 if wsi_contains(id, "hr-user" as *u8) == 1 { wsi_setstr(out, "E-WEB" as *u8); return 0 } 96 if wsi_contains(id, "wiki" as *u8) == 1 { wsi_setstr(out, "E-WEB" as *u8); return 0 } 97 if wsi_contains(id, "cms" as *u8) == 1 { wsi_setstr(out, "E-WEB" as *u8); return 0 } 98 if wsi_contains(id, "hosting" as *u8) == 1 { wsi_setstr(out, "E-WEB" as *u8); return 0 } 99 if wsi_contains(id, "brand" as *u8) == 1 { wsi_setstr(out, "E-WEB" as *u8); return 0 } 100 if wsi_contains(id, "andelin" as *u8) == 1 { wsi_setstr(out, "E-WEB" as *u8); return 0 } 101 if wsi_contains(id, "search" as *u8) == 1 { wsi_setstr(out, "E-WEB" as *u8); return 0 } 102 if wsi_contains(id, "publish" as *u8) == 1 { wsi_setstr(out, "E-WEB" as *u8); return 0 } 103 if wsi_contains(id, "site" as *u8) == 1 { wsi_setstr(out, "E-WEB" as *u8); return 0 } 104 if wsi_contains(id, "browser" as *u8) == 1 { wsi_setstr(out, "E-WEB" as *u8); return 0 } 105 if wsi_contains(id, "media" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 106 if wsi_contains(id, "torrent" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 107 if wsi_contains(id, "reader" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 108 if wsi_contains(id, "library" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 109 if wsi_contains(id, "gallery" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 110 if wsi_contains(id, "video" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 111 if wsi_contains(id, "image" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 112 if wsi_contains(id, "visual" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 113 if wsi_contains(id, "viz" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 114 if wsi_contains(id, "roku" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 115 if wsi_contains(id, "hevc" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 116 if wsi_contains(id, "codec" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 117 if wsi_contains(id, "gpu" as *u8) == 1 { wsi_setstr(out, "E-PLATFORM" as *u8); return 0 } 118 if wsi_contains(id, "apm" as *u8) == 1 { wsi_setstr(out, "E-DEPLOY" as *u8); return 0 } 119 if wsi_contains(id, "monitor" as *u8) == 1 { wsi_setstr(out, "E-DEPLOY" as *u8); return 0 } 120 if wsi_contains(id, "deploy" as *u8) == 1 { wsi_setstr(out, "E-DEPLOY" as *u8); return 0 } 121 if wsi_contains(id, "infra" as *u8) == 1 { wsi_setstr(out, "E-DEPLOY" as *u8); return 0 } 122 if wsi_contains(id, "vault" as *u8) == 1 { wsi_setstr(out, "E-DEPLOY" as *u8); return 0 } 123 if wsi_contains(id, "nas-" as *u8) == 1 { wsi_setstr(out, "E-DEPLOY" as *u8); return 0 } 124 if wsi_contains(id, "dns" as *u8) == 1 { wsi_setstr(out, "E-DEPLOY" as *u8); return 0 } 125 if wsi_contains(id, "host" as *u8) == 1 { wsi_setstr(out, "E-DEPLOY" as *u8); return 0 } 126 if wsi_contains(id, "research" as *u8) == 1 { wsi_setstr(out, "E-RESEARCH" as *u8); return 0 } 127 if wsi_contains(id, "manheim" as *u8) == 1 { wsi_setstr(out, "E-RESEARCH" as *u8); return 0 } 128 if wsi_contains(id, "deepmind" as *u8) == 1 { wsi_setstr(out, "E-RESEARCH" as *u8); return 0 } 129 if wsi_contains(id, "nofloat" as *u8) == 1 { wsi_setstr(out, "E-RESEARCH" as *u8); return 0 } 130 if wsi_contains(id, "model" as *u8) == 1 { wsi_setstr(out, "E-RESEARCH" as *u8); return 0 } 131 if wsi_contains(id, "analyst" as *u8) == 1 { wsi_setstr(out, "E-RESEARCH" as *u8); return 0 } 132 if wsi_contains(id, "game" as *u8) == 1 { wsi_setstr(out, "E-NGE" as *u8); return 0 } 133 if wsi_contains(id, "pets" as *u8) == 1 { wsi_setstr(out, "E-NGE" as *u8); return 0 } 134 if wsi_contains(id, "procgen" as *u8) == 1 { wsi_setstr(out, "E-NGE" as *u8); return 0 } 135 if wsi_contains(id, "pm-" as *u8) == 1 { wsi_setstr(out, "E-PM" as *u8); return 0 } 136 if wsi_contains(id, "sclass" as *u8) == 1 { wsi_setstr(out, "E-PM" as *u8); return 0 } 137 if wsi_contains(id, "workstream" as *u8) == 1 { wsi_setstr(out, "E-PM" as *u8); return 0 } 138 if wsi_contains(id, "orchestr" as *u8) == 1 { wsi_setstr(out, "E-PM" as *u8); return 0 } 139 if wsi_contains(id, "wms" as *u8) == 1 { wsi_setstr(out, "E-PM" as *u8); return 0 } 140 if wsi_contains(id, "council" as *u8) == 1 { wsi_setstr(out, "E-PM" as *u8); return 0 } 141 if wsi_contains(id, "raci" as *u8) == 1 { wsi_setstr(out, "E-PM" as *u8); return 0 } 142 wsi_setstr(out, "E-MISC" as *u8) 143 return 0 144} 145 146// build the 7-field TAB record: id \t empire \t state \t last_touched \t memory_link \t - \t - . 147func wsi_build_record(id: *u8, empire: *u8, state: *u8, mtime: i64, memlink: *u8, out: *u8) -> i64 { 148 var o: i64 = 0 149 o = wme_cat(out, o, id) 150 out[o] = 9 as u8; o = o + 1 151 o = wme_cat(out, o, empire) 152 out[o] = 9 as u8; o = o + 1 153 o = wme_cat(out, o, state) 154 out[o] = 9 as u8; o = o + 1 155 o = wme_catn(out, o, mtime) 156 out[o] = 9 as u8; o = o + 1 157 o = wme_cat(out, o, memlink) 158 out[o] = 9 as u8; o = o + 1 159 out[o] = 45 as u8; o = o + 1 // '-' code_link 160 out[o] = 9 as u8; o = o + 1 161 out[o] = 45 as u8; o = o + 1 // '-' deps 162 out[o] = 0 as u8 163 return o 164} 165 166// build the "ws:" + id key (NUL-term). returns length. 167func wsi_build_key(id: *u8, out: *u8) -> i64 { 168 out[0] = 119 as u8 // 'w' 169 out[1] = 115 as u8 // 's' 170 out[2] = 58 as u8 // ':' 171 var t: i64 = 0 172 while id[t] != (0 as u8) { out[3 + t] = id[t]; t = t + 1 } 173 out[3 + t] = 0 as u8 174 return 3 + t 175} 176 177// HANDLE-BASED idempotency compare: 1 iff open-store snapshot `h` holds `key` byte-equal to `val`. 178// (zero per-call file IO -- the scalable read path, mirrors pq_streq_h.) 179func wsi_streq_h(h: *i64, key: *u8, val: *u8) -> i64 { 180 let pq: *i64 = sys_mmap(16) as *i64 181 let lq: *i64 = sys_mmap(16) as *i64 182 if ss_hget(h, key, pq, lq) != 1 { return 0 } 183 let b: *u8 = pq[0] as *u8 184 let n: i64 = lq[0] 185 let vl: i64 = wme_len(val) 186 if n != vl { return 0 } 187 var i: i64 = 0 188 while i < n { if b[i] != val[i] { return 0 } i = i + 1 } 189 return 1 190} 191 192// merged ws:ids = existing index + every collected id not already a member, into out (NUL-term). 193func wsi_merge_ids(h: *i64, ids: *i64, nids: i64, out: *u8) -> i64 { 194 var o: i64 = 0 195 let pq: *i64 = sys_mmap(16) as *i64 196 let lq: *i64 = sys_mmap(16) as *i64 197 var cur: *u8 = "" as *u8 198 var curn: i64 = 0 199 if ss_hget(h, "ws:ids" as *u8, pq, lq) == 1 { cur = pq[0] as *u8; curn = lq[0] } 200 var t: i64 = 0 201 while t < curn { out[o] = cur[t]; o = o + 1; t = t + 1 } 202 out[o] = 0 as u8 203 var i: i64 = 0 204 while i < nids { 205 let id: *u8 = ids[i] as *u8 206 if ws_member(out, o, id) == 0 { 207 if o > 0 { out[o] = 9 as u8; o = o + 1 } 208 var j: i64 = 0 209 while id[j] != (0 as u8) { out[o] = id[j]; o = o + 1; j = j + 1 } 210 out[o] = 0 as u8 211 } 212 i = i + 1 213 } 214 return o 215} 216 217// derive a stream id from every scanned name into ids_out[] (mmap'd NUL-term ids). 218func wsi_derive_ids(names: *i64, cnt: i64, ids_out: *i64) -> i64 { 219 var i: i64 = 0 220 while i < cnt { 221 let nm: *u8 = names[i] as *u8 222 let idb: *u8 = sys_mmap(256) 223 wsi_id_from_name(nm, idb) 224 ids_out[i] = idb as i64 225 i = i + 1 226 } 227 return cnt 228} 229 230// stage ONE arc record into writer `w` against snapshot `h` (idempotent skip). Tallies 231// out4[1]=registered_new / out4[2]=skipped / out4[3]=errors. Small fn (rule 3: avoid the 232// register-pressure ceiling that mis-compiles a fat body). 233func wsi_reg_one(h: *i64, w: *i64, id: *u8, name: *u8, mtime: i64, nowsec: i64, keybuf: *u8, recbuf: *u8, empbuf: *u8, out4: *i64) -> i64 { 234 wsi_empire_for(id, empbuf) 235 wsi_build_key(id, keybuf) 236 var st: *u8 = "FLOATING" as *u8 237 if (nowsec - mtime) < WSI_FRESH_SEC { st = "ACTIVE" as *u8 } 238 let rlen: i64 = wsi_build_record(id, empbuf, st, mtime, name, recbuf) 239 if wsi_streq_h(h, keybuf, recbuf) == 1 { out4[2] = out4[2] + 1; return 0 } 240 let rc: i64 = ss_add(w, 1, keybuf, recbuf, rlen) 241 if rc < 0 { out4[3] = out4[3] + 1; return rc } 242 out4[1] = out4[1] + 1 243 return 0 244} 245 246// stage the merged ws:ids index into `w` iff it changed (idempotent). Small helper. 247func wsi_stage_ids(h: *i64, w: *i64, ids: *i64, cnt: i64) -> i64 { 248 let mids: *u8 = sys_mmap(WSI_MAGIC_1048576) 249 let mlen: i64 = wsi_merge_ids(h, ids, cnt, mids) 250 if wsi_streq_h(h, "ws:ids" as *u8, mids) == 0 { ss_add(w, 1, "ws:ids" as *u8, mids, mlen) } 251 return 0 252} 253 254// stage every per-arc ws:<id> record into `w` (skipping `omit` for the gate's neg-control). Small 255// helper -- keeps the loop body + scratch buffers OUT of the core (rule 3). 256func wsi_stage_records(h: *i64, w: *i64, names: *i64, mtimes: *i64, ids: *i64, cnt: i64, nowsec: i64, omit: *u8, out4: *i64) -> i64 { 257 let keybuf: *u8 = sys_mmap(512) 258 let recbuf: *u8 = sys_mmap(WSI_MAGIC_1024) 259 let empbuf: *u8 = sys_mmap(64) 260 var has_omit: i64 = 0 261 if omit as i64 != 0 { has_omit = 1 } 262 var i: i64 = 0 263 while i < cnt { 264 let id: *u8 = ids[i] as *u8 265 let nm: *u8 = names[i] as *u8 266 var skip_this: i64 = 0 267 if has_omit == 1 { if wsi_id_eq(id, omit) == 1 { skip_this = 1 } } 268 if skip_this == 0 { wsi_reg_one(h, w, id, nm, mtimes[i], nowsec, keybuf, recbuf, empbuf, out4) } 269 i = i + 1 270 } 271 return 0 272} 273 274// THE CORE: scan every project-*.md in `memdir` and register each into the registry under 275// `prefix` in ONE snapshot / ONE writer / ONE commit (256-cap safe, idempotent). `omit` = a 276// NUL-term id to deliberately skip (or 0) -- the gate's negative control. Counters via out4[]: 277// out4[0]=scanned out4[1]=registered_new out4[2]=skipped out4[3]=errors 278// return: 0 ok, <0 hard error. 279func wsi_ingest_omit_p(prefix: *u8, memdir: *u8, omit: *u8, out4: *i64) -> i64 { 280 let names: *i64 = sys_mmap(8 * WSI_CAP) as *i64 281 let mtimes: *i64 = sys_mmap(8 * WSI_CAP) as *i64 282 let cnt: i64 = wme_scan(memdir, names, mtimes, WSI_CAP) 283 out4[0] = 0; out4[1] = 0; out4[2] = 0; out4[3] = 0 284 if cnt < 0 { out4[3] = 1; return 0 - 1 } 285 out4[0] = cnt 286 let ids: *i64 = sys_mmap(8 * WSI_CAP) as *i64 287 wsi_derive_ids(names, cnt, ids) 288 let nowsec: i64 = sys_now_realtime_sec() 289 let h: *i64 = ss_open(prefix) 290 let w: *i64 = ss_begin() 291 wsi_stage_ids(h, w, ids, cnt) 292 wsi_stage_records(h, w, names, mtimes, ids, cnt, nowsec, omit, out4) 293 if w[1] > 0 { 294 let segid: i64 = ws_seg_next(prefix) 295 let crc: i64 = ss_commit(prefix, w, segid) 296 if crc != 0 { out4[3] = out4[3] + 1; return crc } 297 } 298 if out4[3] > 0 { return 0 - 2 } 299 return 0 300} 301 302// production convenience: ingest into the live WS_PREFIX, omit nothing. 303func wsi_ingest(memdir: *u8, out4: *i64) -> i64 { 304 return wsi_ingest_omit_p(WS_PREFIX, memdir, 0 as *u8, out4) 305} 306 307// NOTE: pure LIB (no main) so the gate can import it. The runnable driver is nx_ws_ingest_run.nx.