code wiki / _hdl_build / nx_vizsla_remind_gate.nx
nx_vizsla_remind_gate.nx source
↩ module page · 303 lines · 12634 B
1// nx_vizsla_remind_gate.nx -- VIZSLA REMINDER gate: lead-time due scan + sent-once ledger
2// proven against hand-computed fixtures. COMPOSITION: the calendar side is loaded through the
3// REAL nx_vizsla_calendar organ; birthdays come from the relate CONTACT file format.
4//
5// calendar: launch 07-21, soon 07-08, far 08-30(out), RRULE standup WEEKLY x4 (07-01..07-22)
6// contacts: mom 07-14, dad 07-08, alex -, leap 02-29
7// A) today=2026-07-07 leads=14,7,1,0 -> due=5 (launch@14, soon@1, standup-0708@1, mom@7, dad@1)
8// B) today=2026-07-21 -> due=2 (launch@0 day-of, standup-0722@1)
9// C) today=2027-02-27 leads=1, no calendar -> leap birthday clamps to 2027-02-28 -> due@1
10// D) mark launch sent -> re-mark new=0 -> B re-run with ledger: launch SENT-SKIPPED, due=1
11//
12// Rows: 1 fixture-loads 2 due-verdict 3 due-event-lead14 4 due-recurring 5 due-birthday7
13// 6 due-birthday1 7 due-day-of 8 leap-clamp 9 mark-sent 10 mark-idempotent
14// 11 sent-skipped 12 due-determinism 13 loud-fail-bad-today[neg] 14 loud-fail-bad-leads[neg]
15// Evidence: VIZSLA-REM-GATE -> stdout + knowledge/status/vizsla_gate.log; exit 0 iff 14/14.
16// spec: knowledge/research/2026-06-22-vizsla-sclass-roadmap.md license_tier: ORIGINAL
17import "nx_syscalls.nx"
18
19func rg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
20func rg_p(s: *u8) -> i64 { sys_write(1, s, rg_slen(s)); return 0 }
21
22func rg_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 rg_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 rg_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, rg_slen(content))
45 sys_close(fd)
46 return 0
47}
48
49func rg_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 rg_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 rg_has(path: *u8, needle: *u8) -> i64 {
97 let szp: *i64 = sys_mmap(16) as *i64
98 let b: *u8 = rg_readall(path, szp)
99 let sz: i64 = szp[0]
100 let n: i64 = rg_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 rg_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 = rg_readall(p1, s1)
119 let b2: *u8 = rg_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 rg_row(name: *u8, pass: i64) -> i64 {
131 rg_p("ROW " as *u8)
132 rg_p(name)
133 if pass == 1 { rg_p(" PASS\n" as *u8) } else { rg_p(" FAIL\n" as *u8) }
134 return pass
135}
136
137func rg_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 rg_ensure(elf: *u8, organ: *u8) -> i64 {
152 let pr: i64 = sys_openat_rd(elf)
153 if pr >= 0 { sys_close(pr); return 0 }
154 rg_p(" instrument missing -> rebuilding via durable runner\n" as *u8)
155 rg_runv("_offc/nx_sov_build_run.elf" as *u8, rg_args(organ, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzr_rebuild.out" as *u8)
156 return 0
157}
158
159func rg_mkpfx(tag: *u8, us: i64) -> *u8 {
160 let pfx: *u8 = sys_mmap(128)
161 var po: i64 = 0
162 po = rg_cat(pfx, po, tag)
163 po = rg_catn(pfx, po, us)
164 po = rg_cat(pfx, po, "-" as *u8)
165 pfx[po] = 0 as u8
166 return pfx
167}
168
169func main(argc: i64, argv: *i64) -> i64 {
170 rg_p("=== VIZSLA REMIND GATE: lead-time due scan + sent-once ledger KATs ===\n" as *u8)
171 let rem: *u8 = "/tmp/nx_vizsla_remind.sov.elf" as *u8
172 let cal: *u8 = "/tmp/nx_vizsla_calendar.sov.elf" as *u8
173 rg_ensure(rem, "nx_vizsla_remind" as *u8)
174 rg_ensure(cal, "nx_vizsla_calendar" as *u8)
175
176 let us: i64 = sys_now_us()
177 let pfxR: *u8 = rg_mkpfx("/tmp/vzrR" as *u8, us)
178 let pfxS: *u8 = rg_mkpfx("/tmp/vzrS" as *u8, us)
179
180 rg_write("/tmp/vzr_cal.txt" as *u8, "EVENT launch 2026-07-21 600 90 team-launch\nEVENT soon 2026-07-08 540 30 checkin\nEVENT far 2026-08-30 540 30 too-far\nRRULE standup 2026-07-01 540 30 WEEKLY 1 4 weekly-standup\n" as *u8)
181 rg_write("/tmp/vzr_ct.txt" as *u8, "TIER inner 7\nCONTACT mom Mom inner 07-14\nCONTACT dad Dad inner 07-08\nCONTACT alex Alex inner -\nCONTACT leap Leapy inner 02-29\n" as *u8)
182
183 var pass: i64 = 0
184 var r: i64 = 0
185
186 // row 1: calendar fixture loads through the real organ
187 let rc1: i64 = rg_runv(cal, rg_args("load" as *u8, "/tmp/vzr_cal.txt" as *u8, pfxR, "6601" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzr_l1.txt" as *u8)
188 r = 0
189 if rc1 == 0 {
190 if rg_has("/tmp/vzr_l1.txt" as *u8, "VIZSLA-CAL-LOAD scanned=4 new=4" as *u8) == 1 { r = 1 }
191 }
192 pass = pass + rg_row("fixture-loads" as *u8, r)
193
194 // rows 2-6: due at 2026-07-07
195 let rc2: i64 = rg_runv(rem, rg_args("due" as *u8, pfxR, "/tmp/vzr_ct.txt" as *u8, "2026-07-07" as *u8, "14,7,1,0" as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzr_r2.txt" as *u8)
196 r = 0
197 if rc2 == 0 {
198 if rg_has("/tmp/vzr_r2.txt" as *u8, "VIZSLA-REM-VERDICT today=2026-07-07 maxlead=14 due=5 due_events=3 due_birthdays=2 skipped_sent=0" as *u8) == 1 { r = 1 }
199 }
200 pass = pass + rg_row("due-verdict" as *u8, r)
201
202 r = rg_has("/tmp/vzr_r2.txt" as *u8, "VIZSLA-REM-DUE kind=event id=launch date=2026-07-21 in=14 title=team-launch" as *u8)
203 pass = pass + rg_row("due-event-lead14" as *u8, r)
204
205 r = rg_has("/tmp/vzr_r2.txt" as *u8, "VIZSLA-REM-DUE kind=event id=standup date=2026-07-08 in=1 title=weekly-standup" as *u8)
206 pass = pass + rg_row("due-recurring" as *u8, r)
207
208 r = rg_has("/tmp/vzr_r2.txt" as *u8, "VIZSLA-REM-DUE kind=birthday id=mom date=2026-07-14 in=7 title=Mom" as *u8)
209 pass = pass + rg_row("due-birthday7" as *u8, r)
210
211 r = rg_has("/tmp/vzr_r2.txt" as *u8, "VIZSLA-REM-DUE kind=birthday id=dad date=2026-07-08 in=1 title=Dad" as *u8)
212 pass = pass + rg_row("due-birthday1" as *u8, r)
213
214 // row 7: day-of (lead 0) at 2026-07-21
215 let rc7: i64 = rg_runv(rem, rg_args("due" as *u8, pfxR, "/tmp/vzr_ct.txt" as *u8, "2026-07-21" as *u8, "14,7,1,0" as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzr_r7.txt" as *u8)
216 r = 0
217 if rc7 == 0 {
218 if rg_has("/tmp/vzr_r7.txt" as *u8, "VIZSLA-REM-DUE kind=event id=launch date=2026-07-21 in=0 title=team-launch" as *u8) == 1 {
219 if rg_has("/tmp/vzr_r7.txt" as *u8, "VIZSLA-REM-VERDICT today=2026-07-21 maxlead=14 due=2 due_events=2 due_birthdays=0 skipped_sent=0" as *u8) == 1 { r = 1 }
220 }
221 }
222 pass = pass + rg_row("due-day-of" as *u8, r)
223
224 // row 8: Feb-29 birthday clamps in a non-leap year
225 let rc8: i64 = rg_runv(rem, rg_args("due" as *u8, "-" as *u8, "/tmp/vzr_ct.txt" as *u8, "2027-02-27" as *u8, "1" as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzr_r8.txt" as *u8)
226 r = 0
227 if rc8 == 0 {
228 if rg_has("/tmp/vzr_r8.txt" as *u8, "VIZSLA-REM-DUE kind=birthday id=leap date=2027-02-28 in=1 title=Leapy" as *u8) == 1 { r = 1 }
229 }
230 pass = pass + rg_row("leap-clamp" as *u8, r)
231
232 // rows 9-10: sent ledger mark + idempotence
233 let rc9: i64 = rg_runv(rem, rg_args("mark" as *u8, pfxS, "event" as *u8, "launch" as *u8, "2026-07-21" as *u8, "6602" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzr_r9.txt" as *u8)
234 r = 0
235 if rc9 == 0 {
236 if rg_has("/tmp/vzr_r9.txt" as *u8, "VIZSLA-REM-MARK k=event id=launch date=2026-07-21 new=1" as *u8) == 1 { r = 1 }
237 }
238 pass = pass + rg_row("mark-sent" as *u8, r)
239
240 let rc10: i64 = rg_runv(rem, rg_args("mark" as *u8, pfxS, "event" as *u8, "launch" as *u8, "2026-07-21" as *u8, "6603" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzr_r10.txt" as *u8)
241 r = 0
242 if rc10 == 0 {
243 if rg_has("/tmp/vzr_r10.txt" as *u8, "VIZSLA-REM-MARK k=event id=launch date=2026-07-21 new=0" as *u8) == 1 { r = 1 }
244 }
245 pass = pass + rg_row("mark-idempotent" as *u8, r)
246
247 // row 11: sent notice skipped, others still due
248 let rc11: i64 = rg_runv(rem, rg_args("due" as *u8, pfxR, "/tmp/vzr_ct.txt" as *u8, "2026-07-21" as *u8, "14,7,1,0" as *u8, pfxS, 0 as *u8, 0 as *u8), "/tmp/vzr_r11.txt" as *u8)
249 r = 0
250 if rc11 == 0 {
251 if rg_has("/tmp/vzr_r11.txt" as *u8, "VIZSLA-REM-SENT-SKIP kind=event id=launch date=2026-07-21" as *u8) == 1 {
252 if rg_has("/tmp/vzr_r11.txt" as *u8, "VIZSLA-REM-VERDICT today=2026-07-21 maxlead=14 due=1 due_events=1 due_birthdays=0 skipped_sent=1" as *u8) == 1 {
253 if rg_has("/tmp/vzr_r11.txt" as *u8, "VIZSLA-REM-DUE kind=event id=launch" as *u8) == 0 { r = 1 }
254 }
255 }
256 }
257 pass = pass + rg_row("sent-skipped" as *u8, r)
258
259 // row 12: determinism
260 rg_runv(rem, rg_args("due" as *u8, pfxR, "/tmp/vzr_ct.txt" as *u8, "2026-07-07" as *u8, "14,7,1,0" as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzr_r12.txt" as *u8)
261 r = rg_fileeq("/tmp/vzr_r2.txt" as *u8, "/tmp/vzr_r12.txt" as *u8)
262 pass = pass + rg_row("due-determinism" as *u8, r)
263
264 // row 13: bad today (negative control)
265 let rc13: i64 = rg_runv(rem, rg_args("due" as *u8, pfxR, "/tmp/vzr_ct.txt" as *u8, "2026-13-99" as *u8, "14,7,1,0" as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzr_r13.txt" as *u8)
266 r = 0
267 if rc13 == 1 { r = 1 }
268 pass = pass + rg_row("loud-fail-bad-today" as *u8, r)
269
270 // row 14: bad leads (negative control)
271 let rc14: i64 = rg_runv(rem, rg_args("due" as *u8, pfxR, "/tmp/vzr_ct.txt" as *u8, "2026-07-07" as *u8, "x,1" as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzr_r14.txt" as *u8)
272 r = 0
273 if rc14 == 1 { r = 1 }
274 pass = pass + rg_row("loud-fail-bad-leads" as *u8, r)
275
276 let permil: i64 = (pass * 1000) / 14
277 let logfd: i64 = sys_openat_append("knowledge/status/vizsla_gate.log" as *u8, 0x1a4)
278 var fdi: i64 = 0
279 while fdi < 2 {
280 var fd: i64 = 1
281 if fdi == 1 { fd = logfd }
282 if fd > 0 {
283 let line: *u8 = sys_mmap(256)
284 var o: i64 = 0
285 o = rg_cat(line, o, "VIZSLA-REM-GATE epoch=" as *u8)
286 o = rg_catn(line, o, sys_now_realtime_sec())
287 o = rg_cat(line, o, " rows=14 pass=" as *u8)
288 o = rg_catn(line, o, pass)
289 o = rg_cat(line, o, " permil=" as *u8)
290 o = rg_catn(line, o, permil)
291 if pass == 14 {
292 o = rg_cat(line, o, " verdict=GREEN\n" as *u8)
293 } else {
294 o = rg_cat(line, o, " verdict=RED\n" as *u8)
295 }
296 sys_write(fd, line, o)
297 }
298 fdi = fdi + 1
299 }
300 if logfd > 0 { sys_close(logfd) }
301 if pass == 14 { return 0 }
302 return 1
303}