code wiki / _hdl_build / nx_vizsla_plan_gate.nx
nx_vizsla_plan_gate.nx source
↩ module page · 332 lines · 15241 B
1// nx_vizsla_plan_gate.nx -- VIZSLA PLANNER gate: priority/deps/critical-path/milestones/
2// timeblock proven against HAND-COMPUTED fixtures. COMPOSITION: the timeblock rows load a real
3// calendar via nx_vizsla_calendar and place tasks into ITS free windows.
4//
5// plan "trip" (CONF u4=5 u3=10 u2=30 -- DIFFERENT from the 2/7/30 defaults so the config path is
6// load-bearing: invites at 5 days out grades u4/score48; the default bands would say u3/38):
7// venue jason 07-09 120m imp5 deps - today 07-07 -> READY u4 score50
8// invites maria 07-12 60m imp4 deps venue -> BLOCKED u4 score48
9// food jason 07-20 90m imp3 deps invites -> BLOCKED u2 score26
10// music dave 07-20 45m imp2 deps venue -> BLOCKED u2 score24
11// budget maria 07-05 30m imp5 deps - + DONE marker -> DONE
12// MILE m1 07-15: due<=07-15 = venue,invites,budget -> 3 tasks, 1 done, pct=33
13// critical path: venue(120)>invites(60)>food(90) = 270 min
14// verdict: tasks=5 done=1 ready=1 blocked=3 late=0 pct=20 critical_min=270
15// today=07-10 re-run: venue OVERDUE -> urg5 score60 late=1; verdict late=1
16// plan "day" + jason's calendar (meeting 10:00-12:00), timeblock 07-08 bounds 08:00-22:00:
17// free [480,600)+[720,1320) = 720 min; priority deep(50) email(38) mega(22)
18// deep 120m -> 08:00-10:00; email 60m -> 12:00-13:00; mega 700m -> UNPLACED (no window fits)
19// verdict placed=2 unplaced=1 used_min=180 free_min=720
20// plan "cyc": a<->b dependency cycle -> board exits 1 naming stuck=a,b
21//
22// Rows: 1 plan-load 2 idempotent-reload 3 board-ready-priority 4 board-conf-loadbearing
23// 5 board-done 6 board-verdict 7 critical-path 8 milestone-pct 9 board-overdue
24// 10 timeblock-place-first 11 timeblock-next-window 12 timeblock-verdict
25// 13 cycle-detected[neg] 14 board-determinism 15 loud-fail-bad-date[neg]
26// 16 loud-fail-unknown-plan[neg]
27// Evidence: VIZSLA-PLAN-GATE -> stdout + knowledge/status/vizsla_gate.log; exit 0 iff 16/16.
28// spec: knowledge/research/2026-06-22-vizsla-sclass-roadmap.md license_tier: ORIGINAL
29import "nx_syscalls.nx"
30import "nx_gate_verdict.nx"
31
32func pg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
33func pg_p(s: *u8) -> i64 { sys_write(1, s, pg_slen(s)); return 0 }
34
35func pg_cat(dst: *u8, off: i64, s: *u8) -> i64 {
36 var i: i64 = 0
37 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 }
38 return off + i
39}
40
41func pg_catn(dst: *u8, off: i64, v: i64) -> i64 {
42 var o: i64 = off
43 var m: i64 = v
44 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m }
45 let t: *u8 = sys_mmap(28)
46 var k: i64 = 0
47 if m == 0 { t[0] = 48 as u8; k = 1 }
48 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
49 var i: i64 = 0
50 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 }
51 return o + k
52}
53
54func pg_write(path: *u8, content: *u8) -> i64 {
55 let fd: i64 = sys_openat_wr(path, 0x1a4)
56 if fd < 0 { return 0 - 1 }
57 sys_write(fd, content, pg_slen(content))
58 sys_close(fd)
59 return 0
60}
61
62func pg_readall(path: *u8, szout: *i64) -> *u8 {
63 let fd: i64 = sys_openat_rd(path)
64 if fd < 0 { szout[0] = 0 - 1; return 0 as *u8 }
65 let sz: i64 = sys_lseek(fd, 0, 2)
66 sys_lseek(fd, 0, 0)
67 let buf: *u8 = sys_mmap(sz + 64)
68 var got: i64 = 0
69 var n: i64 = 1
70 while n > 0 {
71 n = sys_read(fd, (buf as i64 + got) as *u8, 65536)
72 if n > 0 { got = got + n }
73 }
74 sys_close(fd)
75 szout[0] = got
76 return buf
77}
78
79func pg_runv(elf: *u8, args: *i64, outpath: *u8) -> i64 {
80 let pid: i64 = sys_fork()
81 if pid == 0 {
82 if (outpath as i64) != 0 {
83 let ofd: i64 = sys_openat_wr(outpath, 0x1a4)
84 if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) }
85 }
86 let argv: *i64 = sys_mmap(128) as *i64
87 argv[0] = elf as i64
88 var i: i64 = 0
89 var go: i64 = 1
90 while go == 1 {
91 if args[i] == 0 { go = 0 } else {
92 argv[i + 1] = args[i]
93 i = i + 1
94 }
95 }
96 argv[i + 1] = 0
97 let envp: *i64 = sys_mmap(16) as *i64
98 envp[0] = 0
99 sys_execve(elf, argv, envp)
100 sys_exit(127)
101 }
102 let st: *i64 = sys_mmap(16) as *i64
103 sys_wait4(pid, st, 0)
104 let sig: i64 = st[0] & 0x7f
105 if sig != 0 { return 128 + sig }
106 return (st[0] >> 8) & 0xff
107}
108
109func pg_has(path: *u8, needle: *u8) -> i64 {
110 let szp: *i64 = sys_mmap(16) as *i64
111 let b: *u8 = pg_readall(path, szp)
112 let sz: i64 = szp[0]
113 let n: i64 = pg_slen(needle)
114 if sz < n { return 0 }
115 var i: i64 = 0
116 while i + n <= sz {
117 var ok: i64 = 1
118 var j: i64 = 0
119 while j < n {
120 if b[i + j] != needle[j] { ok = 0; j = n } else { j = j + 1 }
121 }
122 if ok == 1 { return 1 }
123 i = i + 1
124 }
125 return 0
126}
127
128func pg_fileeq(p1: *u8, p2: *u8) -> i64 {
129 let s1: *i64 = sys_mmap(16) as *i64
130 let s2: *i64 = sys_mmap(16) as *i64
131 let b1: *u8 = pg_readall(p1, s1)
132 let b2: *u8 = pg_readall(p2, s2)
133 if s1[0] != s2[0] { return 0 }
134 if s1[0] <= 0 { return 0 }
135 var i: i64 = 0
136 while i < s1[0] {
137 if b1[i] != b2[i] { return 0 }
138 i = i + 1
139 }
140 return 1
141}
142
143func pg_row(name: *u8, pass: i64) -> i64 {
144 pg_p("ROW " as *u8)
145 pg_p(name)
146 if pass == 1 { pg_p(" PASS\n" as *u8) } else { pg_p(" FAIL\n" as *u8) }
147 return pass
148}
149
150func pg_args(a1: *u8, a2: *u8, a3: *u8, a4: *u8, a5: *u8, a6: *u8, a7: *u8, a8: *u8) -> *i64 {
151 let a: *i64 = sys_mmap(128) as *i64
152 a[0] = a1 as i64
153 a[1] = a2 as i64
154 a[2] = a3 as i64
155 a[3] = a4 as i64
156 a[4] = a5 as i64
157 a[5] = a6 as i64
158 a[6] = a7 as i64
159 a[7] = a8 as i64
160 a[8] = 0
161 return a
162}
163
164func pg_ensure(elf: *u8, organ: *u8) -> i64 {
165 let pr: i64 = sys_openat_rd(elf)
166 if pr >= 0 { sys_close(pr); return 0 }
167 pg_p(" instrument missing -> rebuilding via durable runner\n" as *u8)
168 pg_runv("_offc/nx_sov_build_run.elf" as *u8, pg_args(organ, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_rebuild.out" as *u8)
169 return 0
170}
171
172func pg_mkpfx(tag: *u8, us: i64) -> *u8 {
173 let pfx: *u8 = sys_mmap(128)
174 var po: i64 = 0
175 po = pg_cat(pfx, po, tag)
176 po = pg_catn(pfx, po, us)
177 po = pg_cat(pfx, po, "-" as *u8)
178 pfx[po] = 0 as u8
179 return pfx
180}
181
182func main(argc: i64, argv: *i64) -> i64 {
183 pg_p("=== VIZSLA PLAN GATE: priority/deps/critical-path/milestone/timeblock KATs ===\n" as *u8)
184 let pln: *u8 = "buildroot/_build/nx_vizsla_plan.sov.elf" as *u8
185 let cal: *u8 = "buildroot/_build/nx_vizsla_calendar.sov.elf" as *u8
186 pg_ensure(pln, "nx_vizsla_plan" as *u8)
187 pg_ensure(cal, "nx_vizsla_calendar" as *u8)
188
189 let us: i64 = sys_now_us()
190 let pfxP: *u8 = pg_mkpfx("/tmp/vzpP" as *u8, us)
191 let pfxC: *u8 = pg_mkpfx("/tmp/vzpC" as *u8, us)
192
193 let trip: *u8 = "CONF trip 5 10 30\nTASK trip venue jason 2026-07-09 120 5 - book-venue\nTASK trip invites maria 2026-07-12 60 4 venue send-invites\nTASK trip food jason 2026-07-20 90 3 invites plan-food\nTASK trip music dave 2026-07-20 45 2 venue playlist\nTASK trip budget maria 2026-07-05 30 5 - set-budget\nMILE trip m1 2026-07-15 invites-out\nDONE trip budget 2026-07-04\n" as *u8
194 pg_write("/tmp/vzp_trip.txt" as *u8, trip)
195 let day: *u8 = "TASK day deep jason 2026-07-09 120 5 - deep-work\nTASK day mega jason 2026-07-25 700 1 - huge-thing\nTASK day email jason 2026-07-12 60 4 - inbox-zero\n" as *u8
196 pg_write("/tmp/vzp_day.txt" as *u8, day)
197 let cyc: *u8 = "TASK cyc a jason 2026-07-09 30 3 b task-a\nTASK cyc b maria 2026-07-09 30 3 a task-b\n" as *u8
198 pg_write("/tmp/vzp_cyc.txt" as *u8, cyc)
199 pg_write("/tmp/vzp_cal.txt" as *u8, "EVENT j1 2026-07-08 600 120 meeting\n" as *u8)
200
201 var pass: i64 = 0
202 var r: i64 = 0
203
204 // row 1: load the trip plan
205 let rc1: i64 = pg_runv(pln, pg_args("load" as *u8, "/tmp/vzp_trip.txt" as *u8, pfxP, "6401" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_r1.txt" as *u8)
206 r = 0
207 if rc1 == 0 {
208 if pg_has("/tmp/vzp_r1.txt" as *u8, "VIZSLA-PLAN-LOAD scanned=8 new=8 dup_infile=0 dup_instore=0 segment=seg-6401" as *u8) == 1 { r = 1 }
209 }
210 pass = pass + pg_row("plan-load" as *u8, r)
211
212 // row 2: idempotent reload
213 let rc2: i64 = pg_runv(pln, pg_args("load" as *u8, "/tmp/vzp_trip.txt" as *u8, pfxP, "6402" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_r2.txt" as *u8)
214 r = 0
215 if rc2 == 0 {
216 if pg_has("/tmp/vzp_r2.txt" as *u8, "VIZSLA-PLAN-LOAD scanned=8 new=0 dup_infile=0 dup_instore=8 segment=none" as *u8) == 1 { r = 1 }
217 }
218 pass = pass + pg_row("idempotent-reload" as *u8, r)
219
220 // rows 3-8: board at 2026-07-07
221 let rc3: i64 = pg_runv(pln, pg_args("board" as *u8, pfxP, "trip" as *u8, "2026-07-07" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_r3.txt" as *u8)
222 r = 0
223 if rc3 == 0 {
224 if pg_has("/tmp/vzp_r3.txt" as *u8, "VIZSLA-PLAN-TASK plan=trip id=venue owner=jason due=2026-07-09 state=READY urg=4 imp=5 score=50 late=0 title=book-venue" as *u8) == 1 { r = 1 }
225 }
226 pass = pass + pg_row("board-ready-priority" as *u8, r)
227
228 r = pg_has("/tmp/vzp_r3.txt" as *u8, "VIZSLA-PLAN-TASK plan=trip id=invites owner=maria due=2026-07-12 state=BLOCKED urg=4 imp=4 score=48 late=0 title=send-invites" as *u8)
229 pass = pass + pg_row("board-conf-loadbearing" as *u8, r)
230
231 r = pg_has("/tmp/vzp_r3.txt" as *u8, "VIZSLA-PLAN-TASK plan=trip id=budget owner=maria due=2026-07-05 state=DONE title=set-budget" as *u8)
232 pass = pass + pg_row("board-done" as *u8, r)
233
234 r = pg_has("/tmp/vzp_r3.txt" as *u8, "VIZSLA-PLAN-VERDICT plan=trip tasks=5 done=1 ready=1 blocked=3 late=0 pct=20 critical_min=270" as *u8)
235 pass = pass + pg_row("board-verdict" as *u8, r)
236
237 r = pg_has("/tmp/vzp_r3.txt" as *u8, "VIZSLA-PLAN-CRITICAL plan=trip effort_min=270 path=venue>invites>food" as *u8)
238 pass = pass + pg_row("critical-path" as *u8, r)
239
240 r = pg_has("/tmp/vzp_r3.txt" as *u8, "VIZSLA-PLAN-MILE plan=trip id=m1 date=2026-07-15 due_tasks=3 done=1 pct=33" as *u8)
241 pass = pass + pg_row("milestone-pct" as *u8, r)
242
243 // row 9: board at 2026-07-10 -> venue overdue
244 let rc9: i64 = pg_runv(pln, pg_args("board" as *u8, pfxP, "trip" as *u8, "2026-07-10" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_r9.txt" as *u8)
245 r = 0
246 if rc9 == 0 {
247 if pg_has("/tmp/vzp_r9.txt" as *u8, "VIZSLA-PLAN-TASK plan=trip id=venue owner=jason due=2026-07-09 state=READY urg=5 imp=5 score=60 late=1 title=book-venue" as *u8) == 1 {
248 if pg_has("/tmp/vzp_r9.txt" as *u8, "VIZSLA-PLAN-VERDICT plan=trip tasks=5 done=1 ready=1 blocked=3 late=1 pct=20 critical_min=270" as *u8) == 1 { r = 1 }
249 }
250 }
251 pass = pass + pg_row("board-overdue" as *u8, r)
252
253 // rows 10-12: timeblock the day plan into jason's real calendar
254 pg_runv(pln, pg_args("load" as *u8, "/tmp/vzp_day.txt" as *u8, pfxP, "6403" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_l10.txt" as *u8)
255 pg_runv(cal, pg_args("load" as *u8, "/tmp/vzp_cal.txt" as *u8, pfxC, "6405" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_l10b.txt" as *u8)
256 let rc10: i64 = pg_runv(pln, pg_args("timeblock" as *u8, pfxP, "day" as *u8, pfxC, "2026-07-08" as *u8, "480" as *u8, "1320" as *u8, 0 as *u8), "/tmp/vzp_r10.txt" as *u8)
257 r = 0
258 if rc10 == 0 {
259 if pg_has("/tmp/vzp_r10.txt" as *u8, "VIZSLA-PLAN-BLOCK plan=day date=2026-07-08 start=08:00 end=10:00 task=deep" as *u8) == 1 { r = 1 }
260 }
261 pass = pass + pg_row("timeblock-place-first" as *u8, r)
262
263 r = pg_has("/tmp/vzp_r10.txt" as *u8, "VIZSLA-PLAN-BLOCK plan=day date=2026-07-08 start=12:00 end=13:00 task=email" as *u8)
264 pass = pass + pg_row("timeblock-next-window" as *u8, r)
265
266 r = 0
267 if pg_has("/tmp/vzp_r10.txt" as *u8, "VIZSLA-PLAN-UNPLACED plan=day task=mega effort_min=700 reason=no-free-window-fits" as *u8) == 1 {
268 if pg_has("/tmp/vzp_r10.txt" as *u8, "VIZSLA-PLAN-TIMEBLOCK plan=day date=2026-07-08 placed=2 unplaced=1 used_min=180 free_min=720" as *u8) == 1 { r = 1 }
269 }
270 pass = pass + pg_row("timeblock-verdict" as *u8, r)
271
272 // row 13: dependency cycle -> loud fail naming the stuck tasks (negative control)
273 pg_runv(pln, pg_args("load" as *u8, "/tmp/vzp_cyc.txt" as *u8, pfxP, "6404" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_l13.txt" as *u8)
274 let rc13: i64 = pg_runv(pln, pg_args("board" as *u8, pfxP, "cyc" as *u8, "2026-07-07" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_r13.txt" as *u8)
275 r = 0
276 if rc13 == 1 {
277 if pg_has("/tmp/vzp_r13.txt" as *u8, "VIZSLA-PLAN-CYCLE plan=cyc stuck=a,b" as *u8) == 1 { r = 1 }
278 }
279 pass = pass + pg_row("cycle-detected" as *u8, r)
280
281 // row 14: determinism
282 pg_runv(pln, pg_args("board" as *u8, pfxP, "trip" as *u8, "2026-07-07" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_r14.txt" as *u8)
283 r = pg_fileeq("/tmp/vzp_r3.txt" as *u8, "/tmp/vzp_r14.txt" as *u8)
284 pass = pass + pg_row("board-determinism" as *u8, r)
285
286 // row 15: bad date (negative control)
287 let rc15: i64 = pg_runv(pln, pg_args("board" as *u8, pfxP, "trip" as *u8, "2026-13-99" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_r15.txt" as *u8)
288 r = 0
289 if rc15 == 1 { r = 1 }
290 pass = pass + pg_row("loud-fail-bad-date" as *u8, r)
291
292 // row 16: unknown plan (negative control)
293 let rc16: i64 = pg_runv(pln, pg_args("board" as *u8, pfxP, "ghost" as *u8, "2026-07-07" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzp_r16.txt" as *u8)
294 r = 0
295 if rc16 == 1 { r = 1 }
296 pass = pass + pg_row("loud-fail-unknown-plan" as *u8, r)
297
298 let permil: i64 = (pass * 1000) / 16
299 let logfd: i64 = sys_openat_append("knowledge/status/vizsla_gate.log" as *u8, 0x1a4)
300 var fdi: i64 = 0
301 while fdi < 2 {
302 var fd: i64 = 1
303 if fdi == 1 { fd = logfd }
304 if fd > 0 {
305 let line: *u8 = sys_mmap(256)
306 var o: i64 = 0
307 o = pg_cat(line, o, "VIZSLA-PLAN-GATE epoch=" as *u8)
308 o = pg_catn(line, o, sys_now_realtime_sec())
309 o = pg_cat(line, o, " rows=16 pass=" as *u8)
310 o = pg_catn(line, o, pass)
311 o = pg_cat(line, o, " permil=" as *u8)
312 o = pg_catn(line, o, permil)
313 if pass == 16 {
314 o = pg_cat(line, o, " verdict=GREEN\n" as *u8)
315 } else {
316 o = pg_cat(line, o, " verdict=RED\n" as *u8)
317 }
318 sys_write(fd, line, o)
319 }
320 fdi = fdi + 1
321 }
322 if logfd > 0 { sys_close(logfd) }
323 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
324 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
325 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
326 let ctr__dry: *i64 = gv_ctr()
327 ctr__dry[0] = pass
328 ctr__dry[1] = 16
329 let rc__dry: i64 = gv_verdict("VIZSLA-PLAN-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
330 sys_exit(rc__dry)
331 return rc__dry
332}