code wiki / _hdl_build / nx_reader_render_gate.nx

nx_reader_render_gate.nx source

↩ module page · 124 lines · 10372 B

1import "nx_gate_gn.nx" 2// nx_reader_render_gate.nx -- liar-kill gate for the ZERO-JAVASCRIPT sovereign reader (operator: "no js, nishi 3// everywhere"). Self-contained + sovereign (fork/exec): regen the fixture book.json, run nx_reader_render, then 4// assert the emitted page has ZERO <script>/eval/javascript: AND delivers the reading experience purely in 5// HTML+CSS -- nested TOC anchors, native <details> drawer, radio/:checked theming, cover + inline images. 6// THE point: all reader logic is in the Nishi organ; the browser runs no code. expect_exit: 0 7import "nx_syscalls.nx" 8import "nx_gate_verdict.nx" 9 10func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 11func gslen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 12func gfind(hay: *u8, hl: i64, needle: *u8) -> i64 { 13 let nl: i64 = gslen(needle); if nl == 0 { return 0-1 } 14 var i: i64 = 0 15 while i + nl <= hl { var k: i64=0; var hit: i64=1; while k<nl { if hay[i+k]!=needle[k]{hit=0;k=nl}else{k=k+1} } if hit==1 {return i} i=i+1 } 16 return 0-1 17} 18func ghas(hay: *u8, hl: i64, needle: *u8) -> i64 { if gfind(hay, hl, needle) >= 0 { return 1 } return 0 } 19func spawn(path: *u8, a0: *u8, a1: *u8, redir: *u8) -> i64 { 20 let pid: i64 = sys_fork() 21 if pid == 0 { 22 let fd: i64 = sys_openat_wr(redir, 420) 23 if fd >= 0 { sys_dup3(fd, 1, 0); sys_dup3(fd, 2, 0) } 24 let argv: *i64 = sys_mmap(64) as *i64 25 var n: i64 = 0 26 argv[0] = path as i64; n = 1 27 if (a0 as i64) != 0 { argv[n] = a0 as i64; n = n + 1 } 28 if (a1 as i64) != 0 { argv[n] = a1 as i64; n = n + 1 } 29 argv[n] = 0 30 let envp: *i64 = sys_mmap(16) as *i64 31 envp[0] = "PATH=/usr/bin:/bin\x00" as *u8 as i64; envp[1] = 0 32 sys_execve(path, argv, envp) 33 sys_exit(127) 34 } 35 let st: *i64 = sys_mmap(16) as *i64 36 sys_wait4(pid, st, 0) 37 return (st[0] >> 8) & 0xff 38} 39 40func main() -> i64 { 41 gp("=== nx_reader_render_gate: ZERO-JS sovereign reader (no js, nishi everywhere) ===\n" as *u8) 42 let RUNNER: *u8 = "_offc/nx_sov_build_run.elf\x00" as *u8 43 let SCRATCH: *u8 = "knowledge/status/reader_render_gate_scratch.log\x00" as *u8 44 45 spawn(RUNNER, "nx_epub_fixture_build\x00" as *u8, 0 as *u8, SCRATCH) 46 spawn(RUNNER, "nx_epub_book\x00" as *u8, 0 as *u8, SCRATCH) 47 spawn("_offc/nx_epub_book.elf\x00" as *u8, "knowledge/fixtures/nishi_fixture.epub\x00" as *u8, "nishi_fixture\x00" as *u8, SCRATCH) 48 spawn(RUNNER, "nx_reader_xray\x00" as *u8, 0 as *u8, SCRATCH) // book-intrinsic X-Ray BEFORE render -> panel is deterministic 49 spawn(RUNNER, "nx_reader_render\x00" as *u8, 0 as *u8, SCRATCH) 50 51 let lp: *i64 = sys_mmap(8) as *i64; lp[0] = 0 52 let h: *u8 = sys_read_file("knowledge/staging/media/reader_static_nishi_fixture.html\x00" as *u8, lp) 53 if (h as i64) == 0 { gp("READER-RENDER-GATE verdict=RED reason=output-missing\n" as *u8); sys_exit(1); return 1 } 54 let n: i64 = lp[0] 55 gp(" rendered bytes=" as *u8); gn(n); gp("\n" as *u8) 56 57 var pass: i64 = 0; var fail: i64 = 0 58 // THE point: zero client code 59 if gfind(h, n, "<script" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL has-script\n" as *u8) } 60 if gfind(h, n, "eval(" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL has-eval\n" as *u8) } 61 if gfind(h, n, "javascript:" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL has-jsurl\n" as *u8) } 62 if gfind(h, n, "onclick" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL has-inline-handler\n" as *u8) } 63 // reading experience in pure HTML+CSS 64 if ghas(h, n, "Alice (Nishi Fixture)" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-title\n" as *u8) } 65 if ghas(h, n, "<details class=\"toc\">" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-details-drawer\n" as *u8) } 66 if ghas(h, n, "href=\"#c1\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-toc-anchor\n" as *u8) } 67 if ghas(h, n, "class=\"d1\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-nested-toc\n" as *u8) } // hierarchy preserved 68 if ghas(h, n, "name=\"nxtheme\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-theme-radios\n" as *u8) } 69 if ghas(h, n, ":checked~.app" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-css-theming\n" as *u8) } // themes via CSS, not JS 70 if ghas(h, n, "reader/nishi_fixture/cover.png" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-cover\n" as *u8) } 71 if ghas(h, n, "reader/nishi_fixture/fig1.png" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-inline-img\n" as *u8) } // R-ART-2 inline figure 72 if ghas(h, n, "id=\"c0\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-section\n" as *u8) } 73 // a11y (SC38): skip-to-content link + named TOC landmark + main landmark (screen-reader navigable, still 0 JS) 74 if ghas(h, n, "class=\"skip\" href=\"#main\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-skip-link\n" as *u8) } 75 if ghas(h, n, "<nav aria-label=\"Table of contents\">" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-toc-landmark\n" as *u8) } 76 if ghas(h, n, "<main id=\"main\">" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-main-landmark\n" as *u8) } 77 // SC57 touch targets: >=44px on touch devices (Apple HIG / Material), still 0 JS 78 if ghas(h, n, "@media(pointer:coarse)" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-touch-media\n" as *u8) } 79 if ghas(h, n, "min-height:44px" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-44px-target\n" as *u8) } 80 if ghas(h, n, ":focus-visible" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-focus-visible\n" as *u8) } // WCAG 2.4.7 81 if ghas(h, n, "prefers-reduced-motion" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-reduced-motion\n" as *u8) } // WCAG 2.3.3 82 // reading-time estimate (organ-computed, zero-JS) 83 if ghas(h, n, "min read" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-reading-time\n" as *u8) } 84 // X-Ray reading aid: book-intrinsic notable-term index rendered as a zero-JS <details> panel with jump anchors 85 if ghas(h, n, "<details class=\"xray\">" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-xray-panel\n" as *u8) } 86 if ghas(h, n, "notable terms" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-xray-caption\n" as *u8) } 87 if ghas(h, n, "<b>Alice</b>" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-xray-term\n" as *u8) } 88 // SC39 a11y: dyslexia-friendly reading mode (zero-JS radio:checked -> font/spacing vars) 89 if ghas(h, n, "name=\"nxfont\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-font-mode-radios\n" as *u8) } 90 if ghas(h, n, "#fn-dys:checked~.app" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-dyslexia-css\n" as *u8) } 91 if ghas(h, n, "for=\"fn-dys\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-dyslexia-toggle\n" as *u8) } 92 // X-Ray concordance: per-chapter distribution chips (jump to each chapter the term appears in) 93 if ghas(h, n, "class=\"xr-dist\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-xray-distribution\n" as *u8) } 94 if ghas(h, n, ">1\xc2\xb73</a>" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-concordance-chip(Alice ch1:3)\n" as *u8) } 95 // footnotes (zero-JS): superscript ref -> note list with :target highlight + back-link; marker fully consumed 96 if ghas(h, n, "<sup class=\"fnref\">" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-footnote-ref\n" as *u8) } 97 if ghas(h, n, "class=\"footnotes\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-footnote-list\n" as *u8) } 98 if ghas(h, n, "href=\"#fn1\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-footnote-link\n" as *u8) } 99 if ghas(h, n, "<li id=\"fn1\">A telescope" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-footnote-note-text\n" as *u8) } 100 if ghas(h, n, "class=\"fnback\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-footnote-backlink\n" as *u8) } 101 if gfind(h, n, "[[fnref:" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL fnref-marker-leaked-as-text\n" as *u8) } 102 // extraction teeth: the note was pulled OUT of prose into book.json fn[] 103 let bjl: *i64 = sys_mmap(8) as *i64; bjl[0] = 0 104 let bjf: *u8 = sys_read_file("knowledge/staging/media/reader/nishi_fixture/book.json\x00" as *u8, bjl) 105 if (bjf as i64) != 0 { if ghas(bjf, bjl[0], "\"fn\":[{\"id\":\"fn1\",\"text\":\"A telescope" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-fn-extraction-in-book.json\n" as *u8) } } else { fail=fail+1; gp(" FAIL book.json-missing\n" as *u8) } 106 // reading-quality: drop-caps + print stylesheet + title-dedup (no repeated chapter-title <p>) 107 if ghas(h, n, "::first-letter" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-dropcap\n" as *u8) } 108 if ghas(h, n, "@media print" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-print-css\n" as *u8) } 109 if gfind(h, n, "<p>Chapter One</p>" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL title-dup-not-removed\n" as *u8) } 110 // teeth: the search discriminates (a present marker found, a bogus one absent) 111 if gfind(h, n, "id=\"c0\"" as *u8) >= 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL teeth-present\n" as *u8) } 112 if gfind(h, n, "data-bogus-xyz" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL teeth-absent\n" as *u8) } 113 114 gp("READER-RENDER-GATE pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail) 115 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 116 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 117 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 118 let ctr__dry: *i64 = gv_ctr() 119 ctr__dry[0] = pass 120 ctr__dry[1] = pass + fail 121 let rc__dry: i64 = gv_verdict("READER-RENDER-GATE" as *u8, ctr__dry, "sovereign reader: 0 JS, logic in the Nishi organ, interactions pure HTML+CSS)" as *u8) 122 sys_exit(rc__dry) 123 return rc__dry 124}