code wiki / _hdl_build / nx_ws_miner.nx

nx_ws_miner.nx source

↩ module page · 835 lines · 30956 B

1// nx_ws_miner.nx -- F217-class HISTORIC WORKSTREAM MINER (ws=ws-intel, 2026-07-20). 2// Mines the append-only ws_sync journal (the ecosystem's workstream HISTORY) into 3// machine-readable intelligence: per-lane lifecycle (kickoffs/beats/dones, first/last ts, 4// distinct actors, DONE|ACTIVE|STALE|ABANDONED), per-actor engagement, honest totals. 5// The journal IS the historic record -- this organ makes it QUERYABLE (JSON verb) and 6// PUBLISHABLE (HTML page verb) so monitoring parallel + historic workstreams is a live 7// ecosystem surface, not Claude-context archaeology. Sibling of nx_ws_kickoff_sync 8// (the writer) and nx_ws_cycle (evidence-derived phase). Composes -- does not duplicate. 9// SCALE LAW: reads windowed + envelope DECLARED in output (window_bytes / truncated / 10// lanes_capped / actors_capped) -- silent capping forbidden by construction. 11// license_tier: ORIGINAL No hw writes (Rule 26). 12// mine <journal> [stale_sec] [abandoned_sec] -> JSON to stdout 13// page <journal> <outfile> [stale_sec] [abandoned_sec] -> HTML file + marker line 14// selftest <scratch-journal> -> gate T1..T9 (caller pre-cleans path) 15import "nx_syscalls.nx" 16import "nx_gate_verdict.nx" 17const WM_MAGIC_4096: i64 = 4096 18const WM_MAGIC_2000: i64 = 2000 19const WM_MAGIC_3000: i64 = 3000 20const WM_MAGIC_7200: i64 = 7200 21 22const WM_WIN: i64 = 4194304 23const WM_OUT: i64 = 262144 24const WM_SOFT: i64 = 40960 25const WM_SOFT2: i64 = 57344 26const WM_PAGE_SOFT: i64 = 245760 27const WM_NOTE_MAX: i64 = 160 28const WM_NAME_MAX: i64 = 120 29const WM_STALE_DEF: i64 = 3600 30const WM_ABAND_DEF: i64 = 604800 31 32// ---------- buffer + parse helpers (proven ks_* idioms, nx_ws_kickoff_sync lineage) ---------- 33func wm_cat(d: *u8, o: i64, s: *u8) -> i64 { var p: i64=o; var i: i64=0; while s[i]!=(0 as u8){ d[p]=s[i]; p=p+1; i=i+1 } return p } 34func wm_catn(d: *u8, o: i64, v: i64) -> i64 { 35 let t: *u8 = sys_mmap(28) 36 var m: i64 = v 37 var p: i64 = o 38 if m < 0 { d[p]=45 as u8; p=p+1; m=0-m } 39 var k: i64 = 0 40 if m == 0 { t[0]=48 as u8; k=1 } 41 while m > 0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } 42 var i: i64 = 0 43 while i < k { d[p]=t[k-1-i]; p=p+1; i=i+1 } 44 return p 45} 46func wm_vlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 47func wm_atoi_z(s: *u8) -> i64 { var v: i64=0; var i: i64=0; while s[i]!=(0 as u8){ let c: i64=s[i] as i64; if c>=48 { if c<=57 { v=v*10+(c-48) } } i=i+1 } return v } 48func wm_read(path: *u8, buf: *u8, cap: i64) -> i64 { 49 let fd: i64 = sys_openat_rd(path) 50 if fd < 0 { return 0 } 51 var n: i64 = 0 52 var go: i64 = 1 53 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 } } 54 sys_close(fd) 55 return n 56} 57// append one frame: <ts>\t<verb>\t<ws>\t<actor>\t<note>\n (ts<0 => real clock) 58func wm_append(journal: *u8, ts: i64, verb: *u8, ws: *u8, actor: *u8, note: *u8) -> i64 { 59 var t: i64 = ts 60 if t < 0 { t = sys_now_realtime_sec() } 61 let ln: *u8 = sys_mmap(WM_MAGIC_4096) 62 var o: i64 = 0 63 o = wm_catn(ln, o, t) 64 ln[o]=9 as u8; o=o+1 65 o = wm_cat(ln, o, verb) 66 ln[o]=9 as u8; o=o+1 67 o = wm_cat(ln, o, ws) 68 ln[o]=9 as u8; o=o+1 69 o = wm_cat(ln, o, actor) 70 ln[o]=9 as u8; o=o+1 71 o = wm_cat(ln, o, note) 72 ln[o]=10 as u8; o=o+1 73 let fd: i64 = sys_openat_append(journal, 0x1a4) 74 if fd < 0 { return -1 } 75 sys_write(fd, ln, o) 76 sys_close(fd) 77 return 0 78} 79func wm_le(q: *u8, i: i64, n: i64) -> i64 { 80 var le: i64 = i 81 var s: i64 = 1 82 while s==1 { if le>=n { s=0 } else { if q[le]==(10 as u8){s=0} else {le=le+1} } } 83 return le 84} 85func wm_col(q: *u8, ls: i64, le: i64, c: i64, out: *i64) -> i64 { 86 var col: i64 = 0 87 var p: i64 = ls 88 while col < c { 89 var s: i64 = 1 90 while s == 1 { if p >= le { return 0 } if q[p]==(9 as u8) { s = 0 } else { p = p+1 } } 91 p = p + 1 92 col = col + 1 93 } 94 var e: i64 = p 95 var s2: i64 = 1 96 while s2 == 1 { if e >= le { s2 = 0 } else { if q[e]==(9 as u8) { s2 = 0 } else { e = e+1 } } } 97 out[0] = p 98 out[1] = e 99 return 1 100} 101func wm_lit_eq(q: *u8, s: i64, e: i64, lit: *u8) -> i64 { 102 var i: i64 = 0 103 while s+i < e { if lit[i]==(0 as u8) { return 0 } if q[s+i]!=lit[i] { return 0 } i=i+1 } 104 if lit[i]!=(0 as u8) { return 0 } 105 return 1 106} 107func wm_span_eq(q: *u8, s1: i64, e1: i64, s2: i64, e2: i64) -> i64 { 108 if e1-s1 != e2-s2 { return 0 } 109 var i: i64 = 0 110 while s1+i < e1 { if q[s1+i]!=q[s2+i] { return 0 } i=i+1 } 111 return 1 112} 113func wm_atoi(q: *u8, s: i64, e: i64) -> i64 { 114 var v: i64 = 0 115 var i: i64 = s 116 while i < e { let c: i64 = q[i] as i64; if c>=48 { if c<=57 { v = v*10 + (c-48) } } i=i+1 } 117 return v 118} 119func wm_frames(q: *u8, n: i64) -> i64 { 120 var c: i64 = 0 121 var i: i64 = 0 122 while i < n { let le: i64 = wm_le(q,i,n); c=c+1; i = le + 1 } 123 return c 124} 125 126// ---------- lane scans (ws identified by col2 span; lanes = first-KICKOFF occurrences) ---------- 127func wm_first_kick(q: *u8, upto: i64, ws_s: i64, ws_e: i64) -> i64 { 128 let cv: *i64 = sys_mmap(16) as *i64 129 let cw: *i64 = sys_mmap(16) as *i64 130 var i: i64 = 0 131 while i < upto { 132 let le: i64 = wm_le(q,i,upto) 133 if wm_col(q,i,le,1,cv)==1 { if wm_lit_eq(q,cv[0],cv[1],"KICKOFF" as *u8)==1 { 134 if wm_col(q,i,le,2,cw)==1 { if wm_span_eq(q,cw[0],cw[1],ws_s,ws_e)==1 { return 0 } } 135 } } 136 i = le + 1 137 } 138 return 1 139} 140func wm_has(q: *u8, n: i64, verb: *u8, ws_s: i64, ws_e: i64) -> i64 { 141 let cv: *i64 = sys_mmap(16) as *i64 142 let cw: *i64 = sys_mmap(16) as *i64 143 var i: i64 = 0 144 while i < n { 145 let le: i64 = wm_le(q,i,n) 146 if wm_col(q,i,le,1,cv)==1 { if wm_lit_eq(q,cv[0],cv[1],verb)==1 { 147 if wm_col(q,i,le,2,cw)==1 { if wm_span_eq(q,cw[0],cw[1],ws_s,ws_e)==1 { return 1 } } 148 } } 149 i = le + 1 150 } 151 return 0 152} 153func wm_count_verb(q: *u8, cx: *i64, verb: *u8, ws_s: i64, ws_e: i64) -> i64 { 154 let n: i64 = cx[0] 155 let cv: *i64 = sys_mmap(16) as *i64 156 let cw: *i64 = sys_mmap(16) as *i64 157 var c: i64 = 0 158 var i: i64 = 0 159 while i < n { 160 let le: i64 = wm_le(q,i,n) 161 if wm_col(q,i,le,1,cv)==1 { if wm_lit_eq(q,cv[0],cv[1],verb)==1 { 162 if wm_col(q,i,le,2,cw)==1 { if wm_span_eq(q,cw[0],cw[1],ws_s,ws_e)==1 { c=c+1 } } 163 } } 164 i = le + 1 165 } 166 return c 167} 168func wm_first_ts(q: *u8, cx: *i64, ws_s: i64, ws_e: i64) -> i64 { 169 let n: i64 = cx[0] 170 let cw: *i64 = sys_mmap(16) as *i64 171 let c0: *i64 = sys_mmap(16) as *i64 172 var i: i64 = 0 173 while i < n { 174 let le: i64 = wm_le(q,i,n) 175 if wm_col(q,i,le,2,cw)==1 { if wm_span_eq(q,cw[0],cw[1],ws_s,ws_e)==1 { 176 if wm_col(q,i,le,0,c0)==1 { return wm_atoi(q,c0[0],c0[1]) } 177 } } 178 i = le + 1 179 } 180 return -1 181} 182func wm_last_ts(q: *u8, cx: *i64, ws_s: i64, ws_e: i64) -> i64 { 183 let n: i64 = cx[0] 184 let cw: *i64 = sys_mmap(16) as *i64 185 let c0: *i64 = sys_mmap(16) as *i64 186 var last: i64 = -1 187 var i: i64 = 0 188 while i < n { 189 let le: i64 = wm_le(q,i,n) 190 if wm_col(q,i,le,2,cw)==1 { if wm_span_eq(q,cw[0],cw[1],ws_s,ws_e)==1 { 191 if wm_col(q,i,le,0,c0)==1 { last = wm_atoi(q,c0[0],c0[1]) } 192 } } 193 i = le + 1 194 } 195 return last 196} 197func wm_note_span(q: *u8, cx: *i64, ws_s: i64, ws_e: i64, out: *i64) -> i64 { 198 let n: i64 = cx[0] 199 let cw: *i64 = sys_mmap(16) as *i64 200 let cn: *i64 = sys_mmap(16) as *i64 201 var ns: i64 = -1 202 var ne: i64 = -1 203 var i: i64 = 0 204 while i < n { 205 let le: i64 = wm_le(q,i,n) 206 if wm_col(q,i,le,2,cw)==1 { if wm_span_eq(q,cw[0],cw[1],ws_s,ws_e)==1 { 207 if wm_col(q,i,le,4,cn)==1 { ns=cn[0]; ne=cn[1] } 208 } } 209 i = le + 1 210 } 211 if ns >= 0 { out[0]=ns; out[1]=ne; return 1 } 212 return 0 213} 214func wm_ws_actors(q: *u8, cx: *i64, ws_s: i64, ws_e: i64) -> i64 { 215 let n: i64 = cx[0] 216 let cw: *i64 = sys_mmap(16) as *i64 217 let ca: *i64 = sys_mmap(16) as *i64 218 let cw2: *i64 = sys_mmap(16) as *i64 219 let ca2: *i64 = sys_mmap(16) as *i64 220 var c: i64 = 0 221 var i: i64 = 0 222 while i < n { 223 let le: i64 = wm_le(q,i,n) 224 if wm_col(q,i,le,2,cw)==1 { if wm_span_eq(q,cw[0],cw[1],ws_s,ws_e)==1 { 225 if wm_col(q,i,le,3,ca)==1 { 226 var seen: i64 = 0 227 var j: i64 = 0 228 while j < i { 229 let je: i64 = wm_le(q,j,i) 230 if wm_col(q,j,je,2,cw2)==1 { if wm_span_eq(q,cw2[0],cw2[1],ws_s,ws_e)==1 { 231 if wm_col(q,j,je,3,ca2)==1 { if wm_span_eq(q,ca2[0],ca2[1],ca[0],ca[1])==1 { seen = 1 } } 232 } } 233 j = je + 1 234 } 235 if seen==0 { c=c+1 } 236 } 237 } } 238 i = le + 1 239 } 240 return c 241} 242// state: 0 DONE / 1 ACTIVE / 2 STALE / 3 ABANDONED (thresholds are DATA in cx, never magic) 243func wm_state(q: *u8, cx: *i64, ws_s: i64, ws_e: i64) -> i64 { 244 if wm_has(q,cx[0],"DONE" as *u8,ws_s,ws_e)==1 { return 0 } 245 let lt: i64 = wm_last_ts(q,cx,ws_s,ws_e) 246 if lt < 0 { return 3 } 247 let age: i64 = cx[1] - lt 248 if age > cx[3] { return 3 } 249 if age > cx[2] { return 2 } 250 return 1 251} 252func wm_state_name(st: i64) -> *u8 { 253 if st==0 { return "DONE" as *u8 } 254 if st==1 { return "ACTIVE" as *u8 } 255 if st==2 { return "STALE" as *u8 } 256 return "ABANDONED" as *u8 257} 258func wm_lanes_total(q: *u8, cx: *i64, t: *i64) -> i64 { 259 let n: i64 = cx[0] 260 let cv: *i64 = sys_mmap(16) as *i64 261 let cw: *i64 = sys_mmap(16) as *i64 262 t[0]=0; t[1]=0; t[2]=0; t[3]=0; t[4]=0 263 var i: i64 = 0 264 while i < n { 265 let le: i64 = wm_le(q,i,n) 266 if wm_col(q,i,le,1,cv)==1 { if wm_lit_eq(q,cv[0],cv[1],"KICKOFF" as *u8)==1 { 267 if wm_col(q,i,le,2,cw)==1 { if wm_first_kick(q,i,cw[0],cw[1])==1 { 268 t[0]=t[0]+1 269 let st: i64 = wm_state(q,cx,cw[0],cw[1]) 270 t[1+st]=t[1+st]+1 271 } } 272 } } 273 i = le + 1 274 } 275 return 0 276} 277func wm_ws_span_lit(q: *u8, cx: *i64, ws: *u8, out: *i64) -> i64 { 278 let n: i64 = cx[0] 279 let cw: *i64 = sys_mmap(16) as *i64 280 var i: i64 = 0 281 while i < n { 282 let le: i64 = wm_le(q,i,n) 283 if wm_col(q,i,le,2,cw)==1 { if wm_lit_eq(q,cw[0],cw[1],ws)==1 { out[0]=cw[0]; out[1]=cw[1]; return 1 } } 284 i = le + 1 285 } 286 return 0 287} 288func wm_actor_span_lit(q: *u8, cx: *i64, actor: *u8, out: *i64) -> i64 { 289 let n: i64 = cx[0] 290 let ca: *i64 = sys_mmap(16) as *i64 291 var i: i64 = 0 292 while i < n { 293 let le: i64 = wm_le(q,i,n) 294 if wm_col(q,i,le,3,ca)==1 { if wm_lit_eq(q,ca[0],ca[1],actor)==1 { out[0]=ca[0]; out[1]=ca[1]; return 1 } } 295 i = le + 1 296 } 297 return 0 298} 299 300// ---------- actor scans ---------- 301func wm_actor_seen(q: *u8, upto: i64, a_s: i64, a_e: i64) -> i64 { 302 let ca: *i64 = sys_mmap(16) as *i64 303 var i: i64 = 0 304 while i < upto { 305 let le: i64 = wm_le(q,i,upto) 306 if wm_col(q,i,le,3,ca)==1 { if wm_span_eq(q,ca[0],ca[1],a_s,a_e)==1 { return 1 } } 307 i = le + 1 308 } 309 return 0 310} 311func wm_actors_distinct(q: *u8, cx: *i64) -> i64 { 312 let n: i64 = cx[0] 313 let ca: *i64 = sys_mmap(16) as *i64 314 var c: i64 = 0 315 var i: i64 = 0 316 while i < n { 317 let le: i64 = wm_le(q,i,n) 318 if wm_col(q,i,le,3,ca)==1 { if wm_actor_seen(q,i,ca[0],ca[1])==0 { c=c+1 } } 319 i = le + 1 320 } 321 return c 322} 323func wm_actor_frames(q: *u8, cx: *i64, a_s: i64, a_e: i64) -> i64 { 324 let n: i64 = cx[0] 325 let ca: *i64 = sys_mmap(16) as *i64 326 var c: i64 = 0 327 var i: i64 = 0 328 while i < n { 329 let le: i64 = wm_le(q,i,n) 330 if wm_col(q,i,le,3,ca)==1 { if wm_span_eq(q,ca[0],ca[1],a_s,a_e)==1 { c=c+1 } } 331 i = le + 1 332 } 333 return c 334} 335func wm_actor_ws(q: *u8, cx: *i64, a_s: i64, a_e: i64) -> i64 { 336 let n: i64 = cx[0] 337 let ca: *i64 = sys_mmap(16) as *i64 338 let cw: *i64 = sys_mmap(16) as *i64 339 let ca2: *i64 = sys_mmap(16) as *i64 340 let cw2: *i64 = sys_mmap(16) as *i64 341 var c: i64 = 0 342 var i: i64 = 0 343 while i < n { 344 let le: i64 = wm_le(q,i,n) 345 if wm_col(q,i,le,3,ca)==1 { if wm_span_eq(q,ca[0],ca[1],a_s,a_e)==1 { 346 if wm_col(q,i,le,2,cw)==1 { 347 var seen: i64 = 0 348 var j: i64 = 0 349 while j < i { 350 let je: i64 = wm_le(q,j,i) 351 if wm_col(q,j,je,3,ca2)==1 { if wm_span_eq(q,ca2[0],ca2[1],a_s,a_e)==1 { 352 if wm_col(q,j,je,2,cw2)==1 { if wm_span_eq(q,cw2[0],cw2[1],cw[0],cw[1])==1 { seen=1 } } 353 } } 354 j = je + 1 355 } 356 if seen==0 { c=c+1 } 357 } 358 } } 359 i = le + 1 360 } 361 return c 362} 363 364// ---------- emit helpers (quotes/braces emitted as BYTES -- no escaped-quote literals) ---------- 365func wm_jesc(d: *u8, o: i64, q: *u8, s: i64, e: i64, maxb: i64) -> i64 { 366 var p: i64 = o 367 var i: i64 = s 368 var used: i64 = 0 369 while i < e { 370 if used >= maxb { i = e } else { 371 let c: i64 = q[i] as i64 372 if c == 34 { d[p]=92 as u8; p=p+1; d[p]=34 as u8; p=p+1 } else { if c == 92 { d[p]=92 as u8; p=p+1; d[p]=92 as u8; p=p+1 } else { if c < 32 { d[p]=32 as u8; p=p+1 } else { d[p]=c as u8; p=p+1 } } } 373 used = used + 2 374 i = i + 1 375 } 376 } 377 return p 378} 379func wm_key(d: *u8, o: i64, name: *u8) -> i64 { 380 d[o]=34 as u8 381 var p: i64 = o + 1 382 p = wm_cat(d,p,name) 383 d[p]=34 as u8 384 p = p + 1 385 d[p]=58 as u8 386 p = p + 1 387 return p 388} 389func wm_qlit(d: *u8, o: i64, s: *u8) -> i64 { 390 var p: i64 = o 391 d[p]=34 as u8; p=p+1 392 p = wm_cat(d,p,s) 393 d[p]=34 as u8; p=p+1 394 return p 395} 396func wm_emit_lane(d: *u8, o: i64, q: *u8, cx: *i64, ws_s: i64, ws_e: i64) -> i64 { 397 var p: i64 = o 398 d[p]=123 as u8; p=p+1 399 p = wm_key(d,p,"ws" as *u8) 400 d[p]=34 as u8; p=p+1 401 p = wm_jesc(d,p,q,ws_s,ws_e,WM_NAME_MAX) 402 d[p]=34 as u8; p=p+1 403 d[p]=44 as u8; p=p+1 404 p = wm_key(d,p,"state" as *u8) 405 let st: i64 = wm_state(q,cx,ws_s,ws_e) 406 let sn: *u8 = wm_state_name(st) 407 p = wm_qlit(d,p,sn) 408 d[p]=44 as u8; p=p+1 409 p = wm_key(d,p,"kickoffs" as *u8) 410 let k: i64 = wm_count_verb(q,cx,"KICKOFF" as *u8,ws_s,ws_e) 411 p = wm_catn(d,p,k) 412 d[p]=44 as u8; p=p+1 413 p = wm_key(d,p,"beats" as *u8) 414 let b: i64 = wm_count_verb(q,cx,"BEAT" as *u8,ws_s,ws_e) 415 p = wm_catn(d,p,b) 416 d[p]=44 as u8; p=p+1 417 p = wm_key(d,p,"dones" as *u8) 418 let dn: i64 = wm_count_verb(q,cx,"DONE" as *u8,ws_s,ws_e) 419 p = wm_catn(d,p,dn) 420 d[p]=44 as u8; p=p+1 421 p = wm_key(d,p,"first_ts" as *u8) 422 let ft: i64 = wm_first_ts(q,cx,ws_s,ws_e) 423 p = wm_catn(d,p,ft) 424 d[p]=44 as u8; p=p+1 425 p = wm_key(d,p,"last_ts" as *u8) 426 let lt: i64 = wm_last_ts(q,cx,ws_s,ws_e) 427 p = wm_catn(d,p,lt) 428 d[p]=44 as u8; p=p+1 429 p = wm_key(d,p,"age_sec" as *u8) 430 var age: i64 = -1 431 if lt >= 0 { age = cx[1] - lt } 432 p = wm_catn(d,p,age) 433 d[p]=44 as u8; p=p+1 434 p = wm_key(d,p,"actors" as *u8) 435 let ac: i64 = wm_ws_actors(q,cx,ws_s,ws_e) 436 p = wm_catn(d,p,ac) 437 d[p]=44 as u8; p=p+1 438 p = wm_key(d,p,"last_note" as *u8) 439 d[p]=34 as u8; p=p+1 440 let no: *i64 = sys_mmap(16) as *i64 441 let hn: i64 = wm_note_span(q,cx,ws_s,ws_e,no) 442 if hn==1 { p = wm_jesc(d,p,q,no[0],no[1],WM_NOTE_MAX) } 443 d[p]=34 as u8; p=p+1 444 d[p]=125 as u8; p=p+1 445 return p 446} 447func wm_emit_actor(d: *u8, o: i64, q: *u8, cx: *i64, a_s: i64, a_e: i64) -> i64 { 448 var p: i64 = o 449 d[p]=123 as u8; p=p+1 450 p = wm_key(d,p,"actor" as *u8) 451 d[p]=34 as u8; p=p+1 452 p = wm_jesc(d,p,q,a_s,a_e,WM_NAME_MAX) 453 d[p]=34 as u8; p=p+1 454 d[p]=44 as u8; p=p+1 455 let fc: i64 = wm_actor_frames(q,cx,a_s,a_e) 456 p = wm_key(d,p,"frames" as *u8) 457 p = wm_catn(d,p,fc) 458 d[p]=44 as u8; p=p+1 459 let wc: i64 = wm_actor_ws(q,cx,a_s,a_e) 460 p = wm_key(d,p,"workstreams" as *u8) 461 p = wm_catn(d,p,wc) 462 d[p]=125 as u8; p=p+1 463 return p 464} 465func wm_mine_json(q: *u8, cx: *i64, d: *u8) -> i64 { 466 let n: i64 = cx[0] 467 var p: i64 = 0 468 d[p]=123 as u8; p=p+1 469 p = wm_key(d,p,"v" as *u8) 470 p = wm_catn(d,p,1) 471 d[p]=44 as u8; p=p+1 472 p = wm_key(d,p,"tool" as *u8) 473 p = wm_qlit(d,p,"nx_ws_miner" as *u8) 474 d[p]=44 as u8; p=p+1 475 p = wm_key(d,p,"journal" as *u8) 476 d[p]=34 as u8; p=p+1 477 let jp: *u8 = cx[5] as *u8 478 let jl: i64 = wm_vlen(jp) 479 p = wm_jesc(d,p,jp,0,jl,200) 480 d[p]=34 as u8; p=p+1 481 d[p]=44 as u8; p=p+1 482 p = wm_key(d,p,"journal_bytes" as *u8) 483 p = wm_catn(d,p,n) 484 d[p]=44 as u8; p=p+1 485 p = wm_key(d,p,"window_bytes" as *u8) 486 p = wm_catn(d,p,WM_WIN) 487 d[p]=44 as u8; p=p+1 488 p = wm_key(d,p,"truncated" as *u8) 489 p = wm_catn(d,p,cx[4]) 490 d[p]=44 as u8; p=p+1 491 p = wm_key(d,p,"now" as *u8) 492 p = wm_catn(d,p,cx[1]) 493 d[p]=44 as u8; p=p+1 494 p = wm_key(d,p,"stale_sec" as *u8) 495 p = wm_catn(d,p,cx[2]) 496 d[p]=44 as u8; p=p+1 497 p = wm_key(d,p,"abandoned_sec" as *u8) 498 p = wm_catn(d,p,cx[3]) 499 d[p]=44 as u8; p=p+1 500 p = wm_key(d,p,"note_max_bytes" as *u8) 501 p = wm_catn(d,p,WM_NOTE_MAX) 502 d[p]=44 as u8; p=p+1 503 let fr: i64 = wm_frames(q,n) 504 p = wm_key(d,p,"frames" as *u8) 505 p = wm_catn(d,p,fr) 506 d[p]=44 as u8; p=p+1 507 let t: *i64 = sys_mmap(64) as *i64 508 wm_lanes_total(q,cx,t) 509 let ad: i64 = wm_actors_distinct(q,cx) 510 p = wm_key(d,p,"totals" as *u8) 511 d[p]=123 as u8; p=p+1 512 p = wm_key(d,p,"workstreams" as *u8) 513 p = wm_catn(d,p,t[0]) 514 d[p]=44 as u8; p=p+1 515 p = wm_key(d,p,"done" as *u8) 516 p = wm_catn(d,p,t[1]) 517 d[p]=44 as u8; p=p+1 518 p = wm_key(d,p,"active" as *u8) 519 p = wm_catn(d,p,t[2]) 520 d[p]=44 as u8; p=p+1 521 p = wm_key(d,p,"stale" as *u8) 522 p = wm_catn(d,p,t[3]) 523 d[p]=44 as u8; p=p+1 524 p = wm_key(d,p,"abandoned" as *u8) 525 p = wm_catn(d,p,t[4]) 526 d[p]=44 as u8; p=p+1 527 p = wm_key(d,p,"actors" as *u8) 528 p = wm_catn(d,p,ad) 529 d[p]=125 as u8; p=p+1 530 d[p]=44 as u8; p=p+1 531 p = wm_key(d,p,"lanes" as *u8) 532 d[p]=91 as u8; p=p+1 533 let cv: *i64 = sys_mmap(16) as *i64 534 let cw: *i64 = sys_mmap(16) as *i64 535 var capped: i64 = 0 536 var first: i64 = 1 537 var i: i64 = 0 538 while i < n { 539 let le: i64 = wm_le(q,i,n) 540 if wm_col(q,i,le,1,cv)==1 { if wm_lit_eq(q,cv[0],cv[1],"KICKOFF" as *u8)==1 { 541 if wm_col(q,i,le,2,cw)==1 { if wm_first_kick(q,i,cw[0],cw[1])==1 { 542 if p > WM_SOFT { capped=1 } else { 543 if first==0 { d[p]=44 as u8; p=p+1 } 544 first=0 545 p = wm_emit_lane(d,p,q,cx,cw[0],cw[1]) 546 } 547 } } 548 } } 549 i = le + 1 550 } 551 d[p]=93 as u8; p=p+1 552 d[p]=44 as u8; p=p+1 553 p = wm_key(d,p,"lanes_capped" as *u8) 554 p = wm_catn(d,p,capped) 555 d[p]=44 as u8; p=p+1 556 p = wm_key(d,p,"actors_list" as *u8) 557 d[p]=91 as u8; p=p+1 558 let ca: *i64 = sys_mmap(16) as *i64 559 var acapped: i64 = 0 560 var afirst: i64 = 1 561 var j: i64 = 0 562 while j < n { 563 let je: i64 = wm_le(q,j,n) 564 if wm_col(q,j,je,3,ca)==1 { if wm_actor_seen(q,j,ca[0],ca[1])==0 { 565 if p > WM_SOFT2 { acapped=1 } else { 566 if afirst==0 { d[p]=44 as u8; p=p+1 } 567 afirst=0 568 p = wm_emit_actor(d,p,q,cx,ca[0],ca[1]) 569 } 570 } } 571 j = je + 1 572 } 573 d[p]=93 as u8; p=p+1 574 d[p]=44 as u8; p=p+1 575 p = wm_key(d,p,"actors_capped" as *u8) 576 p = wm_catn(d,p,acapped) 577 d[p]=125 as u8; p=p+1 578 d[p]=10 as u8; p=p+1 579 return p 580} 581 582// ---------- HTML page (no CSS braces, no bang/hash literals -- emitted as bytes where needed) ---------- 583func wm_hesc(d: *u8, o: i64, q: *u8, s: i64, e: i64, maxb: i64) -> i64 { 584 var p: i64 = o 585 var i: i64 = s 586 var used: i64 = 0 587 while i < e { 588 if used >= maxb { i = e } else { 589 let c: i64 = q[i] as i64 590 if c == 60 { p = wm_cat(d,p,"&lt;" as *u8) } else { if c == 62 { p = wm_cat(d,p,"&gt;" as *u8) } else { if c == 38 { p = wm_cat(d,p,"&amp;" as *u8) } else { if c < 32 { d[p]=32 as u8; p=p+1 } else { d[p]=c as u8; p=p+1 } } } } 591 used = used + 5 592 i = i + 1 593 } 594 } 595 return p 596} 597func wm_td_n(d: *u8, o: i64, v: i64) -> i64 { 598 var p: i64 = o 599 p = wm_cat(d,p,"<td>" as *u8) 600 p = wm_catn(d,p,v) 601 p = wm_cat(d,p,"</td>" as *u8) 602 return p 603} 604func wm_page_html(q: *u8, cx: *i64, d: *u8) -> i64 { 605 let n: i64 = cx[0] 606 var p: i64 = 0 607 p = wm_cat(d,p,"<" as *u8) 608 d[p]=33 as u8 609 p = p + 1 610 p = wm_cat(d,p,"doctype html><html><head><meta charset=utf-8><title>Nishi Workstream Miner</title></head><body>" as *u8) 611 p = wm_cat(d,p,"<h1>Nishi Workstream Miner -- historic + parallel lanes</h1>" as *u8) 612 let t: *i64 = sys_mmap(64) as *i64 613 wm_lanes_total(q,cx,t) 614 let ad: i64 = wm_actors_distinct(q,cx) 615 let fr: i64 = wm_frames(q,n) 616 p = wm_cat(d,p,"<p>workstreams=" as *u8) 617 p = wm_catn(d,p,t[0]) 618 p = wm_cat(d,p," done=" as *u8) 619 p = wm_catn(d,p,t[1]) 620 p = wm_cat(d,p," active=" as *u8) 621 p = wm_catn(d,p,t[2]) 622 p = wm_cat(d,p," stale=" as *u8) 623 p = wm_catn(d,p,t[3]) 624 p = wm_cat(d,p," abandoned=" as *u8) 625 p = wm_catn(d,p,t[4]) 626 p = wm_cat(d,p," actors=" as *u8) 627 p = wm_catn(d,p,ad) 628 p = wm_cat(d,p," frames=" as *u8) 629 p = wm_catn(d,p,fr) 630 p = wm_cat(d,p,"</p>" as *u8) 631 p = wm_cat(d,p,"<table border=1><tr><th>workstream</th><th>state</th><th>kick</th><th>beat</th><th>done</th><th>age-min</th><th>actors</th><th>last checkpoint</th></tr>" as *u8) 632 let cv: *i64 = sys_mmap(16) as *i64 633 let cw: *i64 = sys_mmap(16) as *i64 634 let no: *i64 = sys_mmap(16) as *i64 635 var truncated_rows: i64 = 0 636 var i: i64 = 0 637 while i < n { 638 let le: i64 = wm_le(q,i,n) 639 if wm_col(q,i,le,1,cv)==1 { if wm_lit_eq(q,cv[0],cv[1],"KICKOFF" as *u8)==1 { 640 if wm_col(q,i,le,2,cw)==1 { if wm_first_kick(q,i,cw[0],cw[1])==1 { 641 if p > WM_PAGE_SOFT { truncated_rows = truncated_rows + 1 } else { 642 p = wm_cat(d,p,"<tr><td>" as *u8) 643 p = wm_hesc(d,p,q,cw[0],cw[1],WM_NAME_MAX) 644 p = wm_cat(d,p,"</td><td>" as *u8) 645 let st: i64 = wm_state(q,cx,cw[0],cw[1]) 646 let sn: *u8 = wm_state_name(st) 647 p = wm_cat(d,p,sn) 648 p = wm_cat(d,p,"</td>" as *u8) 649 let k: i64 = wm_count_verb(q,cx,"KICKOFF" as *u8,cw[0],cw[1]) 650 p = wm_td_n(d,p,k) 651 let b: i64 = wm_count_verb(q,cx,"BEAT" as *u8,cw[0],cw[1]) 652 p = wm_td_n(d,p,b) 653 let dn: i64 = wm_count_verb(q,cx,"DONE" as *u8,cw[0],cw[1]) 654 p = wm_td_n(d,p,dn) 655 let lt: i64 = wm_last_ts(q,cx,cw[0],cw[1]) 656 var agem: i64 = -1 657 if lt >= 0 { agem = (cx[1] - lt) / 60 } 658 p = wm_td_n(d,p,agem) 659 let ac: i64 = wm_ws_actors(q,cx,cw[0],cw[1]) 660 p = wm_td_n(d,p,ac) 661 p = wm_cat(d,p,"<td>" as *u8) 662 let hn: i64 = wm_note_span(q,cx,cw[0],cw[1],no) 663 if hn==1 { p = wm_hesc(d,p,q,no[0],no[1],WM_NOTE_MAX) } 664 p = wm_cat(d,p,"</td></tr>" as *u8) 665 } 666 } } 667 } } 668 i = le + 1 669 } 670 p = wm_cat(d,p,"</table>" as *u8) 671 if truncated_rows > 0 { 672 p = wm_cat(d,p,"<p>ENVELOPE: rows_truncated=" as *u8) 673 p = wm_catn(d,p,truncated_rows) 674 p = wm_cat(d,p,"</p>" as *u8) 675 } 676 p = wm_cat(d,p,"<p>envelope window_bytes=" as *u8) 677 p = wm_catn(d,p,WM_WIN) 678 p = wm_cat(d,p," journal_bytes=" as *u8) 679 p = wm_catn(d,p,n) 680 p = wm_cat(d,p," truncated=" as *u8) 681 p = wm_catn(d,p,cx[4]) 682 p = wm_cat(d,p," generated=" as *u8) 683 p = wm_catn(d,p,cx[1]) 684 p = wm_cat(d,p," | source=knowledge/status/ws_sync.jrnl | tool=nx_ws_miner (MCP) | <a href=/standup>standup</a> <a href=/frontier>frontier</a> <a href=/roi>roi</a></p>" as *u8) 685 p = wm_cat(d,p,"</body></html>" as *u8) 686 d[p]=10 as u8 687 p = p + 1 688 return p 689} 690 691// ---------- substring find (selftest smoke) ---------- 692func wm_find(d: *u8, dn: i64, lit: *u8) -> i64 { 693 let ll: i64 = wm_vlen(lit) 694 if ll == 0 { return 0 } 695 var i: i64 = 0 696 while i + ll <= dn { 697 var k: i64 = 0 698 var ok: i64 = 1 699 while k < ll { if d[i+k]!=lit[k] { ok=0; k=ll } else { k=k+1 } } 700 if ok==1 { return 1 } 701 i = i + 1 702 } 703 return 0 704} 705 706// ---------- selftest gate (T1..T9, deterministic via injected timestamps) ---------- 707func wm_selftest(journal: *u8) -> i64 { 708 let ctr: *i64 = gv_ctr() 709 gv_head("nx_ws_miner selftest -- historic workstream mining teeth (caller pre-cleans journal)" as *u8) 710 let q: *u8 = sys_mmap(WM_WIN) 711 let cx: *i64 = sys_mmap(64) as *i64 712 let t: *i64 = sys_mmap(64) as *i64 713 let sp: *i64 = sys_mmap(16) as *i64 714 let now: i64 = sys_now_realtime_sec() 715 let rcap: i64 = WM_WIN - 8 716 // T1 empty journal -> zero lanes, no fabrication 717 var n: i64 = wm_read(journal,q,rcap) 718 cx[0]=n; cx[1]=now; cx[2]=WM_STALE_DEF; cx[3]=WM_ABAND_DEF; cx[4]=0; cx[5]=journal as i64 719 wm_lanes_total(q,cx,t) 720 var ok1: i64 = 0 721 if t[0]==0 { if n==0 { ok1=1 } } 722 gv_check("T1 empty journal zero lanes no fabrication" as *u8, ok1, ctr) 723 // seed lane A: full lifecycle at fixed ancient timestamps 724 wm_append(journal, 1000, "KICKOFF" as *u8, "laneA" as *u8, "actor1" as *u8, "start-A" as *u8) 725 wm_append(journal, WM_MAGIC_2000, "BEAT" as *u8, "laneA" as *u8, "actor1" as *u8, "mid-A" as *u8) 726 wm_append(journal, WM_MAGIC_3000, "DONE" as *u8, "laneA" as *u8, "actor1" as *u8, "end-A" as *u8) 727 n = wm_read(journal,q,rcap) 728 cx[0]=n 729 wm_lanes_total(q,cx,t) 730 var ok2: i64 = 0 731 if t[0]==1 { if t[1]==1 { ok2=1 } } 732 gv_check("T2 lifecycle lane counted once and DONE" as *u8, ok2, ctr) 733 var ok3: i64 = 0 734 if wm_ws_span_lit(q,cx,"laneA" as *u8,sp)==1 { 735 let ka: i64 = wm_count_verb(q,cx,"KICKOFF" as *u8,sp[0],sp[1]) 736 let ba: i64 = wm_count_verb(q,cx,"BEAT" as *u8,sp[0],sp[1]) 737 let fa: i64 = wm_first_ts(q,cx,sp[0],sp[1]) 738 let la: i64 = wm_last_ts(q,cx,sp[0],sp[1]) 739 if ka==1 { if ba==1 { if fa==1000 { if la==WM_MAGIC_3000 { ok3=1 } } } } 740 } 741 gv_check("T3 per-lane counts and first/last ts exact" as *u8, ok3, ctr) 742 // T4 ancient kickoff without done -> ABANDONED 743 wm_append(journal, 1000, "KICKOFF" as *u8, "laneB" as *u8, "actor2" as *u8, "start-B" as *u8) 744 n = wm_read(journal,q,rcap) 745 cx[0]=n 746 var ok4: i64 = 0 747 if wm_ws_span_lit(q,cx,"laneB" as *u8,sp)==1 { let st4: i64 = wm_state(q,cx,sp[0],sp[1]); if st4==3 { ok4=1 } } 748 gv_check("T4 ancient undone lane detected ABANDONED" as *u8, ok4, ctr) 749 // T5 mid-age lane -> STALE 750 let ts5: i64 = now - WM_MAGIC_7200 751 wm_append(journal, ts5, "KICKOFF" as *u8, "laneD" as *u8, "actor3" as *u8, "start-D" as *u8) 752 n = wm_read(journal,q,rcap) 753 cx[0]=n 754 var ok5: i64 = 0 755 if wm_ws_span_lit(q,cx,"laneD" as *u8,sp)==1 { let st5: i64 = wm_state(q,cx,sp[0],sp[1]); if st5==2 { ok5=1 } } 756 gv_check("T5 hour-old undone lane detected STALE" as *u8, ok5, ctr) 757 // T6 fresh lane -> ACTIVE 758 let ts6: i64 = now - 10 759 wm_append(journal, ts6, "KICKOFF" as *u8, "laneC" as *u8, "actor2" as *u8, "start-C" as *u8) 760 n = wm_read(journal,q,rcap) 761 cx[0]=n 762 var ok6: i64 = 0 763 if wm_ws_span_lit(q,cx,"laneC" as *u8,sp)==1 { let st6: i64 = wm_state(q,cx,sp[0],sp[1]); if st6==1 { ok6=1 } } 764 gv_check("T6 fresh undone lane detected ACTIVE" as *u8, ok6, ctr) 765 // T7 distinct actors overall + per-actor workstream reach (actor2 touched laneB + laneC) 766 let adc: i64 = wm_actors_distinct(q,cx) 767 var ok7: i64 = 0 768 if adc==3 { 769 if wm_actor_span_lit(q,cx,"actor2" as *u8,sp)==1 { 770 let wc: i64 = wm_actor_ws(q,cx,sp[0],sp[1]) 771 if wc==2 { ok7=1 } 772 } 773 } 774 gv_check("T7 distinct actors 3 and actor2 reach 2 lanes" as *u8, ok7, ctr) 775 // T8 neg-control: absent workstream honestly ABSENT (no fabricated span/ts) 776 var ok8: i64 = 0 777 if wm_ws_span_lit(q,cx,"laneNOPE" as *u8,sp)==0 { ok8=1 } 778 gv_check("T8 neg-control absent lane stays absent" as *u8, ok8, ctr) 779 // T9 JSON emit smoke: valid open brace + totals + envelope keys present 780 let d: *u8 = sys_mmap(WM_OUT) 781 let dl: i64 = wm_mine_json(q,cx,d) 782 var ok9: i64 = 0 783 if dl > 0 { if d[0]==(123 as u8) { if wm_find(d,dl,"workstreams" as *u8)==1 { if wm_find(d,dl,"lanes_capped" as *u8)==1 { if wm_find(d,dl,"ABANDONED" as *u8)==1 { ok9=1 } } } } } 784 gv_check("T9 JSON emit carries totals plus declared envelope" as *u8, ok9, ctr) 785 let rc: i64 = gv_verdict("WS-MINER-GATE" as *u8, ctr, "historic workstream miner teeth green" as *u8) 786 return rc 787} 788 789func main(argc: i64, argv: *i64) -> i64 { 790 if argc < 3 { gv_puts("usage: nx_ws_miner {mine <journal> [stale_sec] [abandoned_sec] | page <journal> <outfile> [stale_sec] [abandoned_sec] | selftest <journal>}\n" as *u8); sys_exit(2); return 2 } 791 let verb: *u8 = argv[1] as *u8 792 let journal: *u8 = argv[2] as *u8 793 let vl: i64 = wm_vlen(verb) 794 if wm_lit_eq(verb,0,vl,"selftest" as *u8)==1 { let rc: i64 = wm_selftest(journal); sys_exit(rc); return rc } 795 let q: *u8 = sys_mmap(WM_WIN) 796 let rcap: i64 = WM_WIN - 8 797 let n: i64 = wm_read(journal,q,rcap) 798 let cx: *i64 = sys_mmap(64) as *i64 799 cx[0]=n 800 cx[1]=sys_now_realtime_sec() 801 cx[2]=WM_STALE_DEF 802 cx[3]=WM_ABAND_DEF 803 cx[4]=0 804 if n >= rcap { cx[4]=1 } 805 cx[5]=journal as i64 806 if wm_lit_eq(verb,0,vl,"mine" as *u8)==1 { 807 if argc >= 4 { let sv: i64 = wm_atoi_z(argv[3] as *u8); if sv > 0 { cx[2]=sv } } 808 if argc >= 5 { let av: i64 = wm_atoi_z(argv[4] as *u8); if av > 0 { cx[3]=av } } 809 let d: *u8 = sys_mmap(WM_OUT) 810 let dl: i64 = wm_mine_json(q,cx,d) 811 sys_write(1,d,dl) 812 sys_exit(0) 813 return 0 814 } 815 if wm_lit_eq(verb,0,vl,"page" as *u8)==1 { 816 if argc < 4 { gv_puts("page needs <journal> <outfile>\n" as *u8); sys_exit(2); return 2 } 817 if argc >= 5 { let sv2: i64 = wm_atoi_z(argv[4] as *u8); if sv2 > 0 { cx[2]=sv2 } } 818 if argc >= 6 { let av2: i64 = wm_atoi_z(argv[5] as *u8); if av2 > 0 { cx[3]=av2 } } 819 let outfile: *u8 = argv[3] as *u8 820 let d: *u8 = sys_mmap(WM_OUT) 821 let dl: i64 = wm_page_html(q,cx,d) 822 let fd: i64 = sys_openat_wr(outfile, 0x1a4) 823 if fd < 0 { gv_puts("WSMINE-PAGE OPEN-FAIL\n" as *u8); sys_exit(1); return 1 } 824 sys_write(fd,d,dl) 825 sys_close(fd) 826 gv_puts("WSMINE-PAGE bytes=" as *u8) 827 gv_num(dl) 828 gv_puts("\n" as *u8) 829 sys_exit(0) 830 return 0 831 } 832 gv_puts("unknown verb\n" as *u8) 833 sys_exit(2) 834 return 2 835}