code wiki / _hdl_build / nx_ale_flywheel.nx

nx_ale_flywheel.nx source

↩ module page · 207 lines · 10279 B

1// nx_ale_flywheel.nx -- ALE-R5: the sovereign ALE SCORE-FLYWHEEL (the RSI loop driver). Runs a 2// task manifest through the ALE-R1 measure (_offc/nx_ale_harness.elf) and CLASSIFIES each task: 3// SOLVED = harness exit 0 AND milli-score == 1000 (the agent fully produced the graded artifact) 4// GAP = otherwise (refused/unscored [exit!=0] OR partial [score<1000]) -- a CAPABILITY GAP 5// It reports each GAP (task + exit + score) so the loop can GAP-ANALYZE -> build the missing 6// transform/skill -> re-attempt. That is the RSI loop toward the exam: measure -> gap -> build -> 7// re-measure -> close. Reuses the harness (DRY); the measure owns scoring, the flywheel owns triage. 8// args mode: nx_ale_flywheel <manifest> -> classify that manifest, print FLYWHEEL + per-gap. 9// no-arg: SELF-GATE -- a CONTROL manifest [a known-SOLVED task + a PERMANENT-GAP task 10// (ctl_never_supported, an executor token never built)] must classify exactly 1 solved + 1 gap 11// (separation bites), AND an all-solved manifest must yield 0 gaps (no false gap) -> 12// FLYWHEELGATE verdict=GREEN to knowledge/status/ale_flywheel.log + stdout. 13// Landmines: nested ifs (no &&/||), flat exprs, <=6 args/func, no empty-string literal, strings via 14// Write. license_tier: ORIGINAL 15// 16// module: nishi-core.ale.flywheel 17// depends: nishi-core.sys.syscalls 18// capability: ALE_SCORE_FLYWHEEL_RSI 19import "nx_syscalls.nx" 20const K_MAGIC_65536: i64 = 65536 21const K_MAGIC_2048: i64 = 2048 22const K_MAGIC_2047: i64 = 2047 23 24func fl_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 25func fl_fp(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } 26func fl_fn(fd: i64, v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) }; let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48; k = 1 }; while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }; var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }; sys_write(fd, bb, k); return 0 } 27func fl_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 28func fl_unlink(path: *u8) -> i64 { return __syscall(263, AT_FDCWD, path, 0, 0, 0, 0) } 29 30func fl_read(path: *u8, buf: *u8, cap: i64) -> i64 { 31 let fd: i64 = sys_openat_rd(path) 32 if fd < 0 { return 0 } 33 var n: i64 = 0 34 var go: i64 = 1 35 while go == 1 { 36 let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - 1 - n) 37 if r <= 0 { go = 0 } else { n = n + r } 38 if n >= cap - 1 { go = 0 } 39 } 40 sys_close(fd) 41 return n 42} 43 44func fl_score_of(path: *u8) -> i64 { 45 let sb: *u8 = sys_mmap(64) 46 let n: i64 = fl_read(path, sb, 64) 47 if n <= 0 { return 0 - 1 } 48 var v: i64 = 0 49 var i: i64 = 0 50 while i < n { if sb[i] >= (48 as u8) { if sb[i] <= (57 as u8) { v = v * 10 + (sb[i] - 48) } } i = i + 1 } 51 return v 52} 53 54func fl_write_file(path: *u8, s: *u8) -> i64 { 55 fl_unlink(path) 56 let fd: i64 = sys_openat_wr(path, 0x1a4) 57 if fd < 0 { return 0 } 58 sys_write(fd, s, fl_len(s)) 59 sys_close(fd) 60 return 1 61} 62 63func fl_idx_path(dst: *u8, prefix: *u8, idx: i64) -> i64 { 64 var o: i64 = 0 65 var i: i64 = 0 66 while prefix[i] != (0 as u8) { dst[o] = prefix[i]; o = o + 1; i = i + 1 } 67 var m: i64 = idx 68 let t: *u8 = sys_mmap(28) 69 var k: i64 = 0 70 if m == 0 { t[0] = 48 as u8; k = 1 } 71 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 72 var p: i64 = 0 73 while p < k { dst[o] = t[k - 1 - p]; o = o + 1; p = p + 1 } 74 dst[o] = 0 as u8 75 return o 76} 77 78func fl_run_harness(task: *u8, sb: *u8, out: *u8, score: *u8) -> i64 { 79 let pid: i64 = sys_fork() 80 if pid == 0 { 81 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 82 if dn >= 0 { sys_dup3(dn, 1, 0); sys_dup3(dn, 2, 0) } 83 let argv: *i64 = sys_mmap(48) as *i64 84 argv[0] = "_offc/nx_ale_harness.elf" as *u8 as i64 85 argv[1] = task as i64 86 argv[2] = sb as i64 87 argv[3] = out as i64 88 argv[4] = score as i64 89 argv[5] = 0 90 let envp: *i64 = sys_mmap(16) as *i64 91 envp[0] = 0 92 sys_execve("_offc/nx_ale_harness.elf" as *u8, argv, envp) 93 sys_exit(127) 94 } 95 let st: *i64 = sys_mmap(16) as *i64 96 sys_wait4(pid, st, 0) 97 return (st[0] >> 8) & 0xff 98} 99 100// classify each manifest task: res[0]=n_tasks res[1]=n_solved res[2]=n_gaps. verbose -> per-gap line. 101// ledger_fd >= 0 -> append each detected gap as a durable ALEGAP row (the auto-file surface the 102// gap-filer turns into queue rungs). Self-gate runs pass -1 (never pollute the real ledger). 103func fl_run(manifestpath: *u8, res: *i64, verbose: i64, ledger_fd: i64) -> i64 { 104 let buf: *u8 = sys_mmap(K_MAGIC_65536) 105 let n: i64 = fl_read(manifestpath, buf, K_MAGIC_65536) 106 var n_tasks: i64 = 0 107 var n_solved: i64 = 0 108 var n_gaps: i64 = 0 109 var idx: i64 = 0 110 var ls: i64 = 0 111 var i: i64 = 0 112 while i <= n { 113 var eol: i64 = 0 114 if i == n { eol = 1 } else { if buf[i] == (10 as u8) { eol = 1 } } 115 if eol == 1 { 116 if i > ls { if buf[ls] != (35 as u8) { 117 let tpath: *u8 = sys_mmap(K_MAGIC_2048) 118 var k: i64 = 0 119 var p: i64 = ls 120 while p < i { if k < K_MAGIC_2047 { tpath[k] = buf[p]; k = k + 1 } p = p + 1 } 121 tpath[k] = 0 as u8 122 if k > 0 { 123 n_tasks = n_tasks + 1 124 let sb: *u8 = sys_mmap(256); fl_idx_path(sb, "/tmp/_fly_sb_" as *u8, idx) 125 let out: *u8 = sys_mmap(256); fl_idx_path(out, "/tmp/_fly_out_" as *u8, idx) 126 let sc: *u8 = sys_mmap(256); fl_idx_path(sc, "/tmp/_fly_sc_" as *u8, idx) 127 sys_mkdir(sb, 0x1ed); sys_mkdir(out, 0x1ed) 128 fl_unlink(sc) 129 let rc: i64 = fl_run_harness(tpath, sb, out, sc) 130 var score: i64 = 0 - 1 131 if rc == 0 { score = fl_score_of(sc) } 132 var solved: i64 = 0 133 if rc == 0 { if score == 1000 { solved = 1 } } 134 if solved == 1 { n_solved = n_solved + 1 } else { 135 n_gaps = n_gaps + 1 136 if verbose == 1 { fl_p(" GAPFOUND task=" as *u8); fl_p(tpath); fl_p(" exit=" as *u8); fl_fn(1, rc); fl_p(" score=" as *u8); fl_fn(1, score); fl_p(" (missing capability)\n" as *u8) } 137 if ledger_fd >= 0 { fl_fp(ledger_fd, "ALEGAP\ttask=" as *u8); fl_fp(ledger_fd, tpath); fl_fp(ledger_fd, "\texit=" as *u8); fl_fn(ledger_fd, rc); fl_fp(ledger_fd, "\tscore=" as *u8); fl_fn(ledger_fd, score); fl_fp(ledger_fd, "\n" as *u8) } 138 } 139 idx = idx + 1 140 } 141 } } 142 ls = i + 1 143 } 144 i = i + 1 145 } 146 res[0] = n_tasks; res[1] = n_solved; res[2] = n_gaps 147 return 0 148} 149 150func main(argc: i64, argv: *i64) -> i64 { 151 if argc >= 2 { 152 let res: *i64 = sys_mmap(64) as *i64 153 // args/live mode AUTO-FILES gaps to the durable ledger (the gap-filer's input surface). 154 let glfd: i64 = sys_openat_append("knowledge/status/ale_gaps.tsv" as *u8, 0x1a4) 155 fl_p("=== ALE flywheel (run manifest) ===\n" as *u8) 156 fl_run(argv[1] as *u8, res, 1, glfd) 157 if glfd >= 0 { sys_close(glfd) } 158 fl_p("FLYWHEEL n_tasks=" as *u8); fl_fn(1, res[0]); fl_p(" solved=" as *u8); fl_fn(1, res[1]); fl_p(" gaps=" as *u8); fl_fn(1, res[2]); fl_p(" mode=RUN\n" as *u8) 159 sys_exit(0); return 0 160 } 161 162 fl_p("=== ALE-flywheel gate (ALE-R5: measure -> classify SOLVED/GAP -> the RSI loop) ===\n" as *u8) 163 // CONTROL: [solved task + PERMANENT-gap task] -> must separate exactly 1 solved + 1 gap. 164 fl_write_file("/tmp/_fly_ctl.manifest" as *u8, "knowledge/specs/ale_examples/task_count.txt\nknowledge/specs/ale_examples/task_gapctl.txt\n" as *u8) 165 let res: *i64 = sys_mmap(64) as *i64 166 fl_run("/tmp/_fly_ctl.manifest" as *u8, res, 1, 0 - 1) 167 let nt: i64 = res[0] 168 let nsv: i64 = res[1] 169 let ng: i64 = res[2] 170 var c_tasks: i64 = 0 171 if nt == 2 { c_tasks = 1 } 172 var c_solved: i64 = 0 173 if nsv == 1 { c_solved = 1 } 174 var c_gap: i64 = 0 175 if ng == 1 { c_gap = 1 } 176 // NO-FALSE-GAP: an all-solved manifest must classify 0 gaps. 177 fl_write_file("/tmp/_fly_pos.manifest" as *u8, "knowledge/specs/ale_examples/task_count.txt\nknowledge/specs/ale_examples/task_doc.txt\n" as *u8) 178 let resp: *i64 = sys_mmap(64) as *i64 179 fl_run("/tmp/_fly_pos.manifest" as *u8, resp, 0, 0 - 1) 180 var c_nofalse: i64 = 0 181 if resp[2] == 0 { if resp[1] == 2 { c_nofalse = 1 } } 182 183 fl_p(" ctl: n_tasks=" as *u8); fl_fn(1, nt); fl_p(" solved=" as *u8); fl_fn(1, nsv); fl_p(" gaps=" as *u8); fl_fn(1, ng) 184 fl_p(" | pos: solved=" as *u8); fl_fn(1, resp[1]); fl_p(" gaps=" as *u8); fl_fn(1, resp[2]) 185 fl_p("\n c_tasks=" as *u8); fl_fn(1, c_tasks); fl_p(" c_solved=" as *u8); fl_fn(1, c_solved); fl_p(" c_gap_detected=" as *u8); fl_fn(1, c_gap); fl_p(" c_no_false_gap=" as *u8); fl_fn(1, c_nofalse); fl_p("\n" as *u8) 186 187 var allok: i64 = 1 188 if c_tasks == 0 { allok = 0 } 189 if c_solved == 0 { allok = 0 } 190 if c_gap == 0 { allok = 0 } 191 if c_nofalse == 0 { allok = 0 } 192 193 let lfd: i64 = sys_openat_append("knowledge/status/ale_flywheel.log" as *u8, 0x1a4) 194 if allok == 1 { 195 fl_p("FLYWHEELGATE verdict=GREEN separates_solved_gap=1 no_false_gap=1 rung=ALE-R5\n" as *u8) 196 if lfd >= 0 { 197 fl_fp(lfd, "FLYWHEELGATE verdict=GREEN ctl_solved=" as *u8); fl_fn(lfd, nsv) 198 fl_fp(lfd, " ctl_gaps=" as *u8); fl_fn(lfd, ng) 199 fl_fp(lfd, " no_false_gap=1 rung=ALE-R5 epoch=" as *u8); fl_fn(lfd, sys_now_realtime_sec()) 200 fl_fp(lfd, "\n" as *u8); sys_close(lfd) 201 } 202 sys_exit(0); return 0 203 } 204 fl_p("FLYWHEELGATE verdict=RED\n" as *u8) 205 if lfd >= 0 { fl_fp(lfd, "FLYWHEELGATE verdict=RED ct=" as *u8); fl_fn(lfd, c_tasks); fl_fp(lfd, " cs=" as *u8); fl_fn(lfd, c_solved); fl_fp(lfd, " cg=" as *u8); fl_fn(lfd, c_gap); fl_fp(lfd, " cnf=" as *u8); fl_fn(lfd, c_nofalse); fl_fp(lfd, "\n" as *u8); sys_close(lfd) } 206 sys_exit(1); return 1 207}