code wiki / _hdl_build / nx_vizsla_notify_gate.nx

nx_vizsla_notify_gate.nx source

↩ module page · 310 lines · 13084 B

1// nx_vizsla_notify_gate.nx -- VIZSLA OUTWARD-DELIVERY gate: reminders REACH you. COMPOSITION: the 2// calendar store is loaded through the blessed calendar organ; notify forks the blessed remind engine 3// for the due computation; the notification store is the once-only delivery ledger. 4// 5// fixture: calendar mtg 2026-07-08 10:00, gala 2026-08-20 18:00; contacts mom 07-14, dad 07-08. 6// deliver today=2026-07-08 leads=6,0 -> mtg(event in0) + dad(bday in0) + mom(bday in6) = 3 delivered 7// re-deliver same -> 0 delivered / 3 skipped (own store is the ledger) 8// deliver today=2026-08-14 leads=6,0 -> gala(event in6, NEW occurrence) = 1 delivered 9// feed -> 4 notifications; feed birthday -> 2 (mom, dad) 10// email today=2026-07-08 -> RFC5322 digest, 3 reminders, Date: Wed, 08 Jul 2026 09:00:00 +0000 11// 12// Rows: 1 fixture-loads 2 deliver-onsite 3 feed-lists 4 deliver-idempotent 5 deliver-new-occurrence 13// 6 feed-after 7 feed-kind-filter 8 email-compose 9 email-date-header 10 email-body-bullet 14// 11 feed-determinism 12 loud-fail-bad-today[neg] 13 loud-fail-bad-leads[neg] 15// Evidence: VIZSLA-NOTIFY-GATE -> stdout + knowledge/status/vizsla_gate.log; exit 0 iff 13/13. 16// spec: knowledge/research/2026-06-22-vizsla-sclass-roadmap.md license_tier: ORIGINAL 17import "nx_syscalls.nx" 18 19func ng_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 20func ng_p(s: *u8) -> i64 { sys_write(1, s, ng_slen(s)); return 0 } 21 22func ng_cat(dst: *u8, off: i64, s: *u8) -> i64 { 23 var i: i64 = 0 24 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 } 25 return off + i 26} 27 28func ng_catn(dst: *u8, off: i64, v: i64) -> i64 { 29 var o: i64 = off 30 var m: i64 = v 31 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m } 32 let t: *u8 = sys_mmap(28) 33 var k: i64 = 0 34 if m == 0 { t[0] = 48 as u8; k = 1 } 35 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 36 var i: i64 = 0 37 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 } 38 return o + k 39} 40 41func ng_write(path: *u8, content: *u8) -> i64 { 42 let fd: i64 = sys_openat_wr(path, 0x1a4) 43 if fd < 0 { return 0 - 1 } 44 sys_write(fd, content, ng_slen(content)) 45 sys_close(fd) 46 return 0 47} 48 49func ng_readall(path: *u8, szout: *i64) -> *u8 { 50 let fd: i64 = sys_openat_rd(path) 51 if fd < 0 { szout[0] = 0 - 1; return 0 as *u8 } 52 let sz: i64 = sys_lseek(fd, 0, 2) 53 sys_lseek(fd, 0, 0) 54 let buf: *u8 = sys_mmap(sz + 64) 55 var got: i64 = 0 56 var n: i64 = 1 57 while n > 0 { 58 n = sys_read(fd, (buf as i64 + got) as *u8, 65536) 59 if n > 0 { got = got + n } 60 } 61 sys_close(fd) 62 szout[0] = got 63 return buf 64} 65 66func ng_runv(elf: *u8, args: *i64, outpath: *u8) -> i64 { 67 let pid: i64 = sys_fork() 68 if pid == 0 { 69 if (outpath as i64) != 0 { 70 let ofd: i64 = sys_openat_wr(outpath, 0x1a4) 71 if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) } 72 } 73 let argv: *i64 = sys_mmap(128) as *i64 74 argv[0] = elf as i64 75 var i: i64 = 0 76 var go: i64 = 1 77 while go == 1 { 78 if args[i] == 0 { go = 0 } else { 79 argv[i + 1] = args[i] 80 i = i + 1 81 } 82 } 83 argv[i + 1] = 0 84 let envp: *i64 = sys_mmap(16) as *i64 85 envp[0] = 0 86 sys_execve(elf, argv, envp) 87 sys_exit(127) 88 } 89 let st: *i64 = sys_mmap(16) as *i64 90 sys_wait4(pid, st, 0) 91 let sig: i64 = st[0] & 0x7f 92 if sig != 0 { return 128 + sig } 93 return (st[0] >> 8) & 0xff 94} 95 96func ng_has(path: *u8, needle: *u8) -> i64 { 97 let szp: *i64 = sys_mmap(16) as *i64 98 let b: *u8 = ng_readall(path, szp) 99 let sz: i64 = szp[0] 100 let n: i64 = ng_slen(needle) 101 if sz < n { return 0 } 102 var i: i64 = 0 103 while i + n <= sz { 104 var ok: i64 = 1 105 var j: i64 = 0 106 while j < n { 107 if b[i + j] != needle[j] { ok = 0; j = n } else { j = j + 1 } 108 } 109 if ok == 1 { return 1 } 110 i = i + 1 111 } 112 return 0 113} 114 115func ng_fileeq(p1: *u8, p2: *u8) -> i64 { 116 let s1: *i64 = sys_mmap(16) as *i64 117 let s2: *i64 = sys_mmap(16) as *i64 118 let b1: *u8 = ng_readall(p1, s1) 119 let b2: *u8 = ng_readall(p2, s2) 120 if s1[0] != s2[0] { return 0 } 121 if s1[0] <= 0 { return 0 } 122 var i: i64 = 0 123 while i < s1[0] { 124 if b1[i] != b2[i] { return 0 } 125 i = i + 1 126 } 127 return 1 128} 129 130func ng_row(name: *u8, pass: i64) -> i64 { 131 ng_p("ROW " as *u8) 132 ng_p(name) 133 if pass == 1 { ng_p(" PASS\n" as *u8) } else { ng_p(" FAIL\n" as *u8) } 134 return pass 135} 136 137func ng_args(a1: *u8, a2: *u8, a3: *u8, a4: *u8, a5: *u8, a6: *u8, a7: *u8, a8: *u8) -> *i64 { 138 let a: *i64 = sys_mmap(128) as *i64 139 a[0] = a1 as i64 140 a[1] = a2 as i64 141 a[2] = a3 as i64 142 a[3] = a4 as i64 143 a[4] = a5 as i64 144 a[5] = a6 as i64 145 a[6] = a7 as i64 146 a[7] = a8 as i64 147 a[8] = 0 148 return a 149} 150 151func ng_ensure(elf: *u8, organ: *u8) -> i64 { 152 let pr: i64 = sys_openat_rd(elf) 153 if pr >= 0 { sys_close(pr); return 0 } 154 ng_p(" instrument missing -> rebuilding via durable runner\n" as *u8) 155 ng_runv("_offc/nx_sov_build_run.elf" as *u8, ng_args(organ, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_rebuild.out" as *u8) 156 return 0 157} 158 159func main(argc: i64, argv: *i64) -> i64 { 160 ng_p("=== VIZSLA NOTIFY GATE: outward delivery (on-site once-only + RFC5322 email compose) ===\n" as *u8) 161 let ntf: *u8 = "/tmp/nx_vizsla_notify.sov.elf" as *u8 162 let cal: *u8 = "/tmp/nx_vizsla_calendar.sov.elf" as *u8 163 ng_ensure(ntf, "nx_vizsla_notify" as *u8) 164 ng_ensure(cal, "nx_vizsla_calendar" as *u8) 165 // notify forks the BLESSED _offc/nx_vizsla_remind.elf -- ensure it exists 166 let rp: i64 = sys_openat_rd("_offc/nx_vizsla_remind.elf" as *u8) 167 if rp >= 0 { sys_close(rp) } else { 168 ng_runv("_offc/nx_sov_build_run.elf" as *u8, ng_args("nx_vizsla_remind" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_rem.out" as *u8) 169 } 170 171 let us: i64 = sys_now_us() 172 let cpfx: *u8 = sys_mmap(128) 173 var po: i64 = 0 174 po = ng_cat(cpfx, po, "/tmp/vznC" as *u8) 175 po = ng_catn(cpfx, po, us) 176 po = ng_cat(cpfx, po, "-" as *u8) 177 cpfx[po] = 0 as u8 178 let npfx: *u8 = sys_mmap(128) 179 po = 0 180 po = ng_cat(npfx, po, "/tmp/vznN" as *u8) 181 po = ng_catn(npfx, po, us) 182 po = ng_cat(npfx, po, "-" as *u8) 183 npfx[po] = 0 as u8 184 185 ng_write("/tmp/vzn_cal.txt" as *u8, "EVENT mtg 2026-07-08 600 60 standup-mtg\nEVENT gala 2026-08-20 1080 120 summer-gala\n" as *u8) 186 ng_write("/tmp/vzn_ct.txt" as *u8, "TIER inner 7\nCONTACT mom Mom inner 07-14\nCONTACT dad Dad inner 07-08\n" as *u8) 187 188 var pass: i64 = 0 189 var r: i64 = 0 190 191 // row 1: calendar loads 192 let rc1: i64 = ng_runv(cal, ng_args("load" as *u8, "/tmp/vzn_cal.txt" as *u8, cpfx, "7501" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_l1.txt" as *u8) 193 r = 0 194 if rc1 == 0 { if ng_has("/tmp/vzn_l1.txt" as *u8, "VIZSLA-CAL-LOAD scanned=2 new=2" as *u8) == 1 { r = 1 } } 195 pass = pass + ng_row("fixture-loads" as *u8, r) 196 197 // row 2: deliver on-site 198 let rc2: i64 = ng_runv(ntf, ng_args("deliver" as *u8, npfx, cpfx, "/tmp/vzn_ct.txt" as *u8, "2026-07-08" as *u8, "6,0" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_r2.txt" as *u8) 199 r = 0 200 if rc2 == 0 { if ng_has("/tmp/vzn_r2.txt" as *u8, "VIZSLA-NOTIFY-DELIVER channel=onsite today=2026-07-08 delivered=3 skipped=0" as *u8) == 1 { r = 1 } } 201 pass = pass + ng_row("deliver-onsite" as *u8, r) 202 203 // row 3: feed lists the delivered notices 204 let rc3: i64 = ng_runv(ntf, ng_args("feed" as *u8, npfx, "-" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_r3.txt" as *u8) 205 r = 0 206 if rc3 == 0 { 207 if ng_has("/tmp/vzn_r3.txt" as *u8, "VIZSLA-NOTIFY channel=onsite kind=birthday id=mom date=2026-07-14 on=2026-07-08 title=Mom" as *u8) == 1 { 208 if ng_has("/tmp/vzn_r3.txt" as *u8, "VIZSLA-NOTIFY-FEED kind=- notifications=3" as *u8) == 1 { r = 1 } 209 } 210 } 211 pass = pass + ng_row("feed-lists" as *u8, r) 212 213 // row 4: idempotent re-deliver 214 let rc4: i64 = ng_runv(ntf, ng_args("deliver" as *u8, npfx, cpfx, "/tmp/vzn_ct.txt" as *u8, "2026-07-08" as *u8, "6,0" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_r4.txt" as *u8) 215 r = 0 216 if rc4 == 0 { if ng_has("/tmp/vzn_r4.txt" as *u8, "delivered=0 skipped=3 segment=none" as *u8) == 1 { r = 1 } } 217 pass = pass + ng_row("deliver-idempotent" as *u8, r) 218 219 // row 5: a genuinely new occurrence delivers 220 let rc5: i64 = ng_runv(ntf, ng_args("deliver" as *u8, npfx, cpfx, "/tmp/vzn_ct.txt" as *u8, "2026-08-14" as *u8, "6,0" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_r5.txt" as *u8) 221 r = 0 222 if rc5 == 0 { if ng_has("/tmp/vzn_r5.txt" as *u8, "today=2026-08-14 delivered=1 skipped=0" as *u8) == 1 { r = 1 } } 223 pass = pass + ng_row("deliver-new-occurrence" as *u8, r) 224 225 // row 6: feed now shows 4 226 let rc6: i64 = ng_runv(ntf, ng_args("feed" as *u8, npfx, "-" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_r6.txt" as *u8) 227 r = 0 228 if rc6 == 0 { if ng_has("/tmp/vzn_r6.txt" as *u8, "VIZSLA-NOTIFY-FEED kind=- notifications=4" as *u8) == 1 { r = 1 } } 229 pass = pass + ng_row("feed-after" as *u8, r) 230 231 // row 7: kind filter 232 let rc7: i64 = ng_runv(ntf, ng_args("feed" as *u8, npfx, "birthday" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_r7.txt" as *u8) 233 r = 0 234 if rc7 == 0 { 235 if ng_has("/tmp/vzn_r7.txt" as *u8, "VIZSLA-NOTIFY-FEED kind=birthday notifications=2" as *u8) == 1 { 236 if ng_has("/tmp/vzn_r7.txt" as *u8, "kind=event" as *u8) == 0 { r = 1 } 237 } 238 } 239 pass = pass + ng_row("feed-kind-filter" as *u8, r) 240 241 // row 8: email compose 242 let rc8: i64 = ng_runv(ntf, ng_args("email" as *u8, cpfx, "/tmp/vzn_ct.txt" as *u8, "2026-07-08" as *u8, "6,0" as *u8, "vizsla@jasonewest.com" as *u8, "you@example.com" as *u8, "/tmp/vzn_out.eml" as *u8), "/tmp/vzn_r8.txt" as *u8) 243 r = 0 244 if rc8 == 0 { 245 if ng_has("/tmp/vzn_r8.txt" as *u8, "VIZSLA-NOTIFY-EMAIL today=2026-07-08 reminders=3" as *u8) == 1 { 246 if ng_has("/tmp/vzn_out.eml" as *u8, "From: vizsla@jasonewest.com" as *u8) == 1 { 247 if ng_has("/tmp/vzn_out.eml" as *u8, "To: you@example.com" as *u8) == 1 { 248 if ng_has("/tmp/vzn_out.eml" as *u8, "Subject: Your reminders for 2026-07-08" as *u8) == 1 { r = 1 } 249 } 250 } 251 } 252 } 253 pass = pass + ng_row("email-compose" as *u8, r) 254 255 // row 9: valid RFC5322 Date header (DOW math end-to-end: 2026-07-08 = Wednesday) 256 r = ng_has("/tmp/vzn_out.eml" as *u8, "Date: Wed, 08 Jul 2026 09:00:00 +0000" as *u8) 257 pass = pass + ng_row("email-date-header" as *u8, r) 258 259 // row 10: the digest body carries the reminders 260 r = 0 261 if ng_has("/tmp/vzn_out.eml" as *u8, "Nishi Vizsla reminders:" as *u8) == 1 { 262 if ng_has("/tmp/vzn_out.eml" as *u8, "* Mom (birthday) on 2026-07-14 -- in 6 days" as *u8) == 1 { r = 1 } 263 } 264 pass = pass + ng_row("email-body-bullet" as *u8, r) 265 266 // row 11: feed determinism 267 ng_runv(ntf, ng_args("feed" as *u8, npfx, "-" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_r11.txt" as *u8) 268 r = ng_fileeq("/tmp/vzn_r6.txt" as *u8, "/tmp/vzn_r11.txt" as *u8) 269 pass = pass + ng_row("feed-determinism" as *u8, r) 270 271 // row 12: bad today (negative control) 272 let rc12: i64 = ng_runv(ntf, ng_args("deliver" as *u8, npfx, cpfx, "/tmp/vzn_ct.txt" as *u8, "2026-13-99" as *u8, "6,0" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_r12.txt" as *u8) 273 r = 0 274 if rc12 == 1 { r = 1 } 275 pass = pass + ng_row("loud-fail-bad-today" as *u8, r) 276 277 // row 13: bad leads propagate from remind (negative control) 278 let rc13: i64 = ng_runv(ntf, ng_args("deliver" as *u8, npfx, cpfx, "/tmp/vzn_ct.txt" as *u8, "2026-07-08" as *u8, "x,1" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzn_r13.txt" as *u8) 279 r = 0 280 if rc13 == 1 { r = 1 } 281 pass = pass + ng_row("loud-fail-bad-leads" as *u8, r) 282 283 let permil: i64 = (pass * 1000) / 13 284 let logfd: i64 = sys_openat_append("knowledge/status/vizsla_gate.log" as *u8, 0x1a4) 285 var fdi: i64 = 0 286 while fdi < 2 { 287 var fd: i64 = 1 288 if fdi == 1 { fd = logfd } 289 if fd > 0 { 290 let line: *u8 = sys_mmap(256) 291 var o: i64 = 0 292 o = ng_cat(line, o, "VIZSLA-NOTIFY-GATE epoch=" as *u8) 293 o = ng_catn(line, o, sys_now_realtime_sec()) 294 o = ng_cat(line, o, " rows=13 pass=" as *u8) 295 o = ng_catn(line, o, pass) 296 o = ng_cat(line, o, " permil=" as *u8) 297 o = ng_catn(line, o, permil) 298 if pass == 13 { 299 o = ng_cat(line, o, " verdict=GREEN\n" as *u8) 300 } else { 301 o = ng_cat(line, o, " verdict=RED\n" as *u8) 302 } 303 sys_write(fd, line, o) 304 } 305 fdi = fdi + 1 306 } 307 if logfd > 0 { sys_close(logfd) } 308 if pass == 13 { return 0 } 309 return 1 310}