code wiki / _hdl_build / nx_vizsla_notes_gate.nx
nx_vizsla_notes_gate.nx source
↩ module page · 398 lines · 18588 B
1// nx_vizsla_notes_gate.nx -- VIZSLA V4b gate: the event-anchored timed
2// meaningful-note engine, proven against a HAND-COMPUTED fixture (oracle = this
3// header). No mocks: drives the real organ over real seg_store records.
4//
5// conf: window_days=3. today=2026-06-14.
6// events: e1 2026-06-20 mom birthday; e2 2026-07-01 alex surgery;
7// e3 2026-06-10 sam wedding; e4 2026-09-15 pat graduation.
8// notes:
9// n1 e1 BEFORE 7 card signature:img-mom -> release 06-13, deadline 06-20; SENT 06-14 -> SENT
10// n2 e2 BEFORE 3 text voice:vm-alex -> release 06-28, deadline 07-01; today<release -> WAITING
11// n3 e3 AFTER 2 card handwritten:scan-sam -> release 06-12, deadline 06-15; 06-12<=06-14<=06-15 -> DUE
12// n4 e4 ON 0 call text:congrats-pat -> release 09-15, deadline 09-18; today<release -> WAITING
13// n5 e3 BEFORE 7 card text:goodluck-sam -> release 06-03, deadline 06-10 (event); today>deadline -> LATE
14// => notes=5 waiting=2 due=1 late=1 sent=1 ; due-only = {n3}
15// DATA-DRIVEN: window_days=1 (only change) => n3 deadline 06-13, today 06-14 > -> LATE
16// => notes=5 waiting=2 due=0 late=2 sent=1, same binary.
17//
18// Rows:
19// 1 loud-fail-missing-conf schedule on absent conf => exit 1
20// 2 load-events scanned=10 new=10 segment=seg-7001
21// 3 idempotent-reload new=0 dup_instore=10 segment=none (law 10)
22// 4 before-waiting n2 BEFORE release=2026-06-28 WAITING
23// 5 after-due n3 AFTER release=2026-06-12 deadline=2026-06-15 DUE
24// 6 before-late n5 BEFORE release=2026-06-03 deadline=2026-06-10 LATE
25// 7 on-waiting n4 ON release=2026-09-15 WAITING
26// 8 sent-closes n1 SENT
27// 9 schedule-verdict notes=5 waiting=2 due=1 late=1 sent=1
28// 10 due-filter due lists n3 + DUE-VERDICT due=1 + WAITING absent
29// 11 release-date-inverse+personal n1 release=2026-06-13 + personal=signature:img-mom
30// 12 data-driven-window window=1 => verdict due=0 late=2 (same binary)
31// 13 loud-fail-unknown-event NOTE -> missing EVENT => schedule exit 1
32// 14 schedule-determinism byte-identical twice
33// Evidence: VIZSLA-NOTE-GATE -> stdout + knowledge/status/vizsla_gate.log; exit 0 iff 14/14.
34// Tamper: pass a bogus instrument path as argv[1] => all rows FAIL => RED.
35// spec: knowledge/specs/2026-06-14-thankyounotes-product-spec.md license_tier: ORIGINAL
36import "nx_syscalls.nx"
37import "nx_gate_verdict.nx"
38
39func rg_slen(s: *u8) -> i64 {
40 var n: i64 = 0
41 while s[n] != (0 as u8) { n = n + 1 }
42 return n
43}
44
45func rg_p(s: *u8) -> i64 {
46 sys_write(1, s, rg_slen(s))
47 return 0
48}
49
50func rg_cat(dst: *u8, off: i64, s: *u8) -> i64 {
51 var i: i64 = 0
52 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 }
53 return off + i
54}
55
56func rg_catn(dst: *u8, off: i64, v: i64) -> i64 {
57 var o: i64 = off
58 var m: i64 = v
59 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m }
60 let t: *u8 = sys_mmap(28)
61 var k: i64 = 0
62 if m == 0 { t[0] = 48 as u8; k = 1 }
63 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
64 var i: i64 = 0
65 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 }
66 return o + k
67}
68
69func rg_write(path: *u8, content: *u8) -> i64 {
70 let fd: i64 = sys_openat_wr(path, 0x1a4)
71 if fd < 0 { return 0 - 1 }
72 sys_write(fd, content, rg_slen(content))
73 sys_close(fd)
74 return 0
75}
76
77func rg_readall(path: *u8, szout: *i64) -> *u8 {
78 let fd: i64 = sys_openat_rd(path)
79 if fd < 0 { szout[0] = 0 - 1; return 0 as *u8 }
80 let sz: i64 = sys_lseek(fd, 0, 2)
81 sys_lseek(fd, 0, 0)
82 let buf: *u8 = sys_mmap(sz + 64)
83 var got: i64 = 0
84 var n: i64 = 1
85 while n > 0 {
86 n = sys_read(fd, (buf as i64 + got) as *u8, 65536)
87 if n > 0 { got = got + n }
88 }
89 sys_close(fd)
90 szout[0] = got
91 return buf
92}
93
94func rg_run(elf: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, outpath: *u8) -> i64 {
95 let pid: i64 = sys_fork()
96 if pid == 0 {
97 if (outpath as i64) != 0 {
98 let ofd: i64 = sys_openat_wr(outpath, 0x1a4)
99 if ofd >= 0 { sys_dup3(ofd, 1, 0); sys_dup3(ofd, 2, 0) }
100 }
101 let argv: *i64 = sys_mmap(64) as *i64
102 argv[0] = elf as i64
103 var i: i64 = 1
104 if (a1 as i64) != 0 { argv[i] = a1 as i64; i = i + 1 }
105 if (a2 as i64) != 0 { argv[i] = a2 as i64; i = i + 1 }
106 if (a3 as i64) != 0 { argv[i] = a3 as i64; i = i + 1 }
107 if (a4 as i64) != 0 { argv[i] = a4 as i64; i = i + 1 }
108 argv[i] = 0
109 let envp: *i64 = sys_mmap(16) as *i64
110 envp[0] = 0
111 sys_execve(elf, argv, envp)
112 sys_exit(127)
113 }
114 let st: *i64 = sys_mmap(16) as *i64
115 sys_wait4(pid, st, 0)
116 let sig: i64 = st[0] & 0x7f
117 if sig != 0 { return 128 + sig }
118 return (st[0] >> 8) & 0xff
119}
120
121func rg_has(path: *u8, needle: *u8) -> i64 {
122 let szp: *i64 = sys_mmap(16) as *i64
123 let b: *u8 = rg_readall(path, szp)
124 let sz: i64 = szp[0]
125 let n: i64 = rg_slen(needle)
126 if sz < n { return 0 }
127 var i: i64 = 0
128 while i + n <= sz {
129 var ok: i64 = 1
130 var j: i64 = 0
131 while j < n {
132 if b[i + j] != needle[j] { ok = 0; j = n } else { j = j + 1 }
133 }
134 if ok == 1 { return 1 }
135 i = i + 1
136 }
137 return 0
138}
139
140func rg_fileeq(p1: *u8, p2: *u8) -> i64 {
141 let s1: *i64 = sys_mmap(16) as *i64
142 let s2: *i64 = sys_mmap(16) as *i64
143 let b1: *u8 = rg_readall(p1, s1)
144 let b2: *u8 = rg_readall(p2, s2)
145 if s1[0] != s2[0] { return 0 }
146 if s1[0] <= 0 { return 0 }
147 var i: i64 = 0
148 while i < s1[0] {
149 if b1[i] != b2[i] { return 0 }
150 i = i + 1
151 }
152 return 1
153}
154
155func rg_row(name: *u8, pass: i64) -> i64 {
156 rg_p("ROW " as *u8)
157 rg_p(name)
158 if pass == 1 { rg_p(" PASS\n" as *u8) } else { rg_p(" FAIL\n" as *u8) }
159 return pass
160}
161
162func main(argc: i64, argv: *i64) -> i64 {
163 rg_p("=== VIZSLA NOTES GATE: hand-computed event-timed meaningful-note KATs (before/on/after) ===\n" as *u8)
164 var rb: *u8 = "buildroot/_build/nx_vizsla_notes.sov.elf" as *u8
165 if argc > 1 { rb = argv[1] as *u8 }
166 let pr: i64 = sys_openat_rd(rb)
167 if pr >= 0 { sys_close(pr) }
168 else {
169 rg_p(" instrument missing -> rebuilding via durable runner\n" as *u8)
170 rg_run("_offc/nx_sov_build_run.elf" as *u8, "nx_vizsla_notes" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, "/tmp/nt_rebuild.out" as *u8)
171 }
172
173 let pfx: *u8 = sys_mmap(128)
174 var po: i64 = 0
175 po = rg_cat(pfx, po, "/tmp/ntG" as *u8)
176 po = rg_catn(pfx, po, sys_now_us())
177 po = rg_cat(pfx, po, "-" as *u8)
178 pfx[po] = 0 as u8
179
180 let conf: *u8 = "CONF window_days 3\nCONF soon_days 14\n" as *u8
181 rg_write("/tmp/nt_conf.txt" as *u8, conf)
182 let conf1: *u8 = "CONF window_days 1\nCONF soon_days 14\n" as *u8
183 rg_write("/tmp/nt_conf1.txt" as *u8, conf1)
184 let log: *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\nEVENT e4 2026-09-15 pat graduation milestone\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\nNOTE n4 e4 ON 0 call text:congrats-pat\nNOTE n5 e3 BEFORE 7 card text:goodluck-sam\nSENT n1 2026-06-14\n" as *u8
185 rg_write("/tmp/nt_log.txt" as *u8, log)
186 let badlog: *u8 = "EVENT e1 2026-06-20 mom birthday card-gift\nNOTE nb e9 ON 0 card text:hi\n" as *u8
187 rg_write("/tmp/nt_badlog.txt" as *u8, badlog)
188 // templates (no graduation/ON row -> n4 draft must loud-fail naming the gap)
189 let tmpl: *u8 = "TMPL birthday BEFORE Happy early birthday {contact}! Thinking of you before {date}. Enclosed: {personal}\nTMPL wedding AFTER Dear {contact}, thank you for sharing your wedding with us. Enclosed: {personal}\nTMPL surgery BEFORE {contact}, wishing you strength before your surgery on {date}. Enclosed: {personal}\n" as *u8
190 rg_write("/tmp/nt_tmpl.txt" as *u8, tmpl)
191 // occasions catalog (TYN-003): wedding gets a TIGHT 1-day window -> n3 flips
192 // DUE(global 3)->LATE(occasion 1); proves per-occasion timing is data-driven
193 let occ: *u8 = "CONF window_days 3\nOCCASION birthday BEFORE 3 7 arrive-by-the-day\nOCCASION wedding AFTER 0 1 thank-you-window-tight\nOCCASION surgery BEFORE 2 5 before-procedure\n" as *u8
194 rg_write("/tmp/nt_occ.txt" as *u8, occ)
195
196 let fcf: *u8 = "/tmp/nt_conf.txt" as *u8
197 let flog: *u8 = "/tmp/nt_log.txt" as *u8
198 var pass: i64 = 0
199 var r: i64 = 0
200
201 // row 1: loud-fail on missing conf
202 let rc1: i64 = rg_run(rb, "schedule" as *u8, pfx, "/tmp/nt_NOPE.txt" as *u8, "2026-06-14" as *u8, "/tmp/nt_out1.txt" as *u8)
203 r = 0
204 if rc1 == 1 { r = 1 }
205 pass = pass + rg_row("loud-fail-missing-conf" as *u8, r)
206
207 // row 2: load 10 records into seg-7001
208 let rc2: i64 = rg_run(rb, "load" as *u8, flog, pfx, "7001" as *u8, "/tmp/nt_out2.txt" as *u8)
209 r = 0
210 if rc2 == 0 {
211 if rg_has("/tmp/nt_out2.txt" as *u8, "VIZSLA-NOTE-LOAD scanned=10 new=10 dup_infile=0 dup_instore=0 segment=seg-7001" as *u8) == 1 { r = 1 }
212 }
213 pass = pass + rg_row("load-events" as *u8, r)
214
215 // row 3: idempotent reload
216 let rc3: i64 = rg_run(rb, "load" as *u8, flog, pfx, "7009" as *u8, "/tmp/nt_out3.txt" as *u8)
217 r = 0
218 if rc3 == 0 {
219 if rg_has("/tmp/nt_out3.txt" as *u8, "VIZSLA-NOTE-LOAD scanned=10 new=0 dup_infile=0 dup_instore=10 segment=none" as *u8) == 1 { r = 1 }
220 }
221 pass = pass + rg_row("idempotent-reload" as *u8, r)
222
223 // rows 4-9: schedule
224 let rc4: i64 = rg_run(rb, "schedule" as *u8, pfx, fcf, "2026-06-14" as *u8, "/tmp/nt_sch.txt" as *u8)
225 r = 0
226 if rc4 == 0 {
227 if rg_has("/tmp/nt_sch.txt" as *u8, "id=n2 event=e2 contact=alex kind=surgery rel=BEFORE release=2026-06-28 deadline=2026-07-01 state=WAITING" as *u8) == 1 { r = 1 }
228 }
229 pass = pass + rg_row("before-waiting" as *u8, r)
230
231 r = rg_has("/tmp/nt_sch.txt" as *u8, "id=n3 event=e3 contact=sam kind=wedding rel=AFTER release=2026-06-12 deadline=2026-06-15 state=DUE" as *u8)
232 pass = pass + rg_row("after-due" as *u8, r)
233
234 r = rg_has("/tmp/nt_sch.txt" as *u8, "id=n5 event=e3 contact=sam kind=wedding rel=BEFORE release=2026-06-03 deadline=2026-06-10 state=LATE" as *u8)
235 pass = pass + rg_row("before-late" as *u8, r)
236
237 r = rg_has("/tmp/nt_sch.txt" as *u8, "id=n4 event=e4 contact=pat kind=graduation rel=ON release=2026-09-15 deadline=2026-09-18 state=WAITING" as *u8)
238 pass = pass + rg_row("on-waiting" as *u8, r)
239
240 r = rg_has("/tmp/nt_sch.txt" as *u8, "id=n1 event=e1 contact=mom kind=birthday rel=BEFORE release=2026-06-13 deadline=2026-06-20 state=SENT" as *u8)
241 pass = pass + rg_row("sent-closes" as *u8, r)
242
243 r = rg_has("/tmp/nt_sch.txt" as *u8, "VIZSLA-NOTE-VERDICT notes=5 waiting=2 due=1 late=1 sent=1" as *u8)
244 pass = pass + rg_row("schedule-verdict" as *u8, r)
245
246 // row 10: due filter -- only DUE notes, WAITING absent
247 let rc10: i64 = rg_run(rb, "due" as *u8, pfx, fcf, "2026-06-14" as *u8, "/tmp/nt_due.txt" as *u8)
248 r = 0
249 if rc10 == 0 {
250 if rg_has("/tmp/nt_due.txt" as *u8, "VIZSLA-NOTE-DUE-VERDICT due=1" as *u8) == 1 {
251 if rg_has("/tmp/nt_due.txt" as *u8, "id=n3 " as *u8) == 1 {
252 if rg_has("/tmp/nt_due.txt" as *u8, "state=WAITING" as *u8) == 0 { r = 1 }
253 }
254 }
255 }
256 pass = pass + rg_row("due-filter" as *u8, r)
257
258 // row 11: days->date inverse + personalization carried (the "signal" capture)
259 r = 0
260 if rg_has("/tmp/nt_sch.txt" as *u8, "id=n1 " as *u8) == 1 {
261 if rg_has("/tmp/nt_sch.txt" as *u8, "release=2026-06-13" as *u8) == 1 {
262 if rg_has("/tmp/nt_sch.txt" as *u8, "personal=signature:img-mom" as *u8) == 1 { r = 1 }
263 }
264 }
265 pass = pass + rg_row("release-date-inverse+personal" as *u8, r)
266
267 // row 12: DATA-DRIVEN window_days=1 file flips n3 DUE->LATE, same binary
268 let rc12: i64 = rg_run(rb, "schedule" as *u8, pfx, "/tmp/nt_conf1.txt" as *u8, "2026-06-14" as *u8, "/tmp/nt_sch1.txt" as *u8)
269 r = 0
270 if rc12 == 0 {
271 if rg_has("/tmp/nt_sch1.txt" as *u8, "VIZSLA-NOTE-VERDICT notes=5 waiting=2 due=0 late=2 sent=1" as *u8) == 1 { r = 1 }
272 }
273 pass = pass + rg_row("data-driven-window" as *u8, r)
274
275 // row 13: loud-fail on a NOTE referencing an unknown EVENT
276 let bpfx: *u8 = sys_mmap(128)
277 var bo: i64 = 0
278 bo = rg_cat(bpfx, bo, "/tmp/ntBAD" as *u8)
279 bo = rg_catn(bpfx, bo, sys_now_us())
280 bo = rg_cat(bpfx, bo, "-" as *u8)
281 bpfx[bo] = 0 as u8
282 rg_run(rb, "load" as *u8, "/tmp/nt_badlog.txt" as *u8, bpfx, "8001" as *u8, "/tmp/nt_bload.txt" as *u8)
283 let rc13: i64 = rg_run(rb, "schedule" as *u8, bpfx, fcf, "2026-06-14" as *u8, "/tmp/nt_bsch.txt" as *u8)
284 r = 0
285 if rc13 == 1 { r = 1 }
286 pass = pass + rg_row("loud-fail-unknown-event" as *u8, r)
287
288 // row 14: schedule determinism
289 rg_run(rb, "schedule" as *u8, pfx, fcf, "2026-06-14" as *u8, "/tmp/nt_sch2.txt" as *u8)
290 r = rg_fileeq("/tmp/nt_sch.txt" as *u8, "/tmp/nt_sch2.txt" as *u8)
291 pass = pass + rg_row("schedule-determinism" as *u8, r)
292
293 // row 15: draft fills the birthday/BEFORE template (slots contact/date/personal)
294 let rc15: i64 = rg_run(rb, "draft" as *u8, pfx, "/tmp/nt_tmpl.txt" as *u8, "n1" as *u8, "/tmp/nt_d1.txt" as *u8)
295 r = 0
296 if rc15 == 0 {
297 if rg_has("/tmp/nt_d1.txt" as *u8, "VIZSLA-DRAFT id=n1 kind=birthday rel=BEFORE channel=card personal=signature:img-mom" as *u8) == 1 {
298 if rg_has("/tmp/nt_d1.txt" as *u8, "Happy early birthday mom! Thinking of you before 2026-06-20. Enclosed: signature:img-mom" as *u8) == 1 { r = 1 }
299 }
300 }
301 pass = pass + rg_row("draft-fills-birthday" as *u8, r)
302
303 // row 16: draft fills the wedding/AFTER template
304 let rc16: i64 = rg_run(rb, "draft" as *u8, pfx, "/tmp/nt_tmpl.txt" as *u8, "n3" as *u8, "/tmp/nt_d3.txt" as *u8)
305 r = 0
306 if rc16 == 0 {
307 if rg_has("/tmp/nt_d3.txt" as *u8, "Dear sam, thank you for sharing your wedding with us. Enclosed: handwritten:scan-sam" as *u8) == 1 { r = 1 }
308 }
309 pass = pass + rg_row("draft-fills-wedding" as *u8, r)
310
311 // row 17: missing template (graduation/ON) = loud-fail naming the gap
312 let rc17: i64 = rg_run(rb, "draft" as *u8, pfx, "/tmp/nt_tmpl.txt" as *u8, "n4" as *u8, "/tmp/nt_d4.txt" as *u8)
313 r = 0
314 if rc17 == 1 { r = 1 }
315 pass = pass + rg_row("draft-missing-template-loud-fail" as *u8, r)
316
317 // row 18: draftdue drafts only the DUE notes (n3); n1 SENT so its draft absent
318 let rc18: i64 = rg_run(rb, "draftdue" as *u8, pfx, "/tmp/nt_tmpl.txt" as *u8, "2026-06-14" as *u8, "/tmp/nt_dd.txt" as *u8)
319 r = 0
320 if rc18 == 0 {
321 if rg_has("/tmp/nt_dd.txt" as *u8, "VIZSLA-NOTE-DRAFT-DUE-VERDICT drafted=1" as *u8) == 1 {
322 if rg_has("/tmp/nt_dd.txt" as *u8, "Dear sam, thank you for sharing your wedding" as *u8) == 1 {
323 if rg_has("/tmp/nt_dd.txt" as *u8, "Happy early birthday mom" as *u8) == 0 { r = 1 }
324 }
325 }
326 }
327 pass = pass + rg_row("draftdue-due-only" as *u8, r)
328
329 // row 19: occasions list = the etiquette / customary-timing reference
330 let rc19: i64 = rg_run(rb, "occasions" as *u8, "/tmp/nt_occ.txt" as *u8, 0 as *u8, 0 as *u8, "/tmp/nt_o19.txt" as *u8)
331 r = 0
332 if rc19 == 0 {
333 if rg_has("/tmp/nt_o19.txt" as *u8, "VIZSLA-OCCASION kind=wedding rel=AFTER offset=0 window=1 etiquette=thank-you-window-tight" as *u8) == 1 {
334 if rg_has("/tmp/nt_o19.txt" as *u8, "VIZSLA-OCCASION-VERDICT occasions=3" as *u8) == 1 { r = 1 }
335 }
336 }
337 pass = pass + rg_row("occasions-list" as *u8, r)
338
339 // row 20: suggest the customary timing + etiquette for a known kind
340 let rc20: i64 = rg_run(rb, "suggest" as *u8, "/tmp/nt_occ.txt" as *u8, "wedding" as *u8, 0 as *u8, "/tmp/nt_o20.txt" as *u8)
341 r = 0
342 if rc20 == 0 {
343 if rg_has("/tmp/nt_o20.txt" as *u8, "VIZSLA-SUGGEST kind=wedding rel=AFTER offset=0 window=1 etiquette=thank-you-window-tight" as *u8) == 1 { r = 1 }
344 }
345 pass = pass + rg_row("suggest-known" as *u8, r)
346
347 // row 21: suggest on an unknown kind = loud-fail naming the gap
348 let rc21: i64 = rg_run(rb, "suggest" as *u8, "/tmp/nt_occ.txt" as *u8, "zzz" as *u8, 0 as *u8, "/tmp/nt_o21.txt" as *u8)
349 r = 0
350 if rc21 == 1 { r = 1 }
351 pass = pass + rg_row("suggest-unknown-loud-fail" as *u8, r)
352
353 // row 22: PER-OCCASION window -- wedding's tight 1-day window flips n3
354 // DUE(global 3)->LATE; same binary, data-driven (TYN-003 intelligence)
355 let rc22: i64 = rg_run(rb, "schedule" as *u8, pfx, "/tmp/nt_occ.txt" as *u8, "2026-06-14" as *u8, "/tmp/nt_o22.txt" as *u8)
356 r = 0
357 if rc22 == 0 {
358 if rg_has("/tmp/nt_o22.txt" as *u8, "id=n3 event=e3 contact=sam kind=wedding rel=AFTER release=2026-06-12 deadline=2026-06-13 state=LATE" as *u8) == 1 {
359 if rg_has("/tmp/nt_o22.txt" as *u8, "VIZSLA-NOTE-VERDICT notes=5 waiting=2 due=0 late=2 sent=1" as *u8) == 1 { r = 1 }
360 }
361 }
362 pass = pass + rg_row("per-occasion-window" as *u8, r)
363
364 let permil: i64 = (pass * 1000) / 22
365 let logfd: i64 = sys_openat_append("knowledge/status/vizsla_gate.log" as *u8, 0x1a4)
366 var fdi: i64 = 0
367 while fdi < 2 {
368 var fd: i64 = 1
369 if fdi == 1 { fd = logfd }
370 if fd > 0 {
371 let line: *u8 = sys_mmap(256)
372 var o: i64 = 0
373 o = rg_cat(line, o, "VIZSLA-NOTE-GATE epoch=" as *u8)
374 o = rg_catn(line, o, sys_now_realtime_sec())
375 o = rg_cat(line, o, " rows=22 pass=" as *u8)
376 o = rg_catn(line, o, pass)
377 o = rg_cat(line, o, " permil=" as *u8)
378 o = rg_catn(line, o, permil)
379 if pass == 22 {
380 o = rg_cat(line, o, " verdict=GREEN\n" as *u8)
381 } else {
382 o = rg_cat(line, o, " verdict=RED\n" as *u8)
383 }
384 sys_write(fd, line, o)
385 }
386 fdi = fdi + 1
387 }
388 if logfd > 0 { sys_close(logfd) }
389 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
390 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
391 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
392 let ctr__dry: *i64 = gv_ctr()
393 ctr__dry[0] = pass
394 ctr__dry[1] = 22
395 let rc__dry: i64 = gv_verdict("VIZSLA-NOTES-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
396 sys_exit(rc__dry)
397 return rc__dry
398}