code wiki / _hdl_build / nx_artloop.nx
nx_artloop.nx source
↩ module page · 221 lines · 10364 B
1// nx_artloop.nx -- AL1: THE RECURSIVE ART-LOOP BEAT (operator 2026-08-09: "i want nishi ecosystem to
2// gain these functionalities as a recursive learning setup so that it can keep growing" + "you need
3// to have benchmarks and oracles so you arent just generating junk").
4// One beat = one unattended cycle of the emit-score-look loop, clock-plane scheduled:
5// fork the DEPLOYED engine `sweep` (6 procedurally-derived material families rendered, scored,
6// contact-sheeted to the served site by the engine itself), then bank the cycle APPEND-ONLY.
7// ORACLES -- junk cannot pass, and a drifting instrument cannot silently bless anything:
8// O1 INSTRUMENT SANITY: the caricature controls must hold their banked bands EVERY cycle --
9// flat_control < 300 (TOY) and squares_control in [598,658] (banked 628); plus a LIVE benchmark
10// re-score: breeders1 must hold [779,799] (banked 789). Any drift => the CRITIC moved => RED,
11// and no other number this cycle is believable (stale-instrument law).
12// O2 JUNK FLOOR: the shipped-default variant must clear squares_control + 120. A frame that cannot
13// beat a literal random-squares mosaic by a real margin is junk => RED.
14// O3 RATCHET: best= is the historical max of the default variant's STRUCTURE score (the composite
15// is a structure floor, NEVER quality -- caricature conviction 2026-08-09); dropping below the
16// banked best is a regression => RED. The record still lands FIRST: report, never hide.
17// JOURNAL: knowledge/status/artloop.jrnl, append-only via full-rewrite to .tmp + sys_renameat
18// (atomic -- a crash never truncates history). One line per cycle, RAW sweep receipt included
19// (bank the raw record; derived analysis is downstream's job). PICKS stay judged by eyes (AL2).
20// license_tier: ORIGINAL expect_exit: 0
21import "nx_syscalls.nx"
22import "nx_tool_run.nx"
23
24const AL_CAP: i64 = 65536
25const AL_JCAP: i64 = 2097152
26
27func aw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
28func acat(o: *u8, at: i64, s: *u8) -> i64 { var i: i64=0; var a: i64=at; while s[i]!=(0 as u8){o[a]=s[i]; a=a+1; i=i+1} return a }
29func anum(o: *u8, at: i64, v: i64) -> i64 {
30 var a: i64=at; var m: i64=v
31 if m==0 { o[a]=48 as u8; return a+1 }
32 if m<0 { o[a]=45 as u8; a=a+1; m=0-m }
33 let t: *u8 = sys_mmap(32); var k: i64=0
34 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 }
35 var q: i64=k-1
36 while q>=0 { o[a]=t[q]; a=a+1; q=q-1 }
37 return a
38}
39func apn(v: i64) -> i64 { let b: *u8 = sys_mmap(32); let e: i64 = anum(b,0,v); sys_write(1,b,e); return 0 }
40
41// find needle in hay[from..n): return index or -1 (separate cursor, explicit result -- the eol law)
42func afind(hay: *u8, n: i64, from: i64, needle: *u8) -> i64 {
43 var nl: i64=0
44 while needle[nl]!=(0 as u8) { nl=nl+1 }
45 if nl==0 { return 0-1 }
46 var i: i64=from
47 while i+nl<=n {
48 var k: i64=0
49 var ok: i64=1
50 while k<nl { if hay[i+k]!=needle[k] { ok=0; k=nl } else { k=k+1 } }
51 if ok==1 { return i }
52 i=i+1
53 }
54 return 0-1
55}
56func aint(b: *u8, pos: i64, n: i64) -> i64 {
57 var v: i64=0
58 var i: i64=pos
59 var got: i64=0
60 while i<n {
61 let c: i64 = b[i] as i64
62 if c>=48 { if c<=57 { v=v*10+(c-48); got=1; i=i+1 } else { i=n } } else { i=n }
63 }
64 if got==0 { return 0-1 }
65 return v
66}
67
68// fork ./nx_frame_score.elf <artifact>, parse the first "quality": value. -1 on any failure.
69func ascore(art: *u8) -> i64 {
70 let out: *u8 = sys_mmap(AL_CAP)
71 let ol: *i64 = sys_mmap(8) as *i64
72 ol[0]=0
73 let av: *i64 = sys_mmap(32) as *i64
74 av[0] = "./nx_frame_score.elf" as *u8 as i64
75 av[1] = art as i64
76 av[2] = 0
77 let rc: i64 = tr_run_capture("./nx_frame_score.elf" as *u8, av, out, AL_CAP, ol)
78 if rc != 0 { return 0-1 }
79 let n: i64 = ol[0]
80 let p: i64 = afind(out, n, 0, "\x22quality\x22:" as *u8)
81 if p < 0 { return 0-1 }
82 return aint(out, p+10, n)
83}
84
85func main() -> i64 {
86 aw("=== nx_artloop: one unattended cycle of the recursive art loop ===\x0a" as *u8)
87 // ---- O1 instrument sanity: controls + live benchmark hold their banked bands ----
88 let qf: i64 = ascore("knowledge/flat_control.nxfh" as *u8)
89 let qs: i64 = ascore("knowledge/squares_control.nxfh" as *u8)
90 let qb: i64 = ascore("knowledge/breeders1.nxfh" as *u8)
91 aw(" O1 flat=" as *u8); apn(qf)
92 aw(" squares=" as *u8); apn(qs)
93 aw(" breeders=" as *u8); apn(qb)
94 aw(" (bands: flat<300, squares 598..658, breeders 779..799)\x0a" as *u8)
95 var o1: i64 = 1
96 if qf < 0 { o1 = 0 }
97 if qf >= 300 { o1 = 0 }
98 if qs < 598 { o1 = 0 }
99 if qs > 658 { o1 = 0 }
100 if qb < 779 { o1 = 0 }
101 if qb > 799 { o1 = 0 }
102 if o1 == 0 {
103 aw("ARTLOOP O1 RED: instrument drifted -- nothing this cycle is believable\x0averdict=RED\x0a" as *u8)
104 return 1
105 }
106 // ---- run the deployed engine sweep (renders + scores + publishes the sheet itself) ----
107 let out: *u8 = sys_mmap(AL_CAP)
108 let ol: *i64 = sys_mmap(8) as *i64
109 ol[0]=0
110 let av: *i64 = sys_mmap(32) as *i64
111 av[0] = "./nx_m2d_engine.elf" as *u8 as i64
112 av[1] = "sweep" as *u8 as i64
113 av[2] = 0
114 let rc: i64 = tr_run_capture("./nx_m2d_engine.elf" as *u8, av, out, AL_CAP, ol)
115 let n: i64 = ol[0]
116 if rc != 0 { aw("ARTLOOP RED: sweep exit != 0\x0averdict=RED\x0a" as *u8); return 1 }
117 if n < 200 { aw("ARTLOOP RED: sweep output vacuous (<200B)\x0averdict=RED\x0a" as *u8); return 1 }
118 let pv: i64 = afind(out, n, 0, "\x22v\x22:0" as *u8)
119 if pv < 0 { aw("ARTLOOP RED: no v0 in sweep receipt\x0averdict=RED\x0a" as *u8); return 1 }
120 let pq: i64 = afind(out, n, pv, "\x22quality\x22:" as *u8)
121 if pq < 0 { aw("ARTLOOP RED: no v0 quality in sweep receipt\x0averdict=RED\x0a" as *u8); return 1 }
122 let q0: i64 = aint(out, pq+10, n)
123 if q0 < 0 { aw("ARTLOOP RED: v0 quality unparsable\x0averdict=RED\x0a" as *u8); return 1 }
124 // ---- journal read: prior best + cycle count (absent journal = first cycle) ----
125 let jl: *i64 = sys_mmap(8) as *i64
126 jl[0]=0
127 var jb: *u8 = sys_read_file("knowledge/status/artloop.jrnl" as *u8, jl)
128 var jn: i64 = jl[0]
129 if (jb as i64) == 0 { jn = 0 }
130 var prevbest: i64 = 0
131 var cycles: i64 = 0
132 var sp: i64 = 0
133 var go: i64 = 1
134 while go == 1 {
135 let hit: i64 = afind(jb, jn, sp, "cycle=" as *u8)
136 if hit < 0 { go = 0 }
137 if go == 1 { cycles = cycles + 1; sp = hit + 6 }
138 }
139 sp = 0
140 go = 1
141 while go == 1 {
142 let hit2: i64 = afind(jb, jn, sp, " best=" as *u8)
143 if hit2 < 0 { go = 0 }
144 if go == 1 { prevbest = aint(jb, hit2+6, jn); sp = hit2 + 6 }
145 }
146 // ---- O4 (2026-08-10): the PERCEPTUAL JUNK FENCE -- nx_percept's ladder REFUSED it as a pick
147 // judge (it cannot reproduce the human top ordering, published honestly) but its junk separation
148 // held 12/13 with margin: junk anchors score NEGATIVE, every real frame POSITIVE. The shipped
149 // frame must stay on the real side of that fence. An independent instrument from the composite.
150 let out4: *u8 = sys_mmap(AL_CAP)
151 let ol4: *i64 = sys_mmap(8) as *i64
152 ol4[0]=0
153 let av4: *i64 = sys_mmap(32) as *i64
154 av4[0] = "./nx_percept.elf" as *u8 as i64
155 av4[1] = "judge" as *u8 as i64
156 av4[2] = "knowledge/nx_m2d_frame.nxfh" as *u8 as i64
157 av4[3] = 0
158 let rc4: i64 = tr_run_capture("./nx_percept.elf" as *u8, av4, out4, AL_CAP, ol4)
159 var pscore: i64 = 0-999
160 if rc4 == 0 {
161 let pp: i64 = afind(out4, ol4[0], 0, "\x22score\x22:" as *u8)
162 if pp >= 0 {
163 var ps4: i64 = pp+8
164 var neg4: i64 = 0
165 if out4[ps4] == (45 as u8) { neg4 = 1; ps4 = ps4 + 1 }
166 pscore = aint(out4, ps4, ol4[0])
167 if neg4 == 1 { if pscore >= 0 { pscore = 0 - pscore } }
168 }
169 }
170 var o4: i64 = 1
171 if pscore <= 0 { o4 = 0 }
172 // ---- teeth O2 + O3 (values first, verdict last) ----
173 let floorq: i64 = qs + 120
174 var best: i64 = q0
175 if prevbest > best { best = prevbest }
176 aw(" cycle=" as *u8); apn(cycles+1)
177 aw(" q0=" as *u8); apn(q0)
178 aw(" junk_floor=" as *u8); apn(floorq)
179 aw(" prev_best=" as *u8); apn(prevbest)
180 aw(" best=" as *u8); apn(best)
181 aw(" pscore=" as *u8); apn(pscore)
182 aw("\x0a" as *u8)
183 var o2: i64 = 1
184 if q0 < floorq { o2 = 0 }
185 var o3: i64 = 1
186 if prevbest > 0 { if q0 < prevbest { o3 = 0 } }
187 // ---- append the cycle record FIRST (report, never hide), atomic tmp+rename ----
188 let nb: *u8 = sys_mmap(AL_JCAP)
189 var w: i64 = 0
190 var ci: i64 = 0
191 while ci < jn { nb[ci] = jb[ci]; ci = ci + 1 }
192 w = jn
193 w = acat(nb, w, "cycle=" as *u8); w = anum(nb, w, cycles+1)
194 w = acat(nb, w, " q0=" as *u8); w = anum(nb, w, q0)
195 w = acat(nb, w, " best=" as *u8); w = anum(nb, w, best)
196 w = acat(nb, w, " flat=" as *u8); w = anum(nb, w, qf)
197 w = acat(nb, w, " squares=" as *u8); w = anum(nb, w, qs)
198 w = acat(nb, w, " breeders=" as *u8); w = anum(nb, w, qb)
199 w = acat(nb, w, " o1=1 o2=" as *u8); w = anum(nb, w, o2)
200 w = acat(nb, w, " o3=" as *u8); w = anum(nb, w, o3)
201 w = acat(nb, w, " o4=" as *u8); w = anum(nb, w, o4)
202 w = acat(nb, w, " pscore=" as *u8); w = anum(nb, w, pscore)
203 w = acat(nb, w, " raw=" as *u8)
204 var ri: i64 = 0
205 while ri < n { if out[ri] != (10 as u8) { nb[w] = out[ri]; w = w + 1 } ri = ri + 1 }
206 nb[w] = 10 as u8
207 w = w + 1
208 let fd: i64 = sys_openat_wr("knowledge/status/artloop.jrnl.tmp" as *u8, 0x1a4)
209 if fd < 0 { aw("ARTLOOP RED: journal tmp open failed\x0averdict=RED\x0a" as *u8); return 1 }
210 sys_write(fd, nb, w)
211 sys_fsync(fd)
212 sys_close(fd)
213 let rr: i64 = sys_renameat("knowledge/status/artloop.jrnl.tmp" as *u8, "knowledge/status/artloop.jrnl" as *u8)
214 if rr != 0 { aw("ARTLOOP RED: journal rename failed\x0averdict=RED\x0a" as *u8); return 1 }
215 aw(" journal += 1 line (append-only, atomic)\x0a" as *u8)
216 if o2 == 0 { aw("ARTLOOP O2 RED: default variant under the junk floor\x0averdict=RED\x0a" as *u8); return 1 }
217 if o3 == 0 { aw("ARTLOOP O3 RED: structure regression vs banked best\x0averdict=RED\x0a" as *u8); return 1 }
218 if o4 == 0 { aw("ARTLOOP O4 RED: shipped frame on the junk side of the perceptual fence\x0averdict=RED\x0a" as *u8); return 1 }
219 aw("verdict=GREEN\x0a" as *u8)
220 return 0
221}