code wiki / _hdl_build / _galx_serve_gate_prod.nx
_galx_serve_gate_prod.nx source
↩ module page · 374 lines · 21043 B
1import "nx_gate_gn.nx"
2import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host
3// _galx_serve_gate_prod.nx -- NO-FAKE-GREEN gate for the PRODUCTION gallery daemon at FULL CORPUS SCALE.
4// Asserts against the REAL corpus served from knowledge/store/galx-prod- (target ~5722 images), NOT a 256 sample:
5// (1) BIND -- the long-lived production daemon (started detached) is LISTENing on 18090.
6// (2) SCALE -- GET / -> 200 AND browse_count (distinct cell anchors '<a class="cell" href="/img/')
7// is in the THOUSANDS (>= GATE_MIN_BROWSE). Proves the 256 cap is GONE -- the full
8// manifest is read via ss_manifest_cap, not ss_manifest.
9// (3) UPPER-CID -- the sampled CID is read off-band from knowledge/status/galx_sample_cid.txt; it was
10// sampled from an UPPER row (>= 4000) of the sidecar (proof its row >= 4000 is in
11// knowledge/status/galx_sample_row.txt). GET / MUST list it -- proves NO 256-truncation:
12// a CID this deep would be invisible under the old cap.
13// (4) IMG-BYTES -- GET /img/<sampledCID> -> 200 image/png AND the served body is byte-identical (memcmp
14// full) to the on-disk source PNG (path read off-band from galx_sample_path.txt).
15// (5) RATE -- snapshot eval_lanes.log linecount; POST /rate (same-origin) score=861 -> EXACTLY one
16// new line == "EVAL img=<sampledCID> lane=O score=861".
17// (6) SAME-ORIG -- POST /rate with a FOREIGN Origin -> 403 AND linecount UNCHANGED (no write).
18// (7) TAMPER-RED -- re-author the daemon spec with tamper=1 (the /img route literal flipped), rewrite its
19// bind port to 18091, recompile (sovereign cc + gcc-as-assembler), spawn it; GET /
20// still 200 (alive) but GET /img/<CID> MUST 404 -- the route is SYNTHESIZED from the
21// spec, not baked. If a spec tamper does NOT change behavior, this arm goes RED.
22// Reads the running prod daemon (does NOT take it down -- persistence is the deliverable). The tamper
23// daemon is a SEPARATE throwaway on 18091.
24// Sovereign (nx_cc/sovereign cc; gcc off-band assembler). license_tier: ORIGINAL
25import "nx_syscalls.nx"
26
27func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
28func gfp(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 }
29func gfn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m; sys_write(fd,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;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 }
30
31func g_run(prog: *u8, a1: *u8, a2: *u8, a3: *u8) -> i64 {
32 let pid: i64 = sys_fork()
33 if pid == 0 {
34 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4)
35 if dn >= 0 { sys_dup3(dn, 1, 0) }
36 if dn >= 0 { sys_dup3(dn, 2, 0) }
37 let argv: *i64 = sys_mmap(64) as *i64
38 argv[0] = prog as i64
39 var k: i64 = 1
40 if a1 != (0 as *u8) { argv[k] = a1 as i64; k = k + 1 }
41 if a2 != (0 as *u8) { argv[k] = a2 as i64; k = k + 1 }
42 if a3 != (0 as *u8) { argv[k] = a3 as i64; k = k + 1 }
43 argv[k] = 0
44 let envp: *i64 = sys_mmap(16) as *i64
45 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0
46 sys_execve(prog, argv, envp)
47 sys_exit(127)
48 }
49 let st: *i64 = sys_mmap(16) as *i64
50 sys_wait4(pid, st, 0)
51 return (st[0] >> 8) & 0xff
52}
53
54func g_spawn(prog: *u8) -> i64 {
55 let pid: i64 = sys_fork()
56 if pid == 0 {
57 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4)
58 if dn >= 0 { sys_dup3(dn, 1, 0) }
59 let argv: *i64 = sys_mmap(32) as *i64
60 argv[0] = prog as i64; argv[1] = 0
61 let envp: *i64 = sys_mmap(16) as *i64
62 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0
63 sys_execve(prog, argv, envp)
64 sys_exit(127)
65 }
66 return pid
67}
68
69func g_kill(pid: i64, sig: i64) -> i64 { nx_kill(pid, sig); return 0 }
70
71func g_addr(port: i64) -> *u8 {
72 let addr: *u8 = sys_mmap(16)
73 addr[0] = 2 as u8
74 addr[1] = 0 as u8
75 addr[2] = ((port >> 8) & 0xff) as u8
76 addr[3] = (port & 0xff) as u8
77 addr[4] = 127 as u8
78 addr[5] = 0 as u8
79 addr[6] = 0 as u8
80 addr[7] = 1 as u8
81 addr[8] = 0 as u8
82 addr[9] = 0 as u8
83 addr[10] = 0 as u8
84 addr[11] = 0 as u8
85 addr[12] = 0 as u8
86 addr[13] = 0 as u8
87 addr[14] = 0 as u8
88 addr[15] = 0 as u8
89 return addr
90}
91
92func g_connect(port: i64) -> i64 {
93 let fd: i64 = sys_socket(2, 1, 0)
94 if fd < 0 { return 0 - 1 }
95 let addr: *u8 = g_addr(port)
96 let rc: i64 = nx_connect_bounded(fd, addr, 16, NX_CONN_DEFAULT_MS)
97 if rc < 0 { sys_close(fd); return 0 - 1 }
98 return fd
99}
100
101func g_wait_listen(port: i64) -> i64 {
102 var tries: i64 = 0
103 while tries < 50 {
104 let fd: i64 = g_connect(port)
105 if fd >= 0 { sys_close(fd); return 1 }
106 sys_sleep_ms(100)
107 tries = tries + 1
108 }
109 return 0
110}
111
112func g_http(port: i64, req: *u8, reqlen: i64, out: *u8, cap: i64) -> i64 {
113 let fd: i64 = g_connect(port)
114 if fd < 0 { return 0 - 1 }
115 sys_write(fd, req, reqlen)
116 var n: i64 = 0
117 var go: i64 = 1
118 while go == 1 {
119 let r: i64 = sys_read(fd, (out as i64 + n) as *u8, cap - 1 - n)
120 if r <= 0 { go = 0 } else { n = n + r }
121 if n >= cap - 1 { go = 0 }
122 }
123 sys_close(fd)
124 return n
125}
126
127func g_find(buf: *u8, n: i64, pat: *u8, plen: i64) -> i64 {
128 var i: i64 = 0
129 while i + plen <= n {
130 var j: i64 = 0
131 var ok: i64 = 1
132 while j < plen { if buf[i+j] != pat[j] { ok = 0 } j = j + 1 }
133 if ok == 1 { return 1 }
134 i = i + 1
135 }
136 return 0
137}
138
139// count non-overlapping occurrences of pat in buf
140func g_count(buf: *u8, n: i64, pat: *u8, plen: i64) -> i64 {
141 var cnt: i64 = 0
142 var i: i64 = 0
143 while i + plen <= n {
144 var j: i64 = 0
145 var ok: i64 = 1
146 while j < plen { if buf[i+j] != pat[j] { ok = 0 } j = j + 1 }
147 if ok == 1 { cnt = cnt + 1; i = i + plen } else { i = i + 1 }
148 }
149 return cnt
150}
151
152func g_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
153
154func g_linecount(path: *u8) -> i64 {
155 let szp: *i64 = sys_mmap(16) as *i64
156 let b: *u8 = sys_read_file(path, szp)
157 let sz: i64 = szp[0]
158 if (b as i64) == 0 { return 0 }
159 var c: i64 = 0
160 var i: i64 = 0
161 while i < sz { if b[i] == (10 as u8) { c = c + 1 } i = i + 1 }
162 return c
163}
164
165// read a one-line oracle file, strip trailing newline, null-terminate into out; return length.
166func g_readline_file(path: *u8, out: *u8, cap: i64) -> i64 {
167 let szp: *i64 = sys_mmap(16) as *i64
168 let b: *u8 = sys_read_file(path, szp)
169 let sz: i64 = szp[0]
170 if (b as i64) == 0 { out[0] = 0 as u8; return 0 }
171 var L: i64 = sz
172 var i: i64 = 0
173 var found: i64 = 0
174 while i < sz { if found == 0 { if b[i] == (10 as u8) { L = i; found = 1 } } i = i + 1 }
175 var n: i64 = 0
176 while n < L { if n < cap - 1 { out[n] = b[n] } n = n + 1 }
177 out[L] = 0 as u8
178 return L
179}
180
181func g_atoi(s: *u8) -> i64 {
182 var v: i64 = 0
183 var i: i64 = 0
184 while s[i] != (0 as u8) { if s[i] >= (48 as u8) { if s[i] <= (57 as u8) { v = v * 10 + ((s[i] as i64) - 48) } } i = i + 1 }
185 return v
186}
187
188func main() -> i64 {
189 let CAP: i64 = 8388608
190 // data-driven minimum browse_count: the gate FAILS if the grid is still the 256 sample.
191 let GATE_MIN_BROWSE: i64 = 4000
192 let GATE_MIN_ROW: i64 = 4000
193 gp("=== gallery-serve PRODUCTION gate @ FULL CORPUS (live daemon @ knowledge/store/galx-prod-) ===\n" as *u8)
194 let lfd: i64 = sys_openat_append("knowledge/status/galx_serve.log" as *u8, 0x1a4)
195
196 // off-band oracle: the sampled UPPER-ROW production CID + its on-disk path + its sidecar row.
197 let cidA: *u8 = sys_mmap(128)
198 let cidlen: i64 = g_readline_file("knowledge/status/galx_sample_cid.txt" as *u8, cidA, 128)
199 let pathA: *u8 = sys_mmap(1024)
200 let pathlen: i64 = g_readline_file("knowledge/status/galx_sample_path.txt" as *u8, pathA, 1024)
201 let rowbuf: *u8 = sys_mmap(64)
202 let rowlen: i64 = g_readline_file("knowledge/status/galx_sample_row.txt" as *u8, rowbuf, 64)
203 let samplerow: i64 = g_atoi(rowbuf)
204 if cidlen != 69 { gp("GALXPROD RED: sample CID oracle not 69 bytes (got "); gn(cidlen); gp(")\n" as *u8); sys_exit(1); return 1 }
205 if pathlen < 8 { gp("GALXPROD RED: sample path oracle empty\n" as *u8); sys_exit(1); return 1 }
206 if samplerow < GATE_MIN_ROW { gp("GALXPROD RED: sample row "); gn(samplerow); gp(" < "); gn(GATE_MIN_ROW); gp(" -- not an UPPER-row CID, cannot prove no-256-truncation\n" as *u8); sys_exit(1); return 1 }
207
208 // ---- ARM 1: BIND -- the live production daemon must be LISTENing on 18090 ----
209 let up: i64 = g_wait_listen(18090)
210 if up != 1 { gp("GALXPROD RED: production daemon not LISTENing on 127.0.0.1:18090\n" as *u8); sys_exit(1); return 1 }
211 gp("GATE ROW bind: GREEN -- live production daemon LISTEN 127.0.0.1:18090\n" as *u8)
212
213 let resp: *u8 = sys_mmap(CAP)
214
215 // ---- ARM 2: SCALE -- GET / 200 and browse_count in the THOUSANDS ----
216 let getroot: *u8 = "GET / HTTP/1.1\r\nHost: 127.0.0.1:18090\r\nConnection: close\r\n\r\n" as *u8
217 let rn2: i64 = g_http(18090, getroot, g_strlen(getroot), resp, CAP)
218 var ok200: i64 = g_find(resp, rn2, "HTTP/1.1 200" as *u8, 12)
219 if ok200 != 1 { gp("GALXPROD RED: GET / not 200\n" as *u8); sys_exit(1); return 1 }
220 let browse_count: i64 = g_count(resp, rn2, "<a class=\"cell\" href=\"/img/" as *u8, 27)
221 if browse_count < GATE_MIN_BROWSE { gp("GALXPROD RED: browse_count "); gn(browse_count); gp(" < "); gn(GATE_MIN_BROWSE); gp(" -- grid still capped near 256 (ss_manifest_cap NOT in effect)\n" as *u8); sys_exit(1); return 1 }
222 gp("GATE ROW scale: GREEN -- GET / 200 and browse_count = "); gn(browse_count); gp(" (thousands; 256 cap GONE)\n" as *u8)
223
224 // also confirm lazy-load attribute is present (does not fetch all PNGs at once)
225 var haslazy: i64 = g_find(resp, rn2, "<img loading=lazy src=\"/img/" as *u8, 28)
226 if haslazy != 1 { gp("GALXPROD RED: grid img tags missing loading=lazy\n" as *u8); sys_exit(1); return 1 }
227 gp("GATE ROW lazy: GREEN -- grid img tags carry loading=lazy\n" as *u8)
228
229 // ---- ARM 3: BROWSE lists the UPPER-ROW sampled CID (no 256-truncation) ----
230 var hasA: i64 = g_find(resp, rn2, cidA, 69)
231 if hasA != 1 { gp("GALXPROD RED: GET / grid missing the UPPER-row sampled CID (row "); gn(samplerow); gp(") -- TRUNCATED\n" as *u8); sys_exit(1); return 1 }
232 gp("GATE ROW upper-cid: GREEN -- GET / lists the row-"); gn(samplerow); gp(" CID (proves full manifest read, no 256-truncation)\n" as *u8)
233
234 // ---- ARM 4: IMG byte-identical to on-disk PNG ----
235 let getimg: *u8 = sys_mmap(512)
236 var gio: i64 = g_strlen("GET /img/")
237 var w: i64 = 0
238 let p1: *u8 = "GET /img/" as *u8
239 while w < gio { getimg[w] = p1[w]; w = w + 1 }
240 var c: i64 = 0
241 while c < 69 { getimg[gio + c] = cidA[c]; c = c + 1 }
242 let p2: *u8 = " HTTP/1.1\r\nHost: 127.0.0.1:18090\r\nConnection: close\r\n\r\n" as *u8
243 var p2l: i64 = g_strlen(p2)
244 var w2: i64 = 0
245 while w2 < p2l { getimg[gio + 69 + w2] = p2[w2]; w2 = w2 + 1 }
246 let imgreqlen: i64 = gio + 69 + p2l
247 let rn3: i64 = g_http(18090, getimg, imgreqlen, resp, CAP)
248 var imgok: i64 = g_find(resp, rn3, "HTTP/1.1 200" as *u8, 12)
249 var imgct: i64 = g_find(resp, rn3, "Content-Type: image/png" as *u8, 23)
250 if imgok != 1 { gp("GALXPROD RED: GET /img/<A> not 200\n" as *u8); sys_exit(1); return 1 }
251 if imgct != 1 { gp("GALXPROD RED: GET /img/<A> missing image/png content-type\n" as *u8); sys_exit(1); return 1 }
252 var bi: i64 = 0
253 var bodyat: i64 = 0 - 1
254 while bi + 4 <= rn3 {
255 var okb: i64 = 1
256 if resp[bi] != (13 as u8) { okb = 0 }
257 if resp[bi+1] != (10 as u8) { okb = 0 }
258 if resp[bi+2] != (13 as u8) { okb = 0 }
259 if resp[bi+3] != (10 as u8) { okb = 0 }
260 if okb == 1 { if bodyat < 0 { bodyat = bi + 4 } }
261 bi = bi + 1
262 }
263 if bodyat < 0 { gp("GALXPROD RED: GET /img/<A> no body delimiter\n" as *u8); sys_exit(1); return 1 }
264 let szp: *i64 = sys_mmap(16) as *i64
265 let disk: *u8 = sys_read_file(pathA, szp)
266 let dlen: i64 = szp[0]
267 let servedlen: i64 = rn3 - bodyat
268 if servedlen != dlen { gp("GALXPROD RED: served PNG length != on-disk ("); gn(servedlen); gp(" vs "); gn(dlen); gp(")\n" as *u8); sys_exit(1); return 1 }
269 var bc: i64 = 0
270 var bmatch: i64 = 1
271 while bc < dlen { if resp[bodyat + bc] != disk[bc] { bmatch = 0 } bc = bc + 1 }
272 if bmatch != 1 { gp("GALXPROD RED: served PNG bytes != on-disk source\n" as *u8); sys_exit(1); return 1 }
273 gp("GATE ROW img-bytes: GREEN -- GET /img/<A> 200 image/png byte-identical to on-disk source ("); gn(dlen); gp(" bytes)\n" as *u8)
274
275 // ---- ARM 5: RATE writes EXACTLY one EVAL O-line ----
276 let before: i64 = g_linecount("knowledge/status/eval_lanes.log" as *u8)
277 let body4: *u8 = sys_mmap(256)
278 var b4: i64 = 0
279 let bp1: *u8 = "img=" as *u8
280 var t1: i64 = 0; while bp1[t1]!=(0 as u8){body4[b4]=bp1[t1]; b4=b4+1; t1=t1+1}
281 c = 0; while c < 69 { body4[b4] = cidA[c]; b4 = b4 + 1; c = c + 1 }
282 let bp2: *u8 = "&score=861" as *u8
283 var t2: i64 = 0; while bp2[t2]!=(0 as u8){body4[b4]=bp2[t2]; b4=b4+1; t2=t2+1}
284 let post: *u8 = sys_mmap(1024)
285 var po: i64 = 0
286 let hp: *u8 = "POST /rate HTTP/1.1\r\nHost: 127.0.0.1:18090\r\nOrigin: http://127.0.0.1:18090\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: " as *u8
287 var th: i64 = 0; while hp[th]!=(0 as u8){post[po]=hp[th]; po=po+1; th=th+1}
288 let clbuf: *u8 = sys_mmap(28); var clm: i64 = b4; var clk: i64 = 0; if clm==0{clbuf[0]=48;clk=1}; let clt: *u8=sys_mmap(28); while clm>0{clt[clk]=(48+(clm%10)) as u8;clm=clm/10;clk=clk+1}; var cli: i64=0; while cli<clk{post[po]=clt[clk-1-cli];po=po+1;cli=cli+1}
289 let hp2: *u8 = "\r\nConnection: close\r\n\r\n" as *u8
290 var th2: i64 = 0; while hp2[th2]!=(0 as u8){post[po]=hp2[th2]; po=po+1; th2=th2+1}
291 var bb4: i64 = 0; while bb4 < b4 { post[po] = body4[bb4]; po = po + 1; bb4 = bb4 + 1 }
292 let rn4: i64 = g_http(18090, post, po, resp, CAP)
293 var rateok: i64 = g_find(resp, rn4, "HTTP/1.1 200" as *u8, 12)
294 if rateok != 1 { gp("GALXPROD RED: POST /rate (same-origin) not 200\n" as *u8); sys_exit(1); return 1 }
295 let after: i64 = g_linecount("knowledge/status/eval_lanes.log" as *u8)
296 if after != before + 1 { gp("GALXPROD RED: POST /rate did not append EXACTLY one line ("); gn(before); gp(" -> "); gn(after); gp(")\n" as *u8); sys_exit(1); return 1 }
297 let lszp: *i64 = sys_mmap(16) as *i64
298 let lb: *u8 = sys_read_file("knowledge/status/eval_lanes.log" as *u8, lszp)
299 let lsz: i64 = lszp[0]
300 let exp: *u8 = sys_mmap(256)
301 var eo: i64 = 0
302 let e1: *u8 = "EVAL img=" as *u8
303 var te1: i64=0; while e1[te1]!=(0 as u8){exp[eo]=e1[te1];eo=eo+1;te1=te1+1}
304 c = 0; while c < 69 { exp[eo] = cidA[c]; eo = eo + 1; c = c + 1 }
305 let e2: *u8 = " lane=O score=861\n" as *u8
306 var te2: i64=0; while e2[te2]!=(0 as u8){exp[eo]=e2[te2];eo=eo+1;te2=te2+1}
307 var tailmatch: i64 = 1
308 if lsz < eo { tailmatch = 0 }
309 if tailmatch == 1 {
310 var em: i64 = 0
311 while em < eo { if lb[lsz - eo + em] != exp[em] { tailmatch = 0 } em = em + 1 }
312 }
313 if tailmatch != 1 { gp("GALXPROD RED: appended line != 'EVAL img=<A> lane=O score=861'\n" as *u8); sys_exit(1); return 1 }
314 gp("GATE ROW rate: GREEN -- POST /rate (same-origin) appended EXACTLY one line == 'EVAL img=<A> lane=O score=861'\n" as *u8)
315
316 // ---- ARM 6: SAME-ORIGIN -- foreign Origin -> 403 AND no write ----
317 let before6: i64 = g_linecount("knowledge/status/eval_lanes.log" as *u8)
318 let post6: *u8 = sys_mmap(1024)
319 var po6: i64 = 0
320 let fp: *u8 = "POST /rate HTTP/1.1\r\nHost: 127.0.0.1:18090\r\nOrigin: http://evil.example.com\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: " as *u8
321 var tf: i64 = 0; while fp[tf]!=(0 as u8){post6[po6]=fp[tf]; po6=po6+1; tf=tf+1}
322 var cli6: i64=0; while cli6<clk{post6[po6]=clt[clk-1-cli6];po6=po6+1;cli6=cli6+1}
323 var tf2: i64 = 0; while hp2[tf2]!=(0 as u8){post6[po6]=hp2[tf2]; po6=po6+1; tf2=tf2+1}
324 var bb6: i64 = 0; while bb6 < b4 { post6[po6] = body4[bb6]; po6 = po6 + 1; bb6 = bb6 + 1 }
325 let rn6: i64 = g_http(18090, post6, po6, resp, CAP)
326 var forbidden: i64 = g_find(resp, rn6, "HTTP/1.1 403" as *u8, 12)
327 let after6: i64 = g_linecount("knowledge/status/eval_lanes.log" as *u8)
328 if forbidden != 1 { gp("GALXPROD RED: cross-origin POST /rate not 403\n" as *u8); sys_exit(1); return 1 }
329 if after6 != before6 { gp("GALXPROD RED: cross-origin POST /rate WROTE to the log ("); gn(before6); gp(" -> "); gn(after6); gp(")\n" as *u8); sys_exit(1); return 1 }
330 gp("GATE ROW same-origin: GREEN -- cross-origin POST /rate -> 403 and eval_lanes.log unchanged (no write)\n" as *u8)
331
332 // ---- ARM 7: TAMPER-RED -- flip the /img route spec field -> GET /img 404 (route synthesized) ----
333 // Author a tamper variant (tamper=1 flips the rl_img route literal), rewrite its bind port to 18091,
334 // recompile sovereignly, spawn it; GET / on 18091 still 200 (alive) but GET /img/<A> MUST 404.
335 let at: i64 = g_run("/tmp/nx_eg.sov.elf" as *u8, "2" as *u8, "nx_gallery_serve_tamper" as *u8, "1" as *u8)
336 if at != 0 { gp("GALXPROD RED: tamper author failed rc="); gn(at); gp("\n" as *u8); sys_exit(1); return 1 }
337 // rewrite "let port: i64 = 18090" -> 18091 in the throwaway tamper source so it binds a free port
338 let sr: i64 = g_run("/bin/sed" as *u8, "-i" as *u8, "s/let port: i64 = 18090/let port: i64 = 18091/" as *u8, "runtime/_hdl_build/nx_gallery_serve_tamper.nx" as *u8)
339 if sr != 0 { gp("GALXPROD RED: tamper port rewrite failed rc="); gn(sr); gp("\n" as *u8); sys_exit(1); return 1 }
340 let bt: i64 = g_run("runtime/_hdl_build/_galx_build_one.sh" as *u8, "nx_gallery_serve_tamper" as *u8, 0 as *u8, 0 as *u8)
341 if bt != 0 { gp("GALXPROD RED: tamper compile failed rc="); gn(bt); gp("\n" as *u8); sys_exit(1); return 1 }
342 let tpid: i64 = g_spawn("/tmp/nx_gallery_serve_tamper.elf" as *u8)
343 let tup: i64 = g_wait_listen(18091)
344 if tup != 1 { gp("GALXPROD RED: tamper daemon never bound 18091\n" as *u8); nx_kill(tpid, 9); sys_exit(1); return 1 }
345 // tamper daemon is alive: GET / must still be 200
346 let getroot2: *u8 = "GET / HTTP/1.1\r\nHost: 127.0.0.1:18091\r\nConnection: close\r\n\r\n" as *u8
347 let rnT0: i64 = g_http(18091, getroot2, g_strlen(getroot2), resp, CAP)
348 var tamperalive: i64 = g_find(resp, rnT0, "HTTP/1.1 200" as *u8, 12)
349 if tamperalive != 1 { gp("GALXPROD RED: tamper daemon GET / not 200 (cannot isolate the route flip)\n" as *u8); nx_kill(tpid, 9); sys_exit(1); return 1 }
350 // GET /img/<A> on the tamper daemon MUST 404 -- the route was synthesized from the (flipped) spec
351 let getimgT: *u8 = sys_mmap(512)
352 var gioT: i64 = g_strlen("GET /img/")
353 var wT: i64 = 0
354 let p1T: *u8 = "GET /img/" as *u8
355 while wT < gioT { getimgT[wT] = p1T[wT]; wT = wT + 1 }
356 var cT: i64 = 0
357 while cT < 69 { getimgT[gioT + cT] = cidA[cT]; cT = cT + 1 }
358 let p2T: *u8 = " HTTP/1.1\r\nHost: 127.0.0.1:18091\r\nConnection: close\r\n\r\n" as *u8
359 var p2lT: i64 = g_strlen(p2T)
360 var w2T: i64 = 0
361 while w2T < p2lT { getimgT[gioT + 69 + w2T] = p2T[w2T]; w2T = w2T + 1 }
362 let rnT: i64 = g_http(18091, getimgT, gioT + 69 + p2lT, resp, CAP)
363 var tamper404: i64 = g_find(resp, rnT, "HTTP/1.1 404" as *u8, 12)
364 var tamper200: i64 = g_find(resp, rnT, "HTTP/1.1 200" as *u8, 12)
365 nx_kill(tpid, 9)
366 if tamper200 == 1 { gp("GALXPROD RED: TAMPER -- GET /img/<A> still 200 after /img route flip (route is BAKED, not synthesized)\n" as *u8); sys_exit(1); return 1 }
367 if tamper404 != 1 { gp("GALXPROD RED: TAMPER -- GET /img/<A> not 404 after /img route flip\n" as *u8); sys_exit(1); return 1 }
368 gp("GATE ROW tamper-red: GREEN -- flipping the /img route spec field -> GET /img/<A> now 404 (route synthesized from spec, not baked)\n" as *u8)
369
370 gp("GALXPROD 7/7 GREEN -- FULL-corpus production daemon: binds 18090, browse_count="); gn(browse_count); gp(" (thousands), lists row-"); gn(samplerow); gp(" CID, /img byte-identical PNG, /rate one O-line (same-origin enforced, cross-origin 403 no-write), tamper-of-/img-route -> behavioral RED\n" as *u8)
371 if lfd >= 0 { gfp(lfd, "GALXPROD verdict=GREEN scale=FULL daemon=nx_gallery_serve namespace=knowledge/store/galx-prod- port=18090 browse_count=" as *u8); gfn(lfd, browse_count); gfp(lfd, " sample_row=" as *u8); gfn(lfd, samplerow); gfp(lfd, " img_byte_identical=1 rate_one_oline=1 same_origin_enforced=1 tamper_red=1 epoch=" as *u8); gfn(lfd, sys_now_realtime_sec()); gfp(lfd, "\n" as *u8); sys_close(lfd) }
372 sys_exit(0)
373 return 0
374}