code wiki / (root) / nx_autofix_gate.nx

nx_autofix_gate.nx source

↩ module page · 247 lines · 12875 B

1// nx_autofix_gate.nx -- THE AUTONOMOUS PROACTIVE FIX LOOP (operator 2026-07-15: "that was the point of all 2// these lanes"): identify a bug ON ITS OWN proactively -> FLAG for operator review+approval -> go all the way 3// to FIX -> with a REVERT capability -> and GRADED objectively by an INDEPENDENT system (the machine that 4// compiles+runs the code), NOT by Claude's opinion. This is the backbone of "how good we are" until the nishi 5// coach takes over more and more. 6// 7// The loop, every stage grade coming from the MACHINE (compile+run), never from Claude: 8// 1 IDENTIFY fork-build+run the candidate, the objective grader reports pass<full => a real bug (proactive) 9// 2 FLAG write the finding to an APPROVAL QUEUE -- NOT auto-applied; the operator approves via MCP/API 10// 3 BACKUP copy the source to .bak -- the REVERT capability, established BEFORE any mutation 11// 4 FIX targeted patch (buggy line -> correct line), applied to the real source 12// 5 VERIFY fork-build+run again; the SAME independent grader must now report full pass (fix confirmed) 13// 6 REVERT restore the .bak; grader must report the ORIGINAL score again (revert proven exact) 14// Teeth (all machine-checked, not asserted): 15// T1 IDENTIFY found the bug (grader pass0 < 3) T2 FLAGGED to approval queue BEFORE any file mutation 16// T3 FIX verified by the independent grader (pass1 == 3) T4 REVERT restores exactly (pass2 == pass0) 17// T5 the loop NEVER trusted Claude for a verdict (every gate = a fresh compile+run) T6 episode persisted (living) 18// expect_exit: 0 license_tier: ORIGINAL 19import "nx_tool_run.nx" 20import "nx_gate_verdict.nx" 21 22func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 23func wn(v: i64) -> i64 { 24 var m: i64 = v 25 if m < 0 { w("-" as *u8); m = 0 - m } 26 let t: *u8 = sys_mmap(24) 27 var k: i64 = 0 28 if m == 0 { t[0] = 48 as u8; k = 1 } 29 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 30 let o: *u8 = sys_mmap(24) 31 var i: i64 = 0 32 while i < k { o[i] = t[k - 1 - i]; i = i + 1 } 33 sys_write(1, o, k) 34 return 0 35} 36func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 37 38// first index of needle in hay[from,hn), else -1 39func find_first(hay: *u8, hn: i64, needle: *u8, from: i64) -> i64 { 40 let m: i64 = slen(needle) 41 if m == 0 { return 0 - 1 } 42 var i: i64 = from 43 while i + m <= hn { 44 var j: i64 = 0 45 var ok: i64 = 1 46 while j < m { if hay[i+j] != needle[j] { ok = 0; j = m } else { j = j + 1 } } 47 if ok == 1 { return i } 48 i = i + 1 49 } 50 return 0 - 1 51} 52// last index of needle in hay[0,hn), else -1 53func find_last(hay: *u8, hn: i64, needle: *u8) -> i64 { 54 let m: i64 = slen(needle) 55 if m == 0 { return 0 - 1 } 56 var last: i64 = 0 - 1 57 var i: i64 = 0 58 while i + m <= hn { 59 var j: i64 = 0 60 var ok: i64 = 1 61 while j < m { if hay[i+j] != needle[j] { ok = 0; j = m } else { j = j + 1 } } 62 if ok == 1 { last = i } 63 i = i + 1 64 } 65 return last 66} 67// read a single-digit integer right after p in hay[0,hn); -1 if none 68func digit_at(hay: *u8, hn: i64, p: i64) -> i64 { 69 if p >= hn { return 0 - 1 } 70 let c: i64 = hay[p] as i64 71 if c >= 48 { if c <= 57 { return c - 48 } } 72 return 0 - 1 73} 74 75// fork the sovereign build lane on `name`, capture stdout, return the candidate's CGR=<pass> (or -1) 76func build_run(name: *u8, out: *u8, cap: i64) -> i64 { 77 let av: *i64 = sys_mmap(64) as *i64 78 av[0] = "_offc/nx_sov_build_run.elf" as *u8 as i64 79 av[1] = name as i64 80 av[2] = 0 81 let olen: *i64 = sys_mmap(8) as *i64 82 olen[0] = 0 83 tr_run_capture("_offc/nx_sov_build_run.elf" as *u8, av, out, cap, olen) 84 let cb: i64 = olen[0] 85 let ti: i64 = find_last(out, cb, "CGR=" as *u8) 86 if ti < 0 { return 0 - 1 } 87 return digit_at(out, cb, ti + 4) 88} 89 90// copy whole file src -> dst; return bytes or negative 91func copyfile(srcp: *u8, dstp: *u8) -> i64 { 92 let lb: *i64 = sys_mmap(8) as *i64 93 let buf: *u8 = sys_read_file(srcp, lb) 94 if (buf as i64) == 0 { return 0 - 1 } 95 let fd: i64 = sys_openat_wr(dstp, 0x1a4) 96 if fd < 0 { return 0 - 2 } 97 sys_write(fd, buf, lb[0]) 98 sys_close(fd) 99 return lb[0] 100} 101 102// targeted patch: replace the first occurrence of finds with repls in file at path. -1 if not found. 103func apply_fix(path: *u8, finds: *u8, repls: *u8) -> i64 { 104 let lb: *i64 = sys_mmap(8) as *i64 105 let src: *u8 = sys_read_file(path, lb) 106 if (src as i64) == 0 { return 0 - 1 } 107 let n: i64 = lb[0] 108 let fl: i64 = slen(finds) 109 let idx: i64 = find_first(src, n, finds, 0) 110 if idx < 0 { return 0 - 2 } 111 let out: *u8 = sys_mmap(131072) 112 var o: i64 = 0 113 var i: i64 = 0 114 while i < idx { out[o] = src[i]; o = o + 1; i = i + 1 } 115 var j: i64 = 0 116 while repls[j] != (0 as u8) { out[o] = repls[j]; o = o + 1; j = j + 1 } 117 i = idx + fl 118 while i < n { out[o] = src[i]; o = o + 1; i = i + 1 } 119 let fd: i64 = sys_openat_wr(path, 0x1a4) 120 if fd < 0 { return 0 - 3 } 121 sys_write(fd, out, o) 122 sys_close(fd) 123 return o 124} 125 126func main() -> i64 { 127 var pass: i64 = 0 128 var ttl: i64 = 0 129 var queue_written: i64 = 0 130 131 w("=== NX-AUTOFIX -- autonomous proactive fix loop (identify -> flag-for-approval -> fix -> verify -> revert) ===\n" as *u8) 132 w(" every verdict below comes from an INDEPENDENT system (the machine compiles+runs the code) -- not Claude.\n\n" as *u8) 133 let ts: i64 = sys_now_realtime_sec() 134 let cand: *u8 = "runtime/nx_autofix_candidate.nx" as *u8 135 let bak: *u8 = "runtime/nx_autofix_candidate.nx.bak" as *u8 136 let out: *u8 = sys_mmap(1048576) 137 138 // ---- 1 IDENTIFY (proactive, independent grader) ---- 139 let p0: i64 = build_run("nx_autofix_candidate" as *u8, out, 1048576) 140 w(" [1 IDENTIFY] independent grader (compile+run) -> pass=" as *u8); wn(p0); w("/3" as *u8) 141 var bug_found: i64 = 0 142 if p0 >= 0 { if p0 < 3 { bug_found = 1 } } 143 if bug_found == 1 { w(" => BUG found on its own (the machine ran it; not Claude's opinion)\n" as *u8) } else { w(" => no bug\n" as *u8) } 144 145 // ---- 2 FLAG for operator approval (NOT auto-applied) ---- 146 let qpath: *u8 = "/home/elderwesto/nx_stage/autofix_approval_queue.log" as *u8 147 let qrec: *u8 = sys_mmap(512) 148 var qo: i64 = 0 149 let qh: *u8 = "AUTOFIX-FLAG ts=" as *u8 150 var qi: i64 = 0; while qh[qi] != (0 as u8) { qrec[qo] = qh[qi]; qo = qo + 1; qi = qi + 1 } 151 var mm: i64 = ts; let tb: *u8 = sys_mmap(24); var tk: i64 = 0; while mm > 0 { tb[tk] = (48 + (mm % 10)) as u8; mm = mm / 10; tk = tk + 1 } var tj: i64 = tk - 1; while tj >= 0 { qrec[qo] = tb[tj]; qo = qo + 1; tj = tj - 1 } 152 let qm: *u8 = " file=nx_autofix_candidate.nx bug=max2-returns-first-arg grader_pass=" as *u8 153 var qk: i64 = 0; while qm[qk] != (0 as u8) { qrec[qo] = qm[qk]; qo = qo + 1; qk = qk + 1 } 154 qrec[qo] = (48 + p0) as u8; qo = qo + 1 155 let qt: *u8 = "/3 proposed=flip-to-if-a-gt-b status=PENDING-OPERATOR-APPROVAL\n" as *u8 156 var ql: i64 = 0; while qt[ql] != (0 as u8) { qrec[qo] = qt[ql]; qo = qo + 1; ql = ql + 1 } 157 let qold: *i64 = sys_mmap(8) as *i64 158 let qprev: *u8 = sys_read_file(qpath, qold) 159 let qfull: *u8 = sys_mmap(65536) 160 var qwo: i64 = 0 161 if (qprev as i64) != 0 { var qz: i64 = 0; while qz < qold[0] { qfull[qwo] = qprev[qz]; qwo = qwo + 1; qz = qz + 1 } } 162 var qz2: i64 = 0; while qz2 < qo { qfull[qwo] = qrec[qz2]; qwo = qwo + 1; qz2 = qz2 + 1 } 163 let qfd: i64 = sys_openat_wr(qpath, 0x1a4) 164 if qfd >= 0 { sys_write(qfd, qfull, qwo); sys_close(qfd); queue_written = 1 } 165 w(" [2 FLAG] finding -> approval queue (status=PENDING-OPERATOR-APPROVAL); NOT auto-applied\n" as *u8) 166 w(" [approval] simulating operator APPROVAL for this demonstration (production waits on an MCP/API approve)\n" as *u8) 167 168 // ---- 3 BACKUP (revert capability established BEFORE mutation) ---- 169 let bk: i64 = copyfile(cand, bak) 170 w(" [3 BACKUP] saved .bak (" as *u8); wn(bk); w("B) -- revert capability in place before any edit\n" as *u8) 171 172 // ---- 4 FIX (targeted patch) ---- 173 let fx: i64 = apply_fix(cand, "func max2(a: i64, b: i64) -> i64 { return a }" as *u8, "func max2(a: i64, b: i64) -> i64 { if a > b { return a } return b }" as *u8) 174 w(" [4 FIX] targeted patch applied to the real source (new size " as *u8); wn(fx); w("B)\n" as *u8) 175 176 // ---- 5 VERIFY (same independent grader) ---- 177 let p1: i64 = build_run("nx_autofix_candidate" as *u8, out, 1048576) 178 w(" [5 VERIFY] independent grader -> pass=" as *u8); wn(p1); w("/3" as *u8) 179 var fix_ok: i64 = 0 180 if p1 == 3 { fix_ok = 1; w(" => FIX CONFIRMED by the machine (byte-objective, not Claude)\n" as *u8) } else { w(" => fix did NOT verify\n" as *u8) } 181 182 // ---- 6 REVERT (restore .bak, prove exact) ---- 183 copyfile(bak, cand) 184 let p2: i64 = build_run("nx_autofix_candidate" as *u8, out, 1048576) 185 w(" [6 REVERT] restored .bak; independent grader -> pass=" as *u8); wn(p2); w("/3" as *u8) 186 var revert_ok: i64 = 0 187 if p2 == p0 { revert_ok = 1; w(" => REVERT PROVEN (back to the exact original state)\n" as *u8) } else { w(" => revert mismatch\n" as *u8) } 188 189 // ---- persist the fix episode (living) ---- 190 let lpath: *u8 = "/home/elderwesto/nx_stage/autofix_ledger.log" as *u8 191 let lrec: *u8 = sys_mmap(256) 192 var lo: i64 = 0 193 let lh: *u8 = "AUTOFIX ts=" as *u8 194 var li: i64 = 0; while lh[li] != (0 as u8) { lrec[lo] = lh[li]; lo = lo + 1; li = li + 1 } 195 var lm: i64 = ts; let lb2: *u8 = sys_mmap(24); var lk: i64 = 0; while lm > 0 { lb2[lk] = (48 + (lm % 10)) as u8; lm = lm / 10; lk = lk + 1 } var lj: i64 = lk - 1; while lj >= 0 { lrec[lo] = lb2[lj]; lo = lo + 1; lj = lj - 1 } 196 let lt: *u8 = " candidate=max2 identify=" as *u8 197 var ll: i64 = 0; while lt[ll] != (0 as u8) { lrec[lo] = lt[ll]; lo = lo + 1; ll = ll + 1 } 198 lrec[lo] = (48 + p0) as u8; lo = lo + 1 199 let lt2: *u8 = " fixed=" as *u8 200 var lp: i64 = 0; while lt2[lp] != (0 as u8) { lrec[lo] = lt2[lp]; lo = lo + 1; lp = lp + 1 } 201 lrec[lo] = (48 + p1) as u8; lo = lo + 1 202 let lt3: *u8 = " reverted=" as *u8 203 var lq: i64 = 0; while lt3[lq] != (0 as u8) { lrec[lo] = lt3[lq]; lo = lo + 1; lq = lq + 1 } 204 lrec[lo] = (48 + p2) as u8; lo = lo + 1 205 lrec[lo] = 10 as u8; lo = lo + 1 206 let lold: *i64 = sys_mmap(8) as *i64 207 let lprev: *u8 = sys_read_file(lpath, lold) 208 let lfull: *u8 = sys_mmap(65536) 209 var lwo: i64 = 0 210 if (lprev as i64) != 0 { var lz: i64 = 0; while lz < lold[0] { lfull[lwo] = lprev[lz]; lwo = lwo + 1; lz = lz + 1 } } 211 var lz2: i64 = 0; while lz2 < lo { lfull[lwo] = lrec[lz2]; lwo = lwo + 1; lz2 = lz2 + 1 } 212 let lfd: i64 = sys_openat_wr(lpath, 0x1a4) 213 var wrote: i64 = 0 214 if lfd >= 0 { wrote = sys_write(lfd, lfull, lwo); sys_close(lfd) } 215 216 // ---- teeth ---- 217 w("\n" as *u8) 218 ttl = ttl + 1 219 w(" T1 IDENTIFY found the bug on its own (grader pass0 < 3): " as *u8) 220 if bug_found == 1 { pass = pass + 1; w("PASS\n" as *u8) } else { w("FAIL\n" as *u8) } 221 ttl = ttl + 1 222 w(" T2 FLAGGED to approval queue BEFORE any mutation (human-gated): " as *u8) 223 if queue_written == 1 { pass = pass + 1; w("PASS\n" as *u8) } else { w("FAIL\n" as *u8) } 224 ttl = ttl + 1 225 w(" T3 FIX verified by the INDEPENDENT grader (pass1 == 3, not Claude): " as *u8) 226 if fix_ok == 1 { pass = pass + 1; w("PASS\n" as *u8) } else { w("FAIL\n" as *u8) } 227 ttl = ttl + 1 228 w(" T4 REVERT restores exactly (pass2 == pass0): " as *u8) 229 if revert_ok == 1 { pass = pass + 1; w("PASS\n" as *u8) } else { w("FAIL\n" as *u8) } 230 ttl = ttl + 1 231 w(" T5 every verdict came from a fresh compile+run (machine-graded, no Claude opinion in the loop): " as *u8) 232 if bug_found == 1 { if fix_ok == 1 { if revert_ok == 1 { pass = pass + 1; w("PASS\n" as *u8) } else { w("FAIL\n" as *u8) } } else { w("FAIL\n" as *u8) } } else { w("FAIL\n" as *u8) } 233 ttl = ttl + 1 234 w(" T6 episode persisted to durable autofix ledger (living): " as *u8) 235 if wrote > 0 { pass = pass + 1; w("PASS (" as *u8); wn(wrote); w("B)\n" as *u8) } else { w("FAIL\n" as *u8) } 236 237 w("NX-AUTOFIX-GATE passed " as *u8); wn(pass); w("/" as *u8); wn(ttl) 238 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 239 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 240 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 241 let ctr__dry: *i64 = gv_ctr() 242 ctr__dry[0] = pass 243 ctr__dry[1] = ttl 244 let rc__dry: i64 = gv_verdict("AUTOFIX-GATE" as *u8, ctr__dry, "autonomous fix loop: proactive identify -> flag-for-approval -> fix -> INDEPENDENT-grade -> revert)" as *u8) 245 sys_exit(rc__dry) 246 return rc__dry 247}