nx_autofix_localfix.nx source
↩ module page · 318 lines · 13507 B
1// nx_autofix_localfix.nx -- THE LOCAL MAKER TAKES STAGE 4 (2026-07-16). The proven autofix loop
2// (nx_autofix_gate, 6/6) has ONE Claude-authored piece left: the corrected line in stage [4 FIX].
3// This organ runs the SAME episode -- identify -> flag -> backup -> fix -> verify -> revert -- but the
4// fix CONTENT is GENERATED BY THE LOCAL 1.5B no-float model (i8 light init, greedy). The independent
5// grader (fresh compile+run, CGR=<pass>) remains the ONLY judge; a model echo or a broken line simply
6// fails [5 VERIFY] and the episode records an honest MAKER-MISS (curriculum), never a fake green.
7//
8// HONEST SCOPE: bug LOCALIZATION is not attempted here -- the buggy line is the known seeded one (same
9// as the gate); what goes local in this rung is the fix GENERATION. Prompting is few-shot (two worked
10// examples of one-line function repairs); the max2 correction itself is the model's own completion.
11//
12// On MAKER-GREEN it appends `CGB ts=<ts> generator=15b-autofix-localfix tasks=1 localpass=1` to the
13// codegen bench ledger -- the autograde target `local-codegen-green` (ge 1) then grades MET from a real
14// machine-verified artifact. Green-only: a miss writes the episode row but never a localpass row.
15// The loop itself must stay sound either way: backup before mutation, revert proven exact at the end.
16// exit: 0 = loop sound (maker green OR honest miss) | 1 = loop unsound (backup/revert/harness failure)
17// license_tier: ORIGINAL
18import "nx_tool_run.nx"
19import "nx_propose_verify_lib.nx"
20const K_MAGIC_131072: i64 = 131072
21const K_MAGIC_262144: i64 = 262144
22const K_MAGIC_4000: i64 = 4000
23const K_MAGIC_1048576: i64 = 1048576
24const K_MAGIC_4096: i64 = 4096
25
26func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
27func wn(v: i64) -> i64 {
28 var m: i64 = v
29 if m < 0 { w("-" as *u8); m = 0 - m }
30 let t: *u8 = sys_mmap(24)
31 var k: i64 = 0
32 if m == 0 { t[0] = 48 as u8; k = 1 }
33 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
34 let o: *u8 = sys_mmap(24)
35 var i: i64 = 0
36 while i < k { o[i] = t[k - 1 - i]; i = i + 1 }
37 sys_write(1, o, k)
38 return 0
39}
40func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
41
42func find_first(hay: *u8, hn: i64, needle: *u8, from: i64) -> i64 {
43 let m: i64 = slen(needle)
44 if m == 0 { return 0 - 1 }
45 var i: i64 = from
46 while i + m <= hn {
47 var j: i64 = 0
48 var ok: i64 = 1
49 while j < m { if hay[i+j] != needle[j] { ok = 0; j = m } else { j = j + 1 } }
50 if ok == 1 { return i }
51 i = i + 1
52 }
53 return 0 - 1
54}
55func find_last(hay: *u8, hn: i64, needle: *u8) -> i64 {
56 let m: i64 = slen(needle)
57 if m == 0 { return 0 - 1 }
58 var last: i64 = 0 - 1
59 var i: i64 = 0
60 while i + m <= hn {
61 var j: i64 = 0
62 var ok: i64 = 1
63 while j < m { if hay[i+j] != needle[j] { ok = 0; j = m } else { j = j + 1 } }
64 if ok == 1 { last = i }
65 i = i + 1
66 }
67 return last
68}
69func digit_at(hay: *u8, hn: i64, p: i64) -> i64 {
70 if p >= hn { return 0 - 1 }
71 let c: i64 = hay[p] as i64
72 if c >= 48 { if c <= 57 { return c - 48 } }
73 return 0 - 1
74}
75func bcat(b: *u8, off: i64, s: *u8) -> i64 {
76 var i: i64 = 0
77 var o: i64 = off
78 while s[i] != (0 as u8) { b[o] = s[i]; o = o + 1; i = i + 1 }
79 return o
80}
81func bcatn(b: *u8, off: i64, v: i64) -> i64 {
82 var m: i64 = v
83 var o: i64 = off
84 if m < 0 { b[o] = 45 as u8; o = o + 1; m = 0 - m }
85 let t: *u8 = sys_mmap(24)
86 var k: i64 = 0
87 if m == 0 { t[0] = 48 as u8; k = 1 }
88 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
89 var i: i64 = 0
90 while i < k { b[o] = t[k - 1 - i]; o = o + 1; i = i + 1 }
91 return o
92}
93
94func build_run(name: *u8, out: *u8, cap: i64) -> i64 {
95 let av: *i64 = sys_mmap(64) as *i64
96 av[0] = "_offc/nx_sov_build_run.elf" as *u8 as i64
97 av[1] = name as i64
98 av[2] = 0
99 let olen: *i64 = sys_mmap(8) as *i64
100 olen[0] = 0
101 tr_run_capture("_offc/nx_sov_build_run.elf" as *u8, av, out, cap, olen)
102 let cb: i64 = olen[0]
103 let ti: i64 = find_last(out, cb, "CGR=" as *u8)
104 if ti < 0 { return 0 - 1 }
105 return digit_at(out, cb, ti + 4)
106}
107
108func copyfile(srcp: *u8, dstp: *u8) -> i64 {
109 let lb: *i64 = sys_mmap(8) as *i64
110 let buf: *u8 = sys_read_file(srcp, lb)
111 if (buf as i64) == 0 { return 0 - 1 }
112 let fd: i64 = sys_openat_wr(dstp, 0x1a4)
113 if fd < 0 { return 0 - 2 }
114 sys_write(fd, buf, lb[0])
115 sys_close(fd)
116 return lb[0]
117}
118
119func apply_fix(path: *u8, finds: *u8, repls: *u8) -> i64 {
120 let lb: *i64 = sys_mmap(8) as *i64
121 let src: *u8 = sys_read_file(path, lb)
122 if (src as i64) == 0 { return 0 - 1 }
123 let n: i64 = lb[0]
124 let fl: i64 = slen(finds)
125 let idx: i64 = find_first(src, n, finds, 0)
126 if idx < 0 { return 0 - 2 }
127 let out: *u8 = sys_mmap(K_MAGIC_131072)
128 var o: i64 = 0
129 var i: i64 = 0
130 while i < idx { out[o] = src[i]; o = o + 1; i = i + 1 }
131 var j: i64 = 0
132 while repls[j] != (0 as u8) { out[o] = repls[j]; o = o + 1; j = j + 1 }
133 i = idx + fl
134 while i < n { out[o] = src[i]; o = o + 1; i = i + 1 }
135 let fd: i64 = sys_openat_wr(path, 0x1a4)
136 if fd < 0 { return 0 - 3 }
137 sys_write(fd, out, o)
138 sys_close(fd)
139 return o
140}
141
142// append a line to a ledger file (read-modify-write, additive)
143func append_line(path: *u8, line: *u8, ln: i64) -> i64 {
144 let ob: *i64 = sys_mmap(8) as *i64
145 let old: *u8 = sys_read_file(path, ob)
146 let full: *u8 = sys_mmap(K_MAGIC_262144)
147 var o: i64 = 0
148 if (old as i64) != 0 { var z: i64 = 0; while z < ob[0] { full[o] = old[z]; o = o + 1; z = z + 1 } }
149 var z2: i64 = 0
150 while z2 < ln { full[o] = line[z2]; o = o + 1; z2 = z2 + 1 }
151 let fd: i64 = sys_openat_wr(path, 0x1a4)
152 if fd < 0 { return 0 - 1 }
153 sys_write(fd, full, o)
154 sys_close(fd)
155 return o
156}
157
158// i8-mode greedy generate (gp[3]=1 pinned -- nsv_init_i8 contract)
159func lf_gen(pb: *u8, plen: i64, tx: *u8, mt: *i64, max_new: i64) -> i64 {
160 let gp: *i64 = sys_mmap(16 * 8) as *i64
161 gp[0] = pb as i64
162 gp[1] = plen
163 gp[2] = max_new
164 gp[3] = 1
165 gp[4] = tx as i64
166 gp[5] = K_MAGIC_4000
167 gp[6] = mt as i64
168 gp[7] = 0 - 1
169 gp[8] = 0
170 gp[9] = 0
171 gp[10] = 0
172 gp[11] = 0
173 gp[12] = 0
174 return nsv_generate(gp)
175}
176
177func main(argc: i64, argv: *i64) -> i64 {
178 var loop_sound: i64 = 1
179 var maker_green: i64 = 0
180 w("=== NX-AUTOFIX-LOCALFIX -- the LOCAL MODEL takes stage [4 FIX]; the machine stays the only judge ===\n" as *u8)
181 let ts: i64 = sys_now_realtime_sec()
182 var mpath: *u8 = "/home/elderwesto/nx_stage/nx_15b_model.gguf" as *u8
183 if argc >= 2 { mpath = argv[1] as *u8 }
184 let cand: *u8 = "runtime/nx_autofix_candidate.nx" as *u8
185 let bak: *u8 = "runtime/nx_autofix_candidate.nx.bak2" as *u8
186 let buggy: *u8 = "func max2(a: i64, b: i64) -> i64 { return a }" as *u8
187 let out: *u8 = sys_mmap(K_MAGIC_1048576)
188
189 // ---- 1 IDENTIFY ----
190 let p0: i64 = build_run("nx_autofix_candidate" as *u8, out, K_MAGIC_1048576)
191 w(" [1 IDENTIFY] independent grader -> pass=" as *u8); wn(p0); w("/3\n" as *u8)
192 var bug_found: i64 = 0
193 if p0 >= 0 { if p0 < 3 { bug_found = 1 } }
194 if bug_found == 0 { w(" no bug present -> nothing to fix; exiting sound\n" as *u8); return 0 }
195
196 // ---- 2 FLAG ----
197 let qrow: *u8 = sys_mmap(512)
198 var qo: i64 = 0
199 qo = bcat(qrow, qo, "AUTOFIX-FLAG ts=" as *u8)
200 qo = bcatn(qrow, qo, ts)
201 qo = bcat(qrow, qo, " file=nx_autofix_candidate.nx bug=max2-returns-first-arg grader_pass=" as *u8)
202 qo = bcatn(qrow, qo, p0)
203 qo = bcat(qrow, qo, "/3 proposed=LOCAL-MODEL-GENERATED-FIX status=PENDING-OPERATOR-APPROVAL\n" as *u8)
204 append_line("/home/elderwesto/nx_stage/autofix_approval_queue.log" as *u8, qrow, qo)
205 w(" [2 FLAG] finding + LOCAL-maker proposal -> approval queue (PENDING-OPERATOR-APPROVAL)\n" as *u8)
206 w(" [approval] simulating operator APPROVAL for this measured episode\n" as *u8)
207
208 // ---- 3 BACKUP ----
209 let bk: i64 = copyfile(cand, bak)
210 if bk <= 0 { w(" BACKUP FAILED -- refusing to mutate without revert capability\n" as *u8); return 1 }
211 w(" [3 BACKUP] .bak2 saved (" as *u8); wn(bk); w("B) BEFORE any mutation\n" as *u8)
212
213 // ---- 4 FIX -- THE LOCAL MAKER ----
214 w(" [4 FIX] local model generating the corrected line (1.5B i8 greedy)...\n" as *u8)
215 let irc: i64 = nsv_init_i8(mpath)
216 if irc != 0 { w(" model init failed -> MAKER-MISS (loop still sound)\n" as *u8); copyfile(bak, cand); return 0 }
217 let pbuf: *u8 = sys_mmap(K_MAGIC_4096)
218 let tx: *u8 = sys_mmap(K_MAGIC_4096)
219 let mt: *i64 = sys_mmap(64) as *i64
220 var po: i64 = 0
221 po = bcat(pbuf, po, "Fix each buggy NishiLang function. Output only the corrected function on one line.\n" as *u8)
222 po = bcat(pbuf, po, "Buggy: func min2(a: i64, b: i64) -> i64 { return b }\n" as *u8)
223 po = bcat(pbuf, po, "Fixed: func min2(a: i64, b: i64) -> i64 { if a < b { return a } return b }\n" as *u8)
224 po = bcat(pbuf, po, "Buggy: func abs1(x: i64) -> i64 { return x }\n" as *u8)
225 po = bcat(pbuf, po, "Fixed: func abs1(x: i64) -> i64 { if x < 0 { return 0 - x } return x }\n" as *u8)
226 po = bcat(pbuf, po, "Buggy: func max2(a: i64, b: i64) -> i64 { return a }\n" as *u8)
227 po = bcat(pbuf, po, "Fixed: " as *u8)
228 let gl: i64 = lf_gen(pbuf, po, tx, mt, 48)
229 var fixline: *u8 = sys_mmap(512)
230 var fl: i64 = 0
231 if gl > 0 {
232 var fs: i64 = find_first(tx, gl, "func max2" as *u8, 0)
233 if fs < 0 { fs = 0 }
234 // clip from fs through the '}' that returns brace depth to 0 -- NOT to the newline: greedy
235 // few-shot completions continue the pattern (" Buggy: ...") on the SAME line, and that bleed
236 // broke the build on episode 1 while the model's fix content was actually CORRECT.
237 var fe: i64 = fs
238 var depth: i64 = 0
239 var seen: i64 = 0
240 var go: i64 = 1
241 while go == 1 {
242 if fe >= gl { go = 0 }
243 else {
244 let c: i64 = tx[fe] as i64
245 if c == 10 { go = 0 }
246 else {
247 if c == 123 { depth = depth + 1; seen = 1 }
248 if c == 125 { depth = depth - 1 }
249 fe = fe + 1
250 if seen == 1 { if depth == 0 { go = 0 } }
251 }
252 }
253 }
254 var z: i64 = fs
255 while z < fe { fixline[fl] = tx[z]; fl = fl + 1; z = z + 1 }
256 fixline[fl] = 0 as u8
257 }
258 w(" [4 FIX] model output (" as *u8); wn(fl); w("B): " as *u8)
259 if fl > 0 { sys_write(1, fixline, fl) }
260 w("\n" as *u8)
261 var echo: i64 = 0
262 if fl > 0 { if find_first(fixline, fl, "return a }" as *u8, 0) >= 0 { if find_first(fixline, fl, "if" as *u8, 0) < 0 { echo = 1 } } }
263 var applied: i64 = 0
264 if fl > 10 { if echo == 0 {
265 let ap: i64 = apply_fix(cand, buggy, fixline)
266 if ap > 0 { applied = 1; w(" [4 FIX] LOCAL-GENERATED line spliced into the real source (" as *u8); wn(ap); w("B)\n" as *u8) }
267 } }
268 if applied == 0 { w(" [4 FIX] unusable generation (empty/echo) -> MAKER-MISS\n" as *u8) }
269
270 // ---- 5 VERIFY ----
271 var p1: i64 = 0 - 1
272 if applied == 1 {
273 p1 = build_run("nx_autofix_candidate" as *u8, out, K_MAGIC_1048576)
274 w(" [5 VERIFY] independent grader -> pass=" as *u8); wn(p1); w("/3" as *u8)
275 if p1 == 3 { maker_green = 1; w(" => LOCAL FIX CONFIRMED BY THE MACHINE (zero Claude in the fix content)\n" as *u8) }
276 else { w(" => local fix did not verify -> MAKER-MISS (banked)\n" as *u8) }
277 }
278
279 // ---- 6 REVERT ----
280 copyfile(bak, cand)
281 let p2: i64 = build_run("nx_autofix_candidate" as *u8, out, K_MAGIC_1048576)
282 w(" [6 REVERT] restored; independent grader -> pass=" as *u8); wn(p2); w("/3\n" as *u8)
283 if p2 != p0 { loop_sound = 0 }
284
285 // ---- persist the episode (living; green-only localpass) ----
286 let erow: *u8 = sys_mmap(512)
287 var eo: i64 = 0
288 eo = bcat(erow, eo, "AUTOFIX-LOCAL ts=" as *u8)
289 eo = bcatn(erow, eo, ts)
290 eo = bcat(erow, eo, " generator=15b-i8-localfix identify=" as *u8)
291 eo = bcatn(erow, eo, p0)
292 eo = bcat(erow, eo, " fixed=" as *u8)
293 eo = bcatn(erow, eo, p1)
294 eo = bcat(erow, eo, " reverted=" as *u8)
295 eo = bcatn(erow, eo, p2)
296 eo = bcat(erow, eo, " maker=" as *u8)
297 if maker_green == 1 { eo = bcat(erow, eo, "GREEN" as *u8) } else { eo = bcat(erow, eo, "MISS" as *u8) }
298 erow[eo] = 10 as u8
299 eo = eo + 1
300 append_line("/home/elderwesto/nx_stage/autofix_ledger.log" as *u8, erow, eo)
301 if maker_green == 1 {
302 let crow: *u8 = sys_mmap(256)
303 var co: i64 = 0
304 co = bcat(crow, co, "CGB ts=" as *u8)
305 co = bcatn(crow, co, ts)
306 co = bcat(crow, co, " generator=15b-autofix-localfix tasks=1 localpass=1\n" as *u8)
307 append_line("/home/elderwesto/nx_stage/codegen_bench_ledger.log" as *u8, crow, co)
308 w(" [ledger] localpass=1 appended (machine-verified local code artifact)\n" as *u8)
309 }
310
311 // ---- verdict ----
312 w("\nNX-AUTOFIX-LOCALFIX loop_sound=" as *u8); wn(loop_sound)
313 w(" maker=" as *u8)
314 if maker_green == 1 { w("GREEN (identify->flag->LOCAL fix->verify->revert, zero Claude fix content)\n" as *u8) }
315 else { w("MISS (honest; episode banked as curriculum; loop integrity intact)\n" as *u8) }
316 if loop_sound == 1 { return 0 }
317 return 1
318}