nx_forge_loop.nx source
↩ module page · 272 lines · 10619 B
1// nx_forge_loop.nx -- FORGE A1: the CLOSED maker-checker loop (the little-coder +18% retry lever).
2// fg_run (rung 1, gated) judges pre-written candidate FILES -- the model seam is open. This organ
3// closes it: per cycle the MODEL produces the candidate over the sovereign serve's POST /gen
4// ("chat" body key = ChatML, serve-core slot-collision fix 2026-07-15; 100%-sovereign CPU path per
5// the C-purge law), and on any failure the NEXT cycle re-prompts WITH the banked VERBATIM
6// toolchain output (compiler stderr / run output / got-bytes) via fm_compose_prompt's repair arm.
7// flp_run rc map: >0 GREEN at cycle N; -2 task unreadable; -3 compose fail at cycle 1 (pack
8// unreadable); -33 compose fail at cycle >1 (repair-ctx growth overflowed the prompt cap);
9// -4 expect unreadable; -21 cycle bound exhausted; -22 bad organ name; -30 model POST failed
10// (fail-loud, NO silent fallback); -31 no "text" in serve reply; -34 candidate write failed.
11// Repair ctx = /tmp/forge_loop_ctx.txt (OWN file; fg_run's /tmp/forge_repair_ctx.txt untouched so
12// driver and loop can run concurrently), truncated per failing cycle = exactly the LAST failure.
13// Ledger = the same append-only forge ledger (every GREEN row = a compile-verified N7 example).
14// ADDITIVE: nx_forge.nx / nx_forge_model.nx are gated and unmodified; this composes their publics.
15// SAMPLING KNOBS (2026-07-16, for the engine's best-of-N stage): bp[24]=temp_pm bp[25]=seed --
16// when temp_pm>0 the /gen body gains "temp"/"seed" keys (serve parses them, gp[8]/gp[11]);
17// zero-default = byte-identical body to the gated greedy behavior (loop gate re-proven).
18// license_tier: ORIGINAL
19import "nx_forge_model.nx"
20
21// {"prompt":"...","max_new":N,"mode":M,"chat":C} -- fm_build_gen_body + the serve's chat key.
22func flp_build_gen_body(prompt: *u8, plen: i64, max_new: i64, mode: i64, chat: i64, out: *u8) -> i64 {
23 let k: *u8 = ",\"chat\":" as *u8
24 var o: i64 = fm_build_gen_body(prompt, plen, max_new, mode, out)
25 o = o - 1
26 var i: i64 = 0
27 while k[i] != (0 as u8) { out[o] = k[i]; o = o + 1; i = i + 1 }
28 let cl: i64 = std_itoa(chat, out + o)
29 o = o + cl
30 out[o] = 125 as u8
31 o = o + 1
32 return o
33}
34
35// splice ,"temp":T,"seed":S before the closing brace of a /gen body (sampled best-of-N).
36func flp_splice_sampling(body: *u8, blen: i64, temp_pm: i64, seedv: i64) -> i64 {
37 let k1: *u8 = ",\"temp\":" as *u8
38 let k2: *u8 = ",\"seed\":" as *u8
39 var o: i64 = blen - 1
40 var i: i64 = 0
41 while k1[i] != (0 as u8) { body[o] = k1[i]; o = o + 1; i = i + 1 }
42 o = o + std_itoa(temp_pm, body + o)
43 i = 0
44 while k2[i] != (0 as u8) { body[o] = k2[i]; o = o + 1; i = i + 1 }
45 o = o + std_itoa(seedv, body + o)
46 body[o] = 125 as u8
47 o = o + 1
48 return o
49}
50
51// one cycle: compose -> model -> extract -> write -> lane build -> run -> byte-exact judge.
52// Banks failure context (truncate = last failure only). bp slots documented in flp_run.
53// Returns 1 GREEN, 0 cycle-failed (repairable, ctx banked), negative = hard stop code.
54func flp_cycle(bp: *i64) -> i64 {
55 let g0: i64 = bp[0]
56 let organ: *u8 = g0 as *u8
57 let g1: i64 = bp[1]
58 let taskb: *u8 = g1 as *u8
59 let g2: i64 = bp[2]
60 let packpath: *u8 = g2 as *u8
61 let g3: i64 = bp[3]
62 let rp: *u8 = g3 as *u8
63 let port: i64 = bp[4]
64 let maxnew: i64 = bp[5]
65 let chat: i64 = bp[6]
66 let g7: i64 = bp[7]
67 let ebuf: *u8 = g7 as *u8
68 let en: i64 = bp[8]
69 let g9: i64 = bp[9]
70 let prompt: *u8 = g9 as *u8
71 let g10: i64 = bp[10]
72 let body: *u8 = g10 as *u8
73 let g11: i64 = bp[11]
74 let resp: *u8 = g11 as *u8
75 let g12: i64 = bp[12]
76 let cand: *u8 = g12 as *u8
77 let g13: i64 = bp[13]
78 let cand2: *u8 = g13 as *u8
79 let g14: i64 = bp[14]
80 let srcpath: *u8 = g14 as *u8
81 let g15: i64 = bp[15]
82 let elfpath: *u8 = g15 as *u8
83 let g16: i64 = bp[16]
84 let av: *i64 = g16 as *i64
85 let g17: i64 = bp[17]
86 let envp: *i64 = g17 as *i64
87 let g18: i64 = bp[18]
88 let st: *i64 = g18 as *i64
89 let g19: i64 = bp[19]
90 let tmpb: *u8 = g19 as *u8
91 let g20: i64 = bp[20]
92 let rbuf: *u8 = g20 as *u8
93 let g21: i64 = bp[21]
94 let ctxpath: *u8 = g21 as *u8
95 let g22: i64 = bp[22]
96 let bldout: *u8 = g22 as *u8
97 let g23: i64 = bp[23]
98 let runout: *u8 = g23 as *u8
99 let temp_pm: i64 = bp[24]
100 let seedv: i64 = bp[25]
101 let plen: i64 = fm_compose_prompt(packpath, taskb, rp, prompt, 16000)
102 if plen <= 0 { return 0 - 3 }
103 var blen: i64 = flp_build_gen_body(prompt, plen, maxnew, 0, chat, body)
104 if temp_pm > 0 { blen = flp_splice_sampling(body, blen, temp_pm, seedv) }
105 let got: i64 = fm_post_gen(127, 0, 0, 1, port, body, blen, resp, 131072)
106 if got <= 0 { return 0 - 30 }
107 let tl: i64 = fm_extract_text(resp, got, cand, 65536)
108 if tl < 0 { return 0 - 31 }
109 var cl: i64 = 0
110 if tl > 0 { cl = fm_strip_fences(cand, tl, cand2) }
111 if cl <= 0 {
112 let cfd: i64 = sys_openat_wr(ctxpath, 420)
113 if cfd >= 0 { fc_ws(cfd, "CYCLE-FAIL empty-candidate (model returned no source)\n" as *u8) }
114 if cfd >= 0 { sys_close(cfd) }
115 std_putln(" -> empty-candidate" as *u8)
116 return 0
117 }
118 let sfd: i64 = sys_openat_wr(srcpath, 420)
119 if sfd < 0 { return 0 - 34 }
120 let wr: i64 = fc_wb(sfd, cand2, cl)
121 sys_close(sfd)
122 if wr != 0 { return 0 - 34 }
123 av[0] = "_offc/nx_sov_build_run.elf" as *u8 as i64
124 av[1] = organ as i64
125 av[2] = "--build-only" as *u8 as i64
126 av[3] = 0
127 let bfail: i64 = fg_spawn(bldout, av, envp, st)
128 if bfail == 1 {
129 let cfd2: i64 = sys_openat_wr(ctxpath, 420)
130 if cfd2 >= 0 { fg_bank(cfd2, "CYCLE-FAIL build; verbatim compiler output:\n" as *u8, bldout, tmpb, 65536) }
131 if cfd2 >= 0 { sys_close(cfd2) }
132 std_putln(" -> BUILD-FAIL (stderr banked)" as *u8)
133 return 0
134 }
135 av[0] = elfpath as i64
136 av[1] = 0
137 let rfail: i64 = fg_spawn(runout, av, envp, st)
138 if rfail == 1 {
139 let cfd3: i64 = sys_openat_wr(ctxpath, 420)
140 if cfd3 >= 0 { fg_bank(cfd3, "CYCLE-FAIL run-nonzero; output:\n" as *u8, runout, tmpb, 65536) }
141 if cfd3 >= 0 { sys_close(cfd3) }
142 std_putln(" -> RUN-FAIL (output banked)" as *u8)
143 return 0
144 }
145 let rn: i64 = fc_read(runout, rbuf, 65536)
146 var ok: i64 = 0
147 if rn == en {
148 var m: i64 = 0
149 var eq: i64 = 1
150 while m < en {
151 let x: i64 = rbuf[m] as i64
152 let y: i64 = ebuf[m] as i64
153 if x != y { eq = 0; m = en }
154 if x == y { m = m + 1 }
155 }
156 ok = eq
157 }
158 if ok == 1 {
159 std_putln(" -> GREEN byte-exact" as *u8)
160 return 1
161 }
162 let cfd4: i64 = sys_openat_wr(ctxpath, 420)
163 if cfd4 >= 0 { fg_bank(cfd4, "CYCLE-FAIL output-mismatch; got:\n" as *u8, runout, tmpb, 65536) }
164 if cfd4 >= 0 { sys_close(cfd4) }
165 std_putln(" -> JUDGE-REJECT (bytes differ)" as *u8)
166 return 0
167}
168
169// the closed loop: task+pack -> model candidate -> byte-exact judge -> repair re-prompt, bounded.
170func flp_run(organ: *u8, taskpath: *u8, expectpath: *u8, packpath: *u8, port: i64, maxc0: i64, maxnew: i64, chat: i64) -> i64 {
171 let ctxpath: *u8 = "/tmp/forge_loop_ctx.txt" as *u8
172 let bldout: *u8 = "/tmp/forge_loop_build.out" as *u8
173 let runout: *u8 = "/tmp/forge_loop_run.out" as *u8
174 let nullp: *u8 = 0 as *u8
175 let ol: i64 = std_slen(organ)
176 if ol <= 2 || ol > 100 { return 0 - 22 }
177 let taskb: *u8 = sys_mmap(8192) as *u8
178 let ebuf: *u8 = sys_mmap(65536) as *u8
179 let prompt: *u8 = sys_mmap(32768) as *u8
180 let body: *u8 = sys_mmap(65536) as *u8
181 let resp: *u8 = sys_mmap(131072) as *u8
182 let cand: *u8 = sys_mmap(65536) as *u8
183 let cand2: *u8 = sys_mmap(65536) as *u8
184 let srcpath: *u8 = sys_mmap(256) as *u8
185 let elfpath: *u8 = sys_mmap(256) as *u8
186 let av: *i64 = sys_mmap(64) as *i64
187 let envp: *i64 = sys_mmap(32) as *i64
188 let st: *i64 = sys_mmap(64) as *i64
189 let tmpb: *u8 = sys_mmap(65536) as *u8
190 let rbuf: *u8 = sys_mmap(65536) as *u8
191 let bp: *i64 = sys_mmap(256) as *i64
192 let tn: i64 = fc_read(taskpath, taskb, 8192)
193 if tn <= 0 { return 0 - 2 }
194 let en: i64 = fc_read(expectpath, ebuf, 65536)
195 if en <= 0 { return 0 - 4 }
196 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64
197 envp[1] = 0
198 fg_mkpath("runtime/" as *u8, organ, ".nx" as *u8, srcpath)
199 fg_mkpath("/tmp/" as *u8, organ, ".sov.elf" as *u8, elfpath)
200 // stale repair ctx from a prior run must not leak into this run's cycle 2
201 let cfd0: i64 = sys_openat_wr(ctxpath, 420)
202 if cfd0 >= 0 { sys_close(cfd0) }
203 bp[0] = organ as i64
204 bp[1] = taskb as i64
205 bp[2] = packpath as i64
206 bp[3] = nullp as i64
207 bp[4] = port
208 bp[5] = maxnew
209 bp[6] = chat
210 bp[7] = ebuf as i64
211 bp[8] = en
212 bp[9] = prompt as i64
213 bp[10] = body as i64
214 bp[11] = resp as i64
215 bp[12] = cand as i64
216 bp[13] = cand2 as i64
217 bp[14] = srcpath as i64
218 bp[15] = elfpath as i64
219 bp[16] = av as i64
220 bp[17] = envp as i64
221 bp[18] = st as i64
222 bp[19] = tmpb as i64
223 bp[20] = rbuf as i64
224 bp[21] = ctxpath as i64
225 bp[22] = bldout as i64
226 bp[23] = runout as i64
227 bp[24] = 0
228 bp[25] = 0
229 var maxc: i64 = maxc0
230 if maxc <= 0 { maxc = 1 }
231 if maxc > 7 { maxc = 7 }
232 var cycle: i64 = 0
233 var verdict: i64 = 0 - 21
234 var done: i64 = 0
235 while done == 0 {
236 if cycle >= maxc { verdict = 0 - 21; done = 1 }
237 if done == 0 {
238 cycle = cycle + 1
239 std_puts("FORGE-LOOP cycle=" as *u8)
240 std_pdec(cycle)
241 var rp: *u8 = nullp
242 if cycle > 1 { rp = ctxpath }
243 bp[3] = rp as i64
244 let r: i64 = flp_cycle(bp)
245 if r == 1 { verdict = cycle; done = 1 }
246 if r < 0 {
247 var vr: i64 = r
248 if r + 3 == 0 && cycle > 1 { vr = 0 - 33 }
249 verdict = vr
250 done = 1
251 }
252 }
253 }
254 let lfd: i64 = sys_openat_append("knowledge/forge/forge_ledger.txt" as *u8, 420)
255 if lfd >= 0 {
256 fc_ws(lfd, "FORGE|" as *u8)
257 fc_ws(lfd, organ)
258 fc_ws(lfd, "|cycles=" as *u8)
259 fg_wdec(lfd, cycle)
260 fc_ws(lfd, "|verdict=" as *u8)
261 if verdict > 0 { fc_ws(lfd, "GREEN" as *u8) }
262 if verdict <= 0 { fc_ws(lfd, "RED" as *u8) }
263 fc_ws(lfd, "|rc=" as *u8)
264 fg_wdec(lfd, verdict)
265 fc_ws(lfd, "|us=" as *u8)
266 let now: i64 = sys_now_us()
267 fg_wdec(lfd, now)
268 fc_ws(lfd, "\n" as *u8)
269 sys_close(lfd)
270 }
271 return verdict
272}