code wiki / _hdl_build / nx_parity_judge.nx

nx_parity_judge.nx source

↩ module page · 169 lines · 7931 B

1// nx_parity_judge.nx -- THE ORGAN EYE (operator 2026-07-16: "this workflow isnt complete until you see 2// the exact same issues i see without your or my involvement"). Given (oracle.png, nishi.png) of the SAME 3// page, it autonomously reports the failure classes a human eyeball found on the top-20 suite -- so the 4// suite self-diagnoses every run with NO human/Claude in the loop: 5// BLANK-NISHI nishi has almost no ink while the oracle has plenty (google: blank page scored 97.3% 6// parity by matching white space -- THE metric hole this organ closes) 7// STRIP-COLLAPSE nishi's ink is squeezed into a narrow vertical band (bing/netflix: 1-char-per-line 8// column collapse from a near-zero-width container) 9// CANVAS-OFF the two sides disagree about the page background color (hackernews: dark canvas vs beige) 10// SPARSE-NISHI nishi paints real ink but a fraction of the oracle's (missing bg-images/sections) 11// CONTENT-OK ink mass + spread comparable -- grade quality by the parity numbers 12// Ink = pixels differing from that side's own dominant background (corner-sampled) by > tol. 13// usage: nx_parity_judge <oracle.png> <nishi.png> [nishi_y_offset] (offset skips the browser chrome bar) 14// license_tier: ORIGINAL 15import "nx_visual_diff.nx" 16const K_MAGIC_4096: i64 = 4096 17 18func rj_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 19func rj_n(v: i64) -> i64 { let t: *u8=sys_mmap(24); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} let b: *u8=sys_mmap(24); var j: i64=0; while j<k{b[j]=t[k-1-j];j=j+1} sys_write(1,b,k); return 0 } 20func rj_atoi(s: *u8) -> i64 { var v: i64=0; var i: i64=0; while s[i]!=(0 as u8){ let c: i64=(s[i] as i64)&255; if c>=48 { if c<=57 { v=v*10+(c-48) } } i=i+1 } return v } 21 22// dominant background = average of the 4 corner 8x8 patches; writes r,g,b to out 23func rj_bg(im: *VdImg, yoff: i64, out: *i64) -> i64 { 24 var sr: i64 = 0 25 var sg: i64 = 0 26 var sb: i64 = 0 27 var n: i64 = 0 28 var cy: i64 = 0 29 while cy < 2 { 30 var cx: i64 = 0 31 while cx < 2 { 32 var y: i64 = 0 33 while y < 8 { 34 var x: i64 = 0 35 while x < 8 { 36 var px: i64 = x + 2 37 var py: i64 = y + 2 38 if cx == 1 { px = im.w - 26 + x } // inset past the ~14px scrollbar strip (it polluted 39 if cy == 1 { py = (im.h - yoff) - 10 + y } // netflix's corner sample -> ink read 999pm) 40 let o: i64 = ((py + yoff) * im.w + px) * im.nc 41 sr = sr + (im.px[o] as i64) 42 sg = sg + (im.px[o+1] as i64) 43 sb = sb + (im.px[o+2] as i64) 44 n = n + 1 45 x = x + 1 46 } 47 y = y + 1 48 } 49 cx = cx + 1 50 } 51 cy = cy + 1 52 } 53 out[0] = sr / n 54 out[1] = sg / n 55 out[2] = sb / n 56 return 0 57} 58// ink per-mille + the narrowest column-span holding >=80% of the ink (permille of width). 59// cols = a caller-provided i64 scratch of at least im.w entries. 60func rj_ink(im: *VdImg, yoff: i64, bg: *i64, tol: i64, cols: *i64, out: *i64) -> i64 { 61 var i: i64 = 0 62 while i < im.w { cols[i] = 0; i = i + 1 } 63 var ink: i64 = 0 64 var tot: i64 = 0 65 var y: i64 = 0 66 let hh: i64 = im.h - yoff 67 let wmax: i64 = im.w - 14 // exclude the scrollbar column from ink 68 while y < hh { 69 var x: i64 = 0 70 while x < wmax { 71 let o: i64 = ((y + yoff) * im.w + x) * im.nc 72 var dr: i64 = (im.px[o] as i64) - bg[0] 73 if dr < 0 { dr = 0 - dr } 74 var dg: i64 = (im.px[o+1] as i64) - bg[1] 75 if dg < 0 { dg = 0 - dg } 76 var db: i64 = (im.px[o+2] as i64) - bg[2] 77 if db < 0 { db = 0 - db } 78 tot = tot + 1 79 if dr > tol { ink = ink + 1; cols[x] = cols[x] + 1; x = x + 2 } 80 else { if dg > tol { ink = ink + 1; cols[x] = cols[x] + 1; x = x + 2 } 81 else { if db > tol { ink = ink + 1; cols[x] = cols[x] + 1; x = x + 2 } 82 else { x = x + 2 } } } 83 } 84 y = y + 2 85 } 86 out[0] = 0 87 if tot > 0 { out[0] = (ink * 1000) / tot } 88 // narrowest window of columns covering 80% of ink (two-pointer over the column histogram) 89 var total_ink: i64 = 0 90 i = 0 91 while i < im.w { total_ink = total_ink + cols[i]; i = i + 1 } 92 out[1] = 1000 93 if total_ink > 0 { 94 let need: i64 = (total_ink * 8) / 10 95 var lo: i64 = 0 96 var hi: i64 = 0 97 var acc: i64 = 0 98 var best: i64 = im.w 99 while hi < im.w { 100 acc = acc + cols[hi] 101 hi = hi + 1 102 var sh: i64 = 1 103 while sh == 1 { 104 if acc - cols[lo] >= need { acc = acc - cols[lo]; lo = lo + 1 } else { sh = 0 } 105 } 106 if acc >= need { if hi - lo < best { best = hi - lo } } 107 } 108 out[1] = (best * 1000) / im.w 109 } 110 return 0 111} 112 113// classify a loaded pair; returns the class code (0 ok · 1 blank · 2 strip · 3 canvas · 4 sparse · 114// 5 no-oracle) and prints the metric line. The gate pins these codes to the human truth set. 115func rj_classify(a: *VdImg, b: *VdImg, byoff: i64) -> i64 { 116 let abg: *i64 = sys_mmap(32) as *i64 117 let bbg: *i64 = sys_mmap(32) as *i64 118 rj_bg(a, 0, abg) 119 rj_bg(b, byoff, bbg) 120 let cols: *i64 = sys_mmap((K_MAGIC_4096 * 8) as nx_size) as *i64 121 let ao: *i64 = sys_mmap(32) as *i64 122 let bo: *i64 = sys_mmap(32) as *i64 123 rj_ink(a, 0, abg, 28, cols, ao) 124 rj_ink(b, byoff, bbg, 28, cols, bo) 125 // canvas delta between the two sides' dominant backgrounds 126 var cd: i64 = 0 127 var k: i64 = 0 128 while k < 3 { 129 var d: i64 = abg[k] - bbg[k] 130 if d < 0 { d = 0 - d } 131 cd = cd + d 132 k = k + 1 133 } 134 cd = cd / 3 135 rj_w("oracle: ink=" as *u8); rj_n(ao[0]); rj_w("pm spread80=" as *u8); rj_n(ao[1]) 136 rj_w("pm nishi: ink=" as *u8); rj_n(bo[0]); rj_w("pm spread80=" as *u8); rj_n(bo[1]) 137 rj_w("pm canvas-delta=" as *u8); rj_n(cd); rj_w("\n" as *u8) 138 // classification (int codes -- never pointer-compare string literals; the gate pins the thresholds 139 // to the HUMAN truth set = today's eyeballed suite images): 140 // 0 ok · 1 blank-nishi · 2 strip-collapse · 3 canvas-off · 4 sparse-nishi · 5 no-oracle-content 141 var cls: i64 = 0 142 if ao[0] < 5 { cls = 5 } // oracle itself blank (bing headless-block) 143 if cls == 0 { if bo[0] >= 2 { if bo[0] <= 60 { if bo[1] < 160 { if ao[1] > 320 { cls = 2 } } } } } // narrow ink strip 144 if cls == 0 { if bo[0] < 8 { if ao[0] >= 15 { if ao[0] >= bo[0] * 4 { cls = 1 } } } } // blank vs real oracle 145 if cls == 0 { if cd > 48 { cls = 3 } } 146 if cls == 0 { if bo[0] * 4 < ao[0] { cls = 4 } } 147 rj_w("JUDGE=" as *u8) 148 if cls == 0 { rj_w("CONTENT-OK" as *u8) } 149 if cls == 1 { rj_w("BLANK-NISHI" as *u8) } 150 if cls == 2 { rj_w("STRIP-COLLAPSE" as *u8) } 151 if cls == 3 { rj_w("CANVAS-OFF" as *u8) } 152 if cls == 4 { rj_w("SPARSE-NISHI" as *u8) } 153 if cls == 5 { rj_w("NO-ORACLE-CONTENT" as *u8) } 154 rj_w("\n" as *u8) 155 return cls 156} 157 158func main(argc: i64, argv: *i64) -> i64 { 159 if argc < 3 { rj_w("usage: nx_parity_judge <oracle.png> <nishi.png> [nishi_y_offset]\n" as *u8); sys_exit(2); return 2 } 160 let a: *VdImg = vd_load(argv[1] as *u8) 161 if (a as i64) == 0 { rj_w("JUDGE=NO-ORACLE\n" as *u8); sys_exit(0); return 0 } 162 let b: *VdImg = vd_load(argv[2] as *u8) 163 if (b as i64) == 0 { rj_w("JUDGE=NO-NISHI\n" as *u8); sys_exit(0); return 0 } 164 var byoff: i64 = 44 165 if argc >= 4 { byoff = rj_atoi(argv[3] as *u8) } 166 rj_classify(a, b, byoff) 167 sys_exit(0) 168 return 0 169}