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}