code wiki / _hdl_build / nx_browser_doc_gate.nx
nx_browser_doc_gate.nx source
↩ module page · 219 lines · 12456 B
1// nx_browser_doc_gate.nx -- gate for the BROWSER-NATIVE document omnitool: nx_browser's load_page diverts a
2// registered document extension (.md/.csv/.docx via knowledge/doc_viewers.conf) through the nx_doc_view dispatch
3// and paints the renderer's HTML inline. E2E and headless: a fixture HTTP server (nx_browser_view_serve, docroot
4// _offc, :8099) serves real files; the REAL browser (SITETEST mode) navigates to them over its own HTTP stack.
5// Rows: 1 instruments 2 neg-html-untouched(+renders) 3 md-converted 4 csv-converted 5 docx-converted
6// 6 all-laid-out-in-browser 7 outputs-sovereign-0js
7// Stale-proofing: expected artifacts are OVERWRITTEN with STALE sentinels before run B (no unlink syscall),
8// so every marker found was written by THIS run. license_tier: ORIGINAL
9import "nx_syscalls.nx"
10import "nx_gate_verdict.nx"
11
12func bg_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8) { n=n+1 } return n }
13func bg_p(s: *u8) -> i64 { sys_write(1, s, bg_slen(s)); return 0 }
14func bg_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8) { dst[off+i]=s[i]; i=i+1 } return off+i }
15func bg_catn(dst: *u8, off: i64, v: i64) -> i64 {
16 var o: i64=off; var m: i64=v; if m<0 { dst[o]=45 as u8; o=o+1; m=0-m }
17 let t: *u8=sys_mmap(28); var k: i64=0; if m==0 { t[0]=48 as u8; k=1 }
18 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 }
19 var i: i64=0; while i<k { dst[o+i]=t[k-1-i]; i=i+1 } return o+k
20}
21func bg_write(path: *u8, content: *u8) -> i64 {
22 let fd: i64=sys_openat_wr(path, 0x1a4); if fd<0 { return 0-1 }
23 sys_write(fd, content, bg_slen(content)); sys_close(fd); return 0
24}
25func bg_readall(path: *u8, szout: *i64) -> *u8 {
26 let fd: i64=sys_openat_rd(path); if fd<0 { szout[0]=0-1; return 0 as *u8 }
27 let buf: *u8=sys_mmap(8388608); var got: i64=0; var n: i64=1
28 while n>0 { n=sys_read(fd,(buf as i64+got) as *u8,131072); if n>0 { got=got+n } }
29 sys_close(fd); szout[0]=got; return buf
30}
31func bg_exists(path: *u8) -> i64 {
32 let fd: i64=sys_openat_rd(path); if fd<0 { return 0 } sys_close(fd); return 1
33}
34// RESOLVE AN ARTIFACT, NEVER ASSUME ONE PATH. First existing of three, so a tree that moved its build output
35// still resolves and the caller can ANNOUNCE which copy it measured.
36func bg_pick3(a: *u8, b: *u8, c: *u8) -> *u8 {
37 if bg_exists(a)==1 { return a }
38 if bg_exists(b)==1 { return b }
39 return c
40}
41func bg_copy(src: *u8, dst: *u8) -> i64 {
42 let lp: *i64=sys_mmap(16) as *i64
43 let b: *u8=sys_read_file(src, lp)
44 if lp[0]<=0 { return 0-1 }
45 let fd: i64=sys_openat_wr(dst, 0x1a4); if fd<0 { return 0-1 }
46 sys_write(fd, b, lp[0]); sys_close(fd); return 0
47}
48func bg_sleep(ms: i64) -> i64 { let b: *u8=sys_mmap(8); sys_poll(b, 0, ms); return 0 }
49func bg_kill(pid: i64) -> i64 { return __syscall(129, pid, 9, 0, 0, 0, 0) } // kill(2), SIGKILL. rv64 kill=129; raw x86 62 is an RV64 KEY translated to lseek(8) -- the kill never happened (debt idx 2277)
50
51// fork+exec elf (argv = {elf, args...}) with stdout+stderr -> outpath; WAIT; return exit code.
52func bg_runv(elf: *u8, args: *i64, outpath: *u8) -> i64 {
53 let pid: i64=sys_fork()
54 if pid==0 {
55 if (outpath as i64)!=0 { let ofd: i64=sys_openat_wr(outpath,0x1a4); if ofd>=0 { sys_dup3(ofd,1,0); sys_dup3(ofd,2,0) } }
56 let argv: *i64=sys_mmap(128) as *i64
57 argv[0]=elf as i64; var i: i64=0; var go: i64=1
58 while go==1 { if args[i]==0 { go=0 } else { argv[i+1]=args[i]; i=i+1 } }
59 argv[i+1]=0
60 let envp: *i64=sys_mmap(16) as *i64; envp[0]=0
61 sys_execve(elf, argv, envp); sys_exit(127)
62 }
63 let st: *i64=sys_mmap(16) as *i64; sys_wait4(pid, st, 0)
64 let sig: i64=st[0]&0x7f; if sig!=0 { return 128+sig }
65 return (st[0]>>8)&0xff
66}
67
68// fork+exec elf detached (stdout -> logpath); NO wait; return child pid.
69func bg_spawn(elf: *u8, logpath: *u8) -> i64 {
70 let pid: i64=sys_fork()
71 if pid==0 {
72 let ofd: i64=sys_openat_wr(logpath,0x1a4); if ofd>=0 { sys_dup3(ofd,1,0); sys_dup3(ofd,2,0) }
73 let argv: *i64=sys_mmap(32) as *i64
74 argv[0]=elf as i64; argv[1]=0
75 let envp: *i64=sys_mmap(16) as *i64; envp[0]=0
76 sys_execve(elf, argv, envp); sys_exit(127)
77 }
78 return pid
79}
80
81func bg_has(path: *u8, needle: *u8) -> i64 {
82 let szp: *i64=sys_mmap(16) as *i64; let b: *u8=bg_readall(path, szp); let sz: i64=szp[0]
83 let n: i64=bg_slen(needle); if sz<n { return 0 }
84 var i: i64=0
85 while i+n<=sz { var ok: i64=1; var j: i64=0; while j<n { if b[i+j]!=needle[j] { ok=0; j=n } else { j=j+1 } } if ok==1 { return 1 } i=i+1 }
86 return 0
87}
88func bg_args2(a1: *u8, a2: *u8) -> *i64 {
89 let a: *i64=sys_mmap(32) as *i64; a[0]=a1 as i64; a[1]=a2 as i64; a[2]=0; return a
90}
91func bg_args4(a1: *u8, a2: *u8, a3: *u8, a4: *u8) -> *i64 {
92 let a: *i64=sys_mmap(48) as *i64; a[0]=a1 as i64; a[1]=a2 as i64; a[2]=a3 as i64; a[3]=a4 as i64; a[4]=0; return a
93}
94func bg_args0() -> *i64 { let a: *i64=sys_mmap(16) as *i64; a[0]=0; return a }
95func bg_row(name: *u8, pass: i64) -> i64 {
96 bg_p("ROW " as *u8); bg_p(name); if pass==1 { bg_p(" PASS\n" as *u8) } else { bg_p(" FAIL\n" as *u8) } return pass
97}
98
99func main(argc: i64, argv: *i64) -> i64 {
100 bg_p("=== BROWSER DOC-OMNITOOL GATE: nx_browser natively opens .md/.csv/.docx it navigates to (E2E, headless) ===\n" as *u8)
101
102 // INSTRUMENTS -- RESOLVED AND ANNOUNCED (fixed 2026-09-03). This tooth asked for /tmp/nx_browser.sov.elf,
103 // and the sovereign builder writes <cwd>/_build/<t>.sov.elf -- it has NOT written /tmp since the build lane
104 // moved. So the FIRST tooth could never pass, every tooth below it was unreachable, and the gate reported the
105 // browser as broken when what was missing was the gate's own path. A SAFETY PROOF THAT CANNOT FIND ITS SUBJECT
106 // DOES NOT FAIL LOUD -- IT REFUSES EVERY SUBJECT AND BLAMES THEM. Resolve in order and SAY which copy ran:
107 // the PROMOTED binary first (the browser the estate actually serves is the better subject than a scratch build),
108 // then a fresh build output, then the legacy /tmp path so an older tree still resolves.
109 let BROWSER: *u8 = bg_pick3("./nx_browser.elf" as *u8, "buildroot/_build/nx_browser.sov.elf" as *u8, "/tmp/nx_browser.sov.elf" as *u8)
110 let SERVER: *u8 = bg_pick3("buildroot/_build/nx_browser_view_serve.sov.elf" as *u8, "./nx_browser_view_serve.elf" as *u8, "/tmp/nx_browser_view_serve.sov.elf" as *u8)
111 bg_p(" browser=" as *u8); bg_p(BROWSER); bg_p("\n server=" as *u8); bg_p(SERVER); bg_p("\n" as *u8)
112 if bg_exists(BROWSER)==0 {
113 bg_p(" building nx_browser (large)...\n" as *u8)
114 bg_runv("_offc/nx_sov_build_run.elf" as *u8, bg_args2("nx_browser" as *u8, "--build-only" as *u8), "/tmp/bdg_bb.log" as *u8)
115 }
116 if bg_exists(SERVER)==0 {
117 bg_runv("_offc/nx_sov_build_run.elf" as *u8, bg_args2("nx_browser_view_serve" as *u8, "--build-only" as *u8), "/tmp/bdg_bs.log" as *u8)
118 }
119 var pass: i64=0; var r: i64=0
120 r=1
121 if bg_exists(BROWSER)==0 { r=0 }
122 if bg_exists(SERVER)==0 { r=0 }
123 if bg_exists("_offc/nx_doc_view.elf" as *u8)==0 { r=0 }
124 if bg_exists("_offc/nx_md.elf" as *u8)==0 { r=0 }
125 if bg_exists("_offc/nx_csv.elf" as *u8)==0 { r=0 }
126 if bg_exists("_offc/nx_docx.elf" as *u8)==0 { r=0 }
127 pass=pass+bg_row("instruments" as *u8, r)
128
129 // fixtures into the server docroot (_offc)
130 bg_write("_offc/bdg_neg.html" as *u8, "<!DOCTYPE html><html><head><title>neg</title></head><body><h1>Plain page</h1><p>normal html pipeline</p></body></html>\n" as *u8)
131 bg_write("_offc/bdg_t.md" as *u8, "# Title\n\nHello **world** from the browser.\n\n- one\n- two\n" as *u8)
132 bg_write("_offc/bdg_t.csv" as *u8, "Name,Role,City\nAlice,Lead,Denver\nBob,Eng,Provo\n" as *u8)
133 // THE .docx FIXTURE IS BUILT AT RUNTIME BY OUR OWN WRITER, NEVER COPIED FROM A PATH THAT MAY NOT EXIST.
134 // It used to copy web_assets/vizsla_agreement_demo.docx, which is ABSENT on this host: the copy failed, no
135 // fixture was ever served, and the tooth below reported the BROWSER broken when the fixture was simply missing.
136 // A GATE THAT FAILS ON AN ABSENT PRECONDITION IS REPORTING ON ITS OWN ENVIRONMENT, IN THE SAME WORD AS A DEFECT.
137 bg_runv("_offc/nx_docx.elf" as *u8, bg_args4("write" as *u8, "_offc/bdg_t.docx" as *u8, "Venue Booking Agreement" as *u8, "Parties agree to the terms set out in this document." as *u8), "/tmp/bdg_docx.log" as *u8)
138 if bg_exists("_url.txt" as *u8)==0 { bg_write("_url.txt" as *u8, "http://127.0.0.1:8099/bdg_neg.html\n" as *u8) }
139
140 // fixture server up (or already up -- same docroot either way)
141 let srvpid: i64=bg_spawn(SERVER, "/tmp/bdg_srv.log" as *u8)
142 bg_sleep(700)
143
144 // RUN A (negative): plain .html must take the normal pipeline -- no doc staging file appears
145 bg_write("/tmp/nxsites" as *u8, "http://127.0.0.1:8099/bdg_neg.html\n" as *u8)
146 bg_runv(BROWSER, bg_args0(), "/tmp/bdg_runA.txt" as *u8)
147 r=0
148 if bg_has("/tmp/bdg_runA.txt" as *u8, "boxes=" as *u8)==1 {
149 if bg_has("/tmp/bdg_runA.txt" as *u8, "FETCH-FAIL" as *u8)==0 {
150 if bg_exists("/tmp/nx_bdoc_in.html" as *u8)==0 { r=1 }
151 }
152 }
153 pass=pass+bg_row("neg-html-normal-pipeline" as *u8, r)
154
155 // stale-proof the expected artifacts, then RUN B: the browser navigates to md + csv + docx
156 bg_write("/tmp/nx_bdoc_md.html" as *u8, "STALE\n" as *u8)
157 bg_write("/tmp/nx_bdoc_csv.html" as *u8, "STALE\n" as *u8)
158 bg_write("/tmp/nx_bdoc_docx.html" as *u8, "STALE\n" as *u8)
159 bg_write("/tmp/nxsites" as *u8, "http://127.0.0.1:8099/bdg_t.md\nhttp://127.0.0.1:8099/bdg_t.csv\nhttp://127.0.0.1:8099/bdg_t.docx\n" as *u8)
160 bg_runv(BROWSER, bg_args0(), "/tmp/bdg_runB.txt" as *u8)
161
162 r=0
163 if bg_has("/tmp/nx_bdoc_md.html" as *u8, "<h1>Title</h1>" as *u8)==1 { if bg_has("/tmp/nx_bdoc_md.html" as *u8, "<b>world</b>" as *u8)==1 { r=1 } }
164 pass=pass+bg_row("md-converted-in-browser" as *u8, r)
165
166 r=0
167 if bg_has("/tmp/nx_bdoc_csv.html" as *u8, "<th>Name</th>" as *u8)==1 { if bg_has("/tmp/nx_bdoc_csv.html" as *u8, "<td>Denver</td>" as *u8)==1 { r=1 } }
168 pass=pass+bg_row("csv-converted-in-browser" as *u8, r)
169
170 r=0
171 if bg_has("/tmp/nx_bdoc_docx.html" as *u8, "Venue Booking Agreement" as *u8)==1 {
172 if bg_has("/tmp/nx_bdoc_docx.html" as *u8, "Parties agree to the terms" as *u8)==1 {
173 if bg_has("/tmp/nx_bdoc_docx.html" as *u8, "Rendered natively from OOXML" as *u8)==1 { r=1 }
174 }
175 }
176 pass=pass+bg_row("docx-converted-in-browser" as *u8, r)
177
178 r=0
179 if bg_has("/tmp/bdg_runB.txt" as *u8, "SITETEST n=3" as *u8)==1 {
180 if bg_has("/tmp/bdg_runB.txt" as *u8, "FETCH-FAIL" as *u8)==0 {
181 if bg_has("/tmp/bdg_runB.txt" as *u8, "doc omnitool rendered" as *u8)==1 { r=1 }
182 }
183 }
184 pass=pass+bg_row("all-laid-out-in-browser" as *u8, r)
185
186 r=1
187 if bg_has("/tmp/nx_bdoc_md.html" as *u8, "<script" as *u8)==1 { r=0 }
188 if bg_has("/tmp/nx_bdoc_csv.html" as *u8, "<script" as *u8)==1 { r=0 }
189 if bg_has("/tmp/nx_bdoc_docx.html" as *u8, "<script" as *u8)==1 { r=0 }
190 pass=pass+bg_row("outputs-sovereign-0js" as *u8, r)
191
192 bg_kill(srvpid)
193
194 let permil: i64=(pass*1000)/7
195 let logfd: i64=sys_openat_append("knowledge/status/vizsla_gate.log" as *u8, 0x1a4)
196 var fdi: i64=0
197 while fdi<2 {
198 var fd: i64=1; if fdi==1 { fd=logfd }
199 if fd>0 {
200 let line: *u8=sys_mmap(256); var o: i64=0
201 o=bg_cat(line,o,"BROWSER-DOC-GATE epoch=" as *u8); o=bg_catn(line,o,sys_now_realtime_sec())
202 o=bg_cat(line,o," rows=7 pass=" as *u8); o=bg_catn(line,o,pass)
203 o=bg_cat(line,o," permil=" as *u8); o=bg_catn(line,o,permil)
204 if pass==7 { o=bg_cat(line,o," verdict=GREEN\n" as *u8) } else { o=bg_cat(line,o," verdict=RED\n" as *u8) }
205 sys_write(fd, line, o)
206 }
207 fdi=fdi+1
208 }
209 if logfd>0 { sys_close(logfd) }
210 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
211 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
212 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
213 let ctr__dry: *i64 = gv_ctr()
214 ctr__dry[0] = pass
215 ctr__dry[1] = 7
216 let rc__dry: i64 = gv_verdict("BROWSER-DOC-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
217 sys_exit(rc__dry)
218 return rc__dry
219}