code wiki / _hdl_build / nx_vizsla_jobs.nx

nx_vizsla_jobs.nx source

↩ module page · 665 lines · 24120 B

1// nx_vizsla_jobs.nx -- NISHI VIZSLA V2a: the job-search engine (career domain). 2// Fills career/AUTHOR (job-search-engine) + career/EDITOR (application-tracker) 3// from the V0 gap profile. V2a = match scoring + tracker + cadence against a 4// FIXTURE-ORACLE corpus; V2b (named follow-on, Market Researcher lane) = live 5// posting census via own-TLS entity-gather feeding the same postings format. 6// 7// Commands (argv[1]): 8// match <profile> <postings> [log] score every posting for every SEEK 9// member: score = sum of that member's 10// SKILL weights whose term appears in 11// the posting's term list. Rank rows 12// score-desc (file order breaks ties); 13// zero-score postings are PRINTED not 14// dropped (matched= counts score>0). 15// track <appfile> <prefix> [segid] APP rows -> canonical records -> CID 16// keys "app:nxc1-..." on seg_store = 17// IDEMPOTENT additive application 18// history (same law/substrate as V1). 19// cadence <prefix> <profile> walk the app history chronologically; 20// LAST status per posting wins; posting 21// whose last status is not in the 22// profile's CLOSED set gets a follow-up 23// row. Closed apps are suppressed from 24// cadence but stay in history (additive). 25// 26// File formats (line records, # comments; ALL model data in files, law 11/25): 27// profile: SEEK <member> 28// SKILL <member> <weight> <term> 29// CLOSED <status> (statuses that need no follow-up) 30// postings: POST <id> <pay_cents> <term> <term> ... 31// apps: APP <date> <post-id> <member> <status> <note> 32// 33// Determinism: stdout has no clocks; epoch headers go to logs only (match log 34// argv-overridable; track/cadence log derived from store prefix = fixture 35// isolation). Loud-fail law: missing files, SKILL for unknown member, 36// non-digit pay/weight = exit 1 named. 37// EXCEED (V2a): ranking is the FAMILY'S fit function -- data-edited skill 38// weights -- not an ad-funded board's pay-to-play order; cadence is the 39// editor-fill that closes application loops. Reach EXCEED lands with V2b. 40// spec: knowledge/specs/2026-06-10-nishi-vizsla-ladder.md license_tier: ORIGINAL 41import "nx_syscalls.nx" 42import "nx_canon_cid.nx" 43import "nx_seg_store.nx" 44const K_MAGIC_4096: i64 = 4096 45const K_MAGIC_131072: i64 = 131072 46const K_MAGIC_2048: i64 = 2048 47const K_MAGIC_65536: i64 = 65536 48 49func vj_slen(s: *u8) -> i64 { 50 var n: i64 = 0 51 while s[n] != (0 as u8) { n = n + 1 } 52 return n 53} 54 55func vj_p(s: *u8) -> i64 { 56 sys_write(1, s, vj_slen(s)) 57 return 0 58} 59 60func vj_eq(a: *u8, b: *u8) -> i64 { 61 var i: i64 = 0 62 var go: i64 = 1 63 while go == 1 { 64 if a[i] != b[i] { return 0 } 65 if a[i] == (0 as u8) { return 1 } 66 i = i + 1 67 } 68 return 0 69} 70 71func vj_dup(s: *u8) -> *u8 { 72 let n: i64 = vj_slen(s) 73 let d: *u8 = sys_mmap(n + 2) 74 var i: i64 = 0 75 while i <= n { d[i] = s[i]; i = i + 1 } 76 return d 77} 78 79func vj_atoi(s: *u8) -> i64 { 80 var v: i64 = 0 81 var i: i64 = 0 82 while s[i] != (0 as u8) { 83 let d: i64 = (s[i] as i64) - 48 84 if d >= 0 { if d <= 9 { v = v * 10 + d } } 85 i = i + 1 86 } 87 return v 88} 89 90func vj_digits(s: *u8) -> i64 { 91 if s[0] == (0 as u8) { return 0 } 92 var i: i64 = 0 93 while s[i] != (0 as u8) { 94 let d: i64 = (s[i] as i64) - 48 95 if d < 0 { return 0 } 96 if d > 9 { return 0 } 97 i = i + 1 98 } 99 return 1 100} 101 102func vj_isws(c: i64) -> i64 { 103 if c == 32 { return 1 } 104 if c == 13 { return 1 } 105 if c == 9 { return 1 } 106 return 0 107} 108 109func vj_tok(b: *u8, off: i64, lend: i64, dst: *u8, cap: i64) -> i64 { 110 var p: i64 = off 111 var go: i64 = 1 112 while go == 1 { 113 if p >= lend { go = 0 } else { 114 if vj_isws(b[p] as i64) == 1 { p = p + 1 } else { go = 0 } 115 } 116 } 117 var t: i64 = 0 118 go = 1 119 while go == 1 { 120 if p >= lend { go = 0 } else { 121 if vj_isws(b[p] as i64) == 1 { go = 0 } else { 122 if t < cap - 1 { dst[t] = b[p]; t = t + 1 } 123 p = p + 1 124 } 125 } 126 } 127 dst[t] = 0 as u8 128 return p 129} 130 131func vj_cat(dst: *u8, off: i64, s: *u8) -> i64 { 132 var i: i64 = 0 133 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 } 134 return off + i 135} 136 137func vj_catn(dst: *u8, off: i64, v: i64) -> i64 { 138 var o: i64 = off 139 var m: i64 = v 140 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m } 141 let t: *u8 = sys_mmap(28) 142 var k: i64 = 0 143 if m == 0 { t[0] = 48 as u8; k = 1 } 144 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 145 var i: i64 = 0 146 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 } 147 return o + k 148} 149 150func vj_find(list: *i64, n: i64, s: *u8) -> i64 { 151 var i: i64 = 0 152 while i < n { 153 if vj_eq(list[i] as *u8, s) == 1 { return i } 154 i = i + 1 155 } 156 return 0 - 1 157} 158 159func vj_kmemeq(b: *u8, off: i64, n: i64, s: *u8) -> i64 { 160 if vj_slen(s) != n { return 0 } 161 var i: i64 = 0 162 while i < n { 163 if b[off + i] != s[i] { return 0 } 164 i = i + 1 165 } 166 return 1 167} 168 169func vj_field(rec: *u8, rl: i64, want: *u8, out: *u8, cap: i64) -> i64 { 170 if rl < 8 { return 0 } 171 let nf: i64 = ss_r32(rec, 4) 172 var off: i64 = 8 173 var fi: i64 = 0 174 while fi < nf { 175 if off + 8 > rl { return 0 } 176 let kl: i64 = ss_r32(rec, off) 177 let koff: i64 = off + 4 178 let vl: i64 = ss_r32(rec, koff + kl) 179 let voff: i64 = koff + kl + 4 180 if vj_kmemeq(rec, koff, kl, want) == 1 { 181 var t: i64 = 0 182 while t < vl { 183 if t < cap - 1 { out[t] = rec[voff + t] } 184 t = t + 1 185 } 186 if t > cap - 1 { t = cap - 1 } 187 out[t] = 0 as u8 188 return 1 189 } 190 off = voff + vl 191 fi = fi + 1 192 } 193 return 0 194} 195 196func vj_isapp(b: *u8, koff: i64, kl: i64) -> i64 { 197 if kl <= 4 { return 0 } 198 return vj_kmemeq(b, koff, 4, "app:" as *u8) 199} 200 201func vj_log(lpath: *u8, tag: *u8, rep: *u8, o: i64) -> i64 { 202 let fd: i64 = sys_openat_append(lpath, 0x1a4) 203 if fd <= 0 { return 0 } 204 let hdr: *u8 = sys_mmap(256) 205 var ho: i64 = 0 206 ho = vj_cat(hdr, ho, "VIZSLA-JOBS epoch=" as *u8) 207 ho = vj_catn(hdr, ho, sys_now_realtime_sec()) 208 ho = vj_cat(hdr, ho, " cmd=" as *u8) 209 ho = vj_cat(hdr, ho, tag) 210 ho = vj_cat(hdr, ho, "\n" as *u8) 211 sys_write(fd, hdr, ho) 212 sys_write(fd, rep, o) 213 sys_close(fd) 214 return 0 215} 216 217func vj_prefixlog(prefix: *u8, out: *u8) -> i64 { 218 var o: i64 = 0 219 o = vj_cat(out, o, prefix) 220 o = vj_cat(out, o, "jobs.log" as *u8) 221 out[o] = 0 as u8 222 return o 223} 224 225// score one member's skills against a posting's term slice 226// sk: [0]=sk_mem [1]=sk_w [2]=sk_term [3]=nskill ; terms = ptr-list slice 227func vj_score(sk: *i64, mi: i64, terms: *i64, nterm: i64) -> i64 { 228 let sk_mem: *i64 = sk[0] as *i64 229 let sk_w: *i64 = sk[1] as *i64 230 let sk_term: *i64 = sk[2] as *i64 231 var sum: i64 = 0 232 var si: i64 = 0 233 while si < sk[3] { 234 if sk_mem[si] == mi { 235 if vj_find(terms, nterm, sk_term[si] as *u8) >= 0 { sum = sum + sk_w[si] } 236 } 237 si = si + 1 238 } 239 return sum 240} 241 242// ---------------- MATCH ---------------- 243func vj_cmd_match(argc: i64, argv: *i64) -> i64 { 244 if argc < 4 { vj_p("VIZSLA-JOBS match needs <profile> <postings> -- fail loud\n" as *u8); return 1 } 245 let ppath: *u8 = argv[2] as *u8 246 let opath: *u8 = argv[3] as *u8 247 var lpath: *u8 = "knowledge/status/vizsla_jobs.log" as *u8 248 if argc > 4 { lpath = argv[4] as *u8 } 249 250 let szp: *i64 = sys_mmap(16) as *i64 251 let pb: *u8 = ss_readall(ppath, szp) 252 let psz: i64 = szp[0] 253 if psz <= 0 { vj_p("VIZSLA-JOBS profile MISSING/EMPTY -- fail loud\n" as *u8); return 1 } 254 let ob: *u8 = ss_readall(opath, szp) 255 let osz: i64 = szp[0] 256 if osz <= 0 { vj_p("VIZSLA-JOBS postings MISSING/EMPTY -- fail loud\n" as *u8); return 1 } 257 258 // profile tables (capacities = buffer sizes, model shape = file content) 259 let seeks: *i64 = sys_mmap(8 * 16) as *i64 260 var nseek: i64 = 0 261 let sk: *i64 = sys_mmap(8 * 8) as *i64 262 sk[0] = sys_mmap(8 * 128) 263 sk[1] = sys_mmap(8 * 128) 264 sk[2] = sys_mmap(8 * 128) 265 sk[3] = 0 266 let sk_mem: *i64 = sk[0] as *i64 267 let sk_w: *i64 = sk[1] as *i64 268 let sk_term: *i64 = sk[2] as *i64 269 270 let t0: *u8 = sys_mmap(128) 271 let t1: *u8 = sys_mmap(128) 272 let t2: *u8 = sys_mmap(128) 273 let t3: *u8 = sys_mmap(128) 274 275 var i: i64 = 0 276 while i < psz { 277 var e: i64 = i 278 var go: i64 = 1 279 while go == 1 { 280 if e >= psz { go = 0 } else { 281 if pb[e] == (10 as u8) { go = 0 } else { e = e + 1 } 282 } 283 } 284 var p: i64 = vj_tok(pb, i, e, t0, 128) 285 if t0[0] == (35 as u8) { t0[0] = 0 as u8 } 286 if vj_eq(t0, "SEEK" as *u8) == 1 { 287 p = vj_tok(pb, p, e, t1, 128) 288 if nseek < 16 { seeks[nseek] = vj_dup(t1) as i64; nseek = nseek + 1 } 289 } 290 if vj_eq(t0, "SKILL" as *u8) == 1 { 291 p = vj_tok(pb, p, e, t1, 128) 292 p = vj_tok(pb, p, e, t2, 128) 293 p = vj_tok(pb, p, e, t3, 128) 294 let mi: i64 = vj_find(seeks, nseek, t1) 295 if mi < 0 { vj_p("VIZSLA-JOBS SKILL references unknown member -- fail loud\n" as *u8); return 1 } 296 if vj_digits(t2) == 0 { vj_p("VIZSLA-JOBS SKILL weight not pure digits -- fail loud\n" as *u8); return 1 } 297 if sk[3] < 128 { 298 sk_mem[sk[3]] = mi 299 sk_w[sk[3]] = vj_atoi(t2) 300 sk_term[sk[3]] = vj_dup(t3) as i64 301 sk[3] = sk[3] + 1 302 } 303 } 304 i = e + 1 305 } 306 if nseek < 1 { vj_p("VIZSLA-JOBS no SEEK members in profile -- fail loud\n" as *u8); return 1 } 307 if sk[3] < 1 { vj_p("VIZSLA-JOBS no SKILL rows in profile -- fail loud\n" as *u8); return 1 } 308 309 // postings: ids, pay, flat term ptr-list with per-post start/count 310 let po_id: *i64 = sys_mmap(8 * 256) as *i64 311 let po_pay: *i64 = sys_mmap(8 * 256) as *i64 312 let po_ts: *i64 = sys_mmap(8 * 256) as *i64 313 let po_tn: *i64 = sys_mmap(8 * 256) as *i64 314 var npost: i64 = 0 315 let terms: *i64 = sys_mmap(8 * K_MAGIC_4096) as *i64 316 var nterm: i64 = 0 317 318 i = 0 319 while i < osz { 320 var e2: i64 = i 321 var go2: i64 = 1 322 while go2 == 1 { 323 if e2 >= osz { go2 = 0 } else { 324 if ob[e2] == (10 as u8) { go2 = 0 } else { e2 = e2 + 1 } 325 } 326 } 327 var p2: i64 = vj_tok(ob, i, e2, t0, 128) 328 if t0[0] == (35 as u8) { t0[0] = 0 as u8 } 329 if vj_eq(t0, "POST" as *u8) == 1 { 330 p2 = vj_tok(ob, p2, e2, t1, 128) 331 p2 = vj_tok(ob, p2, e2, t2, 128) 332 if t1[0] == (0 as u8) { vj_p("VIZSLA-JOBS POST missing id -- fail loud\n" as *u8); return 1 } 333 if vj_digits(t2) == 0 { vj_p("VIZSLA-JOBS POST pay not pure digits -- fail loud\n" as *u8); return 1 } 334 if npost < 256 { 335 po_id[npost] = vj_dup(t1) as i64 336 po_pay[npost] = vj_atoi(t2) 337 po_ts[npost] = nterm 338 var tn: i64 = 0 339 var more: i64 = 1 340 while more == 1 { 341 p2 = vj_tok(ob, p2, e2, t3, 128) 342 if t3[0] == (0 as u8) { more = 0 } else { 343 if nterm < K_MAGIC_4096 { terms[nterm] = vj_dup(t3) as i64; nterm = nterm + 1; tn = tn + 1 } 344 } 345 } 346 po_tn[npost] = tn 347 npost = npost + 1 348 } 349 } 350 i = e2 + 1 351 } 352 if npost < 1 { vj_p("VIZSLA-JOBS no POST rows -- fail loud\n" as *u8); return 1 } 353 354 // rank per member: selection over score desc, file order breaks ties 355 let rep: *u8 = sys_mmap(K_MAGIC_131072) 356 var o: i64 = 0 357 let score: *i64 = sys_mmap(8 * 256) as *i64 358 let used: *i64 = sys_mmap(8 * 256) as *i64 359 var mi2: i64 = 0 360 while mi2 < nseek { 361 var pi: i64 = 0 362 var matched: i64 = 0 363 while pi < npost { 364 let slice: *i64 = ((terms as i64) + po_ts[pi] * 8) as *i64 365 score[pi] = vj_score(sk, mi2, slice, po_tn[pi]) 366 if score[pi] > 0 { matched = matched + 1 } 367 used[pi] = 0 368 pi = pi + 1 369 } 370 var rank: i64 = 1 371 while rank <= npost { 372 var best: i64 = 0 - 1 373 var bs: i64 = 0 - 1 374 pi = 0 375 while pi < npost { 376 var take: i64 = 0 377 if used[pi] == 0 { if score[pi] > bs { take = 1 } } 378 if take == 1 { bs = score[pi]; best = pi } 379 pi = pi + 1 380 } 381 used[best] = 1 382 o = vj_cat(rep, o, "VIZSLA-JOBS-MATCH member=" as *u8) 383 o = vj_cat(rep, o, seeks[mi2] as *u8) 384 o = vj_cat(rep, o, " rank=" as *u8) 385 o = vj_catn(rep, o, rank) 386 o = vj_cat(rep, o, " post=" as *u8) 387 o = vj_cat(rep, o, po_id[best] as *u8) 388 o = vj_cat(rep, o, " score=" as *u8) 389 o = vj_catn(rep, o, score[best]) 390 o = vj_cat(rep, o, " pay=" as *u8) 391 o = vj_catn(rep, o, po_pay[best]) 392 o = vj_cat(rep, o, "\n" as *u8) 393 rank = rank + 1 394 } 395 o = vj_cat(rep, o, "VIZSLA-JOBS-VERDICT member=" as *u8) 396 o = vj_cat(rep, o, seeks[mi2] as *u8) 397 o = vj_cat(rep, o, " postings=" as *u8) 398 o = vj_catn(rep, o, npost) 399 o = vj_cat(rep, o, " matched=" as *u8) 400 o = vj_catn(rep, o, matched) 401 o = vj_cat(rep, o, "\n" as *u8) 402 mi2 = mi2 + 1 403 } 404 sys_write(1, rep, o) 405 vj_log(lpath, "match" as *u8, rep, o) 406 return 0 407} 408 409// ---------------- TRACK (additive application history) ---------------- 410func vj_cmd_track(argc: i64, argv: *i64) -> i64 { 411 if argc < 4 { vj_p("VIZSLA-JOBS track needs <appfile> <prefix> -- fail loud\n" as *u8); return 1 } 412 let apath: *u8 = argv[2] as *u8 413 let prefix: *u8 = argv[3] as *u8 414 var segid: i64 = 0 415 if argc > 4 { segid = vj_atoi(argv[4] as *u8) } 416 if segid == 0 { segid = sys_now_us() } 417 418 let szp: *i64 = sys_mmap(16) as *i64 419 let b: *u8 = ss_readall(apath, szp) 420 let sz: i64 = szp[0] 421 if sz <= 0 { vj_p("VIZSLA-JOBS appfile MISSING/EMPTY -- fail loud\n" as *u8); return 1 } 422 423 let keys: *i64 = sys_mmap(8 * 8) as *i64 424 let vals: *i64 = sys_mmap(8 * 8) as *i64 425 keys[0] = "kind" as *u8 as i64 426 keys[1] = "date" as *u8 as i64 427 keys[2] = "post" as *u8 as i64 428 keys[3] = "member" as *u8 as i64 429 keys[4] = "status" as *u8 as i64 430 keys[5] = "note" as *u8 as i64 431 vals[0] = "app" as *u8 as i64 432 433 let t0: *u8 = sys_mmap(128) 434 let dt: *u8 = sys_mmap(128) 435 let po: *u8 = sys_mmap(128) 436 let me: *u8 = sys_mmap(128) 437 let stt: *u8 = sys_mmap(128) 438 let nt: *u8 = sys_mmap(256) 439 let pp: *i64 = sys_mmap(16) as *i64 440 let ll: *i64 = sys_mmap(16) as *i64 441 442 let w: *i64 = ss_begin() 443 let seen: *i64 = sys_mmap(8 * K_MAGIC_2048) as *i64 444 var nseen: i64 = 0 445 var scanned: i64 = 0 446 var added: i64 = 0 447 var dup_infile: i64 = 0 448 var dup_instore: i64 = 0 449 450 var i: i64 = 0 451 while i < sz { 452 var e: i64 = i 453 var go: i64 = 1 454 while go == 1 { 455 if e >= sz { go = 0 } else { 456 if b[e] == (10 as u8) { go = 0 } else { e = e + 1 } 457 } 458 } 459 var p: i64 = vj_tok(b, i, e, t0, 128) 460 if t0[0] == (35 as u8) { t0[0] = 0 as u8 } 461 if vj_eq(t0, "APP" as *u8) == 1 { 462 scanned = scanned + 1 463 p = vj_tok(b, p, e, dt, 128) 464 p = vj_tok(b, p, e, po, 128) 465 p = vj_tok(b, p, e, me, 128) 466 p = vj_tok(b, p, e, stt, 128) 467 p = vj_tok(b, p, e, nt, 256) 468 if dt[0] == (0 as u8) { vj_p("VIZSLA-JOBS APP missing date -- fail loud\n" as *u8); return 1 } 469 if po[0] == (0 as u8) { vj_p("VIZSLA-JOBS APP missing post-id -- fail loud\n" as *u8); return 1 } 470 if me[0] == (0 as u8) { vj_p("VIZSLA-JOBS APP missing member -- fail loud\n" as *u8); return 1 } 471 if stt[0] == (0 as u8) { vj_p("VIZSLA-JOBS APP missing status -- fail loud\n" as *u8); return 1 } 472 if nt[0] == (0 as u8) { vj_p("VIZSLA-JOBS APP missing note -- fail loud\n" as *u8); return 1 } 473 vals[1] = dt as i64 474 vals[2] = po as i64 475 vals[3] = me as i64 476 vals[4] = stt as i64 477 vals[5] = nt as i64 478 let enc: *u8 = sys_mmap(K_MAGIC_2048) 479 let el: i64 = canon_encode(keys, vals, 6, enc) 480 let cid: *u8 = sys_mmap(96) 481 cid_of(enc, el, cid) 482 let kbuf: *u8 = sys_mmap(128) 483 var ko: i64 = 0 484 ko = vj_cat(kbuf, ko, "app:" as *u8) 485 ko = vj_cat(kbuf, ko, cid) 486 kbuf[ko] = 0 as u8 487 var fresh: i64 = 1 488 if vj_find(seen, nseen, kbuf) >= 0 { fresh = 0; dup_infile = dup_infile + 1 } 489 if fresh == 1 { 490 if nseen < K_MAGIC_2048 { seen[nseen] = vj_dup(kbuf) as i64; nseen = nseen + 1 } 491 } 492 if fresh == 1 { 493 if ss_get_idx(prefix, kbuf, pp, ll) == 1 { fresh = 0; dup_instore = dup_instore + 1 } 494 } 495 if fresh == 1 { 496 if ss_add(w, 1, kbuf, enc, el) != 0 { vj_p("VIZSLA-JOBS writer full -- fail loud\n" as *u8); return 1 } 497 added = added + 1 498 } 499 } 500 i = e + 1 501 } 502 503 var committed: i64 = 0 504 if added > 0 { 505 if ss_commit(prefix, w, segid) != 0 { vj_p("VIZSLA-JOBS commit FAILED -- fail loud\n" as *u8); return 1 } 506 committed = 1 507 } 508 509 let rep: *u8 = sys_mmap(K_MAGIC_4096) 510 var o: i64 = 0 511 o = vj_cat(rep, o, "VIZSLA-JOBS-TRACK scanned=" as *u8) 512 o = vj_catn(rep, o, scanned) 513 o = vj_cat(rep, o, " new=" as *u8) 514 o = vj_catn(rep, o, added) 515 o = vj_cat(rep, o, " dup_infile=" as *u8) 516 o = vj_catn(rep, o, dup_infile) 517 o = vj_cat(rep, o, " dup_instore=" as *u8) 518 o = vj_catn(rep, o, dup_instore) 519 o = vj_cat(rep, o, " segment=" as *u8) 520 if committed == 1 { 521 o = vj_cat(rep, o, "seg-" as *u8) 522 o = vj_catn(rep, o, segid) 523 } else { 524 o = vj_cat(rep, o, "none" as *u8) 525 } 526 o = vj_cat(rep, o, "\n" as *u8) 527 sys_write(1, rep, o) 528 let lp: *u8 = sys_mmap(512) 529 vj_prefixlog(prefix, lp) 530 vj_log(lp, "track" as *u8, rep, o) 531 return 0 532} 533 534// ---------------- CADENCE (last status wins; CLOSED set from data) ---------------- 535func vj_cmd_cadence(argc: i64, argv: *i64) -> i64 { 536 if argc < 4 { vj_p("VIZSLA-JOBS cadence needs <prefix> <profile> -- fail loud\n" as *u8); return 1 } 537 let prefix: *u8 = argv[2] as *u8 538 let ppath: *u8 = argv[3] as *u8 539 540 let szp: *i64 = sys_mmap(16) as *i64 541 let pb: *u8 = ss_readall(ppath, szp) 542 let psz: i64 = szp[0] 543 if psz <= 0 { vj_p("VIZSLA-JOBS profile MISSING/EMPTY -- fail loud\n" as *u8); return 1 } 544 545 // CLOSED statuses from the profile (data-driven, never code) 546 let closed: *i64 = sys_mmap(8 * 16) as *i64 547 var nclosed: i64 = 0 548 let t0: *u8 = sys_mmap(128) 549 let t1: *u8 = sys_mmap(128) 550 var i: i64 = 0 551 while i < psz { 552 var e: i64 = i 553 var go: i64 = 1 554 while go == 1 { 555 if e >= psz { go = 0 } else { 556 if pb[e] == (10 as u8) { go = 0 } else { e = e + 1 } 557 } 558 } 559 var p: i64 = vj_tok(pb, i, e, t0, 128) 560 if t0[0] == (35 as u8) { t0[0] = 0 as u8 } 561 if vj_eq(t0, "CLOSED" as *u8) == 1 { 562 p = vj_tok(pb, p, e, t1, 128) 563 if nclosed < 16 { closed[nclosed] = vj_dup(t1) as i64; nclosed = nclosed + 1 } 564 } 565 i = e + 1 566 } 567 if nclosed < 1 { vj_p("VIZSLA-JOBS profile has no CLOSED rows -- fail loud\n" as *u8); return 1 } 568 569 // chronological walk: last status per post wins (first-seen post order) 570 let segs: *i64 = sys_mmap(8 * 260) as *i64 571 let ns: i64 = ss_manifest(prefix, segs) 572 if ns == 0 { vj_p("VIZSLA-JOBS cadence: no manifest/segments -- fail loud\n" as *u8); return 1 } 573 let posts: *i64 = sys_mmap(8 * 256) as *i64 574 let lastst: *i64 = sys_mmap(8 * 256) as *i64 575 let lastme: *i64 = sys_mmap(8 * 256) as *i64 576 var nposts: i64 = 0 577 var apps: i64 = 0 578 let fpo: *u8 = sys_mmap(128) 579 let fme: *u8 = sys_mmap(128) 580 let fst: *u8 = sys_mmap(128) 581 var s: i64 = 0 582 while s < ns { 583 let path: *u8 = sys_mmap(512) 584 var po2: i64 = 0 585 po2 = vj_cat(path, po2, prefix) 586 po2 = vj_cat(path, po2, segs[s] as *u8) 587 po2 = vj_cat(path, po2, ".docs" as *u8) 588 path[po2] = 0 as u8 589 let szp2: *i64 = sys_mmap(16) as *i64 590 let b: *u8 = ss_readall(path, szp2) 591 let sz: i64 = szp2[0] 592 var j: i64 = 0 593 while j + 9 <= sz { 594 let kind: i64 = b[j] 595 let kl: i64 = ss_r32(b, j + 1) 596 let koff: i64 = j + 5 597 let vl: i64 = ss_r32(b, koff + kl) 598 let voff: i64 = koff + kl + 4 599 var take: i64 = 0 600 if kind == 1 { take = vj_isapp(b, koff, kl) } 601 if take == 1 { 602 let rec: *u8 = (b as i64 + voff) as *u8 603 var okf: i64 = vj_field(rec, vl, "post" as *u8, fpo, 128) 604 okf = okf + vj_field(rec, vl, "member" as *u8, fme, 128) 605 okf = okf + vj_field(rec, vl, "status" as *u8, fst, 128) 606 if okf == 3 { 607 apps = apps + 1 608 var ci: i64 = vj_find(posts, nposts, fpo) 609 if ci < 0 { 610 if nposts < 256 { posts[nposts] = vj_dup(fpo) as i64; ci = nposts; nposts = nposts + 1 } 611 } 612 if ci >= 0 { lastst[ci] = vj_dup(fst) as i64; lastme[ci] = vj_dup(fme) as i64 } 613 } 614 } 615 j = voff + vl 616 } 617 s = s + 1 618 } 619 620 let rep: *u8 = sys_mmap(K_MAGIC_65536) 621 var o: i64 = 0 622 var nopen: i64 = 0 623 var ncl: i64 = 0 624 var pi: i64 = 0 625 while pi < nposts { 626 var iscl: i64 = 0 627 if vj_find(closed, nclosed, lastst[pi] as *u8) >= 0 { iscl = 1 } 628 if iscl == 1 { ncl = ncl + 1 } 629 if iscl == 0 { 630 nopen = nopen + 1 631 o = vj_cat(rep, o, "VIZSLA-JOBS-CADENCE post=" as *u8) 632 o = vj_cat(rep, o, posts[pi] as *u8) 633 o = vj_cat(rep, o, " member=" as *u8) 634 o = vj_cat(rep, o, lastme[pi] as *u8) 635 o = vj_cat(rep, o, " last=" as *u8) 636 o = vj_cat(rep, o, lastst[pi] as *u8) 637 o = vj_cat(rep, o, " action=follow-up\n" as *u8) 638 } 639 pi = pi + 1 640 } 641 o = vj_cat(rep, o, "VIZSLA-JOBS-CADENCE-VERDICT apps=" as *u8) 642 o = vj_catn(rep, o, apps) 643 o = vj_cat(rep, o, " posts=" as *u8) 644 o = vj_catn(rep, o, nposts) 645 o = vj_cat(rep, o, " open=" as *u8) 646 o = vj_catn(rep, o, nopen) 647 o = vj_cat(rep, o, " closed=" as *u8) 648 o = vj_catn(rep, o, ncl) 649 o = vj_cat(rep, o, "\n" as *u8) 650 sys_write(1, rep, o) 651 let lp: *u8 = sys_mmap(512) 652 vj_prefixlog(prefix, lp) 653 vj_log(lp, "cadence" as *u8, rep, o) 654 return 0 655} 656 657func main(argc: i64, argv: *i64) -> i64 { 658 if argc < 2 { vj_p("VIZSLA-JOBS usage: match|track|cadence -- fail loud\n" as *u8); return 1 } 659 let cmd: *u8 = argv[1] as *u8 660 if vj_eq(cmd, "match" as *u8) == 1 { return vj_cmd_match(argc, argv) } 661 if vj_eq(cmd, "track" as *u8) == 1 { return vj_cmd_track(argc, argv) } 662 if vj_eq(cmd, "cadence" as *u8) == 1 { return vj_cmd_cadence(argc, argv) } 663 vj_p("VIZSLA-JOBS unknown command (match|track|cadence) -- fail loud\n" as *u8) 664 return 1 665}