code wiki / _hdl_build / nx_vizsla_venue_gate.nx
nx_vizsla_venue_gate.nx source
↩ module page · 299 lines · 12633 B
1// nx_vizsla_venue_gate.nx -- VIZSLA VENUE gate: the find/hire-buildings pipeline proven against
2// hand-computed fixtures, INCLUDING the booked->calendar bridge composed through the REAL
3// nx_vizsla_calendar organ (the emitted CAL-LINE is loaded and must appear on the day view).
4//
5// fixture: REQ party cap=40 budget=50000c 2026-08-15 18:00 +180
6// hall-a cap60 45000c -> 50+30+(5000*20)/50000=82 stage found->contacted->quoted
7// loft-b cap35 30000c -> 0+30+8=38 too_small stage found
8// barn-c cap80 90000c -> 50+0=50 over_budget stage found
9// initial: booked=none best=hall-a score=82 stages=5
10// then STAGE 2026-07-05 hall-a booked -> booked=hall-a + BOOKED line + CAL-LINE
11// "EVENT venue-party 2026-08-15 1080 180 grange-hall" -> loads into the calendar ->
12// day 2026-08-15 shows 18:00-21:00 venue-party.
13//
14// Rows: 1 venue-load 2 idempotent-reload 3 cand-top-scored 4 cand-over-budget 5 cand-too-small
15// 6 board-verdict 7 stage-latest-wins 8 booked-line 9 cal-bridge-line 10 cal-bridge-composes
16// 11 board-determinism 12 loud-fail-no-req[neg] 13 loud-fail-bad-stage[neg]
17// Evidence: VIZSLA-VEN-GATE -> stdout + knowledge/status/vizsla_gate.log; exit 0 iff 13/13.
18// spec: knowledge/research/2026-06-22-vizsla-sclass-roadmap.md license_tier: ORIGINAL
19import "nx_syscalls.nx"
20import "nx_gate_verdict.nx"
21
22func eg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
23func eg_p(s: *u8) -> i64 { sys_write(1, s, eg_slen(s)); return 0 }
24
25func eg_cat(dst: *u8, off: i64, s: *u8) -> i64 {
26 var i: i64 = 0
27 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 }
28 return off + i
29}
30
31func eg_catn(dst: *u8, off: i64, v: i64) -> i64 {
32 var o: i64 = off
33 var m: i64 = v
34 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m }
35 let t: *u8 = sys_mmap(28)
36 var k: i64 = 0
37 if m == 0 { t[0] = 48 as u8; k = 1 }
38 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
39 var i: i64 = 0
40 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 }
41 return o + k
42}
43
44func eg_write(path: *u8, content: *u8) -> i64 {
45 let fd: i64 = sys_openat_wr(path, 0x1a4)
46 if fd < 0 { return 0 - 1 }
47 sys_write(fd, content, eg_slen(content))
48 sys_close(fd)
49 return 0
50}
51
52func eg_readall(path: *u8, szout: *i64) -> *u8 {
53 let fd: i64 = sys_openat_rd(path)
54 if fd < 0 { szout[0] = 0 - 1; return 0 as *u8 }
55 let sz: i64 = sys_lseek(fd, 0, 2)
56 sys_lseek(fd, 0, 0)
57 let buf: *u8 = sys_mmap(sz + 64)
58 var got: i64 = 0
59 var n: i64 = 1
60 while n > 0 {
61 n = sys_read(fd, (buf as i64 + got) as *u8, 65536)
62 if n > 0 { got = got + n }
63 }
64 sys_close(fd)
65 szout[0] = got
66 return buf
67}
68
69func eg_runv(elf: *u8, args: *i64, outpath: *u8) -> i64 {
70 let pid: i64 = sys_fork()
71 if pid == 0 {
72 if (outpath as i64) != 0 {
73 let ofd: i64 = sys_openat_wr(outpath, 0x1a4)
74 if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) }
75 }
76 let argv: *i64 = sys_mmap(128) as *i64
77 argv[0] = elf as i64
78 var i: i64 = 0
79 var go: i64 = 1
80 while go == 1 {
81 if args[i] == 0 { go = 0 } else {
82 argv[i + 1] = args[i]
83 i = i + 1
84 }
85 }
86 argv[i + 1] = 0
87 let envp: *i64 = sys_mmap(16) as *i64
88 envp[0] = 0
89 sys_execve(elf, argv, envp)
90 sys_exit(127)
91 }
92 let st: *i64 = sys_mmap(16) as *i64
93 sys_wait4(pid, st, 0)
94 let sig: i64 = st[0] & 0x7f
95 if sig != 0 { return 128 + sig }
96 return (st[0] >> 8) & 0xff
97}
98
99func eg_has(path: *u8, needle: *u8) -> i64 {
100 let szp: *i64 = sys_mmap(16) as *i64
101 let b: *u8 = eg_readall(path, szp)
102 let sz: i64 = szp[0]
103 let n: i64 = eg_slen(needle)
104 if sz < n { return 0 }
105 var i: i64 = 0
106 while i + n <= sz {
107 var ok: i64 = 1
108 var j: i64 = 0
109 while j < n {
110 if b[i + j] != needle[j] { ok = 0; j = n } else { j = j + 1 }
111 }
112 if ok == 1 { return 1 }
113 i = i + 1
114 }
115 return 0
116}
117
118func eg_fileeq(p1: *u8, p2: *u8) -> i64 {
119 let s1: *i64 = sys_mmap(16) as *i64
120 let s2: *i64 = sys_mmap(16) as *i64
121 let b1: *u8 = eg_readall(p1, s1)
122 let b2: *u8 = eg_readall(p2, s2)
123 if s1[0] != s2[0] { return 0 }
124 if s1[0] <= 0 { return 0 }
125 var i: i64 = 0
126 while i < s1[0] {
127 if b1[i] != b2[i] { return 0 }
128 i = i + 1
129 }
130 return 1
131}
132
133func eg_row(name: *u8, pass: i64) -> i64 {
134 eg_p("ROW " as *u8)
135 eg_p(name)
136 if pass == 1 { eg_p(" PASS\n" as *u8) } else { eg_p(" FAIL\n" as *u8) }
137 return pass
138}
139
140func eg_args(a1: *u8, a2: *u8, a3: *u8, a4: *u8, a5: *u8) -> *i64 {
141 let a: *i64 = sys_mmap(64) as *i64
142 a[0] = a1 as i64
143 a[1] = a2 as i64
144 a[2] = a3 as i64
145 a[3] = a4 as i64
146 a[4] = a5 as i64
147 a[5] = 0
148 return a
149}
150
151func eg_ensure(elf: *u8, organ: *u8) -> i64 {
152 let pr: i64 = sys_openat_rd(elf)
153 if pr >= 0 { sys_close(pr); return 0 }
154 eg_p(" instrument missing -> rebuilding via durable runner\n" as *u8)
155 eg_runv("_offc/nx_sov_build_run.elf" as *u8, eg_args(organ, 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8), "/tmp/vzv_rebuild.out" as *u8)
156 return 0
157}
158
159func main(argc: i64, argv: *i64) -> i64 {
160 eg_p("=== VIZSLA VENUE GATE: hire-pipeline scoring/stages/booked-calendar-bridge KATs ===\n" as *u8)
161 let ven: *u8 = "buildroot/_build/nx_vizsla_venue.sov.elf" as *u8
162 let cal: *u8 = "buildroot/_build/nx_vizsla_calendar.sov.elf" as *u8
163 eg_ensure(ven, "nx_vizsla_venue" as *u8)
164 eg_ensure(cal, "nx_vizsla_calendar" as *u8)
165
166 let us: i64 = sys_now_us()
167 let pfx: *u8 = sys_mmap(128)
168 var po: i64 = 0
169 po = eg_cat(pfx, po, "/tmp/vzvV" as *u8)
170 po = eg_catn(pfx, po, us)
171 po = eg_cat(pfx, po, "-" as *u8)
172 pfx[po] = 0 as u8
173 let pfxC: *u8 = sys_mmap(128)
174 po = 0
175 po = eg_cat(pfxC, po, "/tmp/vzvC" as *u8)
176 po = eg_catn(pfxC, po, us)
177 po = eg_cat(pfxC, po, "-" as *u8)
178 pfxC[po] = 0 as u8
179
180 let fx: *u8 = "REQ party 40 50000 2026-08-15 1080 180\nVENUE party hall-a 60 45000 555-1000 grange-hall\nVENUE party loft-b 35 30000 555-2000 city-loft\nVENUE party barn-c 80 90000 555-3000 event-barn\nSTAGE 2026-07-01 party hall-a found\nSTAGE 2026-07-02 party hall-a contacted\nSTAGE 2026-07-03 party hall-a quoted\nSTAGE 2026-07-01 party loft-b found\nSTAGE 2026-07-01 party barn-c found\n" as *u8
181 eg_write("/tmp/vzv_fx.txt" as *u8, fx)
182
183 var pass: i64 = 0
184 var r: i64 = 0
185
186 // row 1: load
187 let rc1: i64 = eg_runv(ven, eg_args("load" as *u8, "/tmp/vzv_fx.txt" as *u8, pfx, "6501" as *u8, 0 as *u8), "/tmp/vzv_r1.txt" as *u8)
188 r = 0
189 if rc1 == 0 {
190 if eg_has("/tmp/vzv_r1.txt" as *u8, "VIZSLA-VEN-LOAD scanned=9 new=9 dup_infile=0 dup_instore=0 segment=seg-6501" as *u8) == 1 { r = 1 }
191 }
192 pass = pass + eg_row("venue-load" as *u8, r)
193
194 // row 2: idempotent reload
195 let rc2: i64 = eg_runv(ven, eg_args("load" as *u8, "/tmp/vzv_fx.txt" as *u8, pfx, "6502" as *u8, 0 as *u8), "/tmp/vzv_r2.txt" as *u8)
196 r = 0
197 if rc2 == 0 {
198 if eg_has("/tmp/vzv_r2.txt" as *u8, "VIZSLA-VEN-LOAD scanned=9 new=0 dup_infile=0 dup_instore=9 segment=none" as *u8) == 1 { r = 1 }
199 }
200 pass = pass + eg_row("idempotent-reload" as *u8, r)
201
202 // rows 3-6: initial board
203 let rc3: i64 = eg_runv(ven, eg_args("board" as *u8, pfx, "party" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzv_r3.txt" as *u8)
204 r = 0
205 if rc3 == 0 {
206 if eg_has("/tmp/vzv_r3.txt" as *u8, "VIZSLA-VEN-CAND event=party id=hall-a stage=quoted cap=60 cost=45000 score=82 over_budget=0 too_small=0 contact=555-1000 name=grange-hall" as *u8) == 1 { r = 1 }
207 }
208 pass = pass + eg_row("cand-top-scored" as *u8, r)
209
210 r = eg_has("/tmp/vzv_r3.txt" as *u8, "VIZSLA-VEN-CAND event=party id=barn-c stage=found cap=80 cost=90000 score=50 over_budget=1 too_small=0" as *u8)
211 pass = pass + eg_row("cand-over-budget" as *u8, r)
212
213 r = eg_has("/tmp/vzv_r3.txt" as *u8, "VIZSLA-VEN-CAND event=party id=loft-b stage=found cap=35 cost=30000 score=38 over_budget=0 too_small=1" as *u8)
214 pass = pass + eg_row("cand-too-small" as *u8, r)
215
216 r = eg_has("/tmp/vzv_r3.txt" as *u8, "VIZSLA-VEN-VERDICT event=party venues=3 stages=5 booked=none best=hall-a score=82" as *u8)
217 pass = pass + eg_row("board-verdict" as *u8, r)
218
219 // rows 7-9: book hall-a (later-dated stage wins), bridge lines appear
220 eg_write("/tmp/vzv_book.txt" as *u8, "STAGE 2026-07-05 party hall-a booked\n" as *u8)
221 eg_runv(ven, eg_args("load" as *u8, "/tmp/vzv_book.txt" as *u8, pfx, "6503" as *u8, 0 as *u8), "/tmp/vzv_l7.txt" as *u8)
222 let rc7: i64 = eg_runv(ven, eg_args("board" as *u8, pfx, "party" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzv_r7.txt" as *u8)
223 r = 0
224 if rc7 == 0 {
225 if eg_has("/tmp/vzv_r7.txt" as *u8, "VIZSLA-VEN-CAND event=party id=hall-a stage=booked" as *u8) == 1 {
226 if eg_has("/tmp/vzv_r7.txt" as *u8, "VIZSLA-VEN-VERDICT event=party venues=3 stages=6 booked=hall-a best=hall-a score=82" as *u8) == 1 { r = 1 }
227 }
228 }
229 pass = pass + eg_row("stage-latest-wins" as *u8, r)
230
231 r = eg_has("/tmp/vzv_r7.txt" as *u8, "VIZSLA-VEN-BOOKED event=party id=hall-a date=2026-08-15" as *u8)
232 pass = pass + eg_row("booked-line" as *u8, r)
233
234 r = eg_has("/tmp/vzv_r7.txt" as *u8, "VIZSLA-VEN-CAL-LINE EVENT venue-party 2026-08-15 1080 180 grange-hall" as *u8)
235 pass = pass + eg_row("cal-bridge-line" as *u8, r)
236
237 // row 10: the bridge row COMPOSES -- load it through the real calendar organ, see the event
238 eg_write("/tmp/vzv_cal.txt" as *u8, "EVENT venue-party 2026-08-15 1080 180 grange-hall\n" as *u8)
239 let rcl: i64 = eg_runv(cal, eg_args("load" as *u8, "/tmp/vzv_cal.txt" as *u8, pfxC, "6504" as *u8, 0 as *u8), "/tmp/vzv_l10.txt" as *u8)
240 let rc10: i64 = eg_runv(cal, eg_args("day" as *u8, pfxC, "2026-08-15" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzv_r10.txt" as *u8)
241 r = 0
242 if rcl == 0 { if rc10 == 0 {
243 if eg_has("/tmp/vzv_r10.txt" as *u8, "VIZSLA-CAL-EVENT date=2026-08-15 start=18:00 end=21:00 dur=180 id=venue-party title=grange-hall" as *u8) == 1 { r = 1 }
244 } }
245 pass = pass + eg_row("cal-bridge-composes" as *u8, r)
246
247 // row 11: determinism
248 eg_runv(ven, eg_args("board" as *u8, pfx, "party" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzv_r11.txt" as *u8)
249 r = eg_fileeq("/tmp/vzv_r7.txt" as *u8, "/tmp/vzv_r11.txt" as *u8)
250 pass = pass + eg_row("board-determinism" as *u8, r)
251
252 // row 12: board on an event with no REQ (negative control)
253 let rc12: i64 = eg_runv(ven, eg_args("board" as *u8, pfx, "ghost" as *u8, 0 as *u8, 0 as *u8), "/tmp/vzv_r12.txt" as *u8)
254 r = 0
255 if rc12 == 1 { r = 1 }
256 pass = pass + eg_row("loud-fail-no-req" as *u8, r)
257
258 // row 13: bad stage word (negative control)
259 eg_write("/tmp/vzv_bad.txt" as *u8, "STAGE 2026-07-06 party hall-a maybe\n" as *u8)
260 let rc13: i64 = eg_runv(ven, eg_args("load" as *u8, "/tmp/vzv_bad.txt" as *u8, pfx, "6505" as *u8, 0 as *u8), "/tmp/vzv_r13.txt" as *u8)
261 r = 0
262 if rc13 == 1 { r = 1 }
263 pass = pass + eg_row("loud-fail-bad-stage" as *u8, r)
264
265 let permil: i64 = (pass * 1000) / 13
266 let logfd: i64 = sys_openat_append("knowledge/status/vizsla_gate.log" as *u8, 0x1a4)
267 var fdi: i64 = 0
268 while fdi < 2 {
269 var fd: i64 = 1
270 if fdi == 1 { fd = logfd }
271 if fd > 0 {
272 let line: *u8 = sys_mmap(256)
273 var o: i64 = 0
274 o = eg_cat(line, o, "VIZSLA-VEN-GATE epoch=" as *u8)
275 o = eg_catn(line, o, sys_now_realtime_sec())
276 o = eg_cat(line, o, " rows=13 pass=" as *u8)
277 o = eg_catn(line, o, pass)
278 o = eg_cat(line, o, " permil=" as *u8)
279 o = eg_catn(line, o, permil)
280 if pass == 13 {
281 o = eg_cat(line, o, " verdict=GREEN\n" as *u8)
282 } else {
283 o = eg_cat(line, o, " verdict=RED\n" as *u8)
284 }
285 sys_write(fd, line, o)
286 }
287 fdi = fdi + 1
288 }
289 if logfd > 0 { sys_close(logfd) }
290 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
291 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
292 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
293 let ctr__dry: *i64 = gv_ctr()
294 ctr__dry[0] = pass
295 ctr__dry[1] = 13
296 let rc__dry: i64 = gv_verdict("VIZSLA-VENUE-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
297 sys_exit(rc__dry)
298 return rc__dry
299}