code wiki / _hdl_build / nx_vizsla_digest_gate.nx

nx_vizsla_digest_gate.nx source

↩ module page · 366 lines · 18800 B

1// nx_vizsla_digest_gate.nx -- VIZSLA V5 gate: the daily DIGEST composes the 2// blessed nx_vizsla_relate (brief) + nx_vizsla_notes (draftdue) over fixture 3// data and is proven to consolidate + aggregate them correctly. No mocks: it 4// loads real seg_store fixtures via the real organs and runs the real digest. 5// 6// fixtures (today=2026-06-14): 7// relate: mom(inner,06-20) alex(close,03-15) sam(network,12-01) pat(close,-); 8// TOUCH mom 06-10, alex 02-01; OBLIG OWE alex book-loan, DUE pat loan-50; 9// THANKS mom 06-12, alex 05-01. 10// brief => followups=3 (alex DUE, sam/pat NEW), birthdays=1 (mom in 6d), 11// thankyous=2 (mom PENDING, alex OVERDUE), obligations=2. 12// notes: e1 mom birthday 06-20, e2 alex surgery 07-01, e3 sam wedding 06-10; 13// n1 birthday BEFORE 7, n2 surgery BEFORE 3, n3 wedding AFTER 2; 14// occasions: birthday win 7, wedding win 90 -> n1 DUE + n3 DUE => drafted=2. 15// => VIZSLA-DIGEST-VERDICT followups=3 birthdays=1 thankyous=2 obligations=2 notes_drafted=2 16// 17// Rows: 18// 1 loud-fail-missing-conf digest on absent conf => exit 1 19// 2 loud-fail-missing-key conf missing NOTES_PREFIX => exit 1 20// 3 digest-relationships FOLLOWUP alex + BIRTHDAY mom present 21// 4 digest-notes-drafts the wedding draft prose present 22// 5 digest-verdict-aggregates consolidated verdict 3/1/2/2 + notes_drafted=2 23// 6 digest-determinism byte-identical twice 24// Evidence: VIZSLA-DIGEST-GATE -> stdout + knowledge/status/vizsla_gate.log; exit 0 iff 6/6. 25// Tamper: bogus instrument argv[1] => all rows FAIL => RED. 26// spec: knowledge/specs/2026-06-10-nishi-vizsla-ladder.md license_tier: ORIGINAL 27import "nx_syscalls.nx" 28import "nx_gate_verdict.nx" 29 30func rg_slen(s: *u8) -> i64 { 31 var n: i64 = 0 32 while s[n] != (0 as u8) { n = n + 1 } 33 return n 34} 35 36func rg_p(s: *u8) -> i64 { 37 sys_write(1, s, rg_slen(s)) 38 return 0 39} 40 41func rg_cat(dst: *u8, off: i64, s: *u8) -> i64 { 42 var i: i64 = 0 43 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 } 44 return off + i 45} 46 47func rg_catn(dst: *u8, off: i64, v: i64) -> i64 { 48 var o: i64 = off 49 var m: i64 = v 50 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m } 51 let t: *u8 = sys_mmap(28) 52 var k: i64 = 0 53 if m == 0 { t[0] = 48 as u8; k = 1 } 54 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 55 var i: i64 = 0 56 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 } 57 return o + k 58} 59 60func rg_write(path: *u8, content: *u8) -> i64 { 61 let fd: i64 = sys_openat_wr(path, 0x1a4) 62 if fd < 0 { return 0 - 1 } 63 sys_write(fd, content, rg_slen(content)) 64 sys_close(fd) 65 return 0 66} 67 68func rg_readall(path: *u8, szout: *i64) -> *u8 { 69 let fd: i64 = sys_openat_rd(path) 70 if fd < 0 { szout[0] = 0 - 1; return 0 as *u8 } 71 let sz: i64 = sys_lseek(fd, 0, 2) 72 sys_lseek(fd, 0, 0) 73 let buf: *u8 = sys_mmap(sz + 64) 74 var got: i64 = 0 75 var n: i64 = 1 76 while n > 0 { 77 n = sys_read(fd, (buf as i64 + got) as *u8, 65536) 78 if n > 0 { got = got + n } 79 } 80 sys_close(fd) 81 szout[0] = got 82 return buf 83} 84 85func rg_run(elf: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, outpath: *u8) -> i64 { 86 let pid: i64 = sys_fork() 87 if pid == 0 { 88 if (outpath as i64) != 0 { 89 let ofd: i64 = sys_openat_wr(outpath, 0x1a4) 90 if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) } 91 } 92 let argv: *i64 = sys_mmap(64) as *i64 93 argv[0] = elf as i64 94 var i: i64 = 1 95 if (a1 as i64) != 0 { argv[i] = a1 as i64; i = i + 1 } 96 if (a2 as i64) != 0 { argv[i] = a2 as i64; i = i + 1 } 97 if (a3 as i64) != 0 { argv[i] = a3 as i64; i = i + 1 } 98 if (a4 as i64) != 0 { argv[i] = a4 as i64; i = i + 1 } 99 argv[i] = 0 100 let envp: *i64 = sys_mmap(16) as *i64 101 envp[0] = 0 102 sys_execve(elf, argv, envp) 103 sys_exit(127) 104 } 105 let st: *i64 = sys_mmap(16) as *i64 106 sys_wait4(pid, st, 0) 107 let sig: i64 = st[0] & 0x7f 108 if sig != 0 { return 128 + sig } 109 return (st[0] >> 8) & 0xff 110} 111 112func rg_has(path: *u8, needle: *u8) -> i64 { 113 let szp: *i64 = sys_mmap(16) as *i64 114 let b: *u8 = rg_readall(path, szp) 115 let sz: i64 = szp[0] 116 let n: i64 = rg_slen(needle) 117 if sz < n { return 0 } 118 var i: i64 = 0 119 while i + n <= sz { 120 var ok: i64 = 1 121 var j: i64 = 0 122 while j < n { 123 if b[i + j] != needle[j] { ok = 0; j = n } else { j = j + 1 } 124 } 125 if ok == 1 { return 1 } 126 i = i + 1 127 } 128 return 0 129} 130 131func rg_fileeq(p1: *u8, p2: *u8) -> i64 { 132 let s1: *i64 = sys_mmap(16) as *i64 133 let s2: *i64 = sys_mmap(16) as *i64 134 let b1: *u8 = rg_readall(p1, s1) 135 let b2: *u8 = rg_readall(p2, s2) 136 if s1[0] != s2[0] { return 0 } 137 if s1[0] <= 0 { return 0 } 138 var i: i64 = 0 139 while i < s1[0] { 140 if b1[i] != b2[i] { return 0 } 141 i = i + 1 142 } 143 return 1 144} 145 146func rg_row(name: *u8, pass: i64) -> i64 { 147 rg_p("ROW " as *u8) 148 rg_p(name) 149 if pass == 1 { rg_p(" PASS\n" as *u8) } else { rg_p(" FAIL\n" as *u8) } 150 return pass 151} 152 153func main(argc: i64, argv: *i64) -> i64 { 154 rg_p("=== VIZSLA DIGEST GATE: the daily digest composes brief + notes-due ===\n" as *u8) 155 var rb: *u8 = "buildroot/_build/nx_vizsla_digest.sov.elf" as *u8 156 if argc > 1 { rb = argv[1] as *u8 } 157 let pr: i64 = sys_openat_rd(rb) 158 if pr >= 0 { sys_close(pr) } 159 else { 160 rg_p(" instrument missing -> rebuilding via durable runner\n" as *u8) 161 rg_run("_offc/nx_sov_build_run.elf" as *u8, "nx_vizsla_digest" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, "/tmp/dgg_rebuild.out" as *u8) 162 } 163 164 // epoch-unique virgin store prefixes 165 let rpfx: *u8 = sys_mmap(128) 166 var ro: i64 = 0 167 ro = rg_cat(rpfx, ro, "/tmp/dggR" as *u8); ro = rg_catn(rpfx, ro, sys_now_us()); ro = rg_cat(rpfx, ro, "-" as *u8); rpfx[ro] = 0 as u8 168 let npfx: *u8 = sys_mmap(128) 169 var no: i64 = 0 170 no = rg_cat(npfx, no, "/tmp/dggN" as *u8); no = rg_catn(npfx, no, sys_now_us()); no = rg_cat(npfx, no, "-" as *u8); npfx[no] = 0 as u8 171 172 rg_write("/tmp/dgg_contacts.txt" as *u8, "CONF soon_days 14\nTIER inner 30\nTIER close 90\nTIER network 180\nCONTACT mom Mom inner 06-20\nCONTACT alex Alex-Mentor close 03-15\nCONTACT sam Sam-Colleague network 12-01\nCONTACT pat Pat-Friend close -\n" as *u8) 173 rg_write("/tmp/dgg_relog.txt" as *u8, "TOUCH 2026-06-10 mom weekly-call\nTOUCH 2026-02-01 alex lunch\nOBLIGATION 2026-05-01 OWE alex book-loan 0 borrowed-book\nOBLIGATION 2026-05-05 DUE pat loan-50 5000 lent-cash\nTHANKS 2026-06-12 mom birthday-gift\nTHANKS 2026-05-01 alex referral\n" as *u8) 174 rg_write("/tmp/dgg_nlog.txt" as *u8, "EVENT e1 2026-06-20 mom birthday card-gift\nEVENT e2 2026-07-01 alex surgery recovery\nEVENT e3 2026-06-10 sam wedding congrats\nNOTE n1 e1 BEFORE 7 card signature:img-mom\nNOTE n2 e2 BEFORE 3 text voice:vm-alex\nNOTE n3 e3 AFTER 2 card handwritten:scan-sam\n" as *u8) 175 rg_write("/tmp/dgg_nconf.txt" as *u8, "CONF window_days 3\nOCCASION birthday BEFORE 3 7 arrive-by-the-day\nOCCASION wedding AFTER 0 90 thank-you-within-3-months\nOCCASION surgery BEFORE 2 7 before-procedure\n" as *u8) 176 rg_write("/tmp/dgg_ntmpl.txt" as *u8, "TMPL birthday BEFORE Happy early birthday, {contact}! Wishing you a wonderful day on {date}. Enclosed: {personal}\nTMPL wedding AFTER Dear {contact}, thank you for including us in your wedding -- it was a joy. Enclosed: {personal}\n" as *u8) 177 178 // load fixtures into the two stores via the blessed organs 179 rg_run("_offc/nx_vizsla_relate.elf" as *u8, "load" as *u8, "/tmp/dgg_relog.txt" as *u8, rpfx, "6001" as *u8, "/tmp/dgg_rl.txt" as *u8) 180 rg_run("_offc/nx_vizsla_notes.elf" as *u8, "load" as *u8, "/tmp/dgg_nlog.txt" as *u8, npfx, "6001" as *u8, "/tmp/dgg_nl.txt" as *u8) 181 // bills store + fixtures (for the optional bills section) 182 let bpfx: *u8 = sys_mmap(128) 183 var bpo: i64 = 0 184 bpo = rg_cat(bpfx, bpo, "/tmp/dggB" as *u8); bpo = rg_catn(bpfx, bpo, sys_now_us()); bpo = rg_cat(bpfx, bpo, "-" as *u8); bpfx[bpo] = 0 as u8 185 rg_write("/tmp/dgg_bills.txt" as *u8, "CONF soon_days 7\nBILL rent Landlord 180000 1 MONTHLY MANUAL\nBILL electric PowerCo 12000 15 MONTHLY MANUAL\nBILL netflix Netflix 1599 20 MONTHLY AUTO\nBILL water CityWater 4500 10 MONTHLY MANUAL\nBILL phone TelCo 6000 25 MONTHLY MANUAL\n" as *u8) 186 rg_write("/tmp/dgg_bllog.txt" as *u8, "PAID 2026-06-02 rent 180000 june-rent\nPAID 2026-05-20 netflix 1599 may-auto\n" as *u8) 187 rg_run("_offc/nx_vizsla_bills.elf" as *u8, "load" as *u8, "/tmp/dgg_bllog.txt" as *u8, bpfx, "5001" as *u8, "/tmp/dgg_bl.txt" as *u8) 188 189 // good digest.conf (built with the generated prefixes) 190 let conf: *u8 = sys_mmap(2048) 191 var co: i64 = 0 192 co = rg_cat(conf, co, "RELATE_PREFIX " as *u8); co = rg_cat(conf, co, rpfx); co = rg_cat(conf, co, "\n" as *u8) 193 co = rg_cat(conf, co, "RELATE_CONTACTS /tmp/dgg_contacts.txt\n" as *u8) 194 co = rg_cat(conf, co, "NOTES_PREFIX " as *u8); co = rg_cat(conf, co, npfx); co = rg_cat(conf, co, "\n" as *u8) 195 co = rg_cat(conf, co, "NOTES_CONF /tmp/dgg_nconf.txt\n" as *u8) 196 co = rg_cat(conf, co, "NOTES_TEMPLATES /tmp/dgg_ntmpl.txt\n" as *u8) 197 conf[co] = 0 as u8 198 rg_write("/tmp/dgg.conf" as *u8, conf) 199 // a second conf that ALSO enables bills (= the good conf + BILLS keys) 200 let bconf: *u8 = sys_mmap(2048) 201 var bco: i64 = 0 202 bco = rg_cat(bconf, bco, conf) 203 bco = rg_cat(bconf, bco, "BILLS_PREFIX " as *u8); bco = rg_cat(bconf, bco, bpfx); bco = rg_cat(bconf, bco, "\n" as *u8) 204 bco = rg_cat(bconf, bco, "BILLS_FILE /tmp/dgg_bills.txt\n" as *u8) 205 bconf[bco] = 0 as u8 206 rg_write("/tmp/dgg_bills.conf" as *u8, bconf) 207 // engagement-partner fixtures: calendar + plan + venue stores via the BLESSED organs 208 let cpfx: *u8 = sys_mmap(128) 209 var cpo: i64 = 0 210 cpo = rg_cat(cpfx, cpo, "/tmp/dggC" as *u8); cpo = rg_catn(cpfx, cpo, sys_now_us()); cpo = rg_cat(cpfx, cpo, "-" as *u8); cpfx[cpo] = 0 as u8 211 rg_write("/tmp/dgg_cal.txt" as *u8, "EVENT mtg 2026-06-14 600 60 standup-mtg\n" as *u8) 212 rg_run("_offc/nx_vizsla_calendar.elf" as *u8, "load" as *u8, "/tmp/dgg_cal.txt" as *u8, cpfx, "7001" as *u8, "/tmp/dgg_cl.txt" as *u8) 213 let ppfx: *u8 = sys_mmap(128) 214 var ppo: i64 = 0 215 ppo = rg_cat(ppfx, ppo, "/tmp/dggP" as *u8); ppo = rg_catn(ppfx, ppo, sys_now_us()); ppo = rg_cat(ppfx, ppo, "-" as *u8); ppfx[ppo] = 0 as u8 216 rg_write("/tmp/dgg_plan.txt" as *u8, "TASK dg venue2 jason 2026-06-16 60 5 - book-venue2\n" as *u8) 217 rg_run("_offc/nx_vizsla_plan.elf" as *u8, "load" as *u8, "/tmp/dgg_plan.txt" as *u8, ppfx, "7002" as *u8, "/tmp/dgg_pl.txt" as *u8) 218 let vpfx: *u8 = sys_mmap(128) 219 var vpo: i64 = 0 220 vpo = rg_cat(vpfx, vpo, "/tmp/dggV" as *u8); vpo = rg_catn(vpfx, vpo, sys_now_us()); vpo = rg_cat(vpfx, vpo, "-" as *u8); vpfx[vpo] = 0 as u8 221 rg_write("/tmp/dgg_ven.txt" as *u8, "REQ dgparty 10 20000 2026-06-20 600 120\nVENUE dgparty spot-x 12 15000 555-9 corner-hall\nSTAGE 2026-06-10 dgparty spot-x contacted\n" as *u8) 222 rg_run("_offc/nx_vizsla_venue.elf" as *u8, "load" as *u8, "/tmp/dgg_ven.txt" as *u8, vpfx, "7003" as *u8, "/tmp/dgg_vl.txt" as *u8) 223 // the ENGAGE conf = good conf + calendar/reminders/plan/venue sections 224 let econf: *u8 = sys_mmap(4096) 225 var eco: i64 = 0 226 eco = rg_cat(econf, eco, conf) 227 eco = rg_cat(econf, eco, "CAL_PREFIX " as *u8); eco = rg_cat(econf, eco, cpfx); eco = rg_cat(econf, eco, "\n" as *u8) 228 eco = rg_cat(econf, eco, "REMIND_CONTACTS /tmp/dgg_contacts.txt\n" as *u8) 229 eco = rg_cat(econf, eco, "REMIND_LEADS 6,0\n" as *u8) 230 eco = rg_cat(econf, eco, "PLAN_PREFIX " as *u8); eco = rg_cat(econf, eco, ppfx); eco = rg_cat(econf, eco, "\n" as *u8) 231 eco = rg_cat(econf, eco, "PLAN_NAME dg\n" as *u8) 232 eco = rg_cat(econf, eco, "VENUE_PREFIX " as *u8); eco = rg_cat(econf, eco, vpfx); eco = rg_cat(econf, eco, "\n" as *u8) 233 eco = rg_cat(econf, eco, "VENUE_EVENT dgparty\n" as *u8) 234 econf[eco] = 0 as u8 235 rg_write("/tmp/dgg_engage.conf" as *u8, econf) 236 237 // bad conf: omit NOTES_PREFIX 238 let bad: *u8 = sys_mmap(2048) 239 var bo: i64 = 0 240 bo = rg_cat(bad, bo, "RELATE_PREFIX " as *u8); bo = rg_cat(bad, bo, rpfx); bo = rg_cat(bad, bo, "\n" as *u8) 241 bo = rg_cat(bad, bo, "RELATE_CONTACTS /tmp/dgg_contacts.txt\n" as *u8) 242 bo = rg_cat(bad, bo, "NOTES_CONF /tmp/dgg_nconf.txt\n" as *u8) 243 bo = rg_cat(bad, bo, "NOTES_TEMPLATES /tmp/dgg_ntmpl.txt\n" as *u8) 244 bad[bo] = 0 as u8 245 rg_write("/tmp/dgg_bad.conf" as *u8, bad) 246 247 var pass: i64 = 0 248 var r: i64 = 0 249 250 // row 1: loud-fail on missing conf 251 let rc1: i64 = rg_run(rb, "digest" as *u8, "/tmp/dgg_NOPE.conf" as *u8, "2026-06-14" as *u8, 0 as *u8, "/tmp/dgg_o1.txt" as *u8) 252 r = 0 253 if rc1 == 1 { r = 1 } 254 pass = pass + rg_row("loud-fail-missing-conf" as *u8, r) 255 256 // row 2: loud-fail on a conf missing a required key 257 let rc2: i64 = rg_run(rb, "digest" as *u8, "/tmp/dgg_bad.conf" as *u8, "2026-06-14" as *u8, 0 as *u8, "/tmp/dgg_o2.txt" as *u8) 258 r = 0 259 if rc2 == 1 { r = 1 } 260 pass = pass + rg_row("loud-fail-missing-key" as *u8, r) 261 262 // row 3-6: the real digest 263 let rc3: i64 = rg_run(rb, "digest" as *u8, "/tmp/dgg.conf" as *u8, "2026-06-14" as *u8, 0 as *u8, "/tmp/dgg_dig.txt" as *u8) 264 r = 0 265 if rc3 == 0 { 266 if rg_has("/tmp/dgg_dig.txt" as *u8, " FOLLOWUP contact=alex days=133 (DUE)" as *u8) == 1 { 267 if rg_has("/tmp/dgg_dig.txt" as *u8, " BIRTHDAY contact=mom on=06-20 in=6d" as *u8) == 1 { r = 1 } 268 } 269 } 270 pass = pass + rg_row("digest-relationships" as *u8, r) 271 272 r = rg_has("/tmp/dgg_dig.txt" as *u8, "Dear sam, thank you for including us in your wedding" as *u8) 273 pass = pass + rg_row("digest-notes-drafts" as *u8, r) 274 275 r = rg_has("/tmp/dgg_dig.txt" as *u8, "VIZSLA-DIGEST-VERDICT followups=3 birthdays=1 thankyous=2 obligations=2 notes_drafted=2" as *u8) 276 pass = pass + rg_row("digest-verdict-aggregates" as *u8, r) 277 278 rg_run(rb, "digest" as *u8, "/tmp/dgg.conf" as *u8, "2026-06-14" as *u8, 0 as *u8, "/tmp/dgg_dig2.txt" as *u8) 279 r = rg_fileeq("/tmp/dgg_dig.txt" as *u8, "/tmp/dgg_dig2.txt" as *u8) 280 pass = pass + rg_row("digest-determinism" as *u8, r) 281 282 // row 7: the bills-enabled conf adds a BILLS section 283 let rc7: i64 = rg_run(rb, "digest" as *u8, "/tmp/dgg_bills.conf" as *u8, "2026-06-14" as *u8, 0 as *u8, "/tmp/dgg_digb.txt" as *u8) 284 r = 0 285 if rc7 == 0 { 286 if rg_has("/tmp/dgg_digb.txt" as *u8, "VIZSLA-BILL id=water payee=CityWater amount=4500 due=2026-06-10 autopay=MANUAL state=OVERDUE" as *u8) == 1 { r = 1 } 287 } 288 pass = pass + rg_row("digest-bills-section" as *u8, r) 289 290 // row 8: the consolidated verdict aggregates bills (due/overdue/owed) 291 r = rg_has("/tmp/dgg_digb.txt" as *u8, "VIZSLA-DIGEST-VERDICT followups=3 birthdays=1 thankyous=2 obligations=2 notes_drafted=2 bills_due=2 bills_overdue=1 bills_owed_cents=24099" as *u8) 292 pass = pass + rg_row("digest-bills-verdict" as *u8, r) 293 294 // row 9: bills are OPTIONAL -- the no-bills conf produces NO bills fields 295 r = 0 296 if rg_has("/tmp/dgg_dig.txt" as *u8, "bills_owed_cents" as *u8) == 0 { 297 if rg_has("/tmp/dgg_dig.txt" as *u8, "notes_drafted=2" as *u8) == 1 { r = 1 } 298 } 299 pass = pass + rg_row("digest-bills-optional" as *u8, r) 300 301 // rows 10-14: the ENGAGEMENT-PARTNER digest (calendar + reminders + plan + venue) 302 let rc10: i64 = rg_run(rb, "digest" as *u8, "/tmp/dgg_engage.conf" as *u8, "2026-06-14" as *u8, 0 as *u8, "/tmp/dgg_dige.txt" as *u8) 303 r = 0 304 if rc10 == 0 { 305 if rg_has("/tmp/dgg_dige.txt" as *u8, "== CALENDAR TODAY ==" as *u8) == 1 { 306 if rg_has("/tmp/dgg_dige.txt" as *u8, "VIZSLA-CAL-EVENT date=2026-06-14 start=10:00 end=11:00 dur=60 id=mtg title=standup-mtg" as *u8) == 1 { r = 1 } 307 } 308 } 309 pass = pass + rg_row("digest-engage-calendar" as *u8, r) 310 311 r = 0 312 if rg_has("/tmp/dgg_dige.txt" as *u8, "VIZSLA-REM-DUE kind=birthday id=mom date=2026-06-20 in=6 title=Mom" as *u8) == 1 { 313 if rg_has("/tmp/dgg_dige.txt" as *u8, "VIZSLA-REM-DUE kind=event id=mtg date=2026-06-14 in=0 title=standup-mtg" as *u8) == 1 { r = 1 } 314 } 315 pass = pass + rg_row("digest-engage-reminders" as *u8, r) 316 317 r = 0 318 if rg_has("/tmp/dgg_dige.txt" as *u8, "VIZSLA-PLAN-TASK plan=dg id=venue2 owner=jason due=2026-06-16 state=READY urg=4 imp=5 score=50 late=0 title=book-venue2" as *u8) == 1 { 319 if rg_has("/tmp/dgg_dige.txt" as *u8, "VIZSLA-VEN-CAND event=dgparty id=spot-x stage=contacted cap=12 cost=15000 score=85 over_budget=0 too_small=0 contact=555-9 name=corner-hall" as *u8) == 1 { r = 1 } 320 } 321 pass = pass + rg_row("digest-engage-plan-venue" as *u8, r) 322 323 r = rg_has("/tmp/dgg_dige.txt" as *u8, "VIZSLA-DIGEST-VERDICT followups=3 birthdays=1 thankyous=2 obligations=2 notes_drafted=2 cal_events=1 cal_free_min=1380 reminders_due=2 reminders_birthdays=1 plan_ready=1 plan_blocked=0 plan_late=0 venues=1 venue_booked=0" as *u8) 324 pass = pass + rg_row("digest-engage-verdict" as *u8, r) 325 326 r = 0 327 if rg_has("/tmp/dgg_dig.txt" as *u8, "cal_events=" as *u8) == 0 { 328 if rg_has("/tmp/dgg_dig.txt" as *u8, "reminders_due=" as *u8) == 0 { r = 1 } 329 } 330 pass = pass + rg_row("digest-engage-optional" as *u8, r) 331 332 let permil: i64 = (pass * 1000) / 14 333 let logfd: i64 = sys_openat_append("knowledge/status/vizsla_gate.log" as *u8, 0x1a4) 334 var fdi: i64 = 0 335 while fdi < 2 { 336 var fd: i64 = 1 337 if fdi == 1 { fd = logfd } 338 if fd > 0 { 339 let line: *u8 = sys_mmap(256) 340 var o: i64 = 0 341 o = rg_cat(line, o, "VIZSLA-DIGEST-GATE epoch=" as *u8) 342 o = rg_catn(line, o, sys_now_realtime_sec()) 343 o = rg_cat(line, o, " rows=14 pass=" as *u8) 344 o = rg_catn(line, o, pass) 345 o = rg_cat(line, o, " permil=" as *u8) 346 o = rg_catn(line, o, permil) 347 if pass == 14 { 348 o = rg_cat(line, o, " verdict=GREEN\n" as *u8) 349 } else { 350 o = rg_cat(line, o, " verdict=RED\n" as *u8) 351 } 352 sys_write(fd, line, o) 353 } 354 fdi = fdi + 1 355 } 356 if logfd > 0 { sys_close(logfd) } 357 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 358 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 359 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 360 let ctr__dry: *i64 = gv_ctr() 361 ctr__dry[0] = pass 362 ctr__dry[1] = 14 363 let rc__dry: i64 = gv_verdict("VIZSLA-DIGEST-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 364 sys_exit(rc__dry) 365 return rc__dry 366}