code wiki / _hdl_build / nx_vizsla_notes_gate.nx

nx_vizsla_notes_gate.nx source

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