code wiki / _hdl_build / nx_frame_score.nx
nx_frame_score.nx source
↩ module page · 272 lines · 13742 B
1// nx_frame_score.nx -- score ANY captured frame with the hardened nx_game_critic, ONE ruler ONE scale.
2//
3// WHY (seq890/seq1004): the head-to-head vsbench contract says a Tier-3 EXT cell must be measured off a
4// captured artifact by OUR instrument -- but the organ that minted the first EXT cell existed in NO source
5// tree and was never registered, so the evidence path was not reproducible by any agent. This is that
6// organ rebuilt from the first byte as a REGISTERED MCP tool: OUR render and a REFERENCE render are graded
7// by the SAME deployed binary on the SAME scale, on the NAS, with the artifact on disk.
8//
9// INPUT FORMAT NXFH1 (text-hex framebuffer -- deliberately TEXT so it travels the fs-write lane safely;
10// raw binary through JSON-string tooling is the proven corruption path):
11// line 1: "NXFH1 <w> <h>\n" then w*h pixels as 6 lowercase hex chars each (rrggbb), any
12// whitespace between pixels ignored. Encoder: scratchpad/png2hex.js (same code path for BOTH sides).
13// USAGE: nx_frame_score <path.nxfh> | nx_frame_score selftest
14// Composes nx_game_critic (gc_score/gc_quality/gc_verdict) -- nothing re-implemented.
15// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
16import "nx_syscalls.nx"
17import "nx_game_critic.nx"
18const FS_MAGIC_65536: i64 = 65536
19const FS_MAGIC_3600: i64 = 3600
20
21// ★NO RESOLUTION CEILING. FS_MAXW/FS_MAXH (1024, underived) were REMOVED 2026-08-28, not raised:
22// raising a guessed cap only moves the guess, and this one refused the product's own 1920x1200
23// capture. The declared extent is now bounded by what the file can arithmetically hold (see fs_load).
24// Every pixel of an NXFH1 body is exactly six hex characters -- that is the format, not a tuning
25// number, and it is the divisor the derived bound uses.
26const FS_HEX_PER_PX: i64 = 6
27const FS_SELF_W: i64 = 400 // the canonical comparison scale (the Veloren-cell methodology)
28const FS_SELF_H: i64 = 240
29
30func ocat(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 }
31func onum(o: *u8, at: i64, v: i64) -> i64 {
32 var a: i64=at; var m: i64=v
33 if m==0 { o[a]=48 as u8; return a+1 }
34 if m<0 { o[a]=45 as u8; a=a+1; m=0-m }
35 let t: *u8 = sys_mmap(32); var k: i64=0
36 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 }
37 var q: i64=k-1
38 while q>=0 { o[a]=t[q]; a=a+1; q=q-1 }
39 return a
40}
41func emit(o: *u8, n: i64) -> i64 { sys_write(1, o, n); return 0 }
42
43// hex nibble -> value; -1 on a non-hex byte
44func fs_nib(c: i64) -> i64 {
45 if c >= 48 { if c <= 57 { return c - 48 } }
46 if c >= 97 { if c <= 102 { return c - 87 } }
47 if c >= 65 { if c <= 70 { return c - 55 } }
48 return 0-1
49}
50func fs_isws(c: i64) -> i64 { if c==32 { return 1 } if c==10 { return 1 } if c==13 { return 1 } if c==9 { return 1 } return 0 }
51
52// parse an ascii integer at buf[p..], stop at non-digit; returns value, writes end pos to pp[0]
53func fs_int(b: *u8, p: i64, n: i64, pp: *i64) -> i64 {
54 var v: i64 = 0
55 var i: i64 = p
56 while i < n {
57 let c: i64 = b[i] as i64
58 if c < 48 { pp[0]=i; return v }
59 if c > 57 { pp[0]=i; return v }
60 v = v*10 + (c-48)
61 i = i + 1
62 }
63 pp[0]=i
64 return v
65}
66
67// Load an NXFH1 file into a freshly mmapped packed fb (r | g<<8 | b<<16, the critic's layout).
68// On success writes w,h to whp[0],whp[1] and returns the fb ptr; on any malformation returns 0 --
69// a truncated or corrupt capture must be REFUSED loudly, never scored as a dark frame.
70func fs_load(path: *u8, whp: *i64) -> *i64 {
71 let lenp: *i64 = sys_mmap(8) as *i64
72 lenp[0]=0
73 let b: *u8 = sys_read_file(path, lenp)
74 if (b as i64)==0 { return 0 as *i64 }
75 let n: i64 = lenp[0]
76 if n < 12 { return 0 as *i64 }
77 // magic "NXFH1 "
78 if b[0]!=(78 as u8) { return 0 as *i64 }
79 if b[1]!=(88 as u8) { return 0 as *i64 }
80 if b[2]!=(70 as u8) { return 0 as *i64 }
81 if b[3]!=(72 as u8) { return 0 as *i64 }
82 if b[4]!=(49 as u8) { return 0 as *i64 }
83 let pp: *i64 = sys_mmap(8) as *i64
84 var p: i64 = 5
85 while p < n { if fs_isws(b[p] as i64)==1 { p=p+1 } else { p = n + p; } }
86 p = p - n // first non-ws after magic
87 let w: i64 = fs_int(b, p, n, pp)
88 p = pp[0]
89 while p < n { if fs_isws(b[p] as i64)==1 { p=p+1 } else { p = n + p; } }
90 p = p - n
91 let h: i64 = fs_int(b, p, n, pp)
92 p = pp[0]
93 if w < 8 { return 0 as *i64 }
94 if h < 8 { return 0 as *i64 }
95 // ★THE ONLY HONEST BOUND ON A DECLARED PIXEL COUNT IS WHAT THE FILE CAN ACTUALLY HOLD.
96 // This was `if w > FS_MAXW` / `if h > FS_MAXH` against a bare, underived 1024 -- and 1024 is not a
97 // property of anything in this organ: the framebuffer below is ALREADY sized from w*h, so the cap
98 // bought no safety and cost capability. MEASURED 2026-08-28: a 1920x1200 world capture -- the
99 // product's OWN resolution, per knowledge/capres.conf -- was refused here by the estate's
100 // game-frame critic, and the refusal blamed the CAPTURE ("not a well-formed NXFH1 frame ... or
101 // pixel count != w*h"), naming four possible causes with its own ceiling not among them.
102 // ★A JUDGE THAT REFUSES A FULL-RESOLUTION FRAME AND BLAMES THE FRAME SENDS EVERY INVESTIGATION AT
103 // THE CAPTURE. Raising the cap would only move the guess (operator: a buffer cap is not a number to
104 // tune), so it is DERIVED instead: every pixel is exactly FS_HEX_PER_PX hex characters and
105 // whitespace only makes the body smaller, so a body of (n - p) bytes can encode at most
106 // (n - p)/FS_HEX_PER_PX pixels. A declared w*h above that is unsatisfiable BY ARITHMETIC, so
107 // refusing it is exact rather than a guess -- and it still bounds the mmap below against a corrupt
108 // header declaring an absurd extent, which is the only thing the old cap was really doing.
109 // The end-of-parse truncation check (px == w*h) is unchanged and still catches everything else.
110 let body_cap: i64 = (n - p)/FS_HEX_PER_PX
111 if w*h > body_cap { return 0 as *i64 }
112 let need: i64 = w*h
113 let fb: *i64 = sys_mmap(need*8) as *i64
114 var px: i64 = 0
115 var acc: i64 = 0
116 var nyb: i64 = 0
117 while p < n {
118 let c: i64 = b[p] as i64
119 if fs_isws(c)==0 {
120 let v: i64 = fs_nib(c)
121 if v < 0 { return 0 as *i64 } // junk byte = REFUSE, not "score what parsed"
122 acc = acc*16 + v
123 nyb = nyb + 1
124 if nyb == 6 {
125 if px >= need { return 0 as *i64 } // more pixels than declared = REFUSE
126 // hex is rrggbb; critic wants r | g<<8 | b<<16
127 let r: i64 = (acc / FS_MAGIC_65536) % 256
128 let g: i64 = (acc / 256) % 256
129 let bb: i64 = acc % 256
130 fb[px] = r + g*256 + bb*FS_MAGIC_65536
131 px = px + 1
132 acc = 0
133 nyb = 0
134 }
135 }
136 p = p + 1
137 }
138 if px != need { return 0 as *i64 } // short capture = REFUSE
139 if nyb != 0 { return 0 as *i64 }
140 whp[0]=w
141 whp[1]=h
142 return fb
143}
144
145// score a packed fb and emit the JSON row
146func fs_report(fb: *i64, w: i64, h: i64, label: *u8) -> i64 {
147 let m: *i64 = sys_mmap(GC_N*8) as *i64
148 gc_score(fb, w, h, m)
149 let q: i64 = gc_quality(m)
150 let jb: *u8 = sys_mmap(GC_MAGIC_4096)
151 var j: i64 = 0
152 j = ocat(jb, j, "{\x22organ\x22:\x22nx_frame_score\x22,\x22src\x22:\x22" as *u8)
153 j = ocat(jb, j, label)
154 j = ocat(jb, j, "\x22,\x22w\x22:" as *u8); j = onum(jb, j, w)
155 j = ocat(jb, j, ",\x22h\x22:" as *u8); j = onum(jb, j, h)
156 j = ocat(jb, j, ",\x22pal\x22:" as *u8); j = onum(jb, j, m[GC_M_PAL])
157 j = ocat(jb, j, ",\x22det1\x22:" as *u8); j = onum(jb, j, m[GC_M_DET1])
158 j = ocat(jb, j, ",\x22det4\x22:" as *u8); j = onum(jb, j, m[GC_M_DET4])
159 j = ocat(jb, j, ",\x22grad\x22:" as *u8); j = onum(jb, j, m[GC_M_GRAD])
160 j = ocat(jb, j, ",\x22cov\x22:" as *u8); j = onum(jb, j, m[GC_M_COV])
161 j = ocat(jb, j, ",\x22cohere\x22:" as *u8); j = onum(jb, j, m[GC_M_COHERE])
162 j = ocat(jb, j, ",\x22quality\x22:" as *u8); j = onum(jb, j, q)
163 j = ocat(jb, j, ",\x22verdict\x22:\x22" as *u8); j = ocat(jb, j, gc_verdict(q))
164 j = ocat(jb, j, "\x22,\x22ruler\x22:\x22hardened nx_game_critic (coherence-capped, red-teamed vs noise); one code path for OURS and THEIRS\x22" as *u8)
165 // CALIBRATION CONVICTION 2026-08-09 (operator: "its still a flat screen of squares this isnt
166 // anywhere near 875 out of 1000"): a deterministic random-squares mosaic (knowledge/
167 // squares_control.nxfh, zero art, zero scene) scores 628 RICH on this composite while flat colour
168 // scores 2 TOY and saturated commercial renders read 1000. The composite therefore separates
169 // TOY from STRUCTURED and is UNCALIBRATED AS QUALITY above ~600 -- the commercial band (789-1000)
170 // overlaps the band reachable by coloured squares. The emitter must say so on every read.
171 j = ocat(jb, j, ",\x22calibration\x22:\x22composite is a STRUCTURE floor, not a quality rank: random-squares control scores 628 RICH (measured 2026-08-09, knowledge/squares_control.nxfh); values above ~600 order by statistics, not perceived quality -- never quote composite as quality without a same-class perceptual comparison\x22}" as *u8)
172 jb[j]=10 as u8
173 emit(jb, j+1)
174 return q
175}
176
177// deterministic synthetic frames for selftest -- a flat TOY scene and a gradient RICH scene.
178func fs_mk_toy(fb: *i64, w: i64, h: i64) -> i64 {
179 var i: i64 = 0
180 while i < w*h { fb[i] = 16 + 18*256 + 28*FS_MAGIC_65536; i=i+1 }
181 // three flat discs (the shipped-game failure mode the critic was hardened against)
182 var y: i64 = 0
183 while y < h {
184 var x: i64 = 0
185 while x < w {
186 var k: i64 = 0
187 while k < 3 {
188 let cx: i64 = (w/4)*(k+1)
189 let cy: i64 = h/2
190 let dx: i64 = x-cx
191 let dy: i64 = y-cy
192 if dx*dx + dy*dy < 900 { fb[y*w+x] = 90 + 60*256 + 40*FS_MAGIC_65536 }
193 k = k + 1
194 }
195 x = x + 1
196 }
197 y = y + 1
198 }
199 return 0
200}
201func fs_mk_rich(fb: *i64, w: i64, h: i64) -> i64 {
202 var y: i64 = 0
203 while y < h {
204 var x: i64 = 0
205 while x < w {
206 // smooth two-axis gradient bg (coherent by construction) + varied palette banding
207 let r: i64 = (x*255)/w
208 let g: i64 = (y*255)/h
209 let b: i64 = ((x+y)*255)/(w+h)
210 var v: i64 = r + g*256 + b*FS_MAGIC_65536
211 // structured detail: soft diagonal bands + a lit sphere
212 if ((x/24)+(y/24))%2==0 { v = (r*3/4) + (g*3/4)*256 + (b*3/4)*FS_MAGIC_65536 }
213 let dx: i64 = x - w/2
214 let dy: i64 = y - h/2
215 let d2: i64 = dx*dx + dy*dy
216 if d2 < FS_MAGIC_3600 {
217 let lum: i64 = 255 - (d2*220)/FS_MAGIC_3600
218 v = lum + ((lum*3/4))*256 + ((lum/2))*FS_MAGIC_65536
219 }
220 fb[y*w+x] = v
221 x = x + 1
222 }
223 y = y + 1
224 }
225 return 0
226}
227
228func main(argc: i64, argv: *i64) -> i64 {
229 if argc < 2 {
230 let e: *u8 = "{\x22organ\x22:\x22nx_frame_score\x22,\x22error\x22:\x22usage: nx_frame_score <path.nxfh> | selftest\x22,\x22fix\x22:\x22pass an NXFH1 text-hex frame (scratchpad/png2hex.js emits it) or run selftest\x22}\n" as *u8
231 var n: i64=0
232 while e[n]!=(0 as u8) { n=n+1 }
233 emit(e, n)
234 return 2
235 }
236 let a1: *u8 = argv[1] as *u8
237 // selftest: generate, score, and REQUIRE the toy<rich margin -- verify-by-behavior with no upload
238 if a1[0]==(115 as u8) {
239 if a1[1]==(101 as u8) {
240 let fb1: *i64 = sys_mmap(FS_SELF_W*FS_SELF_H*8) as *i64
241 let fb2: *i64 = sys_mmap(FS_SELF_W*FS_SELF_H*8) as *i64
242 fs_mk_toy(fb1, FS_SELF_W, FS_SELF_H)
243 fs_mk_rich(fb2, FS_SELF_W, FS_SELF_H)
244 let qt: i64 = fs_report(fb1, FS_SELF_W, FS_SELF_H, "selftest-toy" as *u8)
245 let qr: i64 = fs_report(fb2, FS_SELF_W, FS_SELF_H, "selftest-rich" as *u8)
246 let jb: *u8 = sys_mmap(512)
247 var j: i64 = 0
248 j = ocat(jb, j, "{\x22selftest\x22:\x22" as *u8)
249 if qr > qt { if qr - qt >= 250 { j = ocat(jb, j, "PASS" as *u8) } }
250 if qr - qt < 250 { j = ocat(jb, j, "FAIL" as *u8) }
251 j = ocat(jb, j, "\x22,\x22toy\x22:" as *u8); j = onum(jb, j, qt)
252 j = ocat(jb, j, ",\x22rich\x22:" as *u8); j = onum(jb, j, qr)
253 j = ocat(jb, j, ",\x22margin\x22:" as *u8); j = onum(jb, j, qr-qt)
254 j = ocat(jb, j, ",\x22note\x22:\x22a critic that cannot separate a flat toy from a structured scene is not a critic\x22}" as *u8)
255 jb[j]=10 as u8
256 emit(jb, j+1)
257 if qr - qt < 250 { return 1 }
258 return 0
259 }
260 }
261 let whp: *i64 = sys_mmap(16) as *i64
262 let fb: *i64 = fs_load(a1, whp)
263 if (fb as i64)==0 {
264 let e2: *u8 = "{\x22organ\x22:\x22nx_frame_score\x22,\x22error\x22:\x22REFUSED: not a well-formed NXFH1 frame (missing, bad magic, junk bytes, or pixel count != w*h)\x22,\x22note\x22:\x22this organ has NO resolution ceiling since 2026-08-28: the declared w*h is bounded only by what the file can arithmetically hold (6 hex chars per pixel), so a REFUSAL here is about the FILE, never about the frame being too large\x22,\x22fix\x22:\x22re-encode with scratchpad/png2hex.js; a truncated capture must never be scored as a dark frame\x22}\n" as *u8
265 var n2: i64=0
266 while e2[n2]!=(0 as u8) { n2=n2+1 }
267 emit(e2, n2)
268 return 3
269 }
270 fs_report(fb, whp[0], whp[1], a1)
271 return 0
272}