code wiki / _hdl_build / nx_aw_browser_gate.nx

nx_aw_browser_gate.nx source

↩ module page · 212 lines · 11283 B

1// nx_aw_browser_gate.nx -- SOVEREIGN-BROWSER referee for the andelinwest client surfaces (operator: 2// "make sure that everything can work on the nishi os and nishi browser sovereign"). Drives the REAL 3// browser core (br_layout / br_draw_fb_at / br_hit_link -- the ONE core Linux/Windows/NishiOS ship) 4// over the REAL emitted pages (web_assets/sites/andelinwest, the same bytes nx_siteedit publishes): 5// T1 index.html LAYS OUT (ok=1, real page height) 6// T2 the whole-site NAV is CLICKABLE: a doc-coordinate sweep of br_hit_link finds ALL FOUR 7// /practice/<slug>.html links (what a NishiOS user can click to navigate -- GET-nav needs no JS) 8// T3 a practice page lays out (ok=1) -- the click target renders 9// T4 index RENDERS to a framebuffer with real ink (drawn px > threshold), receipt PNG written to 10// knowledge/status/aw_browser_index.png (eyeball evidence) 11// T5 NEG: a click in the dead gutter hits NO link (hit-testing is real, not always-true) 12// T6 HONEST GAP ROWS (documented, not asserted green): the portals' INTERACTIVE flows (login 13// typing, form POST, fetch/sessionStorage JS) are BROWSER-ENGINE rungs the core lacks today -- 14// text-input + form-submit + a session carrier. Public GET surfaces (site pages, /search SERPs, 15// /doc views, portal shells as READ-ONLY pages) are what works now. This gate prints the map. 16// GREEN iff T1-T5 pass. Appends knowledge/status/aw_browser_gate.log. license_tier: ORIGINAL 17// expect_exit: 0 18import "nx_browser_render.nx" 19 20func g_w(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_n(v: i64) -> i64 { let b: *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{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 22func g_lw(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_len(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 24// href bytes at (off,len) in buf equal NUL-terminated lit? 25func g_href_eq(buf: *u8, off: i64, len: i64, lit: *u8) -> i64 { 26 let ln: i64 = g_len(lit) 27 if len != ln { return 0 } 28 var i: i64 = 0 29 while i < ln { if (buf[off+i] as i64) != (lit[i] as i64) { return 0 } i = i + 1 } 30 return 1 31} 32 33const AWB_W: i64 = 500 34 35// Walk the layout-box table (the SAME table the shipped browser click path consults via 36// br_hit_link) and return 1 iff a box carries `href` AND a real clickable rect, ALSO 37// verifying br_hit_link resolves at that box's own coordinates (the true click). 38func g_link_clickable(p: *Page, href: *u8) -> i64 { 39 let ho: *i64 = sys_mmap(16) as *i64 40 let hl: *i64 = sys_mmap(16) as *i64 41 var i: i64 = 0 42 while i < p.tree.count { 43 if p.bhref_off[i] >= 0 { 44 if g_href_eq(p.buf, p.bhref_off[i], p.bhref_len[i], href) == 1 { 45 let bb: *LayoutBox = ((p.tree.boxes as i64) + i*NX_LAYOUT_BOX_BYTES) as *LayoutBox 46 // a user clicks somewhere on the VISIBLE card: probe a small band from the 47 // anchor's origin downward (container-anchor content starts a line below it). 48 var dy: i64 = 2 49 while dy < 96 { 50 if br_hit_link(p, bb.x + 10, bb.y + dy, ho, hl) == 1 { 51 if g_href_eq(p.buf, ho[0], hl[0], href) == 1 { return 1 } 52 } 53 dy = dy + 6 54 } 55 } 56 } 57 i = i + 1 58 } 59 return 0 60} 61 62// D-probe: does a page shape leave the card link clickable? Reports BOTH halves: 63// href-in-box-table (with the box rect) AND hit-resolution at that rect. 64func d_probe(label: *u8, htm: *u8) -> i64 { 65 let p: *Page = sys_mmap(NX_PAGE_BYTES) as *Page 66 p.raw = htm 67 var n: i64 = 0 68 while htm[n] != (0 as u8) { n = n + 1 } 69 p.raw_len = n 70 br_layout(p, 500) 71 let href: *u8 = "/practice/family-law.html" as *u8 72 var in_table: i64 = 0 73 var bx: i64 = 0 - 1 74 var by: i64 = 0 - 1 75 var bw: i64 = 0 - 1 76 var bh: i64 = 0 - 1 77 var i: i64 = 0 78 while i < p.tree.count { 79 if p.bhref_off[i] >= 0 { 80 if g_href_eq(p.buf, p.bhref_off[i], p.bhref_len[i], href) == 1 { 81 in_table = 1 82 let bb: *LayoutBox = ((p.tree.boxes as i64) + i*NX_LAYOUT_BOX_BYTES) as *LayoutBox 83 bx = bb.x; by = bb.y; bw = bb.w; bh = bb.h 84 } 85 } 86 i = i + 1 87 } 88 let ok: i64 = g_link_clickable(p, href) 89 g_w(" D " as *u8); g_w(label); g_w(": in_table=" as *u8); g_n(in_table) 90 g_w(" rect=" as *u8); g_n(bx); g_w("," as *u8); g_n(by); g_w("," as *u8); g_n(bw); g_w("x" as *u8); g_n(bh) 91 g_w(" clickable=" as *u8); g_n(ok); g_w(" (boxes=" as *u8); g_n(p.tree.count); g_w(")\n" as *u8) 92 // topology dump: idx parent kind rect href? 93 var d: i64 = 0 94 while d < p.tree.count { 95 let db: *LayoutBox = ((p.tree.boxes as i64) + d*NX_LAYOUT_BOX_BYTES) as *LayoutBox 96 g_w(" box " as *u8); g_n(d); g_w(" par=" as *u8); g_n(db.parent_idx) 97 g_w(" kind=" as *u8); g_n(db.kind) 98 g_w(" rect=" as *u8); g_n(db.x); g_w("," as *u8); g_n(db.y); g_w("," as *u8); g_n(db.w); g_w("x" as *u8); g_n(db.h) 99 g_w(" href=" as *u8); if p.bhref_off[d] >= 0 { g_n(1) } else { g_n(0) } 100 g_w("\n" as *u8) 101 d = d + 1 102 } 103 return ok 104} 105 106func main() -> i64 { 107 g_w("=== AW BROWSER GATE: the client surfaces on the SOVEREIGN browser core (the NishiOS core) ===\n" as *u8) 108 var pass: i64 = 0 109 110 // localize: two sibling cards -- do the anchors share a parent, or wrap individually? 111 d_probe("two-cards " as *u8, "<!doctype html><html><head><title>t</title></head><body><div class=\"grid\"><a class=\"card\" href=\"/practice/family-law.html\"><h3>Family Law</h3><p>desc one</p></a><a class=\"card\" href=\"/practice/estate-planning.html\"><h3>Estate</h3><p>desc two</p></a></div></body></html>\x00" as *u8) 112 113 114 // T1: the REAL emitted index lays out (the same bytes nx_siteedit publishes) 115 let lp: *i64 = sys_mmap(16) as *i64 116 let html: *u8 = sys_read_file("web_assets/sites/andelinwest/index.html\x00" as *u8, lp) 117 var t1: i64 = 0 118 let page: *Page = sys_mmap(NX_PAGE_BYTES) as *Page 119 if lp[0] > 0 { 120 page.raw = html 121 page.raw_len = lp[0] 122 br_layout(page, AWB_W) 123 if page.ok == 1 { if page.page_h > 400 { t1 = 1 } } 124 } 125 pass = pass + t1 126 g_w(" T1 index.html lays out (ok, page_h=" as *u8); g_n(page.page_h); g_w("): " as *u8) 127 if t1 == 1 { g_w("PASS\n" as *u8) } else { g_w("FAIL\n" as *u8) } 128 129 // T2: every practice link exists as a box the browser click path resolves at its own rect 130 // (the exact navigation a NishiOS user performs -- box-walk + br_hit_link, the U5 idiom) 131 let f_fam: i64 = g_link_clickable(page, "/practice/family-law.html" as *u8) 132 let f_est: i64 = g_link_clickable(page, "/practice/estate-planning.html" as *u8) 133 let f_bus: i64 = g_link_clickable(page, "/practice/business-law.html" as *u8) 134 let f_inj: i64 = g_link_clickable(page, "/practice/personal-injury.html" as *u8) 135 var t2: i64 = 0 136 if f_fam == 1 { if f_est == 1 { if f_bus == 1 { if f_inj == 1 { t2 = 1 } } } } 137 pass = pass + t2 138 g_w(" T2 all 4 practice links click-resolve at their boxes (fam/est/bus/inj=" as *u8) 139 g_n(f_fam); g_n(f_est); g_n(f_bus); g_n(f_inj); g_w("): " as *u8) 140 if t2 == 1 { g_w("PASS\n" as *u8) } else { g_w("FAIL\n" as *u8) } 141 142 // T3: the click target (family-law page) lays out 143 let lp2: *i64 = sys_mmap(16) as *i64 144 let html2: *u8 = sys_read_file("web_assets/sites/andelinwest/practice/family-law.html\x00" as *u8, lp2) 145 var t3: i64 = 0 146 let p2: *Page = sys_mmap(NX_PAGE_BYTES) as *Page 147 if lp2[0] > 0 { 148 p2.raw = html2 149 p2.raw_len = lp2[0] 150 br_layout(p2, AWB_W) 151 if p2.ok == 1 { if p2.page_h > 300 { t3 = 1 } } 152 } 153 pass = pass + t3 154 g_w(" T3 practice page lays out (page_h=" as *u8); g_n(p2.page_h); g_w("): " as *u8) 155 if t3 == 1 { g_w("PASS\n" as *u8) } else { g_w("FAIL\n" as *u8) } 156 157 // T4: render the index viewport; count drawn (non-white) pixels; write the receipt PNG 158 let W: i64 = AWB_W 159 let H: i64 = 400 160 let fb: *Framebuffer = sys_mmap(NX_FRAMEBUFFER_BYTES) as *Framebuffer 161 let px: *u8 = sys_mmap(W*H*4 + 64) 162 nx_framebuffer_init(fb, px, W, H) 163 br_draw_fb_at(fb, page, W, "https://andelinwest.com/\x00" as *u8, 24, 1, 0) 164 var ink: i64 = 0 165 var iy: i64 = 0 166 while iy < H { 167 var ix: i64 = 0 168 while ix < W { 169 let o: i64 = (iy*W + ix)*4 170 if (px[o] as i64) < 240 { ink = ink + 1 } 171 ix = ix + 1 172 } 173 iy = iy + 1 174 } 175 let rgb: *u8 = sys_mmap(W*H*3 + 64) 176 var pxi: i64 = 0 177 while pxi < W*H { rgb[pxi*3]=px[pxi*4]; rgb[pxi*3+1]=px[pxi*4+1]; rgb[pxi*3+2]=px[pxi*4+2]; pxi=pxi+1 } 178 nx_png_write_rgb("knowledge/status/aw_browser_index.png\x00" as *u8, rgb, W, H) 179 var t4: i64 = 0 180 if ink > 5000 { t4 = 1 } 181 pass = pass + t4 182 g_w(" T4 index renders with real ink (drawn px=" as *u8); g_n(ink); g_w(", PNG receipt written): " as *u8) 183 if t4 == 1 { g_w("PASS\n" as *u8) } else { g_w("FAIL\n" as *u8) } 184 185 // T5 NEG: a click far right of the content column hits nothing 186 var t5: i64 = 0 187 if br_hit_link(page, AWB_W - 2, page.page_h - 2, ho, hl) == 0 { t5 = 1 } 188 pass = pass + t5 189 g_w(" T5 NEG dead-gutter click hits no link: " as *u8) 190 if t5 == 1 { g_w("PASS\n" as *u8) } else { g_w("FAIL\n" as *u8) } 191 192 // T6: the honest interaction-gap map (documented rows, not asserted) 193 g_w(" T6 GAP MAP (browser-engine rungs, not portal defects):\n" as *u8) 194 g_w(" works NOW on the sovereign core: site pages + nav clicks, /search SERPs + /doc views\n" as *u8) 195 g_w(" (server-rendered GET), portal shells render read-only.\n" as *u8) 196 g_w(" NEEDS BROWSER RUNGS: text input, form submit (GET/POST), session carrier -> then the\n" as *u8) 197 g_w(" portals' login/upload/compose work JS-free (their APIs are already plain forms + tokens).\n" as *u8) 198 199 g_w("----\nAW-BROWSER rows=5 pass=" as *u8); g_n(pass); g_w("\n" as *u8) 200 let lg: i64 = sys_openat_append("knowledge/status/aw_browser_gate.log" as *u8, 0x1a4) 201 if lg >= 0 { 202 g_lw(lg, "AW-BROWSER index_layout=" as *u8); if t1==1 { g_lw(lg,"1" as *u8) } else { g_lw(lg,"0" as *u8) } 203 g_lw(lg, " nav_links_clickable=" as *u8); if t2==1 { g_lw(lg,"1" as *u8) } else { g_lw(lg,"0" as *u8) } 204 g_lw(lg, " practice_layout=" as *u8); if t3==1 { g_lw(lg,"1" as *u8) } else { g_lw(lg,"0" as *u8) } 205 g_lw(lg, " render_ink=" as *u8); if t4==1 { g_lw(lg,"1" as *u8) } else { g_lw(lg,"0" as *u8) } 206 g_lw(lg, " neg_miss=" as *u8); if t5==1 { g_lw(lg,"1" as *u8) } else { g_lw(lg,"0" as *u8) } 207 if pass == 5 { g_lw(lg, " verdict=GREEN\n" as *u8) } else { g_lw(lg, " verdict=RED\n" as *u8) } 208 sys_close(lg) 209 } 210 if pass == 5 { g_w("AW-BROWSER GREEN (client site navigable on the sovereign core; interaction rungs named)\n" as *u8); sys_exit(0); return 0 } 211 g_w("AW-BROWSER RED\n" as *u8); sys_exit(1); return 1 212}