code wiki / (root) / nx_image_index_gate.nx

nx_image_index_gate.nx source

↩ module page · 206 lines · 10553 B

1// nx_image_index_gate.nx -- referee for the REAL-CORPUS ingestor (nx_image_index). 2// Unlike the search gate (synthetic raw-gray buffers), this builds REAL encoded PNG files at runtime 3// (valid signature + IHDR + zlib stored-block IDAT + IEND, with chunk CRC-32s and the zlib Adler-32 4// computed by the shipped substrate primitives -- same technique as nx_png_real_smoke), writes them to 5// /tmp, forks+execs the REAL /tmp/nx_image_index.sov.elf over them, and verifies the produced 6// fingerprint index. Because each PNG is filled RGB=(v,v,v), Rec.709 luma == v, so the FULL decode path 7// (inflate -> unfilter -> RGB -> gray -> dHash) must reproduce the KNOWN dHashes proven in the search 8// gate -- a true end-to-end KAT, checkable by pure string match: 9// row1 grad-up -> dHash 0000000000000000 (decode->gray->dHash correct, end to end) 10// row2 +bright -> dHash 0000000000000000 (brightness invariance survives a real PNG round-trip) 11// row3 grad-down -> dHash ffffffffffffffff (second KAT, opposite extreme) 12// row4 mid -> present and DISTINCT from grad-up 13// row5 corrupt -> SKIPPED (graceful degradation, Cardinal 14 -- one bad file can't abort a crawl) 14// row6 summary -> ingestor exit 0, indexed=4 skipped=1 15// GREEN iff 6/6. Durable verdict appends to knowledge/status/image_index_gate.log. license_tier: ORIGINAL 16import "nx_syscalls.nx" 17import "nx_crc32.nx" 18import "nx_adler32.nx" 19 20func g_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 21func g_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)}; let t: *u8=sys_mmap(28); 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}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 } 22func g_w(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 } 23func g_wn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; let t: *u8=sys_mmap(28); 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}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 } 24func g_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 25 26func g_write_bytes(path: *u8, buf: *u8, n: i64) -> i64 { 27 let fd: i64=sys_openat_wr(path, 0x1a4) 28 if fd<0 { return 0-1 } 29 sys_write(fd, buf, n) 30 sys_close(fd) 31 return 0 32} 33func g_write_file(path: *u8, data: *u8) -> i64 { return g_write_bytes(path, data, g_strlen(data)) } 34func g_read_small(path: *u8, buf: *u8, cap: i64) -> i64 { 35 let fd: i64=sys_openat_rd(path) 36 if fd<0 { return 0 } 37 var total: i64=0 38 var nrd: i64=sys_read(fd, buf, cap) 39 while nrd>0 { total=total+nrd; if total>=cap { nrd=0 } else { nrd=sys_read(fd, ((buf as i64)+total) as *u8, cap-total) } } 40 sys_close(fd) 41 return total 42} 43func g_find(hay: *u8, n: i64, needle: *u8) -> i64 { 44 let nl: i64=g_strlen(needle) 45 if nl==0 { return 0-1 } 46 var i: i64=0 47 while i+nl<=n { 48 var j: i64=0; var hit: i64=1 49 while j<nl { if hay[i+j]!=needle[j] { hit=0; j=nl } else { j=j+1 } } 50 if hit==1 { return i } 51 i=i+1 52 } 53 return 0-1 54} 55func g_contains(hay: *u8, n: i64, needle: *u8) -> i64 { if g_find(hay,n,needle)>=0 { return 1 } return 0 } 56 57// ===== runtime PNG builder (stored zlib block, RGB 8-bit) ===== 58func gp_wbe(buf: *u8, off: i64, val: i64) -> i64 { 59 buf[off]=((val>>24)&255) as u8 60 buf[off+1]=((val>>16)&255) as u8 61 buf[off+2]=((val>>8)&255) as u8 62 buf[off+3]=(val&255) as u8 63 return 0 64} 65func gp_val(kind: i64, x: i64, w: i64, bright: i64) -> i64 { 66 var v: i64=0 67 if kind==0 { v=x*4 } 68 if kind==1 { v=(w-1-x)*4 } 69 if kind==3 { v=(x&2)*30 } 70 v=v+bright 71 if v<0 { v=0 } 72 if v>255 { v=255 } 73 return v 74} 75func gp_build(out: *u8, w: i64, h: i64, kind: i64, bright: i64) -> i64 { 76 out[0]=137 as u8; out[1]=80 as u8; out[2]=78 as u8; out[3]=71 as u8 77 out[4]=13 as u8; out[5]=10 as u8; out[6]=26 as u8; out[7]=10 as u8 78 var pos: i64=8 79 // IHDR 80 gp_wbe(out,pos,13); pos=pos+4 81 let ihdr_t: i64=pos 82 out[pos]=73 as u8; out[pos+1]=72 as u8; out[pos+2]=68 as u8; out[pos+3]=82 as u8; pos=pos+4 83 gp_wbe(out,pos,w); pos=pos+4 84 gp_wbe(out,pos,h); pos=pos+4 85 out[pos]=8 as u8; out[pos+1]=2 as u8; out[pos+2]=0 as u8; out[pos+3]=0 as u8; out[pos+4]=0 as u8; pos=pos+5 86 gp_wbe(out,pos, nx_crc32(((out as i64)+ihdr_t) as *u8, 17)); pos=pos+4 87 // IDAT (zlib stored block) 88 let payload_len: i64=h*(1+w*3) 89 let zlib_len: i64=2+5+payload_len+4 90 gp_wbe(out,pos,zlib_len); pos=pos+4 91 let idat_t: i64=pos 92 out[pos]=73 as u8; out[pos+1]=68 as u8; out[pos+2]=65 as u8; out[pos+3]=84 as u8; pos=pos+4 93 out[pos]=0x78 as u8; out[pos+1]=0x01 as u8; pos=pos+2 94 out[pos]=0x01 as u8; pos=pos+1 95 out[pos]=(payload_len&255) as u8; out[pos+1]=((payload_len>>8)&255) as u8; pos=pos+2 96 let nlen: i64=(payload_len^0xFFFF)&0xFFFF 97 out[pos]=(nlen&255) as u8; out[pos+1]=((nlen>>8)&255) as u8; pos=pos+2 98 let payload_off: i64=pos 99 var y: i64=0 100 while y<h { 101 out[pos]=0 as u8; pos=pos+1 102 var x: i64=0 103 while x<w { 104 let v: i64=gp_val(kind,x,w,bright) 105 out[pos]=v as u8; out[pos+1]=v as u8; out[pos+2]=v as u8; pos=pos+3 106 x=x+1 107 } 108 y=y+1 109 } 110 gp_wbe(out,pos, adler32(((out as i64)+payload_off) as *u8, payload_len)); pos=pos+4 111 gp_wbe(out,pos, nx_crc32(((out as i64)+idat_t) as *u8, 4+zlib_len)); pos=pos+4 112 // IEND 113 gp_wbe(out,pos,0); pos=pos+4 114 let iend_t: i64=pos 115 out[pos]=73 as u8; out[pos+1]=69 as u8; out[pos+2]=78 as u8; out[pos+3]=68 as u8; pos=pos+4 116 gp_wbe(out,pos, nx_crc32(((out as i64)+iend_t) as *u8, 4)); pos=pos+4 117 return pos 118} 119 120func g_run(corpus: *u8, outidx: *u8, outcap: *u8) -> i64 { 121 let pid: i64=sys_fork() 122 if pid==0 { 123 let out: i64=sys_openat_wr(outcap, 0x1a4) 124 if out>=0 { sys_dup3(out, 1, 0) } 125 let argv: *i64=sys_mmap(8*6) as *i64 126 argv[0]="/tmp/nx_image_index.sov.elf" as *u8 as i64 127 argv[1]=corpus as i64; argv[2]=outidx as i64; argv[3]=0 128 let envp: *i64=sys_mmap(16) as *i64; envp[0]="PATH=/usr/bin:/bin" as *u8 as i64; envp[1]=0 129 sys_execve("/tmp/nx_image_index.sov.elf" as *u8, argv, envp) 130 sys_exit(127) 131 } 132 let st: *i64=sys_mmap(16) as *i64 133 sys_wait4(pid, st, 0) 134 if (st[0]&0x7f)!=0 { return 128+(st[0]&0x7f) } 135 return (st[0]>>8)&0xff 136} 137 138func main() -> i64 { 139 g_puts("=== IMAGE INDEX GATE (real PNG decode -> gray -> dHash KAT + brightness invariance + graceful skip) ===\n" as *u8) 140 let W: i64=16 141 let H: i64=16 142 let pb: *u8=sys_mmap(4096) 143 var sz: i64=0 144 145 sz=gp_build(pb, W, H, 0, 0); g_write_bytes("/tmp/im_up.png" as *u8, pb, sz) 146 sz=gp_build(pb, W, H, 0, 40); g_write_bytes("/tmp/im_bright.png" as *u8, pb, sz) 147 sz=gp_build(pb, W, H, 1, 0); g_write_bytes("/tmp/im_down.png" as *u8, pb, sz) 148 sz=gp_build(pb, W, H, 3, 0); g_write_bytes("/tmp/im_mid.png" as *u8, pb, sz) 149 // corrupt / not-a-PNG file (graceful-skip neg-control) 150 g_write_file("/tmp/im_junk.bin" as *u8, "not-a-png" as *u8) 151 152 g_write_file("/tmp/im_corpus.tsv" as *u8, 153 "/C/up\t/tmp/im_up.png\n/C/bright\t/tmp/im_bright.png\n/C/down\t/tmp/im_down.png\n/C/mid\t/tmp/im_mid.png\n/C/junk\t/tmp/im_junk.bin\n" as *u8) 154 155 let rc: i64=g_run("/tmp/im_corpus.tsv" as *u8, "/tmp/im_real.idx" as *u8, "/tmp/im_idx_out.txt" as *u8) 156 157 let ibuf: *u8=sys_mmap(65536) 158 let ni: i64=g_read_small("/tmp/im_real.idx" as *u8, ibuf, 65536) 159 let obuf: *u8=sys_mmap(8192) 160 let no: i64=g_read_small("/tmp/im_idx_out.txt" as *u8, obuf, 8192) 161 162 g_puts("---- produced fingerprint index ----\n" as *u8) 163 sys_write(1, ibuf, ni) 164 g_puts("---- ingestor stdout ----\n" as *u8) 165 sys_write(1, obuf, no) 166 g_puts("----\n" as *u8) 167 168 var pass: i64=0 169 let rows: i64=6 170 171 let r1: i64=g_contains(ibuf, ni, "/C/up\t0000000000000000\t" as *u8) 172 g_puts(" row1 grad-up KAT -> dHash 0000..0? " as *u8); g_num(r1) 173 if r1==1 { pass=pass+1; g_puts(" PASS (decode->gray->dHash correct end-to-end)\n" as *u8) } else { g_puts(" FAIL\n" as *u8) } 174 175 let r2: i64=g_contains(ibuf, ni, "/C/bright\t0000000000000000\t" as *u8) 176 g_puts(" row2 +brightness PNG -> dHash 0000..0? " as *u8); g_num(r2) 177 if r2==1 { pass=pass+1; g_puts(" PASS (invariance survives full PNG round-trip)\n" as *u8) } else { g_puts(" FAIL\n" as *u8) } 178 179 let r3: i64=g_contains(ibuf, ni, "/C/down\tffffffffffffffff\t" as *u8) 180 g_puts(" row3 grad-down KAT -> dHash ffff..f? " as *u8); g_num(r3) 181 if r3==1 { pass=pass+1; g_puts(" PASS\n" as *u8) } else { g_puts(" FAIL\n" as *u8) } 182 183 let r4a: i64=g_contains(ibuf, ni, "/C/mid\t" as *u8) 184 let r4b: i64=g_contains(ibuf, ni, "/C/mid\t0000000000000000" as *u8) 185 g_puts(" row4 mid distinct -> present? " as *u8); g_num(r4a); g_puts(" !=grad-up? " as *u8); g_num(1-r4b) 186 if r4a==1 { if r4b==0 { pass=pass+1; g_puts(" PASS\n" as *u8) } else { g_puts(" FAIL\n" as *u8) } } else { g_puts(" FAIL\n" as *u8) } 187 188 let r5: i64=g_contains(ibuf, ni, "/C/junk" as *u8) 189 g_puts(" row5 corrupt skipped -> absent? " as *u8); g_num(1-r5) 190 if r5==0 { pass=pass+1; g_puts(" PASS (graceful degradation)\n" as *u8) } else { g_puts(" FAIL (corrupt file leaked into index!)\n" as *u8) } 191 192 let r6a: i64=g_contains(obuf, no, "indexed=4" as *u8) 193 let r6b: i64=g_contains(obuf, no, "skipped=1" as *u8) 194 g_puts(" row6 summary -> exit " as *u8); g_num(rc); g_puts(" indexed=4? " as *u8); g_num(r6a); g_puts(" skipped=1? " as *u8); g_num(r6b) 195 if rc==0 { if r6a==1 { if r6b==1 { pass=pass+1; g_puts(" PASS\n" as *u8) } else { g_puts(" FAIL\n" as *u8) } } else { g_puts(" FAIL\n" as *u8) } } else { g_puts(" FAIL\n" as *u8) } 196 197 g_puts("----\nIMAGE-INDEX-GATE rows=" as *u8); g_num(rows); g_puts(" pass=" as *u8); g_num(pass); g_puts("\n" as *u8) 198 let lg: i64=sys_openat_append("knowledge/status/image_index_gate.log" as *u8, 0x1a4) 199 if lg>=0 { 200 g_w(lg, "IMAGE-INDEX-GATE rows=" as *u8); g_wn(lg, rows); g_w(lg, " pass=" as *u8); g_wn(lg, pass) 201 if pass==rows { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } 202 sys_close(lg) 203 } 204 if pass==rows { g_puts("IMAGE-INDEX-GATE GREEN\n" as *u8); sys_exit(0); return 0 } 205 g_puts("IMAGE-INDEX-GATE RED\n" as *u8); sys_exit(1); return 1 206}