code wiki / _hdl_build / nx_vizsla_ops.nx

nx_vizsla_ops.nx source

↩ module page · 823 lines · 29173 B

1// nx_vizsla_ops.nx -- NISHI VIZSLA V6: the PROJECTS + MAINTENANCE fabric. 2// Operator directive 2026-06-10: "pretty much everything can be broken down 3// into projects we need to do and maintenance we need to do -- from buying 4// stock or valuables to maintaining your oil." MAINTENANCE = recurring 5// cadence over owned assets (catalog interval x latest-done date); PROJECT = 6// finite ordered steps. The researched modern-American catalog 7// (knowledge/vizsla/maintenance_catalog.txt) is DATA -- operator callouts 8// enrich it by editing rows, never code (law 11/25). History = CID records 9// on seg_store: additive, idempotent, tamper-evident (same substrate as 10// V1/V2a/V2c). Feeds (LinkedIn / Rocket Money / PRM / IoT) land as DONE 11// events + asset rows -- named adapters in the spec. 12// 13// Commands (argv[1]): 14// log <logfile> <prefix> [segid] DONE <date> <asset> <task> <note> 15// -> "mnt:" CID records; 16// STEPDONE <date> <proj> <seq> <note> 17// -> "stp:" CID records. 18// due <catalog> <assets> <prefix> <today> maintenance dashboard: per 19// HAVE-asset x class MAINT task, 20// LATEST done date wins; states 21// OK / DUE (due_in<=soon_days) / 22// OVERDUE / NEVER(schedule-first). 23// status <projects> <prefix> project dashboard: steps done / 24// total, next = lowest undone seq, 25// ACTIVE / COMPLETE. 26// 27// Determinism: stdout has no clocks (`today` is argv; epochs -> prefix log). 28// Loud-fail law: missing files, HAVE referencing a class with no MAINT rows, 29// malformed dates/seq = exit 1 named. 30// EXCEED: one additive tamper-evident fabric for ALL family operations -- 31// consumer tools silo these (CarFax vs Mint vs Todoist) with no shared 32// history, no time travel, no tamper evidence. 33// spec: knowledge/specs/2026-06-10-nishi-vizsla-ladder.md license_tier: ORIGINAL 34import "nx_syscalls.nx" 35import "nx_canon_cid.nx" 36import "nx_seg_store.nx" 37const K_MAGIC_1970: i64 = 1970 38const K_MAGIC_146097: i64 = 146097 39const K_MAGIC_719468: i64 = 719468 40const K_MAGIC_2048: i64 = 2048 41const K_MAGIC_4096: i64 = 4096 42const K_MAGIC_1024: i64 = 1024 43const K_MAGIC_131072: i64 = 131072 44const K_MAGIC_65536: i64 = 65536 45 46func vo_slen(s: *u8) -> i64 { 47 var n: i64 = 0 48 while s[n] != (0 as u8) { n = n + 1 } 49 return n 50} 51 52func vo_p(s: *u8) -> i64 { 53 sys_write(1, s, vo_slen(s)) 54 return 0 55} 56 57func vo_eq(a: *u8, b: *u8) -> i64 { 58 var i: i64 = 0 59 var go: i64 = 1 60 while go == 1 { 61 if a[i] != b[i] { return 0 } 62 if a[i] == (0 as u8) { return 1 } 63 i = i + 1 64 } 65 return 0 66} 67 68func vo_dup(s: *u8) -> *u8 { 69 let n: i64 = vo_slen(s) 70 let d: *u8 = sys_mmap(n + 2) 71 var i: i64 = 0 72 while i <= n { d[i] = s[i]; i = i + 1 } 73 return d 74} 75 76func vo_atoi(s: *u8) -> i64 { 77 var v: i64 = 0 78 var i: i64 = 0 79 while s[i] != (0 as u8) { 80 let d: i64 = (s[i] as i64) - 48 81 if d >= 0 { if d <= 9 { v = v * 10 + d } } 82 i = i + 1 83 } 84 return v 85} 86 87func vo_digits(s: *u8) -> i64 { 88 if s[0] == (0 as u8) { return 0 } 89 var i: i64 = 0 90 while s[i] != (0 as u8) { 91 let d: i64 = (s[i] as i64) - 48 92 if d < 0 { return 0 } 93 if d > 9 { return 0 } 94 i = i + 1 95 } 96 return 1 97} 98 99func vo_isws(c: i64) -> i64 { 100 if c == 32 { return 1 } 101 if c == 13 { return 1 } 102 if c == 9 { return 1 } 103 return 0 104} 105 106func vo_tok(b: *u8, off: i64, lend: i64, dst: *u8, cap: i64) -> i64 { 107 var p: i64 = off 108 var go: i64 = 1 109 while go == 1 { 110 if p >= lend { go = 0 } else { 111 if vo_isws(b[p] as i64) == 1 { p = p + 1 } else { go = 0 } 112 } 113 } 114 var t: i64 = 0 115 go = 1 116 while go == 1 { 117 if p >= lend { go = 0 } else { 118 if vo_isws(b[p] as i64) == 1 { go = 0 } else { 119 if t < cap - 1 { dst[t] = b[p]; t = t + 1 } 120 p = p + 1 121 } 122 } 123 } 124 dst[t] = 0 as u8 125 return p 126} 127 128func vo_cat(dst: *u8, off: i64, s: *u8) -> i64 { 129 var i: i64 = 0 130 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 } 131 return off + i 132} 133 134func vo_catn(dst: *u8, off: i64, v: i64) -> i64 { 135 var o: i64 = off 136 var m: i64 = v 137 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m } 138 let t: *u8 = sys_mmap(28) 139 var k: i64 = 0 140 if m == 0 { t[0] = 48 as u8; k = 1 } 141 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 142 var i: i64 = 0 143 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 } 144 return o + k 145} 146 147func vo_find(list: *i64, n: i64, s: *u8) -> i64 { 148 var i: i64 = 0 149 while i < n { 150 if vo_eq(list[i] as *u8, s) == 1 { return i } 151 i = i + 1 152 } 153 return 0 - 1 154} 155 156func vo_kmemeq(b: *u8, off: i64, n: i64, s: *u8) -> i64 { 157 if vo_slen(s) != n { return 0 } 158 var i: i64 = 0 159 while i < n { 160 if b[off + i] != s[i] { return 0 } 161 i = i + 1 162 } 163 return 1 164} 165 166func vo_field(rec: *u8, rl: i64, want: *u8, out: *u8, cap: i64) -> i64 { 167 if rl < 8 { return 0 } 168 let nf: i64 = ss_r32(rec, 4) 169 var off: i64 = 8 170 var fi: i64 = 0 171 while fi < nf { 172 if off + 8 > rl { return 0 } 173 let kl: i64 = ss_r32(rec, off) 174 let koff: i64 = off + 4 175 let vl: i64 = ss_r32(rec, koff + kl) 176 let voff: i64 = koff + kl + 4 177 if vo_kmemeq(rec, koff, kl, want) == 1 { 178 var t: i64 = 0 179 while t < vl { 180 if t < cap - 1 { out[t] = rec[voff + t] } 181 t = t + 1 182 } 183 if t > cap - 1 { t = cap - 1 } 184 out[t] = 0 as u8 185 return 1 186 } 187 off = voff + vl 188 fi = fi + 1 189 } 190 return 0 191} 192 193// key prefix check for our two record kinds 194func vo_iskind(b: *u8, koff: i64, kl: i64, pfx: *u8) -> i64 { 195 if kl <= 4 { return 0 } 196 return vo_kmemeq(b, koff, 4, pfx) 197} 198 199func vo_log_append(prefix: *u8, tag: *u8, rep: *u8, o: i64) -> i64 { 200 let lp: *u8 = sys_mmap(512) 201 var lo: i64 = 0 202 lo = vo_cat(lp, lo, prefix) 203 lo = vo_cat(lp, lo, "ops.log" as *u8) 204 lp[lo] = 0 as u8 205 let fd: i64 = sys_openat_append(lp, 0x1a4) 206 if fd <= 0 { return 0 } 207 let hdr: *u8 = sys_mmap(256) 208 var ho: i64 = 0 209 ho = vo_cat(hdr, ho, "VIZSLA-OPS epoch=" as *u8) 210 ho = vo_catn(hdr, ho, sys_now_realtime_sec()) 211 ho = vo_cat(hdr, ho, " cmd=" as *u8) 212 ho = vo_cat(hdr, ho, tag) 213 ho = vo_cat(hdr, ho, "\n" as *u8) 214 sys_write(fd, hdr, ho) 215 sys_write(fd, rep, o) 216 sys_close(fd) 217 return 0 218} 219 220// civil date "YYYY-MM-DD" -> days since epoch (Hinnant); -1 malformed 221func vo_datedays(s: *u8) -> i64 { 222 let nums: *i64 = sys_mmap(8 * 4) as *i64 223 var nn: i64 = 0 224 var cur: i64 = 0 225 var indig: i64 = 0 226 var i: i64 = 0 227 var go: i64 = 1 228 while go == 1 { 229 let c: i64 = s[i] as i64 230 var isd: i64 = 0 231 if c >= 48 { if c <= 57 { isd = 1 } } 232 if isd == 1 { cur = cur * 10 + (c - 48); indig = 1 } 233 if isd == 0 { 234 if indig == 1 { 235 if nn < 4 { nums[nn] = cur; nn = nn + 1 } 236 cur = 0 237 indig = 0 238 } 239 } 240 if c == 0 { go = 0 } 241 i = i + 1 242 } 243 if nn != 3 { return 0 - 1 } 244 var y: i64 = nums[0] 245 let m: i64 = nums[1] 246 let d: i64 = nums[2] 247 if y < K_MAGIC_1970 { return 0 - 1 } 248 if m < 1 { return 0 - 1 } 249 if m > 12 { return 0 - 1 } 250 if d < 1 { return 0 - 1 } 251 if d > 31 { return 0 - 1 } 252 if m <= 2 { y = y - 1 } 253 let era: i64 = y / 400 254 let yoe: i64 = y - era * 400 255 var mp: i64 = m - 3 256 if m <= 2 { mp = m + 9 } 257 let doy: i64 = (153 * mp + 2) / 5 + d - 1 258 let doe: i64 = yoe * 365 + yoe / 4 - yoe / 100 + doy 259 return era * K_MAGIC_146097 + doe - K_MAGIC_719468 260} 261 262// canonicalize+store one 4-field record; st: [0]=writer [1]=seen ptrs [2]=nseen 263// [3]=added [4]=dup_infile [5]=dup_instore [6]=prefix 264// keys/vals prepared by caller; kp = "mnt:" or "stp:" 265func vo_put(keys: *i64, vals: *i64, nf: i64, kp: *u8, st: *i64) -> i64 { 266 let enc: *u8 = sys_mmap(K_MAGIC_2048) 267 let el: i64 = canon_encode(keys, vals, nf, enc) 268 let cid: *u8 = sys_mmap(96) 269 cid_of(enc, el, cid) 270 let kbuf: *u8 = sys_mmap(128) 271 var ko: i64 = 0 272 ko = vo_cat(kbuf, ko, kp) 273 ko = vo_cat(kbuf, ko, cid) 274 kbuf[ko] = 0 as u8 275 let seen: *i64 = st[1] as *i64 276 var fresh: i64 = 1 277 if vo_find(seen, st[2], kbuf) >= 0 { fresh = 0; st[4] = st[4] + 1 } 278 if fresh == 1 { 279 if st[2] < K_MAGIC_2048 { seen[st[2]] = vo_dup(kbuf) as i64; st[2] = st[2] + 1 } 280 } 281 if fresh == 1 { 282 let pp: *i64 = sys_mmap(16) as *i64 283 let ll: *i64 = sys_mmap(16) as *i64 284 if ss_get_idx(st[6] as *u8, kbuf, pp, ll) == 1 { fresh = 0; st[5] = st[5] + 1 } 285 } 286 if fresh == 1 { 287 if ss_add(st[0] as *i64, 1, kbuf, enc, el) != 0 { return 0 - 1 } 288 st[3] = st[3] + 1 289 } 290 return 0 291} 292 293// ---------------- LOG (DONE + STEPDONE loader) ---------------- 294func vo_cmd_log(argc: i64, argv: *i64) -> i64 { 295 if argc < 4 { vo_p("VIZSLA-OPS log needs <logfile> <prefix> -- fail loud\n" as *u8); return 1 } 296 let lfile: *u8 = argv[2] as *u8 297 let prefix: *u8 = argv[3] as *u8 298 var segid: i64 = 0 299 if argc > 4 { segid = vo_atoi(argv[4] as *u8) } 300 if segid == 0 { segid = sys_now_us() } 301 302 let szp: *i64 = sys_mmap(16) as *i64 303 let b: *u8 = ss_readall(lfile, szp) 304 let sz: i64 = szp[0] 305 if sz <= 0 { vo_p("VIZSLA-OPS logfile MISSING/EMPTY -- fail loud\n" as *u8); return 1 } 306 307 let mkeys: *i64 = sys_mmap(8 * 8) as *i64 308 let mvals: *i64 = sys_mmap(8 * 8) as *i64 309 mkeys[0] = "kind" as *u8 as i64 310 mkeys[1] = "date" as *u8 as i64 311 mkeys[2] = "asset" as *u8 as i64 312 mkeys[3] = "task" as *u8 as i64 313 mkeys[4] = "note" as *u8 as i64 314 mvals[0] = "mnt" as *u8 as i64 315 let skeys: *i64 = sys_mmap(8 * 8) as *i64 316 let svals: *i64 = sys_mmap(8 * 8) as *i64 317 skeys[0] = "kind" as *u8 as i64 318 skeys[1] = "date" as *u8 as i64 319 skeys[2] = "proj" as *u8 as i64 320 skeys[3] = "seq" as *u8 as i64 321 skeys[4] = "note" as *u8 as i64 322 svals[0] = "stp" as *u8 as i64 323 324 let st: *i64 = sys_mmap(8 * 8) as *i64 325 st[0] = ss_begin() as i64 326 st[1] = sys_mmap(8 * K_MAGIC_2048) 327 st[2] = 0 328 st[3] = 0 329 st[4] = 0 330 st[5] = 0 331 st[6] = prefix as i64 332 333 let t0: *u8 = sys_mmap(128) 334 let f1: *u8 = sys_mmap(128) 335 let f2: *u8 = sys_mmap(128) 336 let f3: *u8 = sys_mmap(128) 337 let f4: *u8 = sys_mmap(256) 338 var scanned: i64 = 0 339 340 var i: i64 = 0 341 while i < sz { 342 var e: i64 = i 343 var go: i64 = 1 344 while go == 1 { 345 if e >= sz { go = 0 } else { 346 if b[e] == (10 as u8) { go = 0 } else { e = e + 1 } 347 } 348 } 349 var p: i64 = vo_tok(b, i, e, t0, 128) 350 if t0[0] == (35 as u8) { t0[0] = 0 as u8 } 351 var iskind: i64 = 0 352 if vo_eq(t0, "DONE" as *u8) == 1 { iskind = 1 } 353 if vo_eq(t0, "STEPDONE" as *u8) == 1 { iskind = 2 } 354 if iskind > 0 { 355 scanned = scanned + 1 356 p = vo_tok(b, p, e, f1, 128) 357 p = vo_tok(b, p, e, f2, 128) 358 p = vo_tok(b, p, e, f3, 128) 359 p = vo_tok(b, p, e, f4, 256) 360 if vo_datedays(f1) < 0 { vo_p("VIZSLA-OPS bad date (YYYY-MM-DD) -- fail loud\n" as *u8); return 1 } 361 if f2[0] == (0 as u8) { vo_p("VIZSLA-OPS row missing id field -- fail loud\n" as *u8); return 1 } 362 if f3[0] == (0 as u8) { vo_p("VIZSLA-OPS row missing task/seq -- fail loud\n" as *u8); return 1 } 363 if f4[0] == (0 as u8) { vo_p("VIZSLA-OPS row missing note -- fail loud\n" as *u8); return 1 } 364 var rc: i64 = 0 365 if iskind == 1 { 366 mvals[1] = f1 as i64 367 mvals[2] = f2 as i64 368 mvals[3] = f3 as i64 369 mvals[4] = f4 as i64 370 rc = vo_put(mkeys, mvals, 5, "mnt:" as *u8, st) 371 } 372 if iskind == 2 { 373 if vo_digits(f3) == 0 { vo_p("VIZSLA-OPS STEPDONE seq not digits -- fail loud\n" as *u8); return 1 } 374 svals[1] = f1 as i64 375 svals[2] = f2 as i64 376 svals[3] = f3 as i64 377 svals[4] = f4 as i64 378 rc = vo_put(skeys, svals, 5, "stp:" as *u8, st) 379 } 380 if rc != 0 { vo_p("VIZSLA-OPS writer full -- fail loud\n" as *u8); return 1 } 381 } 382 i = e + 1 383 } 384 385 var committed: i64 = 0 386 if st[3] > 0 { 387 if ss_commit(prefix, st[0] as *i64, segid) != 0 { vo_p("VIZSLA-OPS commit FAILED -- fail loud\n" as *u8); return 1 } 388 committed = 1 389 } 390 391 let rep: *u8 = sys_mmap(K_MAGIC_4096) 392 var o: i64 = 0 393 o = vo_cat(rep, o, "VIZSLA-OPS-LOG scanned=" as *u8) 394 o = vo_catn(rep, o, scanned) 395 o = vo_cat(rep, o, " new=" as *u8) 396 o = vo_catn(rep, o, st[3]) 397 o = vo_cat(rep, o, " dup_infile=" as *u8) 398 o = vo_catn(rep, o, st[4]) 399 o = vo_cat(rep, o, " dup_instore=" as *u8) 400 o = vo_catn(rep, o, st[5]) 401 o = vo_cat(rep, o, " segment=" as *u8) 402 if committed == 1 { 403 o = vo_cat(rep, o, "seg-" as *u8) 404 o = vo_catn(rep, o, segid) 405 } else { 406 o = vo_cat(rep, o, "none" as *u8) 407 } 408 o = vo_cat(rep, o, "\n" as *u8) 409 sys_write(1, rep, o) 410 vo_log_append(prefix, "log" as *u8, rep, o) 411 return 0 412} 413 414// ---------------- DUE (maintenance dashboard) ---------------- 415func vo_cmd_due(argc: i64, argv: *i64) -> i64 { 416 if argc < 6 { vo_p("VIZSLA-OPS due needs <catalog> <assets> <prefix> <today> -- fail loud\n" as *u8); return 1 } 417 let cpath: *u8 = argv[2] as *u8 418 let apath: *u8 = argv[3] as *u8 419 let prefix: *u8 = argv[4] as *u8 420 let today: i64 = vo_datedays(argv[5] as *u8) 421 if today < 0 { vo_p("VIZSLA-OPS bad today date -- fail loud\n" as *u8); return 1 } 422 423 let szp: *i64 = sys_mmap(16) as *i64 424 let cb: *u8 = ss_readall(cpath, szp) 425 let csz: i64 = szp[0] 426 if csz <= 0 { vo_p("VIZSLA-OPS catalog MISSING/EMPTY -- fail loud\n" as *u8); return 1 } 427 let ab: *u8 = ss_readall(apath, szp) 428 let asz: i64 = szp[0] 429 if asz <= 0 { vo_p("VIZSLA-OPS assets MISSING/EMPTY -- fail loud\n" as *u8); return 1 } 430 431 // catalog: MAINT class task interval desc (+ CONF soon_days) 432 let m_class: *i64 = sys_mmap(8 * 256) as *i64 433 let m_task: *i64 = sys_mmap(8 * 256) as *i64 434 let m_int: *i64 = sys_mmap(8 * 256) as *i64 435 var nm: i64 = 0 436 var soon: i64 = 14 437 let t0: *u8 = sys_mmap(128) 438 let t1: *u8 = sys_mmap(128) 439 let t2: *u8 = sys_mmap(128) 440 let t3: *u8 = sys_mmap(128) 441 var i: i64 = 0 442 while i < csz { 443 var e: i64 = i 444 var go: i64 = 1 445 while go == 1 { 446 if e >= csz { go = 0 } else { 447 if cb[e] == (10 as u8) { go = 0 } else { e = e + 1 } 448 } 449 } 450 var p: i64 = vo_tok(cb, i, e, t0, 128) 451 if t0[0] == (35 as u8) { t0[0] = 0 as u8 } 452 if vo_eq(t0, "CONF" as *u8) == 1 { 453 p = vo_tok(cb, p, e, t1, 128) 454 p = vo_tok(cb, p, e, t2, 128) 455 if vo_eq(t1, "soon_days" as *u8) == 1 { soon = vo_atoi(t2) } 456 } 457 if vo_eq(t0, "MAINT" as *u8) == 1 { 458 p = vo_tok(cb, p, e, t1, 128) 459 p = vo_tok(cb, p, e, t2, 128) 460 p = vo_tok(cb, p, e, t3, 128) 461 if vo_digits(t3) == 0 { vo_p("VIZSLA-OPS MAINT interval not digits -- fail loud\n" as *u8); return 1 } 462 if nm < 256 { 463 m_class[nm] = vo_dup(t1) as i64 464 m_task[nm] = vo_dup(t2) as i64 465 m_int[nm] = vo_atoi(t3) 466 nm = nm + 1 467 } 468 } 469 i = e + 1 470 } 471 if nm < 1 { vo_p("VIZSLA-OPS no MAINT rows in catalog -- fail loud\n" as *u8); return 1 } 472 473 // assets + slots (asset x class-task), construction order 474 let s_aid: *i64 = sys_mmap(8 * K_MAGIC_1024) as *i64 475 let s_task: *i64 = sys_mmap(8 * K_MAGIC_1024) as *i64 476 let s_int: *i64 = sys_mmap(8 * K_MAGIC_1024) as *i64 477 let s_days: *i64 = sys_mmap(8 * K_MAGIC_1024) as *i64 478 let s_date: *i64 = sys_mmap(8 * K_MAGIC_1024) as *i64 479 var nslot: i64 = 0 480 var nass: i64 = 0 481 i = 0 482 while i < asz { 483 var e2: i64 = i 484 var go2: i64 = 1 485 while go2 == 1 { 486 if e2 >= asz { go2 = 0 } else { 487 if ab[e2] == (10 as u8) { go2 = 0 } else { e2 = e2 + 1 } 488 } 489 } 490 var p2: i64 = vo_tok(ab, i, e2, t0, 128) 491 if t0[0] == (35 as u8) { t0[0] = 0 as u8 } 492 if vo_eq(t0, "HAVE" as *u8) == 1 { 493 p2 = vo_tok(ab, p2, e2, t1, 128) 494 p2 = vo_tok(ab, p2, e2, t2, 128) 495 if t1[0] == (0 as u8) { vo_p("VIZSLA-OPS HAVE missing asset-id -- fail loud\n" as *u8); return 1 } 496 nass = nass + 1 497 var hits: i64 = 0 498 var mi: i64 = 0 499 while mi < nm { 500 if vo_eq(m_class[mi] as *u8, t2) == 1 { 501 hits = hits + 1 502 if nslot < K_MAGIC_1024 { 503 s_aid[nslot] = vo_dup(t1) as i64 504 s_task[nslot] = m_task[mi] 505 s_int[nslot] = m_int[mi] 506 s_days[nslot] = 0 - 1 507 s_date[nslot] = "never" as *u8 as i64 508 nslot = nslot + 1 509 } 510 } 511 mi = mi + 1 512 } 513 if hits == 0 { vo_p("VIZSLA-OPS HAVE references class with no MAINT rows -- fail loud\n" as *u8); return 1 } 514 } 515 i = e2 + 1 516 } 517 if nass < 1 { vo_p("VIZSLA-OPS no HAVE rows in assets -- fail loud\n" as *u8); return 1 } 518 519 // walk store mnt: records -> latest date per (asset,task) slot 520 let segs: *i64 = sys_mmap(8 * 260) as *i64 521 let ns: i64 = ss_manifest(prefix, segs) 522 let fas: *u8 = sys_mmap(128) 523 let ftk: *u8 = sys_mmap(128) 524 let fdt: *u8 = sys_mmap(128) 525 var s: i64 = 0 526 while s < ns { 527 let path: *u8 = sys_mmap(512) 528 var po: i64 = 0 529 po = vo_cat(path, po, prefix) 530 po = vo_cat(path, po, segs[s] as *u8) 531 po = vo_cat(path, po, ".docs" as *u8) 532 path[po] = 0 as u8 533 let szp2: *i64 = sys_mmap(16) as *i64 534 let b: *u8 = ss_readall(path, szp2) 535 let sz: i64 = szp2[0] 536 var j: i64 = 0 537 while j + 9 <= sz { 538 let kind: i64 = b[j] 539 let kl: i64 = ss_r32(b, j + 1) 540 let koff: i64 = j + 5 541 let vl: i64 = ss_r32(b, koff + kl) 542 let voff: i64 = koff + kl + 4 543 var take: i64 = 0 544 if kind == 1 { take = vo_iskind(b, koff, kl, "mnt:" as *u8) } 545 if take == 1 { 546 let rec: *u8 = (b as i64 + voff) as *u8 547 var okf: i64 = vo_field(rec, vl, "asset" as *u8, fas, 128) 548 okf = okf + vo_field(rec, vl, "task" as *u8, ftk, 128) 549 okf = okf + vo_field(rec, vl, "date" as *u8, fdt, 128) 550 if okf == 3 { 551 let dd: i64 = vo_datedays(fdt) 552 var si: i64 = 0 553 while si < nslot { 554 var hit: i64 = 0 555 if vo_eq(s_aid[si] as *u8, fas) == 1 { if vo_eq(s_task[si] as *u8, ftk) == 1 { hit = 1 } } 556 if hit == 1 { if dd > s_days[si] { s_days[si] = dd; s_date[si] = vo_dup(fdt) as i64 } } 557 si = si + 1 558 } 559 } 560 } 561 j = voff + vl 562 } 563 s = s + 1 564 } 565 566 // emit dashboard 567 let rep: *u8 = sys_mmap(K_MAGIC_131072) 568 var o: i64 = 0 569 var nok: i64 = 0 570 var ndue: i64 = 0 571 var nover: i64 = 0 572 var nnever: i64 = 0 573 var si2: i64 = 0 574 while si2 < nslot { 575 o = vo_cat(rep, o, "VIZSLA-OPS-MAINT asset=" as *u8) 576 o = vo_cat(rep, o, s_aid[si2] as *u8) 577 o = vo_cat(rep, o, " task=" as *u8) 578 o = vo_cat(rep, o, s_task[si2] as *u8) 579 o = vo_cat(rep, o, " last=" as *u8) 580 o = vo_cat(rep, o, s_date[si2] as *u8) 581 o = vo_cat(rep, o, " days=" as *u8) 582 var dys: i64 = 0 - 1 583 if s_days[si2] >= 0 { dys = today - s_days[si2] } 584 o = vo_catn(rep, o, dys) 585 o = vo_cat(rep, o, " interval=" as *u8) 586 o = vo_catn(rep, o, s_int[si2]) 587 o = vo_cat(rep, o, " due_in=" as *u8) 588 if s_days[si2] < 0 { 589 o = vo_catn(rep, o, 0) 590 o = vo_cat(rep, o, " state=NEVER action=schedule-first\n" as *u8) 591 nnever = nnever + 1 592 } else { 593 let din: i64 = s_int[si2] - dys 594 o = vo_catn(rep, o, din) 595 if din < 0 { 596 o = vo_cat(rep, o, " state=OVERDUE action=do-now\n" as *u8) 597 nover = nover + 1 598 } else { 599 if din <= soon { 600 o = vo_cat(rep, o, " state=DUE action=schedule\n" as *u8) 601 ndue = ndue + 1 602 } else { 603 o = vo_cat(rep, o, " state=OK action=none\n" as *u8) 604 nok = nok + 1 605 } 606 } 607 } 608 si2 = si2 + 1 609 } 610 o = vo_cat(rep, o, "VIZSLA-OPS-MAINT-VERDICT assets=" as *u8) 611 o = vo_catn(rep, o, nass) 612 o = vo_cat(rep, o, " tasks=" as *u8) 613 o = vo_catn(rep, o, nslot) 614 o = vo_cat(rep, o, " ok=" as *u8) 615 o = vo_catn(rep, o, nok) 616 o = vo_cat(rep, o, " due=" as *u8) 617 o = vo_catn(rep, o, ndue) 618 o = vo_cat(rep, o, " overdue=" as *u8) 619 o = vo_catn(rep, o, nover) 620 o = vo_cat(rep, o, " never=" as *u8) 621 o = vo_catn(rep, o, nnever) 622 o = vo_cat(rep, o, "\n" as *u8) 623 sys_write(1, rep, o) 624 vo_log_append(prefix, "due" as *u8, rep, o) 625 return 0 626} 627 628// 1 iff (pi,sq) already in the done-pair list 629func vo_dpair_has(d_proj: *i64, d_seq: *i64, ndone: i64, pi: i64, sq: i64) -> i64 { 630 var di: i64 = 0 631 while di < ndone { 632 if d_proj[di] == pi { if d_seq[di] == sq { return 1 } } 633 di = di + 1 634 } 635 return 0 636} 637 638// accumulate one stp: record into the done-pair set. 639// cx: [0]=p_id [1]=np [2]=d_proj [3]=d_seq [4]=ndone 640func vo_stp_acc(rec: *u8, vl: i64, cx: *i64) -> i64 { 641 let fpj: *u8 = sys_mmap(128) 642 let fsq: *u8 = sys_mmap(128) 643 if vo_field(rec, vl, "proj" as *u8, fpj, 128) == 0 { return 0 } 644 if vo_field(rec, vl, "seq" as *u8, fsq, 128) == 0 { return 0 } 645 let pi: i64 = vo_find(cx[0] as *i64, cx[1], fpj) 646 if pi < 0 { return 0 } 647 let sq: i64 = vo_atoi(fsq) 648 if vo_dpair_has(cx[2] as *i64, cx[3] as *i64, cx[4], pi, sq) == 1 { return 0 } 649 if cx[4] >= K_MAGIC_1024 { return 0 } 650 let dp: *i64 = cx[2] as *i64 651 let dq: *i64 = cx[3] as *i64 652 dp[cx[4]] = pi 653 dq[cx[4]] = sq 654 cx[4] = cx[4] + 1 655 return 1 656} 657 658// ---------------- STATUS (project dashboard) ---------------- 659func vo_cmd_status(argc: i64, argv: *i64) -> i64 { 660 if argc < 4 { vo_p("VIZSLA-OPS status needs <projects> <prefix> -- fail loud\n" as *u8); return 1 } 661 let ppath: *u8 = argv[2] as *u8 662 let prefix: *u8 = argv[3] as *u8 663 664 let szp: *i64 = sys_mmap(16) as *i64 665 let pb: *u8 = ss_readall(ppath, szp) 666 let psz: i64 = szp[0] 667 if psz <= 0 { vo_p("VIZSLA-OPS projects MISSING/EMPTY -- fail loud\n" as *u8); return 1 } 668 669 let p_id: *i64 = sys_mmap(8 * 64) as *i64 670 let p_mem: *i64 = sys_mmap(8 * 64) as *i64 671 var np: i64 = 0 672 let st_proj: *i64 = sys_mmap(8 * 512) as *i64 673 let st_seq: *i64 = sys_mmap(8 * 512) as *i64 674 let st_desc: *i64 = sys_mmap(8 * 512) as *i64 675 var nstep: i64 = 0 676 let t0: *u8 = sys_mmap(128) 677 let t1: *u8 = sys_mmap(128) 678 let t2: *u8 = sys_mmap(128) 679 let t3: *u8 = sys_mmap(256) 680 var i: i64 = 0 681 while i < psz { 682 var e: i64 = i 683 var go: i64 = 1 684 while go == 1 { 685 if e >= psz { go = 0 } else { 686 if pb[e] == (10 as u8) { go = 0 } else { e = e + 1 } 687 } 688 } 689 var p: i64 = vo_tok(pb, i, e, t0, 128) 690 if t0[0] == (35 as u8) { t0[0] = 0 as u8 } 691 if vo_eq(t0, "PROJ" as *u8) == 1 { 692 p = vo_tok(pb, p, e, t1, 128) 693 p = vo_tok(pb, p, e, t2, 128) 694 if np < 64 { p_id[np] = vo_dup(t1) as i64; p_mem[np] = vo_dup(t2) as i64; np = np + 1 } 695 } 696 if vo_eq(t0, "STEP" as *u8) == 1 { 697 p = vo_tok(pb, p, e, t1, 128) 698 p = vo_tok(pb, p, e, t2, 128) 699 p = vo_tok(pb, p, e, t3, 256) 700 let pi: i64 = vo_find(p_id, np, t1) 701 if pi < 0 { vo_p("VIZSLA-OPS STEP references unknown PROJ -- fail loud\n" as *u8); return 1 } 702 if vo_digits(t2) == 0 { vo_p("VIZSLA-OPS STEP seq not digits -- fail loud\n" as *u8); return 1 } 703 if nstep < 512 { 704 st_proj[nstep] = pi 705 st_seq[nstep] = vo_atoi(t2) 706 st_desc[nstep] = vo_dup(t3) as i64 707 nstep = nstep + 1 708 } 709 } 710 i = e + 1 711 } 712 if np < 1 { vo_p("VIZSLA-OPS no PROJ rows -- fail loud\n" as *u8); return 1 } 713 714 // walk store stp: records -> done (proj-idx, seq) pairs 715 let d_proj: *i64 = sys_mmap(8 * K_MAGIC_1024) as *i64 716 let d_seq: *i64 = sys_mmap(8 * K_MAGIC_1024) as *i64 717 var ndone: i64 = 0 718 let segs: *i64 = sys_mmap(8 * 260) as *i64 719 let ns: i64 = ss_manifest(prefix, segs) 720 let fpj: *u8 = sys_mmap(128) 721 let fsq: *u8 = sys_mmap(128) 722 var s: i64 = 0 723 while s < ns { 724 let path: *u8 = sys_mmap(512) 725 var po: i64 = 0 726 po = vo_cat(path, po, prefix) 727 po = vo_cat(path, po, segs[s] as *u8) 728 po = vo_cat(path, po, ".docs" as *u8) 729 path[po] = 0 as u8 730 let szp2: *i64 = sys_mmap(16) as *i64 731 let b: *u8 = ss_readall(path, szp2) 732 let sz: i64 = szp2[0] 733 var j: i64 = 0 734 while j + 9 <= sz { 735 let kind: i64 = b[j] 736 let kl: i64 = ss_r32(b, j + 1) 737 let koff: i64 = j + 5 738 let vl: i64 = ss_r32(b, koff + kl) 739 let voff: i64 = koff + kl + 4 740 var take: i64 = 0 741 if kind == 1 { take = vo_iskind(b, koff, kl, "stp:" as *u8) } 742 if take == 1 { 743 let cx: *i64 = sys_mmap(8 * 8) as *i64 744 cx[0] = p_id as i64 745 cx[1] = np 746 cx[2] = d_proj as i64 747 cx[3] = d_seq as i64 748 cx[4] = ndone 749 vo_stp_acc((b as i64 + voff) as *u8, vl, cx) 750 ndone = cx[4] 751 } 752 j = voff + vl 753 } 754 s = s + 1 755 } 756 757 // emit per project (file order) 758 let rep: *u8 = sys_mmap(K_MAGIC_65536) 759 var o: i64 = 0 760 var nact: i64 = 0 761 var ncomp: i64 = 0 762 var pi3: i64 = 0 763 while pi3 < np { 764 var total: i64 = 0 765 var done: i64 = 0 766 var nexti: i64 = 0 - 1 767 var sti: i64 = 0 768 while sti < nstep { 769 if st_proj[sti] == pi3 { 770 total = total + 1 771 var isdone: i64 = 0 772 var di2: i64 = 0 773 while di2 < ndone { 774 if d_proj[di2] == pi3 { if d_seq[di2] == st_seq[sti] { isdone = 1 } } 775 di2 = di2 + 1 776 } 777 if isdone == 1 { done = done + 1 } 778 if isdone == 0 { if nexti < 0 { nexti = sti } } 779 } 780 sti = sti + 1 781 } 782 o = vo_cat(rep, o, "VIZSLA-OPS-PROJ id=" as *u8) 783 o = vo_cat(rep, o, p_id[pi3] as *u8) 784 o = vo_cat(rep, o, " member=" as *u8) 785 o = vo_cat(rep, o, p_mem[pi3] as *u8) 786 o = vo_cat(rep, o, " steps_done=" as *u8) 787 o = vo_catn(rep, o, done) 788 o = vo_cat(rep, o, " steps=" as *u8) 789 o = vo_catn(rep, o, total) 790 o = vo_cat(rep, o, " next=" as *u8) 791 if nexti < 0 { 792 o = vo_cat(rep, o, "none state=COMPLETE\n" as *u8) 793 ncomp = ncomp + 1 794 } else { 795 o = vo_catn(rep, o, st_seq[nexti]) 796 o = vo_cat(rep, o, ":" as *u8) 797 o = vo_cat(rep, o, st_desc[nexti] as *u8) 798 o = vo_cat(rep, o, " state=ACTIVE\n" as *u8) 799 nact = nact + 1 800 } 801 pi3 = pi3 + 1 802 } 803 o = vo_cat(rep, o, "VIZSLA-OPS-PROJ-VERDICT projects=" as *u8) 804 o = vo_catn(rep, o, np) 805 o = vo_cat(rep, o, " active=" as *u8) 806 o = vo_catn(rep, o, nact) 807 o = vo_cat(rep, o, " complete=" as *u8) 808 o = vo_catn(rep, o, ncomp) 809 o = vo_cat(rep, o, "\n" as *u8) 810 sys_write(1, rep, o) 811 vo_log_append(prefix, "status" as *u8, rep, o) 812 return 0 813} 814 815func main(argc: i64, argv: *i64) -> i64 { 816 if argc < 2 { vo_p("VIZSLA-OPS usage: log|due|status -- fail loud\n" as *u8); return 1 } 817 let cmd: *u8 = argv[1] as *u8 818 if vo_eq(cmd, "log" as *u8) == 1 { return vo_cmd_log(argc, argv) } 819 if vo_eq(cmd, "due" as *u8) == 1 { return vo_cmd_due(argc, argv) } 820 if vo_eq(cmd, "status" as *u8) == 1 { return vo_cmd_status(argc, argv) } 821 vo_p("VIZSLA-OPS unknown command (log|due|status) -- fail loud\n" as *u8) 822 return 1 823}