code wiki / _hdl_build / nx_reader_page_gate.nx
nx_reader_page_gate.nx source
↩ module page · 97 lines · 6118 B
1import "nx_gate_gn.nx"
2// nx_reader_page_gate.nx -- liar-kill gate for R-EMIT: the reader last-mile is now ORGAN-EMITTED, byte-identical
3// (zero UI regression), sovereign, and fail-closed. Self-contained + sovereign (fork/exec, no shell): run the
4// emitter (default mode -> bootstrap source + emit served reader.html), assert dest == source byte-for-byte, assert
5// dest has 0 third-party loads, and prove FAIL-CLOSED: a tampered source (CDN <script src>) is REFUSED (exit 2) and
6// the scratch dest is NOT written. expect_exit: 0
7import "nx_syscalls.nx"
8import "nx_reader_sov.nx"
9import "nx_gate_verdict.nx"
10
11func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
12func gslen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
13func gfind(hay: *u8, hl: i64, needle: *u8) -> i64 {
14 let nl: i64 = gslen(needle); if nl == 0 { return 0-1 }
15 var i: i64 = 0
16 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 }
17 return 0-1
18}
19func gexists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 }
20func gunlink(path: *u8) -> i64 { return __syscall(263, 0-100, path, 0, 0, 0, 0) }
21func gwrite(path: *u8, buf: *u8, n: i64) -> i64 { let fd: i64 = sys_openat_wr(path, 0x1a4); if fd<0 {return 0-1} sys_write(fd, buf, n); sys_close(fd); return n }
22func eq_bytes(a: *u8, an: i64, b: *u8, bn: i64) -> i64 { if an != bn { return 0 } var i: i64=0; while i<an { if a[i]!=b[i]{return 0} i=i+1 } return 1 }
23
24func spawn(path: *u8, a0: *u8, a1: *u8, redir: *u8) -> i64 {
25 let pid: i64 = sys_fork()
26 if pid == 0 {
27 let fd: i64 = sys_openat_wr(redir, 420)
28 if fd >= 0 { sys_dup3(fd, 1, 0); sys_dup3(fd, 2, 0) }
29 let argv: *i64 = sys_mmap(64) as *i64
30 var n: i64 = 0
31 argv[0] = path as i64; n = 1
32 if (a0 as i64) != 0 { argv[n] = a0 as i64; n = n + 1 }
33 if (a1 as i64) != 0 { argv[n] = a1 as i64; n = n + 1 }
34 argv[n] = 0
35 let envp: *i64 = sys_mmap(16) as *i64
36 envp[0] = "PATH=/usr/bin:/bin\x00" as *u8 as i64; envp[1] = 0
37 sys_execve(path, argv, envp)
38 sys_exit(127)
39 }
40 let st: *i64 = sys_mmap(16) as *i64
41 sys_wait4(pid, st, 0)
42 return (st[0] >> 8) & 0xff
43}
44
45func main() -> i64 {
46 gp("=== nx_reader_page_gate: reader last-mile is ORGAN-EMITTED, byte-identical, fail-closed (R-EMIT) ===\n" as *u8)
47 let RUNNER: *u8 = "_offc/nx_sov_build_run.elf\x00" as *u8
48 let SCRATCH: *u8 = "knowledge/status/reader_page_gate_scratch.log\x00" as *u8
49
50 // build + run the emitter in DEFAULT mode (bootstrap source + emit served reader.html)
51 let rc: i64 = spawn(RUNNER, "nx_reader_page\x00" as *u8, 0 as *u8, SCRATCH)
52 gp(" emitter (default) runner-exit=" as *u8); gn(rc); gp("\n" as *u8)
53
54 var pass: i64 = 0; var fail: i64 = 0
55
56 // read source + emitted dest
57 let lps: *i64 = sys_mmap(8) as *i64; lps[0] = 0
58 let src: *u8 = sys_read_file("runtime/assets/reader_src.html\x00" as *u8, lps)
59 let sn: i64 = lps[0]
60 let lpd: *i64 = sys_mmap(8) as *i64; lpd[0] = 0
61 let dst: *u8 = sys_read_file("knowledge/staging/media/reader.html\x00" as *u8, lpd)
62 let dn: i64 = lpd[0]
63 if (src as i64)==0 { gp("READER-PAGE-GATE verdict=RED reason=source-missing\n" as *u8); sys_exit(1); return 1 }
64 if (dst as i64)==0 { gp("READER-PAGE-GATE verdict=RED reason=dest-missing\n" as *u8); sys_exit(1); return 1 }
65 gp(" source bytes=" as *u8); gn(sn); gp(" emitted bytes=" as *u8); gn(dn); gp("\n" as *u8)
66
67 // 1. organ faithful: emitted == source, byte-for-byte (zero regression)
68 if eq_bytes(src, sn, dst, dn) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL not-byte-identical\n" as *u8) }
69 // 2. emitted is sovereign (0 third-party)
70 if gfind(dst, dn, "<script src=" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL emitted-external-script\n" as *u8) }
71 if gfind(dst, dn, "src=\"http" as *u8) < 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL emitted-offsite-src\n" as *u8) }
72 // 3. it really IS the working reader (sanity: carries the engine markers)
73 if gfind(dst, dn, "function buildToc" as *u8) >= 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL emitted-missing-logic\n" as *u8) }
74
75 // 4. FAIL-CLOSED predicate -- the SAME reader_sovereign_ok that nx_reader_page enforces at emit time.
76 // A clean page (inline <script> is fine -- only EXTERNAL loads are forbidden) -> 1; a CDN <script src> -> 0.
77 let clean: *u8 = "<!doctype html><html><body><p>hi</p><script>var x=1;</script></body></html>" as *u8
78 let tamper: *u8 = "<!doctype html><html><body><script src=\"https://cdn.jsdelivr.net/x.js\"></script></body></html>" as *u8
79 if reader_sovereign_ok(clean, gslen(clean)) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL predicate-clean\n" as *u8) }
80 if reader_sovereign_ok(tamper, gslen(tamper)) == 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL predicate-tamper-not-refused\n" as *u8) }
81 if reader_sovereign_ok(dst, dn) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL predicate-emitted-not-clean\n" as *u8) }
82
83 // 5. teeth: byte-compare discriminates (self==1; length-diff==0)
84 if eq_bytes(dst, dn, dst, dn) == 1 { pass=pass+1 } else { fail=fail+1; gp(" FAIL teeth-self\n" as *u8) }
85 if eq_bytes(dst, dn, dst, dn-1) == 0 { pass=pass+1 } else { fail=fail+1; gp(" FAIL teeth-diff\n" as *u8) }
86
87 gp("READER-PAGE-GATE pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail)
88 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
89 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
90 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
91 let ctr__dry: *i64 = gv_ctr()
92 ctr__dry[0] = pass
93 ctr__dry[1] = pass + fail
94 let rc__dry: i64 = gv_verdict("READER-PAGE-GATE" as *u8, ctr__dry, "UI organ-emitted, byte-identical, sovereign, fail-closed)" as *u8)
95 sys_exit(rc__dry)
96 return rc__dry
97}