nx_autofix_auto.nx source
↩ module page · 774 lines · 40216 B
1// nx_autofix_auto.nx -- THE SELF-LOCALIZING FIX LOOP (2026-07-16): removes the last a-priori knowledge
2// from the autonomous fix episode. nx_autofix_localfix proved the LOCAL MAKER (model-generated fix,
3// machine-verified) but was TOLD the buggy line. This organ DISCOVERS it: it parses the candidate
4// grader's own per-function FNRES rows to find WHICH function fails, extracts that function's current
5// source line from the file (brace-depth clip), and only then hands it to the local maker. The
6// independent grader (fresh compile+run) remains the only judge at every stage.
7//
8// THE NOT-HARDCODED TOOTH: the SAME organ runs against TWO candidates whose seeded bugs live in
9// DIFFERENT functions (candidate2 -> sgn, candidate3 -> dbl; neither is in the few-shot template).
10// Correct localization must name a different function in each episode -- data-driven, not baked in.
11//
12// Episode: [1 IDENTIFY+LOCATE] grader run -> failing FNRES row -> function name [2 FLAG w/ the
13// DISCOVERED name] [3 BACKUP] [4 FIX = local 1.5B i8 greedy, few-shot, buggy line = the EXTRACTED
14// source] [5 VERIFY = no failing FNRES row] [6 REVERT + re-grade = original failing row returns].
15// RETRY LADDER (2026-07-17): round-2 = ONE greedy retry on a reframed prompt (echo-aware + machine
16// report); rounds 3+ = AF_BON_N SAMPLED retries (pinned temp/top-p/top-k, FIXED seed ladder -> the
17// whole sweep stays deterministic: seeds are part of the input, xorshift64* is seed-deterministic).
18// Greedy is a fixed point (same prompt -> same bytes -- the v2 sweep showed every greedy round-2 on
19// a miss reproduced round-1 byte-identically); independent samples break it (A1 best-of-N precedent).
20// The fresh compile+run grader stays the ONLY judge at every rung; failed samples are reverted.
21// argv: <model> [manifest] [ledger-override] -- the override is the TESTING LANE: a validation run
22// writes episode rows to a scratch ledger so it can never masquerade as the newest official batch
23// (the swebench gate + autograde pulse read the real ledger's newest ts batch).
24// Green-only: CGB localpass row per verified fix (generator=15b-autofix-auto). Misses bank curriculum.
25// exit: 0 = every episode's loop sound (fix green OR honest miss) | 1 = a loop-integrity failure.
26// license_tier: ORIGINAL
27import "nx_tool_run.nx"
28import "nx_propose_verify_lib.nx"
29import "nx_gramdec_lib.nx"
30const AF_MAGIC_131072: i64 = 131072
31const AF_MAGIC_262144: i64 = 262144
32const AF_MAGIC_4000: i64 = 4000
33const AF_MAGIC_1500: i64 = 1500
34const AF_MAGIC_2048: i64 = 2048
35const AF_MAGIC_1048576: i64 = 1048576
36const AF_MAGIC_1024: i64 = 1024
37const AF_MAGIC_4096: i64 = 4096
38const AF_MAGIC_65536: i64 = 65536
39const AF_MAGIC_65500: i64 = 65500
40
41// Best-of-N sampling params: PINNED consts, not per-run knobs -- they are part of the standing
42// benchmark's contract (changing them = a benchmark revision). temp 800 permille = the A1 precedent.
43const AF_BON_N: i64 = 3 // sampled retries after both greedy rounds miss
44const AF_BON_TEMP_PM: i64 = 800 // permille temperature (800 = 0.8)
45const AF_BON_TOPP_PM: i64 = 950 // permille nucleus mass (950 = 0.95)
46const AF_BON_TOPK: i64 = 40 // top-k cutoff (nsv sampler caps at 256)
47const AF_BON_SEED0: i64 = 1000003 // seed ladder: seed(s) = SEED0*(s+1); deterministic, never 0
48
49// NB10 grammar-constrained decode flag (argv[5] starts with 'g' -> 1). Module flag at the TOP of the
50// file (before any reader -- the forward-static-ref rule). 0 = the proven nsv path, byte-identical.
51static g_af_gc: i64
52
53func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
54func wn(v: i64) -> i64 {
55 var m: i64 = v
56 if m < 0 { w("-" as *u8); m = 0 - m }
57 let t: *u8 = sys_mmap(24)
58 var k: i64 = 0
59 if m == 0 { t[0] = 48 as u8; k = 1 }
60 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
61 let o: *u8 = sys_mmap(24)
62 var i: i64 = 0
63 while i < k { o[i] = t[k - 1 - i]; i = i + 1 }
64 sys_write(1, o, k)
65 return 0
66}
67func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
68func find_first(hay: *u8, hn: i64, needle: *u8, from: i64) -> i64 {
69 let m: i64 = slen(needle)
70 if m == 0 { return 0 - 1 }
71 var i: i64 = from
72 while i + m <= hn {
73 var j: i64 = 0
74 var ok: i64 = 1
75 while j < m { if hay[i+j] != needle[j] { ok = 0; j = m } else { j = j + 1 } }
76 if ok == 1 { return i }
77 i = i + 1
78 }
79 return 0 - 1
80}
81func bcat(b: *u8, off: i64, s: *u8) -> i64 {
82 var i: i64 = 0
83 var o: i64 = off
84 while s[i] != (0 as u8) { b[o] = s[i]; o = o + 1; i = i + 1 }
85 return o
86}
87func bcatn(b: *u8, off: i64, v: i64) -> i64 {
88 var m: i64 = v
89 var o: i64 = off
90 if m < 0 { b[o] = 45 as u8; o = o + 1; m = 0 - m }
91 let t: *u8 = sys_mmap(24)
92 var k: i64 = 0
93 if m == 0 { t[0] = 48 as u8; k = 1 }
94 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
95 var i: i64 = 0
96 while i < k { b[o] = t[k - 1 - i]; o = o + 1; i = i + 1 }
97 return o
98}
99func copyfile(srcp: *u8, dstp: *u8) -> i64 {
100 let lb: *i64 = sys_mmap(8) as *i64
101 let buf: *u8 = sys_read_file(srcp, lb)
102 if (buf as i64) == 0 { return 0 - 1 }
103 let fd: i64 = sys_openat_wr(dstp, 0x1a4)
104 if fd < 0 { return 0 - 2 }
105 sys_write(fd, buf, lb[0])
106 sys_close(fd)
107 return lb[0]
108}
109func apply_fix(path: *u8, finds: *u8, repls: *u8) -> i64 {
110 let lb: *i64 = sys_mmap(8) as *i64
111 let src: *u8 = sys_read_file(path, lb)
112 if (src as i64) == 0 { return 0 - 1 }
113 let n: i64 = lb[0]
114 let fl: i64 = slen(finds)
115 let idx: i64 = find_first(src, n, finds, 0)
116 if idx < 0 { return 0 - 2 }
117 let out: *u8 = sys_mmap(AF_MAGIC_131072)
118 var o: i64 = 0
119 var i: i64 = 0
120 while i < idx { out[o] = src[i]; o = o + 1; i = i + 1 }
121 var j: i64 = 0
122 while repls[j] != (0 as u8) { out[o] = repls[j]; o = o + 1; j = j + 1 }
123 i = idx + fl
124 while i < n { out[o] = src[i]; o = o + 1; i = i + 1 }
125 let fd: i64 = sys_openat_wr(path, 0x1a4)
126 if fd < 0 { return 0 - 3 }
127 sys_write(fd, out, o)
128 sys_close(fd)
129 return o
130}
131func append_line(path: *u8, line: *u8, ln: i64) -> i64 {
132 let ob: *i64 = sys_mmap(8) as *i64
133 let old: *u8 = sys_read_file(path, ob)
134 let full: *u8 = sys_mmap(AF_MAGIC_262144)
135 var o: i64 = 0
136 if (old as i64) != 0 { var z: i64 = 0; while z < ob[0] { full[o] = old[z]; o = o + 1; z = z + 1 } }
137 var z2: i64 = 0
138 while z2 < ln { full[o] = line[z2]; o = o + 1; z2 = z2 + 1 }
139 let fd: i64 = sys_openat_wr(path, 0x1a4)
140 if fd < 0 { return 0 - 1 }
141 sys_write(fd, full, o)
142 sys_close(fd)
143 return o
144}
145func lf_gen(pb: *u8, plen: i64, tx: *u8, mt: *i64, max_new: i64) -> i64 {
146 let gp: *i64 = sys_mmap(16 * 8) as *i64
147 gp[0] = pb as i64
148 gp[1] = plen
149 gp[2] = max_new
150 gp[3] = 1
151 gp[4] = tx as i64
152 gp[5] = AF_MAGIC_4000
153 gp[6] = mt as i64
154 gp[7] = 0 - 1
155 gp[8] = 0
156 gp[9] = 0
157 gp[10] = 0
158 gp[11] = 0
159 gp[12] = 0
160 if g_af_gc == 1 { return gdx_generate(gp) }
161 return nsv_generate(gp)
162}
163// sampled variant: temp>0 + explicit seed (gp[8]=temp_pm, gp[9]=top_p_pm, gp[10]=top_k, gp[11]=seed).
164// Deterministic per seed -- the seed ladder makes best-of-N reproducible sweep-to-sweep.
165func lf_gen_t(pb: *u8, plen: i64, tx: *u8, mt: *i64, max_new: i64, temp_pm: i64, seed: i64) -> i64 {
166 let gp: *i64 = sys_mmap(16 * 8) as *i64
167 gp[0] = pb as i64
168 gp[1] = plen
169 gp[2] = max_new
170 gp[3] = 1
171 gp[4] = tx as i64
172 gp[5] = AF_MAGIC_4000
173 gp[6] = mt as i64
174 gp[7] = 0 - 1
175 gp[8] = temp_pm
176 gp[9] = AF_BON_TOPP_PM
177 gp[10] = AF_BON_TOPK
178 gp[11] = seed
179 gp[12] = 0
180 if g_af_gc == 1 { return gdx_generate(gp) }
181 return nsv_generate(gp)
182}
183
184// run the candidate's grader; capture stdout; return capture length via box (negative rc -> 0)
185func grader_run(name: *u8, out: *u8, cap: i64) -> i64 {
186 let av: *i64 = sys_mmap(64) as *i64
187 av[0] = "_offc/nx_sov_build_run.elf" as *u8 as i64
188 av[1] = name as i64
189 av[2] = 0
190 let olen: *i64 = sys_mmap(8) as *i64
191 olen[0] = 0
192 tr_run_capture("_offc/nx_sov_build_run.elf" as *u8, av, out, cap, olen)
193 return olen[0]
194}
195
196// parse FNRES rows in out[0,n): find the FIRST failing one (passed < total); copy its name into
197// namebuf (null-terminated, cap 24). returns 1 found-failing / 0 all-pass / -1 no FNRES rows at all.
198func fn_failing(out: *u8, n: i64, namebuf: *u8) -> i64 {
199 var any: i64 = 0
200 var p: i64 = 0
201 var res: i64 = 0
202 var done: i64 = 0
203 while done == 0 {
204 let r: i64 = find_first(out, n, "FNRES " as *u8, p)
205 if r < 0 { done = 1 }
206 else {
207 any = 1
208 // OFFSET DESYNC FIXED (debt 1785521219). The name is CLAMPED to 23 bytes for namebuf, but
209 // the following fields must be located from the name's TRUE end, not from the clamped
210 // length. Previously every offset below was `r + 6 + nl + 1`, so a function name longer than
211 // 23 chars put q INSIDE the name; the digit scan then hit letters, bailed immediately, and
212 // `passed` stayed 0 -- silently reporting ZERO TESTS PASSED in a tool that judges fixes by
213 // that number. Not a crash, a WRONG NUMBER.
214 // ★ CLAMPING A LENGTH SILENTLY RELOCATES A FIELD -- the damage is not at the truncation site.
215 var i: i64 = r + 6
216 var nl: i64 = 0
217 var nend: i64 = n
218 while i < n { if out[i] == (32 as u8) { nend = i; i = n + 1 } else { if nl < 23 { namebuf[nl] = out[i]; nl = nl + 1 } i = i + 1 } }
219 namebuf[nl] = 0 as u8
220 // passed -- located from the name's TRUE end (nend), never from the clamped nl.
221 var q: i64 = nend + 1
222 var passed: i64 = 0
223 while q < n { let c: i64 = out[q] as i64; if c >= 48 { if c <= 57 { passed = passed * 10 + (c - 48); q = q + 1 } else { q = n + 1 } } else { q = n + 1 } }
224 // q now past the number end sentinel; rescan for total after the space
225 var q2: i64 = nend + 1
226 var sp: i64 = 0
227 while q2 < n { if out[q2] == (32 as u8) { sp = q2; q2 = n + 1 } else { q2 = q2 + 1 } }
228 var total: i64 = 0
229 var q3: i64 = sp + 1
230 while q3 < n { let c3: i64 = out[q3] as i64; if c3 >= 48 { if c3 <= 57 { total = total * 10 + (c3 - 48); q3 = q3 + 1 } else { q3 = n + 1 } } else { q3 = n + 1 } }
231 if passed < total { res = 1; done = 1 }
232 p = r + 6
233 }
234 }
235 if res == 1 { return 1 }
236 if any == 1 { return 0 }
237 return 0 - 1
238}
239
240// extract the one-line `func <name>...` definition from the source file into linebuf (null-terminated).
241func extract_fn_line(path: *u8, name: *u8, linebuf: *u8) -> i64 {
242 let lb: *i64 = sys_mmap(8) as *i64
243 let src: *u8 = sys_read_file(path, lb)
244 if (src as i64) == 0 { return 0 }
245 let n: i64 = lb[0]
246 let needle: *u8 = sys_mmap(64)
247 var no: i64 = 0
248 no = bcat(needle, no, "func " as *u8)
249 no = bcat(needle, no, name)
250 needle[no] = 0 as u8
251 let fs: i64 = find_first(src, n, needle, 0)
252 if fs < 0 { return 0 }
253 // multi-line: stop only at brace-closure (depth 0), never at a newline
254 var fe: i64 = fs
255 var depth: i64 = 0
256 var seen: i64 = 0
257 var go: i64 = 1
258 while go == 1 {
259 if fe >= n { go = 0 }
260 else {
261 let c: i64 = src[fe] as i64
262 if c == 123 { depth = depth + 1; seen = 1 }
263 if c == 125 { depth = depth - 1 }
264 fe = fe + 1
265 if seen == 1 { if depth == 0 { go = 0 } }
266 }
267 }
268 var fl: i64 = 0
269 var z: i64 = fs
270 while z < fe { if fl < AF_MAGIC_1500 { linebuf[fl] = src[z]; fl = fl + 1 } z = z + 1 }
271 linebuf[fl] = 0 as u8
272 return fl
273}
274
275// collect the FNCASE rows for `name` from a grader capture into fb (newline-joined, null-terminated).
276func collect_cases(cap: *u8, n: i64, name: *u8, fb: *u8) -> i64 {
277 var fbn: i64 = 0
278 let cnee: *u8 = sys_mmap(64)
279 var cno: i64 = 0
280 cno = bcat(cnee, cno, "FNCASE " as *u8)
281 cno = bcat(cnee, cno, name)
282 cnee[cno] = 32 as u8
283 cnee[cno + 1] = 0 as u8
284 var cp: i64 = 0
285 var cdone: i64 = 0
286 while cdone == 0 {
287 let cr: i64 = find_first(cap, n, cnee, cp)
288 if cr < 0 { cdone = 1 }
289 else {
290 var ce: i64 = cr
291 var sc: i64 = 1
292 while sc == 1 { if ce >= n { sc = 0 } else { if cap[ce] == (10 as u8) { sc = 0 } else { ce = ce + 1 } } }
293 var zz: i64 = cr
294 while zz < ce { if fbn < 1000 { fb[fbn] = cap[zz]; fbn = fbn + 1 } zz = zz + 1 }
295 if fbn < 1000 { fb[fbn] = 10 as u8; fbn = fbn + 1 }
296 cp = ce
297 }
298 }
299 fb[fbn] = 0 as u8
300 return fbn
301}
302
303// clip `func <name>...` from generated text tx[0,gl) through brace-depth 0 into dst; returns length.
304// MULTI-LINE (2026-07-16): stops ONLY when brace depth returns to 0 (or buffer end) -- newlines are
305// part of the function body now, so multi-line definitions extract and splice whole. One-line
306// behavior is unchanged (depth-0 lands on the same closing brace).
307// NB7 general-model bridge: normalize a generated fix (else-if/else -> valid NishiLang early-return)
308// by forking the gated nx_nishilang_norm organ. Idempotent on clean NishiLang (proven, gate T3) so
309// the 1.5B is untouched; unlocks general coders (coder15/Qwen-class). Fail-open: any hiccup -> raw.
310func nrm_fix(raw: *u8, rawlen: i64, out: *u8) -> i64 {
311 let fd: i64 = sys_openat_wr("/tmp/afx_nn_in.txt" as *u8, 0x1a4)
312 if fd < 0 { var z: i64 = 0; while z < rawlen { out[z] = raw[z]; z = z + 1 } out[rawlen] = 0 as u8; return rawlen }
313 sys_write(fd, raw, rawlen)
314 sys_close(fd)
315 let pid: i64 = sys_fork()
316 if pid == 0 {
317 let av: *i64 = sys_mmap(32) as *i64
318 av[0] = "_offc/nx_nishilang_norm.elf" as *u8 as i64
319 av[1] = "/tmp/afx_nn_in.txt" as *u8 as i64
320 av[2] = "/tmp/afx_nn_out.txt" as *u8 as i64
321 av[3] = 0
322 let envp: *i64 = sys_mmap(16) as *i64
323 envp[0] = 0
324 sys_execve("_offc/nx_nishilang_norm.elf" as *u8, av, envp)
325 sys_exit(127)
326 }
327 let st: *i64 = sys_mmap(16) as *i64
328 sys_wait4(pid, st, 0)
329 let lb: *i64 = sys_mmap(8) as *i64
330 let res: *u8 = sys_read_file("/tmp/afx_nn_out.txt" as *u8, lb)
331 if (res as i64) == 0 { var z2: i64 = 0; while z2 < rawlen { out[z2] = raw[z2]; z2 = z2 + 1 } out[rawlen] = 0 as u8; return rawlen }
332 let rn: i64 = lb[0]
333 var i: i64 = 0
334 while i < rn { out[i] = res[i]; i = i + 1 }
335 out[rn] = 0 as u8
336 return rn
337}
338func clip_fn(tx: *u8, gl: i64, needle: *u8, dst: *u8) -> i64 {
339 var fl: i64 = 0
340 if gl <= 0 { dst[0] = 0 as u8; return 0 }
341 var fs: i64 = find_first(tx, gl, needle, 0)
342 if fs < 0 { fs = 0 }
343 var fe: i64 = fs
344 var depth: i64 = 0
345 var seen: i64 = 0
346 var go: i64 = 1
347 while go == 1 {
348 if fe >= gl { go = 0 }
349 else {
350 let c: i64 = tx[fe] as i64
351 if c == 123 { depth = depth + 1; seen = 1 }
352 if c == 125 { depth = depth - 1 }
353 fe = fe + 1
354 if seen == 1 { if depth == 0 { go = 0 } }
355 }
356 }
357 var z: i64 = fs
358 while z < fe { if fl < AF_MAGIC_1500 { dst[fl] = tx[z]; fl = fl + 1 } z = z + 1 }
359 dst[fl] = 0 as u8
360 // normalize else-if/else -> valid NishiLang (general-model bridge); idempotent on clean input
361 let nb: *u8 = sys_mmap(AF_MAGIC_2048)
362 let nl: i64 = nrm_fix(dst, fl, nb)
363 var k: i64 = 0
364 while k < nl { dst[k] = nb[k]; k = k + 1 }
365 dst[nl] = 0 as u8
366 return nl
367}
368
369// one full self-localizing episode against candidate build-name `cname` with source path `cpath`.
370// `ledp` = the episode-row ledger (production default or the argv[3] testing-lane override).
371// returns 1 maker-green / 0 honest-miss / -1 loop-unsound.
372// strict=1 -> append the NishiLang-syntax rule to the maker prompt (for GENERAL coders like coder15
373// that emit else-if/abs); strict=0 -> clean prompt (the tuned 1.5B is confused by the rule -> the
374// negation mention makes it add spurious negative branches, regressing dbl). Per-maker, set from argv[4].
375func episode(cname: *u8, cpath: *u8, bakp: *u8, ts: i64, out: *u8, ledp: *u8, strict: i64) -> i64 {
376 w("\n--- EPISODE: " as *u8); w(cname); w(" ---\n" as *u8)
377 // 1 IDENTIFY + LOCATE
378 let n0: i64 = grader_run(cname, out, AF_MAGIC_1048576)
379 let name: *u8 = sys_mmap(32)
380 let loc: i64 = fn_failing(out, n0, name)
381 if loc != 1 { w(" [1 LOCATE] no failing function found -> nothing to fix\n" as *u8); return 0 }
382 w(" [1 LOCATE] grader rows name the failing function: " as *u8); w(name); w(" (DISCOVERED, not told)\n" as *u8)
383 // extract its current source line
384 let buggy: *u8 = sys_mmap(AF_MAGIC_2048)
385 let bl: i64 = extract_fn_line(cpath, name, buggy)
386 if bl <= 0 { w(" extract failed -> miss\n" as *u8); return 0 }
387 w(" [1 EXTRACT] current source: " as *u8); w(buggy); w("\n" as *u8)
388 // collect the grader's FNCASE rows for the located function -- pure machine feedback the maker
389 // sees verbatim (present only on candidates that emit per-case rows; absent rows change nothing).
390 let fb: *u8 = sys_mmap(AF_MAGIC_1024)
391 let fbn: i64 = collect_cases(out, n0, name, fb)
392 if fbn > 0 { w(" [1 CASES] machine-reported failing cases fed to the maker:\n" as *u8); w(fb) }
393 // 2 FLAG with the discovered name
394 let qrow: *u8 = sys_mmap(512)
395 var qo: i64 = 0
396 qo = bcat(qrow, qo, "AUTOFIX-FLAG ts=" as *u8)
397 qo = bcatn(qrow, qo, ts)
398 qo = bcat(qrow, qo, " file=" as *u8)
399 qo = bcat(qrow, qo, cname)
400 qo = bcat(qrow, qo, ".nx bug=LOCATED:" as *u8)
401 qo = bcat(qrow, qo, name)
402 qo = bcat(qrow, qo, " proposed=LOCAL-MODEL-GENERATED-FIX status=PENDING-OPERATOR-APPROVAL\n" as *u8)
403 append_line("/home/elderwesto/nx_stage/autofix_approval_queue.log" as *u8, qrow, qo)
404 w(" [2 FLAG] finding (with the discovered function) -> approval queue; approval simulated for this measured episode\n" as *u8)
405 // 3 BACKUP
406 let bk: i64 = copyfile(cpath, bakp)
407 if bk <= 0 { w(" BACKUP FAILED -> refusing to mutate\n" as *u8); return 0 - 1 }
408 w(" [3 BACKUP] " as *u8); wn(bk); w("B saved before any mutation\n" as *u8)
409 // 4 FIX -- local maker on the EXTRACTED line
410 let pbuf: *u8 = sys_mmap(AF_MAGIC_4096)
411 let tx: *u8 = sys_mmap(AF_MAGIC_4096)
412 let mt: *i64 = sys_mmap(64) as *i64
413 var po: i64 = 0
414 po = bcat(pbuf, po, "Fix each buggy NishiLang function. Output only the corrected function on one line.\n" as *u8)
415 if strict == 1 { po = bcat(pbuf, po, "NishiLang syntax (STRICT): NO else, NO else-if -- separate `if COND { return V }` lines with early return. Call NO helper functions (no abs/min/max/pow) -- inline with only + - * / % and comparisons. Negate as `0 - x`, never `-x`.\n" as *u8) }
416 po = bcat(pbuf, po, "Buggy: func min2(a: i64, b: i64) -> i64 { return b }\n" as *u8)
417 po = bcat(pbuf, po, "Fixed: func min2(a: i64, b: i64) -> i64 { if a < b { return a } return b }\n" as *u8)
418 po = bcat(pbuf, po, "Buggy: func abs1(x: i64) -> i64 { return x }\n" as *u8)
419 po = bcat(pbuf, po, "Fixed: func abs1(x: i64) -> i64 { if x < 0 { return 0 - x } return x }\n" as *u8)
420 if fbn > 0 {
421 po = bcat(pbuf, po, "Machine test report for the next function:\n" as *u8)
422 po = bcat(pbuf, po, fb)
423 }
424 po = bcat(pbuf, po, "Buggy: " as *u8)
425 po = bcat(pbuf, po, buggy)
426 po = bcat(pbuf, po, "\nFixed: " as *u8)
427 let gl: i64 = lf_gen(pbuf, po, tx, mt, 120)
428 // clip: from "func <name>" through brace-depth 0
429 let needle: *u8 = sys_mmap(64)
430 var no: i64 = 0
431 no = bcat(needle, no, "func " as *u8)
432 no = bcat(needle, no, name)
433 needle[no] = 0 as u8
434 let fixline: *u8 = sys_mmap(AF_MAGIC_2048)
435 let fl: i64 = clip_fn(tx, gl, needle, fixline)
436 w(" [4 FIX] model output (" as *u8); wn(fl); w("B): " as *u8)
437 if fl > 0 { sys_write(1, fixline, fl) }
438 w("\n" as *u8)
439 var applied: i64 = 0
440 var same: i64 = 0
441 var echoed: i64 = 0
442 if fl == bl { var zz: i64 = 0; same = 1; while zz < fl { if fixline[zz] != buggy[zz] { same = 0; zz = fl } else { zz = zz + 1 } } }
443 if fl > 10 { if same == 0 {
444 let ap: i64 = apply_fix(cpath, buggy, fixline)
445 if ap > 0 { applied = 1; w(" [4 FIX] LOCAL-GENERATED line spliced (" as *u8); wn(ap); w("B)\n" as *u8) }
446 } }
447 if fl > 10 { if same == 1 { echoed = 1; w(" [4 FIX] generation REPEATED the buggy line verbatim -> ECHO (rejected pre-verify, never spliced)\n" as *u8) } }
448 if applied == 0 { if echoed == 0 { w(" [4 FIX] unusable generation (empty) -> MAKER-MISS\n" as *u8) } }
449 // 5 VERIFY: no failing FNRES row anymore
450 var green: i64 = 0
451 var n1: i64 = 0
452 var attempts: i64 = 1
453 if applied == 1 {
454 n1 = grader_run(cname, out, AF_MAGIC_1048576)
455 let nm2: *u8 = sys_mmap(32)
456 let loc1: i64 = fn_failing(out, n1, nm2)
457 w(" [5 VERIFY] grader re-run -> " as *u8)
458 if loc1 == 0 { green = 1; w("ALL FUNCTIONS PASS => LOCAL FIX CONFIRMED (discovered, generated, machine-verified)\n" as *u8) }
459 else { w("still failing (" as *u8); if loc1 == 1 { w(nm2) } else { w("no rows -- build broke" as *u8) } w(") -> trying round 2\n" as *u8) }
460 }
461 // ROUND 2 (bounded -- exactly one retry, no cascade): restore the original, then feed the maker
462 // ITS OWN failed attempt + the machine-reported failing cases. TWO ways in: (a) a WRONG-but-different
463 // fix that verified red (post-fix cases available in n1), or (b) an ECHO of the buggy line rejected
464 // pre-verify (no post-fix run happened -> n1=0 -> reuse the ORIGINAL report). Greedy decoding
465 // reproduces an echo from an identical prompt, so the echo retry MUST reframe: a diff-framed
466 // "change the line, do not repeat it" instruction is what breaks the fixed point.
467 var try2: i64 = 0
468 if green == 0 { if applied == 1 { try2 = 1 } if echoed == 1 { try2 = 1 } }
469 if try2 == 1 {
470 attempts = 2
471 let fb2: *u8 = sys_mmap(AF_MAGIC_1024)
472 let fbn2: i64 = collect_cases(out, n1, name, fb2)
473 // echo path never ran a post-fix grader (n1=0) -> fall back to the ORIGINAL machine report
474 var rep: *u8 = fb2
475 var repn: i64 = fbn2
476 if repn <= 0 { rep = fb; repn = fbn }
477 copyfile(bakp, cpath)
478 var po2: i64 = 0
479 po2 = bcat(pbuf, po2, "Fix each buggy NishiLang function. Output only the corrected function on one line.\n" as *u8)
480 if strict == 1 { po2 = bcat(pbuf, po2, "NishiLang syntax (STRICT): NO else, NO else-if -- separate `if COND { return V }` lines with early return. Call NO helper functions (no abs/min/max/pow) -- inline with only + - * / % and comparisons. Negate as `0 - x`, never `-x`.\n" as *u8) }
481 po2 = bcat(pbuf, po2, "Buggy: func min2(a: i64, b: i64) -> i64 { return b }\n" as *u8)
482 po2 = bcat(pbuf, po2, "Fixed: func min2(a: i64, b: i64) -> i64 { if a < b { return a } return b }\n" as *u8)
483 if echoed == 1 {
484 po2 = bcat(pbuf, po2, "Your previous answer was IDENTICAL to the buggy line and was rejected. The buggy line is WRONG -- you MUST change its operator or logic so the function is correct. Do not repeat the buggy line.\n" as *u8)
485 }
486 if repn > 0 {
487 po2 = bcat(pbuf, po2, "Machine test report for the buggy function:\n" as *u8)
488 po2 = bcat(pbuf, po2, rep)
489 }
490 po2 = bcat(pbuf, po2, "Wrong attempt: " as *u8)
491 po2 = bcat(pbuf, po2, fixline)
492 po2 = bcat(pbuf, po2, "\nBuggy: " as *u8)
493 po2 = bcat(pbuf, po2, buggy)
494 po2 = bcat(pbuf, po2, "\nFixed: " as *u8)
495 let gl2: i64 = lf_gen(pbuf, po2, tx, mt, 120)
496 let fix2: *u8 = sys_mmap(AF_MAGIC_2048)
497 let fl2: i64 = clip_fn(tx, gl2, needle, fix2)
498 w(" [4 ROUND-2] model output (" as *u8); wn(fl2); w("B): " as *u8)
499 if fl2 > 0 { sys_write(1, fix2, fl2) }
500 w("\n" as *u8)
501 var same2: i64 = 0
502 if fl2 == fl { var zz3: i64 = 0; same2 = 1; while zz3 < fl2 { if fix2[zz3] != fixline[zz3] { same2 = 0; zz3 = fl2 } else { zz3 = zz3 + 1 } } }
503 // reject a fresh echo of the buggy line pre-verify (same discipline as round 1)
504 var echo2: i64 = 0
505 if fl2 == bl { var zc: i64 = 0; echo2 = 1; while zc < fl2 { if fix2[zc] != buggy[zc] { echo2 = 0; zc = fl2 } else { zc = zc + 1 } } }
506 if fl2 > 10 { if same2 == 0 { if echo2 == 0 {
507 let ap2: i64 = apply_fix(cpath, buggy, fix2)
508 if ap2 > 0 {
509 n1 = grader_run(cname, out, AF_MAGIC_1048576)
510 let nm4: *u8 = sys_mmap(32)
511 let loc4: i64 = fn_failing(out, n1, nm4)
512 w(" [5 VERIFY-2] grader re-run -> " as *u8)
513 if loc4 == 0 { green = 1; w("ALL FUNCTIONS PASS => ROUND-2 FIX CONFIRMED (self-corrected on machine feedback)\n" as *u8) }
514 else { w("still failing -> greedy rounds exhausted; sampled retries next\n" as *u8) }
515 }
516 } } }
517 if green == 0 { if fl2 <= 10 { w(" [4 ROUND-2] unusable generation -> sampled retries next\n" as *u8) } else { if same2 == 1 { w(" [4 ROUND-2] repeated the identical attempt -> sampled retries next\n" as *u8) } else { if echo2 == 1 { w(" [4 ROUND-2] echoed the buggy line again -> sampled retries next\n" as *u8) } } } }
518 // ROUNDS 3+ -- BEST-OF-N SAMPLED RETRIES (only when BOTH greedy rounds missed). Greedy retries
519 // beyond this point are provably useless (fixed point); independent samples on the SAME reframed
520 // prompt explore alternatives. Pinned seed ladder keeps the sweep deterministic. Every candidate:
521 // pre-verify rejected if short/echo/known-wrong/dup (no grader spend on repeats), spliced, judged
522 // by the fresh compile+run, and the candidate file RESTORED before the next attempt unless green.
523 if green == 0 {
524 copyfile(bakp, cpath)
525 let fix3: *u8 = sys_mmap(AF_MAGIC_2048)
526 let tried: *u8 = sys_mmap(AF_BON_N * AF_MAGIC_2048)
527 let triedl: *i64 = sys_mmap(AF_BON_N * 8) as *i64
528 var ntried: i64 = 0
529 var s: i64 = 0
530 while s < AF_BON_N {
531 if green == 0 {
532 attempts = attempts + 1
533 let gl3: i64 = lf_gen_t(pbuf, po2, tx, mt, 120, AF_BON_TEMP_PM, AF_BON_SEED0 * (s + 1))
534 let fl3: i64 = clip_fn(tx, gl3, needle, fix3)
535 w(" [4 SAMPLE-" as *u8); wn(s + 1); w("] model output (" as *u8); wn(fl3); w("B): " as *u8)
536 if fl3 > 0 { sys_write(1, fix3, fl3) }
537 w("\n" as *u8)
538 var reject: i64 = 0
539 if fl3 <= 10 { reject = 1 }
540 if reject == 0 { if fl3 == bl { var za: i64 = 0; var eqa: i64 = 1; while za < fl3 { if fix3[za] != buggy[za] { eqa = 0; za = fl3 } else { za = za + 1 } } if eqa == 1 { reject = 1 } } }
541 if reject == 0 { if fl3 == fl { var zb: i64 = 0; var eqb: i64 = 1; while zb < fl3 { if fix3[zb] != fixline[zb] { eqb = 0; zb = fl3 } else { zb = zb + 1 } } if eqb == 1 { reject = 1 } } }
542 if reject == 0 { if fl3 == fl2 { var zc2: i64 = 0; var eqc: i64 = 1; while zc2 < fl3 { if fix3[zc2] != fix2[zc2] { eqc = 0; zc2 = fl3 } else { zc2 = zc2 + 1 } } if eqc == 1 { reject = 1 } } }
543 if reject == 0 {
544 var d: i64 = 0
545 while d < ntried {
546 if fl3 == triedl[d] {
547 let tp: *u8 = ((tried as i64) + d * AF_MAGIC_2048) as *u8
548 var zd: i64 = 0
549 var eqd: i64 = 1
550 while zd < fl3 { if fix3[zd] != tp[zd] { eqd = 0; zd = fl3 } else { zd = zd + 1 } }
551 if eqd == 1 { reject = 1; d = ntried }
552 }
553 d = d + 1
554 }
555 }
556 if reject == 1 { w(" [4 SAMPLE-" as *u8); wn(s + 1); w("] rejected pre-verify (short/echo/known-wrong/dup) -> no grader spend\n" as *u8) }
557 if reject == 0 {
558 let tp2: *u8 = ((tried as i64) + ntried * AF_MAGIC_2048) as *u8
559 var ze: i64 = 0
560 while ze < fl3 { tp2[ze] = fix3[ze]; ze = ze + 1 }
561 tp2[fl3] = 0 as u8
562 triedl[ntried] = fl3
563 ntried = ntried + 1
564 let ap3: i64 = apply_fix(cpath, buggy, fix3)
565 if ap3 > 0 {
566 n1 = grader_run(cname, out, AF_MAGIC_1048576)
567 let nm5: *u8 = sys_mmap(32)
568 let loc5: i64 = fn_failing(out, n1, nm5)
569 w(" [5 VERIFY-S" as *u8); wn(s + 1); w("] grader re-run -> " as *u8)
570 if loc5 == 0 { green = 1; w("ALL FUNCTIONS PASS => SAMPLED FIX CONFIRMED (best-of-N, machine-verified)\n" as *u8) }
571 else { w("still failing -> restored; next sample\n" as *u8); copyfile(bakp, cpath) }
572 } else {
573 w(" [4 SAMPLE-" as *u8); wn(s + 1); w("] splice failed -> restored, skipped\n" as *u8)
574 copyfile(bakp, cpath)
575 }
576 }
577 }
578 s = s + 1
579 }
580 if green == 0 { w(" [4 BEST-OF-N] sampled retries exhausted -> MAKER-MISS (all attempts banked)\n" as *u8) }
581 }
582 }
583 // 5b SYMJUDGE (2026-07-20, autonomous-builder lane): the SYMBOLIC JUDGE -- a tests-green fix
584 // must ALSO hold the function's property contract (knowledge/store/symprop- plane row) over a
585 // deterministic domain sweep (exhaustive when the domain fits the row's budget). Kills the
586 // overfit-patch class the baked tests cannot see (fix passes tests, wrong elsewhere) and the
587 // crash class (SIGFPE/hang-free bounded sweep). Fn with NO contract row -> stage honestly
588 // SKIPPED (tests-only verdict stands, ledger symj=SKIP) so uncontracted lanes are unchanged.
589 var symj: i64 = 2
590 if green == 1 {
591 let sjav: *i64 = sys_mmap(64) as *i64
592 sjav[0] = "_offc/nx_symjudge.elf" as *u8 as i64
593 sjav[1] = cpath as i64
594 sjav[2] = name as i64
595 sjav[3] = "knowledge/store/symprop-" as *u8 as i64
596 sjav[4] = "nx_symj_af" as *u8 as i64
597 sjav[5] = 0
598 let sjb: *u8 = sys_mmap(AF_MAGIC_65536)
599 let sjl: *i64 = sys_mmap(8) as *i64
600 tr_run_capture("_offc/nx_symjudge.elf" as *u8, sjav, sjb, AF_MAGIC_65500, sjl)
601 let sn: i64 = sjl[0]
602 var sgreen: i64 = 0
603 var sskip: i64 = 0
604 if find_first(sjb, sn, " verdict=GREEN" as *u8, 0) >= 0 { sgreen = 1 }
605 if find_first(sjb, sn, "REFUSED row-missing" as *u8, 0) >= 0 { sskip = 1 }
606 if find_first(sjb, sn, "REFUSED plane-empty" as *u8, 0) >= 0 { sskip = 1 }
607 if sgreen == 1 { symj = 1; w(" [5b SYMJUDGE] property contract HOLDS over the sweep => fix stands\n" as *u8) }
608 if sgreen == 0 { if sskip == 1 { w(" [5b SYMJUDGE] no property contract for this fn -> stage SKIPPED (tests-only verdict)\n" as *u8) } }
609 if sgreen == 0 { if sskip == 0 {
610 symj = 0
611 green = 0
612 w(" [5b SYMJUDGE] tests-green fix VIOLATES the property contract (overfit/crash class) => DEMOTED to MISS:\n " as *u8)
613 let vat: i64 = find_first(sjb, sn, "SYMJ" as *u8, 0)
614 if vat >= 0 {
615 var vee: i64 = vat
616 var gvs: i64 = 1
617 while gvs == 1 { if vee >= sn { gvs = 0 } else { if sjb[vee] == (10 as u8) { gvs = 0 } else { vee = vee + 1 } } }
618 sys_write(1, ((sjb as i64) + vat) as *u8, vee - vat)
619 w("\n" as *u8)
620 }
621 } }
622 }
623 // 6 REVERT + prove the original failing function returns
624 copyfile(bakp, cpath)
625 let n2: i64 = grader_run(cname, out, AF_MAGIC_1048576)
626 let nm3: *u8 = sys_mmap(32)
627 let loc2: i64 = fn_failing(out, n2, nm3)
628 var revert_ok: i64 = 0
629 if loc2 == 1 { var zz2: i64 = 0; revert_ok = 1; var gg: i64 = 1; while gg == 1 { if name[zz2] != nm3[zz2] { revert_ok = 0; gg = 0 } else { if name[zz2] == (0 as u8) { gg = 0 } else { zz2 = zz2 + 1 } } } }
630 w(" [6 REVERT] restored; failing function is again: " as *u8)
631 if loc2 == 1 { w(nm3) } else { w("(none?)" as *u8) }
632 if revert_ok == 1 { w(" => revert proven exact\n" as *u8) } else { w(" => REVERT MISMATCH\n" as *u8) }
633 // episode ledger row
634 let erow: *u8 = sys_mmap(512)
635 var eo: i64 = 0
636 eo = bcat(erow, eo, "AUTOFIX-AUTO ts=" as *u8)
637 eo = bcatn(erow, eo, ts)
638 eo = bcat(erow, eo, " cand=" as *u8)
639 eo = bcat(erow, eo, cname)
640 eo = bcat(erow, eo, " located=" as *u8)
641 eo = bcat(erow, eo, name)
642 eo = bcat(erow, eo, " attempts=" as *u8)
643 eo = bcatn(erow, eo, attempts)
644 eo = bcat(erow, eo, " maker=" as *u8)
645 if green == 1 { eo = bcat(erow, eo, "GREEN" as *u8) } else { eo = bcat(erow, eo, "MISS" as *u8) }
646 eo = bcat(erow, eo, " revert=" as *u8)
647 eo = bcatn(erow, eo, revert_ok)
648 eo = bcat(erow, eo, " symj=" as *u8)
649 if symj == 1 { eo = bcat(erow, eo, "GREEN" as *u8) }
650 if symj == 0 { eo = bcat(erow, eo, "RED" as *u8) }
651 if symj == 2 { eo = bcat(erow, eo, "SKIP" as *u8) }
652 eo = bcat(erow, eo, " gc=" as *u8)
653 eo = bcatn(erow, eo, g_af_gc)
654 erow[eo] = 10 as u8
655 eo = eo + 1
656 append_line(ledp, erow, eo)
657 if green == 1 {
658 let crow: *u8 = sys_mmap(256)
659 var co: i64 = 0
660 co = bcat(crow, co, "CGB ts=" as *u8)
661 co = bcatn(crow, co, ts)
662 co = bcat(crow, co, " generator=15b-autofix-auto tasks=1 localpass=1\n" as *u8)
663 append_line("/home/elderwesto/nx_stage/codegen_bench_ledger.log" as *u8, crow, co)
664 }
665 if revert_ok == 0 { return 0 - 1 }
666 return green
667}
668
669func main(argc: i64, argv: *i64) -> i64 {
670 w("=== NX-AUTOFIX-AUTO -- SELF-LOCALIZING fix loop: discover the failing function, generate, verify ===\n" as *u8)
671 let ts: i64 = sys_now_realtime_sec()
672 var mpath: *u8 = "/home/elderwesto/nx_stage/nx_15b_model.gguf" as *u8
673 if argc >= 2 { mpath = argv[1] as *u8 }
674 // argv[3] = ledger override (testing lane): episode rows land in a scratch ledger, never the
675 // official one, so a validation run cannot become the newest batch the gate/pulse read.
676 var ledp: *u8 = "/home/elderwesto/nx_stage/autofix_ledger.log" as *u8
677 if argc >= 4 { ledp = argv[3] as *u8 }
678 // argv[4] = prompt mode: "strict" -> append the NishiLang-syntax rule (general coders); anything
679 // else (default "clean") -> no rule (the tuned 1.5B is regressed by it). Per-maker, set by the caller.
680 var strict: i64 = 0
681 if argc >= 5 { let sc: *u8 = argv[4] as *u8; if sc[0] == (115 as u8) { strict = 1 } }
682 // argv[5] = decode mode: "gc" -> NB10 grammar-constrained decode (token mask at sample time).
683 if argc >= 6 { let gm: *u8 = argv[5] as *u8; if gm[0] == (103 as u8) { g_af_gc = 1 } }
684 let irc: i64 = nsv_init_i8(mpath)
685 if irc != 0 { w("model init failed -> cannot run maker episodes\n" as *u8); return 1 }
686 let out: *u8 = sys_mmap(AF_MAGIC_1048576)
687
688 // MANIFEST MODE (argv[2] = verified manifest from nx_autofix_intake_gate; rows `name|path`):
689 // the episode list becomes DATA -- any lane's verified instances run through the same loop.
690 if argc >= 3 {
691 let manp: *u8 = argv[2] as *u8
692 let mlb: *i64 = sys_mmap(8) as *i64
693 let man: *u8 = sys_read_file(manp, mlb)
694 if (man as i64) == 0 { w("cannot read manifest\n" as *u8); return 1 }
695 let mn: i64 = mlb[0]
696 var greens: i64 = 0
697 var misses: i64 = 0
698 var unsound: i64 = 0
699 var total: i64 = 0
700 var p: i64 = 0
701 while p < mn {
702 var e: i64 = p
703 var f: i64 = 0
704 while f == 0 { if e >= mn { f = 1 } else { if man[e] == (10 as u8) { f = 1 } else { e = e + 1 } } }
705 var isrow: i64 = 0
706 if e > p { if man[p] != (35 as u8) { isrow = 1 } }
707 if isrow == 1 {
708 let cname: *u8 = sys_mmap(96)
709 let cpath: *u8 = sys_mmap(160)
710 let bakp: *u8 = sys_mmap(176)
711 // locate the pipe with a flag-exit scan (a negated index does not leave
712 // `while b < e` -- the `b = 0 - b` pseudo-break spins forever), then copy halves.
713 var pipe: i64 = 0 - 1
714 var b: i64 = p
715 var bd: i64 = 0
716 while bd == 0 { if b >= e { bd = 1 } else { if man[b] == (124 as u8) { pipe = b; bd = 1 } else { b = b + 1 } } }
717 var nl: i64 = 0
718 var pl: i64 = 0
719 if pipe > p {
720 var x: i64 = p
721 while x < pipe { if nl < 90 { cname[nl] = man[x]; nl = nl + 1 } x = x + 1 }
722 var y: i64 = pipe + 1
723 while y < e { if pl < 150 { cpath[pl] = man[y]; pl = pl + 1 } y = y + 1 }
724 }
725 cname[nl] = 0 as u8
726 cpath[pl] = 0 as u8
727 if nl > 0 { if pl > 0 {
728 var z: i64 = 0
729 while z < pl { bakp[z] = cpath[z]; z = z + 1 }
730 bakp[pl] = 46 as u8
731 bakp[pl+1] = 98 as u8
732 bakp[pl+2] = 97 as u8
733 bakp[pl+3] = 107 as u8
734 bakp[pl+4] = 51 as u8
735 bakp[pl+5] = 0 as u8
736 total = total + 1
737 let g: i64 = episode(cname, cpath, bakp, ts, out, ledp, strict)
738 if g == 1 { greens = greens + 1 }
739 if g == 0 { misses = misses + 1 }
740 if g == (0 - 1) { unsound = unsound + 1 }
741 } }
742 }
743 p = e + 1
744 }
745 w("\nNX-AUTOFIX-AUTO manifest sweep: " as *u8)
746 wn(total); w(" instances | " as *u8)
747 wn(greens); w(" GREEN | " as *u8)
748 wn(misses); w(" MISS | " as *u8)
749 wn(unsound); w(" UNSOUND (resolve rate " as *u8)
750 if total > 0 { wn((greens * 100) / total) } else { wn(0) }
751 w("% under the SWE-bench contract; every green machine-verified, zero Claude content)\n" as *u8)
752 if unsound > 0 { return 1 }
753 return 0
754 }
755
756 let g1: i64 = episode("nx_autofix_candidate2" as *u8, "runtime/nx_autofix_candidate2.nx" as *u8, "runtime/nx_autofix_candidate2.nx.bak3" as *u8, ts, out, ledp, strict)
757 let g2: i64 = episode("nx_autofix_candidate3" as *u8, "runtime/nx_autofix_candidate3.nx" as *u8, "runtime/nx_autofix_candidate3.nx.bak3" as *u8, ts, out, ledp, strict)
758 let g3: i64 = episode("nx_autofix_candidate4" as *u8, "runtime/nx_autofix_candidate4.nx" as *u8, "runtime/nx_autofix_candidate4.nx.bak3" as *u8, ts, out, ledp, strict)
759 let g4: i64 = episode("nx_autofix_candidate5" as *u8, "runtime/nx_autofix_candidate5.nx" as *u8, "runtime/nx_autofix_candidate5.nx.bak3" as *u8, ts, out, ledp, strict)
760 w("\nNX-AUTOFIX-AUTO episodes: cand2(sgn)=" as *u8)
761 if g1 == 1 { w("GREEN" as *u8) } else { if g1 == 0 { w("MISS" as *u8) } else { w("UNSOUND" as *u8) } }
762 w(" cand3(dbl)=" as *u8)
763 if g2 == 1 { w("GREEN" as *u8) } else { if g2 == 0 { w("MISS" as *u8) } else { w("UNSOUND" as *u8) } }
764 w(" cand4(absdiff+FNCASE-feedback)=" as *u8)
765 if g3 == 1 { w("GREEN" as *u8) } else { if g3 == 0 { w("MISS" as *u8) } else { w("UNSOUND" as *u8) } }
766 w(" cand5(WILD:model-authored sum100)=" as *u8)
767 if g4 == 1 { w("GREEN" as *u8) } else { if g4 == 0 { w("MISS" as *u8) } else { w("UNSOUND" as *u8) } }
768 w(" (localization DISCOVERED per-episode from FNRES rows; greens are machine-verified, zero Claude content)\n" as *u8)
769 if g1 == (0 - 1) { return 1 }
770 if g2 == (0 - 1) { return 1 }
771 if g3 == (0 - 1) { return 1 }
772 if g4 == (0 - 1) { return 1 }
773 return 0
774}