code wiki / _hdl_build / nx_vizsla_digest.nx

nx_vizsla_digest.nx source

↩ module page · 537 lines · 22251 B

1// nx_vizsla_digest.nx -- NISHI VIZSLA V5: the proactive DAILY DIGEST. 2// Operator directive 2026-06-14: make the assistant PROACTIVE -- it tells you 3// what to do today before you ask. This is the consigliere's daily brief 4// ACROSS the whole assistant: it COMPOSES the already-gated organs (it does NOT 5// re-implement them -- rule 22, composition over duplication) into one report: 6// 1) RELATIONSHIPS to tend -> nx_vizsla_relate brief 7// 2) NOTES to send (drafted) -> nx_vizsla_notes draftdue 8// 3) BILLS due/overdue -> nx_vizsla_bills status (OPTIONAL: only if the 9// conf names BILLS_PREFIX + BILLS_FILE) 10// -- ENGAGEMENT-PARTNER sections (2026-07-08, operator: "engagement partner ... 11// birthday and important event reminder"), each OPTIONAL like bills: 12// 4) TODAY'S CALENDAR -> nx_vizsla_calendar day (CAL_PREFIX) 13// 5) REMINDERS DUE -> nx_vizsla_remind due (REMIND_CONTACTS + 14// REMIND_LEADS; calendar side = CAL_PREFIX if set; 15// optional REMIND_SENT ledger dedups delivery) 16// 6) PLAN status -> nx_vizsla_plan board (PLAN_PREFIX + PLAN_NAME) 17// 7) VENUE hunt -> nx_vizsla_venue board (VENUE_PREFIX + VENUE_EVENT) 18// designed to be run on a pulse/schedule each day; the consolidated verdict 19// aggregates the sub-reports' counts. Determinism: today via argv. 20// 21// Command: digest <digest.conf> <today> 22// digest.conf (line records, # comments) names where the data lives: 23// RELATE_PREFIX <store-prefix> (nx_vizsla_relate store) 24// RELATE_CONTACTS <contacts.txt> 25// NOTES_PREFIX <store-prefix> (nx_vizsla_notes store) 26// NOTES_CONF <notes_conf.txt> (occasions + windows) 27// NOTES_TEMPLATES <note_templates.txt> 28// It forks the BLESSED organs _offc/nx_vizsla_relate.elf + _offc/nx_vizsla_notes.elf 29// (so run from the nxc2 dir). Loud-fail: missing conf / missing key / 30// a sub-organ that errors. 31// 32// HONEST SCOPE: the digest PRODUCES the day's actionable report + logs it; the 33// actual PUSH (email/notification to your phone) is an outward-facing boundary 34// step (consent-gated). "Automatic each day" = this organ on a pulse/cron. 35// 36// module: nishi-core.vizsla.digest 37// depends: nishi-core.lib.syscalls 38// capability: VIZSLA_DAILY_DIGEST 39// spec: knowledge/specs/2026-06-10-nishi-vizsla-ladder.md license_tier: ORIGINAL 40import "nx_syscalls.nx" 41const K_MAGIC_65536: i64 = 65536 42const K_MAGIC_262144: i64 = 262144 43 44func dg_slen(s: *u8) -> i64 { 45 var n: i64 = 0 46 while s[n] != (0 as u8) { n = n + 1 } 47 return n 48} 49 50func dg_p(s: *u8) -> i64 { 51 sys_write(1, s, dg_slen(s)) 52 return 0 53} 54 55func dg_eq(a: *u8, b: *u8) -> i64 { 56 var i: i64 = 0 57 var go: i64 = 1 58 while go == 1 { 59 if a[i] != b[i] { return 0 } 60 if a[i] == (0 as u8) { return 1 } 61 i = i + 1 62 } 63 return 0 64} 65 66func dg_isws(c: i64) -> i64 { 67 if c == 32 { return 1 } 68 if c == 13 { return 1 } 69 if c == 9 { return 1 } 70 return 0 71} 72 73func dg_tok(b: *u8, off: i64, lend: i64, dst: *u8, cap: i64) -> i64 { 74 var p: i64 = off 75 var go: i64 = 1 76 while go == 1 { 77 if p >= lend { go = 0 } else { 78 if dg_isws(b[p] as i64) == 1 { p = p + 1 } else { go = 0 } 79 } 80 } 81 var t: i64 = 0 82 go = 1 83 while go == 1 { 84 if p >= lend { go = 0 } else { 85 if dg_isws(b[p] as i64) == 1 { go = 0 } else { 86 if t < cap - 1 { dst[t] = b[p]; t = t + 1 } 87 p = p + 1 88 } 89 } 90 } 91 dst[t] = 0 as u8 92 return p 93} 94 95func dg_cat(dst: *u8, off: i64, s: *u8) -> i64 { 96 var i: i64 = 0 97 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 } 98 return off + i 99} 100 101func dg_catn(dst: *u8, off: i64, v: i64) -> i64 { 102 var o: i64 = off 103 var m: i64 = v 104 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m } 105 let t: *u8 = sys_mmap(28) 106 var k: i64 = 0 107 if m == 0 { t[0] = 48 as u8; k = 1 } 108 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 109 var i: i64 = 0 110 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 } 111 return o + k 112} 113 114func dg_readall(path: *u8, szout: *i64) -> *u8 { 115 let fd: i64 = sys_openat_rd(path) 116 if fd < 0 { szout[0] = 0 - 1; return 0 as *u8 } 117 let sz: i64 = sys_lseek(fd, 0, 2) 118 sys_lseek(fd, 0, 0) 119 let buf: *u8 = sys_mmap(sz + 64) 120 var got: i64 = 0 121 var n: i64 = 1 122 while n > 0 { 123 n = sys_read(fd, (buf as i64 + got) as *u8, K_MAGIC_65536) 124 if n > 0 { got = got + n } 125 } 126 sys_close(fd) 127 szout[0] = got 128 return buf 129} 130 131// fork/exec a blessed organ with up to 4 args after the command; child stdout+ 132// stderr -> outpath. returns the child exit code. 133func dg_run(elf: *u8, a0: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, outpath: *u8) -> i64 { 134 let pid: i64 = sys_fork() 135 if pid == 0 { 136 let ofd: i64 = sys_openat_wr(outpath, 0x1a4) 137 if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) } 138 let argv: *i64 = sys_mmap(64) as *i64 139 argv[0] = elf as i64 140 var i: i64 = 1 141 if (a0 as i64) != 0 { argv[i] = a0 as i64; i = i + 1 } 142 if (a1 as i64) != 0 { argv[i] = a1 as i64; i = i + 1 } 143 if (a2 as i64) != 0 { argv[i] = a2 as i64; i = i + 1 } 144 if (a3 as i64) != 0 { argv[i] = a3 as i64; i = i + 1 } 145 if (a4 as i64) != 0 { argv[i] = a4 as i64; i = i + 1 } 146 argv[i] = 0 147 let envp: *i64 = sys_mmap(16) as *i64 148 envp[0] = 0 149 sys_execve(elf, argv, envp) 150 sys_exit(127) 151 } 152 let st: *i64 = sys_mmap(16) as *i64 153 sys_wait4(pid, st, 0) 154 let sig: i64 = st[0] & 0x7f 155 if sig != 0 { return 128 + sig } 156 return (st[0] >> 8) & 0xff 157} 158 159// dg_run with a 6th arg (nx_vizsla_remind due takes cmd+5 when the sent ledger is named) 160func dg_run6(elf: *u8, a0: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, a5: *u8, outpath: *u8) -> i64 { 161 let pid: i64 = sys_fork() 162 if pid == 0 { 163 let ofd: i64 = sys_openat_wr(outpath, 0x1a4) 164 if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) } 165 let argv: *i64 = sys_mmap(64) as *i64 166 argv[0] = elf as i64 167 var i: i64 = 1 168 if (a0 as i64) != 0 { argv[i] = a0 as i64; i = i + 1 } 169 if (a1 as i64) != 0 { argv[i] = a1 as i64; i = i + 1 } 170 if (a2 as i64) != 0 { argv[i] = a2 as i64; i = i + 1 } 171 if (a3 as i64) != 0 { argv[i] = a3 as i64; i = i + 1 } 172 if (a4 as i64) != 0 { argv[i] = a4 as i64; i = i + 1 } 173 if (a5 as i64) != 0 { argv[i] = a5 as i64; i = i + 1 } 174 argv[i] = 0 175 let envp: *i64 = sys_mmap(16) as *i64 176 envp[0] = 0 177 sys_execve(elf, argv, envp) 178 sys_exit(127) 179 } 180 let st: *i64 = sys_mmap(16) as *i64 181 sys_wait4(pid, st, 0) 182 let sig: i64 = st[0] & 0x7f 183 if sig != 0 { return 128 + sig } 184 return (st[0] >> 8) & 0xff 185} 186 187// find "key" in buf and return the integer immediately following it; -1 if the 188// key is absent (a missing sub-report shows as -1 in the digest -- visible, not hidden) 189func dg_extract(buf: *u8, sz: i64, key: *u8) -> i64 { 190 let n: i64 = dg_slen(key) 191 var i: i64 = 0 192 while i + n <= sz { 193 var ok: i64 = 1 194 var j: i64 = 0 195 while j < n { 196 if buf[i + j] != key[j] { ok = 0; j = n } else { j = j + 1 } 197 } 198 if ok == 1 { 199 var p: i64 = i + n 200 var neg: i64 = 0 201 if p < sz { if buf[p] == (45 as u8) { neg = 1; p = p + 1 } } 202 var v: i64 = 0 203 var got: i64 = 0 204 var go: i64 = 1 205 while go == 1 { 206 if p >= sz { go = 0 } else { 207 let d: i64 = (buf[p] as i64) - 48 208 if d >= 0 { if d <= 9 { v = v * 10 + d; got = 1; p = p + 1 } else { go = 0 } } else { go = 0 } 209 } 210 } 211 if got == 0 { return 0 - 1 } 212 if neg == 1 { return 0 - v } 213 return v 214 } 215 i = i + 1 216 } 217 return 0 - 1 218} 219 220// offset of the first occurrence of needle in buf, or -1 221func dg_find(buf: *u8, sz: i64, needle: *u8) -> i64 { 222 let n: i64 = dg_slen(needle) 223 var i: i64 = 0 224 while i + n <= sz { 225 var ok: i64 = 1 226 var j: i64 = 0 227 while j < n { 228 if buf[i + j] != needle[j] { ok = 0; j = n } else { j = j + 1 } 229 } 230 if ok == 1 { return i } 231 i = i + 1 232 } 233 return 0 - 1 234} 235 236// read digest.conf and copy the value for <key> into out; returns 1 if found 237func dg_conf_get(cb: *u8, csz: i64, key: *u8, out: *u8, cap: i64) -> i64 { 238 let t0: *u8 = sys_mmap(256) 239 let t1: *u8 = sys_mmap(512) 240 var i: i64 = 0 241 while i < csz { 242 var e: i64 = i 243 var go: i64 = 1 244 while go == 1 { 245 if e >= csz { go = 0 } else { 246 if cb[e] == (10 as u8) { go = 0 } else { e = e + 1 } 247 } 248 } 249 var p: i64 = dg_tok(cb, i, e, t0, 256) 250 if t0[0] == (35 as u8) { t0[0] = 0 as u8 } 251 if dg_eq(t0, key) == 1 { 252 dg_tok(cb, p, e, t1, 512) 253 if t1[0] != (0 as u8) { 254 var k: i64 = 0 255 while t1[k] != (0 as u8) { if k < cap - 1 { out[k] = t1[k] }; k = k + 1 } 256 out[k] = 0 as u8 257 return 1 258 } 259 } 260 i = e + 1 261 } 262 return 0 263} 264 265func dg_cmd_digest(argc: i64, argv: *i64) -> i64 { 266 if argc < 4 { dg_p("VIZSLA-DIGEST digest needs <digest.conf> <today> -- fail loud\n" as *u8); return 1 } 267 let szp: *i64 = sys_mmap(16) as *i64 268 let cb: *u8 = dg_readall(argv[2] as *u8, szp) 269 let csz: i64 = szp[0] 270 if csz <= 0 { dg_p("VIZSLA-DIGEST conf MISSING/EMPTY -- fail loud\n" as *u8); return 1 } 271 let today: *u8 = argv[3] as *u8 272 273 let rprefix: *u8 = sys_mmap(512) 274 let rcontacts: *u8 = sys_mmap(512) 275 let nprefix: *u8 = sys_mmap(512) 276 let nconf: *u8 = sys_mmap(512) 277 let ntmpl: *u8 = sys_mmap(512) 278 if dg_conf_get(cb, csz, "RELATE_PREFIX" as *u8, rprefix, 512) == 0 { dg_p("VIZSLA-DIGEST conf missing RELATE_PREFIX -- fail loud\n" as *u8); return 1 } 279 if dg_conf_get(cb, csz, "RELATE_CONTACTS" as *u8, rcontacts, 512) == 0 { dg_p("VIZSLA-DIGEST conf missing RELATE_CONTACTS -- fail loud\n" as *u8); return 1 } 280 if dg_conf_get(cb, csz, "NOTES_PREFIX" as *u8, nprefix, 512) == 0 { dg_p("VIZSLA-DIGEST conf missing NOTES_PREFIX -- fail loud\n" as *u8); return 1 } 281 if dg_conf_get(cb, csz, "NOTES_CONF" as *u8, nconf, 512) == 0 { dg_p("VIZSLA-DIGEST conf missing NOTES_CONF -- fail loud\n" as *u8); return 1 } 282 if dg_conf_get(cb, csz, "NOTES_TEMPLATES" as *u8, ntmpl, 512) == 0 { dg_p("VIZSLA-DIGEST conf missing NOTES_TEMPLATES -- fail loud\n" as *u8); return 1 } 283 284 // compose: run the two blessed organs over the named data 285 let rc_b: i64 = dg_run("_offc/nx_vizsla_relate.elf" as *u8, "brief" as *u8, rprefix, rcontacts, today, 0 as *u8, "/tmp/dg_brief.txt" as *u8) 286 if rc_b != 0 { dg_p("VIZSLA-DIGEST relate brief FAILED -- fail loud\n" as *u8); return 1 } 287 let rc_n: i64 = dg_run("_offc/nx_vizsla_notes.elf" as *u8, "draftdue" as *u8, nprefix, ntmpl, today, nconf, "/tmp/dg_notes.txt" as *u8) 288 if rc_n != 0 { dg_p("VIZSLA-DIGEST notes draftdue FAILED -- fail loud\n" as *u8); return 1 } 289 290 let bsz: *i64 = sys_mmap(16) as *i64 291 let bbuf: *u8 = dg_readall("/tmp/dg_brief.txt" as *u8, bsz) 292 let nsz: *i64 = sys_mmap(16) as *i64 293 let nbuf: *u8 = dg_readall("/tmp/dg_notes.txt" as *u8, nsz) 294 295 // OPTIONAL bills section: if the conf names BILLS_PREFIX + BILLS_FILE, run 296 // the bills tracker too (keeps digest backward-compatible without bills) 297 let bprefix: *u8 = sys_mmap(512) 298 let bfile: *u8 = sys_mmap(512) 299 var has_bills: i64 = 0 300 if dg_conf_get(cb, csz, "BILLS_PREFIX" as *u8, bprefix, 512) == 1 { 301 if dg_conf_get(cb, csz, "BILLS_FILE" as *u8, bfile, 512) == 1 { has_bills = 1 } 302 } 303 let blsz: *i64 = sys_mmap(16) as *i64 304 var blbuf: *u8 = 0 as *u8 305 var bills_due: i64 = 0 306 var bills_over: i64 = 0 307 var bills_owed: i64 = 0 308 if has_bills == 1 { 309 let rc_bl: i64 = dg_run("_offc/nx_vizsla_bills.elf" as *u8, "status" as *u8, bprefix, bfile, today, 0 as *u8, "/tmp/dg_bills.txt" as *u8) 310 if rc_bl != 0 { dg_p("VIZSLA-DIGEST bills status FAILED -- fail loud\n" as *u8); return 1 } 311 blbuf = dg_readall("/tmp/dg_bills.txt" as *u8, blsz) 312 let voff: i64 = dg_find(blbuf, blsz[0], "VIZSLA-BILL-VERDICT" as *u8) 313 if voff >= 0 { 314 let vt: *u8 = (blbuf as i64 + voff) as *u8 315 let vl: i64 = blsz[0] - voff 316 bills_due = dg_extract(vt, vl, "due=" as *u8) 317 bills_over = dg_extract(vt, vl, "overdue=" as *u8) 318 bills_owed = dg_extract(vt, vl, "owed_cents=" as *u8) 319 } 320 } 321 322 // OPTIONAL calendar section: CAL_PREFIX -> today's events + free/busy 323 let calpfx: *u8 = sys_mmap(512) 324 var has_cal: i64 = 0 325 if dg_conf_get(cb, csz, "CAL_PREFIX" as *u8, calpfx, 512) == 1 { has_cal = 1 } 326 let calsz: *i64 = sys_mmap(16) as *i64 327 var calbuf: *u8 = 0 as *u8 328 var cal_events: i64 = 0 329 var cal_free: i64 = 0 330 if has_cal == 1 { 331 let rc_c: i64 = dg_run("_offc/nx_vizsla_calendar.elf" as *u8, "day" as *u8, calpfx, today, 0 as *u8, 0 as *u8, "/tmp/dg_cal.txt" as *u8) 332 if rc_c != 0 { dg_p("VIZSLA-DIGEST calendar day FAILED -- fail loud\n" as *u8); return 1 } 333 calbuf = dg_readall("/tmp/dg_cal.txt" as *u8, calsz) 334 let cvoff: i64 = dg_find(calbuf, calsz[0], "VIZSLA-CAL-DAY-VERDICT" as *u8) 335 if cvoff >= 0 { 336 let cvt: *u8 = (calbuf as i64 + cvoff) as *u8 337 let cvl: i64 = calsz[0] - cvoff 338 cal_events = dg_extract(cvt, cvl, "events=" as *u8) 339 cal_free = dg_extract(cvt, cvl, "free_min=" as *u8) 340 } 341 } 342 343 // OPTIONAL reminders section: REMIND_CONTACTS + REMIND_LEADS (+ REMIND_SENT ledger); 344 // the calendar side rides CAL_PREFIX when present 345 let rcontacts2: *u8 = sys_mmap(512) 346 let rleads: *u8 = sys_mmap(128) 347 let rsent: *u8 = sys_mmap(512) 348 var has_rem: i64 = 0 349 if dg_conf_get(cb, csz, "REMIND_CONTACTS" as *u8, rcontacts2, 512) == 1 { 350 if dg_conf_get(cb, csz, "REMIND_LEADS" as *u8, rleads, 128) == 1 { has_rem = 1 } 351 } 352 var has_sent: i64 = 0 353 if dg_conf_get(cb, csz, "REMIND_SENT" as *u8, rsent, 512) == 1 { has_sent = 1 } 354 let remsz: *i64 = sys_mmap(16) as *i64 355 var rembuf: *u8 = 0 as *u8 356 var rem_due: i64 = 0 357 var rem_bd: i64 = 0 358 if has_rem == 1 { 359 var remcal: *u8 = "-" as *u8 360 if has_cal == 1 { remcal = calpfx } 361 var rc_r: i64 = 0 362 if has_sent == 1 { 363 rc_r = dg_run6("_offc/nx_vizsla_remind.elf" as *u8, "due" as *u8, remcal, rcontacts2, today, rleads, rsent, "/tmp/dg_rem.txt" as *u8) 364 } else { 365 rc_r = dg_run("_offc/nx_vizsla_remind.elf" as *u8, "due" as *u8, remcal, rcontacts2, today, rleads, "/tmp/dg_rem.txt" as *u8) 366 } 367 if rc_r != 0 { dg_p("VIZSLA-DIGEST remind due FAILED -- fail loud\n" as *u8); return 1 } 368 rembuf = dg_readall("/tmp/dg_rem.txt" as *u8, remsz) 369 let rvoff: i64 = dg_find(rembuf, remsz[0], "VIZSLA-REM-VERDICT" as *u8) 370 if rvoff >= 0 { 371 let rvt: *u8 = (rembuf as i64 + rvoff) as *u8 372 let rvl: i64 = remsz[0] - rvoff 373 rem_due = dg_extract(rvt, rvl, " due=" as *u8) 374 rem_bd = dg_extract(rvt, rvl, "due_birthdays=" as *u8) 375 } 376 } 377 378 // OPTIONAL plan section: PLAN_PREFIX + PLAN_NAME -> ready/blocked/late 379 let pprefix: *u8 = sys_mmap(512) 380 let pname: *u8 = sys_mmap(256) 381 var has_plan: i64 = 0 382 if dg_conf_get(cb, csz, "PLAN_PREFIX" as *u8, pprefix, 512) == 1 { 383 if dg_conf_get(cb, csz, "PLAN_NAME" as *u8, pname, 256) == 1 { has_plan = 1 } 384 } 385 let plsz: *i64 = sys_mmap(16) as *i64 386 var plbuf: *u8 = 0 as *u8 387 var plan_ready: i64 = 0 388 var plan_blocked: i64 = 0 389 var plan_late: i64 = 0 390 if has_plan == 1 { 391 let rc_p: i64 = dg_run("_offc/nx_vizsla_plan.elf" as *u8, "board" as *u8, pprefix, pname, today, 0 as *u8, "/tmp/dg_plan.txt" as *u8) 392 if rc_p != 0 { dg_p("VIZSLA-DIGEST plan board FAILED -- fail loud\n" as *u8); return 1 } 393 plbuf = dg_readall("/tmp/dg_plan.txt" as *u8, plsz) 394 let pvoff: i64 = dg_find(plbuf, plsz[0], "VIZSLA-PLAN-VERDICT" as *u8) 395 if pvoff >= 0 { 396 let pvt: *u8 = (plbuf as i64 + pvoff) as *u8 397 let pvl: i64 = plsz[0] - pvoff 398 plan_ready = dg_extract(pvt, pvl, "ready=" as *u8) 399 plan_blocked = dg_extract(pvt, pvl, "blocked=" as *u8) 400 plan_late = dg_extract(pvt, pvl, "late=" as *u8) 401 } 402 } 403 404 // OPTIONAL venue section: VENUE_PREFIX + VENUE_EVENT -> the hire pipeline board 405 let vprefix: *u8 = sys_mmap(512) 406 let vevent: *u8 = sys_mmap(256) 407 var has_ven: i64 = 0 408 if dg_conf_get(cb, csz, "VENUE_PREFIX" as *u8, vprefix, 512) == 1 { 409 if dg_conf_get(cb, csz, "VENUE_EVENT" as *u8, vevent, 256) == 1 { has_ven = 1 } 410 } 411 let vnsz: *i64 = sys_mmap(16) as *i64 412 var vnbuf: *u8 = 0 as *u8 413 var ven_count: i64 = 0 414 var ven_booked: i64 = 0 415 if has_ven == 1 { 416 let rc_v: i64 = dg_run("_offc/nx_vizsla_venue.elf" as *u8, "board" as *u8, vprefix, vevent, 0 as *u8, 0 as *u8, "/tmp/dg_ven.txt" as *u8) 417 if rc_v != 0 { dg_p("VIZSLA-DIGEST venue board FAILED -- fail loud\n" as *u8); return 1 } 418 vnbuf = dg_readall("/tmp/dg_ven.txt" as *u8, vnsz) 419 let vvoff: i64 = dg_find(vnbuf, vnsz[0], "VIZSLA-VEN-VERDICT" as *u8) 420 if vvoff >= 0 { 421 let vvt: *u8 = (vnbuf as i64 + vvoff) as *u8 422 let vvl: i64 = vnsz[0] - vvoff 423 ven_count = dg_extract(vvt, vvl, "venues=" as *u8) 424 ven_booked = 1 425 if dg_find(vvt, vvl, "booked=none" as *u8) >= 0 { ven_booked = 0 } 426 } 427 } 428 429 let followups: i64 = dg_extract(bbuf, bsz[0], "followups=" as *u8) 430 let birthdays: i64 = dg_extract(bbuf, bsz[0], "birthdays=" as *u8) 431 let thankyous: i64 = dg_extract(bbuf, bsz[0], "thankyous=" as *u8) 432 let obligations: i64 = dg_extract(bbuf, bsz[0], "obligations=" as *u8) 433 let drafted: i64 = dg_extract(nbuf, nsz[0], "drafted=" as *u8) 434 435 let rep: *u8 = sys_mmap(K_MAGIC_262144) 436 var o: i64 = 0 437 o = dg_cat(rep, o, "VIZSLA-DIGEST date=" as *u8) 438 o = dg_cat(rep, o, today) 439 o = dg_cat(rep, o, "\n== RELATIONSHIPS (who to tend today) ==\n" as *u8) 440 var bi: i64 = 0 441 while bi < bsz[0] { rep[o] = bbuf[bi]; o = o + 1; bi = bi + 1 } 442 o = dg_cat(rep, o, "== NOTES TO SEND (drafts ready) ==\n" as *u8) 443 var ni: i64 = 0 444 while ni < nsz[0] { rep[o] = nbuf[ni]; o = o + 1; ni = ni + 1 } 445 if has_bills == 1 { 446 o = dg_cat(rep, o, "== BILLS (due / overdue) ==\n" as *u8) 447 var bli: i64 = 0 448 while bli < blsz[0] { rep[o] = blbuf[bli]; o = o + 1; bli = bli + 1 } 449 } 450 if has_cal == 1 { 451 o = dg_cat(rep, o, "== CALENDAR TODAY ==\n" as *u8) 452 var ci: i64 = 0 453 while ci < calsz[0] { rep[o] = calbuf[ci]; o = o + 1; ci = ci + 1 } 454 } 455 if has_rem == 1 { 456 o = dg_cat(rep, o, "== REMINDERS (birthdays + important events) ==\n" as *u8) 457 var ri: i64 = 0 458 while ri < remsz[0] { rep[o] = rembuf[ri]; o = o + 1; ri = ri + 1 } 459 } 460 if has_plan == 1 { 461 o = dg_cat(rep, o, "== PLAN (ready / blocked / late) ==\n" as *u8) 462 var pli: i64 = 0 463 while pli < plsz[0] { rep[o] = plbuf[pli]; o = o + 1; pli = pli + 1 } 464 } 465 if has_ven == 1 { 466 o = dg_cat(rep, o, "== VENUE HUNT ==\n" as *u8) 467 var vni: i64 = 0 468 while vni < vnsz[0] { rep[o] = vnbuf[vni]; o = o + 1; vni = vni + 1 } 469 } 470 o = dg_cat(rep, o, "VIZSLA-DIGEST-VERDICT followups=" as *u8) 471 o = dg_catn(rep, o, followups) 472 o = dg_cat(rep, o, " birthdays=" as *u8) 473 o = dg_catn(rep, o, birthdays) 474 o = dg_cat(rep, o, " thankyous=" as *u8) 475 o = dg_catn(rep, o, thankyous) 476 o = dg_cat(rep, o, " obligations=" as *u8) 477 o = dg_catn(rep, o, obligations) 478 o = dg_cat(rep, o, " notes_drafted=" as *u8) 479 o = dg_catn(rep, o, drafted) 480 if has_bills == 1 { 481 o = dg_cat(rep, o, " bills_due=" as *u8) 482 o = dg_catn(rep, o, bills_due) 483 o = dg_cat(rep, o, " bills_overdue=" as *u8) 484 o = dg_catn(rep, o, bills_over) 485 o = dg_cat(rep, o, " bills_owed_cents=" as *u8) 486 o = dg_catn(rep, o, bills_owed) 487 } 488 if has_cal == 1 { 489 o = dg_cat(rep, o, " cal_events=" as *u8) 490 o = dg_catn(rep, o, cal_events) 491 o = dg_cat(rep, o, " cal_free_min=" as *u8) 492 o = dg_catn(rep, o, cal_free) 493 } 494 if has_rem == 1 { 495 o = dg_cat(rep, o, " reminders_due=" as *u8) 496 o = dg_catn(rep, o, rem_due) 497 o = dg_cat(rep, o, " reminders_birthdays=" as *u8) 498 o = dg_catn(rep, o, rem_bd) 499 } 500 if has_plan == 1 { 501 o = dg_cat(rep, o, " plan_ready=" as *u8) 502 o = dg_catn(rep, o, plan_ready) 503 o = dg_cat(rep, o, " plan_blocked=" as *u8) 504 o = dg_catn(rep, o, plan_blocked) 505 o = dg_cat(rep, o, " plan_late=" as *u8) 506 o = dg_catn(rep, o, plan_late) 507 } 508 if has_ven == 1 { 509 o = dg_cat(rep, o, " venues=" as *u8) 510 o = dg_catn(rep, o, ven_count) 511 o = dg_cat(rep, o, " venue_booked=" as *u8) 512 o = dg_catn(rep, o, ven_booked) 513 } 514 o = dg_cat(rep, o, "\n" as *u8) 515 sys_write(1, rep, o) 516 517 let fd: i64 = sys_openat_append("knowledge/status/vizsla_digest.log" as *u8, 0x1a4) 518 if fd > 0 { 519 let hdr: *u8 = sys_mmap(128) 520 var ho: i64 = 0 521 ho = dg_cat(hdr, ho, "VIZSLA-DIGEST epoch=" as *u8) 522 ho = dg_catn(hdr, ho, sys_now_realtime_sec()) 523 ho = dg_cat(hdr, ho, "\n" as *u8) 524 sys_write(fd, hdr, ho) 525 sys_write(fd, rep, o) 526 sys_close(fd) 527 } 528 return 0 529} 530 531func main(argc: i64, argv: *i64) -> i64 { 532 if argc < 2 { dg_p("VIZSLA-DIGEST usage: digest <digest.conf> <today> -- fail loud\n" as *u8); return 1 } 533 let cmd: *u8 = argv[1] as *u8 534 if dg_eq(cmd, "digest" as *u8) == 1 { return dg_cmd_digest(argc, argv) } 535 dg_p("VIZSLA-DIGEST unknown command (digest) -- fail loud\n" as *u8) 536 return 1 537}