code wiki / _hdl_build / nx_reader_render_gate.nx
nx_reader_render_gate.nx source
↩ module page · 116 lines · 9980 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"
8
9func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
10func gslen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
11func gfind(hay: *u8, hl: i64, needle: *u8) -> i64 {
12 let nl: i64 = gslen(needle); if nl == 0 { return 0-1 }
13 var i: i64 = 0
14 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 }
15 return 0-1
16}
17func ghas(hay: *u8, hl: i64, needle: *u8) -> i64 { if gfind(hay, hl, needle) >= 0 { return 1 } return 0 }
18func spawn(path: *u8, a0: *u8, a1: *u8, redir: *u8) -> i64 {
19 let pid: i64 = sys_fork()
20 if pid == 0 {
21 let fd: i64 = sys_openat_wr(redir, 420)
22 if fd >= 0 { sys_dup3(fd, 1, 0); sys_dup3(fd, 2, 0) }
23 let argv: *i64 = sys_mmap(64) as *i64
24 var n: i64 = 0
25 argv[0] = path as i64; n = 1
26 if (a0 as i64) != 0 { argv[n] = a0 as i64; n = n + 1 }
27 if (a1 as i64) != 0 { argv[n] = a1 as i64; n = n + 1 }
28 argv[n] = 0
29 let envp: *i64 = sys_mmap(16) as *i64
30 envp[0] = "PATH=/usr/bin:/bin\x00" as *u8 as i64; envp[1] = 0
31 sys_execve(path, argv, envp)
32 sys_exit(127)
33 }
34 let st: *i64 = sys_mmap(16) as *i64
35 sys_wait4(pid, st, 0)
36 return (st[0] >> 8) & 0xff
37}
38
39func main() -> i64 {
40 gp("=== nx_reader_render_gate: ZERO-JS sovereign reader (no js, nishi everywhere) ===\n" as *u8)
41 let RUNNER: *u8 = "_offc/nx_sov_build_run.elf\x00" as *u8
42 let SCRATCH: *u8 = "knowledge/status/reader_render_gate_scratch.log\x00" as *u8
43
44 spawn(RUNNER, "nx_epub_fixture_build\x00" as *u8, 0 as *u8, SCRATCH)
45 spawn(RUNNER, "nx_epub_book\x00" as *u8, 0 as *u8, SCRATCH)
46 spawn("_offc/nx_epub_book.elf\x00" as *u8, "knowledge/fixtures/nishi_fixture.epub\x00" as *u8, "nishi_fixture\x00" as *u8, SCRATCH)
47 spawn(RUNNER, "nx_reader_xray\x00" as *u8, 0 as *u8, SCRATCH) // book-intrinsic X-Ray BEFORE render -> panel is deterministic
48 spawn(RUNNER, "nx_reader_render\x00" as *u8, 0 as *u8, SCRATCH)
49
50 let lp: *i64 = sys_mmap(8) as *i64; lp[0] = 0
51 let h: *u8 = sys_read_file("knowledge/staging/media/reader_static_nishi_fixture.html\x00" as *u8, lp)
52 if (h as i64) == 0 { gp("READER-RENDER-GATE verdict=RED reason=output-missing\n" as *u8); sys_exit(1); return 1 }
53 let n: i64 = lp[0]
54 gp(" rendered bytes=" as *u8); gn(n); gp("\n" as *u8)
55
56 var pass: i64 = 0; var fail: i64 = 0
57 // THE point: zero client code
58 if gfind(h, n, "<script" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL has-script\n" as *u8) }
59 if gfind(h, n, "eval(" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL has-eval\n" as *u8) }
60 if gfind(h, n, "javascript:" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL has-jsurl\n" as *u8) }
61 if gfind(h, n, "onclick" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL has-inline-handler\n" as *u8) }
62 // reading experience in pure HTML+CSS
63 if ghas(h, n, "Alice (Nishi Fixture)" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-title\n" as *u8) }
64 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) }
65 if ghas(h, n, "href=\"#c1\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-toc-anchor\n" as *u8) }
66 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
67 if ghas(h, n, "name=\"nxtheme\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-theme-radios\n" as *u8) }
68 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
69 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) }
70 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
71 if ghas(h, n, "id=\"c0\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-section\n" as *u8) }
72 // a11y (SC38): skip-to-content link + named TOC landmark + main landmark (screen-reader navigable, still 0 JS)
73 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) }
74 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) }
75 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) }
76 // SC57 touch targets: >=44px on touch devices (Apple HIG / Material), still 0 JS
77 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) }
78 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) }
79 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
80 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
81 // reading-time estimate (organ-computed, zero-JS)
82 if ghas(h, n, "min read" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-reading-time\n" as *u8) }
83 // X-Ray reading aid: book-intrinsic notable-term index rendered as a zero-JS <details> panel with jump anchors
84 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) }
85 if ghas(h, n, "notable terms" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-xray-caption\n" as *u8) }
86 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) }
87 // SC39 a11y: dyslexia-friendly reading mode (zero-JS radio:checked -> font/spacing vars)
88 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) }
89 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) }
90 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) }
91 // X-Ray concordance: per-chapter distribution chips (jump to each chapter the term appears in)
92 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) }
93 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) }
94 // footnotes (zero-JS): superscript ref -> note list with :target highlight + back-link; marker fully consumed
95 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) }
96 if ghas(h, n, "class=\"footnotes\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-footnote-list\n" as *u8) }
97 if ghas(h, n, "href=\"#fn1\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-footnote-link\n" as *u8) }
98 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) }
99 if ghas(h, n, "class=\"fnback\"" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-footnote-backlink\n" as *u8) }
100 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) }
101 // extraction teeth: the note was pulled OUT of prose into book.json fn[]
102 let bjl: *i64 = sys_mmap(8) as *i64; bjl[0] = 0
103 let bjf: *u8 = sys_read_file("knowledge/staging/media/reader/nishi_fixture/book.json\x00" as *u8, bjl)
104 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) }
105 // reading-quality: drop-caps + print stylesheet + title-dedup (no repeated chapter-title <p>)
106 if ghas(h, n, "::first-letter" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-dropcap\n" as *u8) }
107 if ghas(h, n, "@media print" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL no-print-css\n" as *u8) }
108 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) }
109 // teeth: the search discriminates (a present marker found, a bogus one absent)
110 if gfind(h, n, "id=\"c0\"" as *u8) >= 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL teeth-present\n" as *u8) }
111 if gfind(h, n, "data-bogus-xyz" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL teeth-absent\n" as *u8) }
112
113 gp("READER-RENDER-GATE pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail)
114 if fail == 0 { gp(" verdict=GREEN (sovereign reader: 0 JS, logic in the Nishi organ, interactions pure HTML+CSS)\n" as *u8); sys_exit(0); return 0 }
115 gp(" verdict=RED\n" as *u8); sys_exit(1); return 1
116}