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}