code wiki / _hdl_build / nx_reader_xray_gate.nx
nx_reader_xray_gate.nx source
↩ module page · 149 lines · 8879 B
1// nx_reader_xray_gate.nx -- liar-kill gate for the sovereign book-intrinsic X-Ray (nx_reader_xray).
2// Rebuilds the Alice fixture end-to-end, runs the X-Ray TWICE, and asserts on the REAL xray.json:
3// correctness : Alice present, count==6, first==0, ranked #1 (before Rabbit & White Rabbit); bigram "White
4// Rabbit" detected; standalone "Rabbit" detected; nterms==3.
5// determinism : run #1 and run #2 produce BYTE-IDENTICAL xray.json (no random, no clock, no order drift).
6// liar-kill : title noise ("Chapter") ABSENT, sentence-opener/stopwords ("I"/"She"/"There") ABSENT,
7// below-threshold one-offs ("DRINK ME", count 1 < MINOCC) ABSENT. If any leaks, FAIL.
8// GREEN = the X-Ray is a correct, deterministic, noise-free index -- NOT "we beat Kindle". Self-contained,
9// sovereign (fork/exec, no shell). expect_exit: 0 license_tier: ORIGINAL
10import "nx_syscalls.nx"
11import "nx_gate_verdict.nx"
12
13func xp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
14func xn(v0: i64) -> i64 { var v: i64=v0; if v<0 { sys_write(1,"-" as *u8,1); v=0-v } let b: *u8=sys_mmap(24); var k: i64=0; if v==0 {b[0]=48 as u8;k=1} while v>0 {b[k]=(48+(v%10)) as u8; v=v/10; k=k+1} let o: *u8=sys_mmap(24); var j: i64=0; while j<k {o[j]=b[k-1-j];j=j+1} sys_write(1,o,k); return 0 }
15func xslen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
16
17func spawn(path: *u8, a0: *u8, a1: *u8, redir: *u8) -> i64 {
18 let pid: i64 = sys_fork()
19 if pid == 0 {
20 let fd: i64 = sys_openat_wr(redir, 420)
21 if fd >= 0 { sys_dup3(fd, 1, 0); sys_dup3(fd, 2, 0) }
22 let argv: *i64 = sys_mmap(64) as *i64
23 var n: i64 = 0
24 argv[0] = path as i64; n = 1
25 if (a0 as i64) != 0 { argv[n] = a0 as i64; n = n + 1 }
26 if (a1 as i64) != 0 { argv[n] = a1 as i64; n = n + 1 }
27 argv[n] = 0
28 let envp: *i64 = sys_mmap(16) as *i64
29 envp[0] = "PATH=/usr/bin:/bin\x00" as *u8 as i64; envp[1] = 0
30 sys_execve(path, argv, envp)
31 sys_exit(127)
32 }
33 let st: *i64 = sys_mmap(16) as *i64
34 sys_wait4(pid, st, 0)
35 return (st[0] >> 8) & 0xff
36}
37
38func xfind(hay: *u8, hl: i64, needle: *u8) -> i64 {
39 let nl: i64 = xslen(needle)
40 if nl == 0 { return 0-1 }
41 var i: i64 = 0
42 while i + nl <= hl {
43 var k: i64 = 0; var hit: i64 = 1
44 while k < nl { if hay[i+k] != needle[k] { hit = 0; k = nl } else { k = k + 1 } }
45 if hit == 1 { return i }
46 i = i + 1
47 }
48 return 0-1
49}
50func xhas(hay: *u8, hl: i64, needle: *u8) -> i64 { if xfind(hay, hl, needle) >= 0 { return 1 } return 0 }
51// parse the int that follows `pos` (skips non-digits to the first digit/minus) -- same shape as render's jint
52func xint(hay: *u8, hl: i64, pos: i64) -> i64 {
53 var i: i64 = pos
54 while i < hl { let c: i64 = hay[i] as i64; if c==0x2d { break } if c>=48 { if c<=57 { break } } i=i+1 }
55 var neg: i64 = 0
56 if i < hl { if hay[i]==(0x2d as u8) { neg=1; i=i+1 } }
57 var v: i64 = 0
58 while i < hl { let c: i64 = hay[i] as i64; if c<48 { break } if c>57 { break } v=v*10+(c-48); i=i+1 }
59 if neg==1 { return 0-v }
60 return v
61}
62func xfrom(hay: *u8, hl: i64, start: i64, needle: *u8) -> i64 {
63 let nl: i64 = xslen(needle); if nl==0 { return 0-1 }
64 var i: i64 = start; if i<0 { i=0 }
65 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 }
66 return 0-1
67}
68
69func main() -> i64 {
70 xp("=== nx_reader_xray_gate: sovereign book-intrinsic X-Ray (liar-kill, organ-graded) ===\n" as *u8)
71 let RUNNER: *u8 = "_offc/nx_sov_build_run.elf\x00" as *u8
72 let SCRATCH: *u8 = "knowledge/status/reader_xray_scratch.log\x00" as *u8
73 let XPATH: *u8 = "knowledge/staging/media/reader/nishi_fixture/xray.json\x00" as *u8
74
75 // ---- rebuild inputs end-to-end, then run the X-Ray TWICE (determinism check) ----
76 spawn(RUNNER, "nx_epub_fixture_build\x00" as *u8, 0 as *u8, SCRATCH)
77 spawn("_offc/nx_epub_book.elf\x00" as *u8, "knowledge/fixtures/nishi_fixture.epub\x00" as *u8, "nishi_fixture\x00" as *u8, SCRATCH)
78 spawn(RUNNER, "nx_reader_xray\x00" as *u8, 0 as *u8, SCRATCH)
79 let l1: *i64 = sys_mmap(8) as *i64; l1[0]=0
80 let b1: *u8 = sys_read_file(XPATH, l1)
81 let n1: i64 = l1[0]
82 spawn(RUNNER, "nx_reader_xray\x00" as *u8, 0 as *u8, SCRATCH)
83 let l2: *i64 = sys_mmap(8) as *i64; l2[0]=0
84 let b2: *u8 = sys_read_file(XPATH, l2)
85 let n2: i64 = l2[0]
86
87 if (b1 as i64)==0 { xp("READER-XRAY-GATE verdict=RED reason=xray.json-missing\n" as *u8); sys_exit(1); return 1 }
88 if n1 <= 0 { xp("READER-XRAY-GATE verdict=RED reason=xray.json-empty\n" as *u8); sys_exit(1); return 1 }
89
90 // echo the measured artifact (show-raw-output)
91 xp(" xray.json (" as *u8); xn(n1); xp(" bytes): " as *u8); sys_write(1, b1, n1); xp("\n" as *u8)
92
93 // ---- locate Alice + parse its count/first ----
94 let posA: i64 = xfind(b1, n1, "\"name\":\"Alice\"" as *u8)
95 let posR: i64 = xfind(b1, n1, "\"name\":\"Rabbit\"" as *u8)
96 let posW: i64 = xfind(b1, n1, "\"name\":\"White Rabbit\"" as *u8)
97 var a_count: i64 = 0-1
98 var a_first: i64 = 0-1
99 if posA >= 0 {
100 let cat: i64 = xfrom(b1, n1, posA, "\"count\":" as *u8)
101 if cat >= 0 { a_count = xint(b1, n1, cat) }
102 let fat: i64 = xfrom(b1, n1, posA, "\"first\":" as *u8)
103 if fat >= 0 { a_first = xint(b1, n1, fat) }
104 }
105
106 // ---- determinism: byte-identical across the two runs ----
107 var ident: i64 = 1
108 if n1 != n2 { ident = 0 } else { var i: i64 = 0; while i < n1 { if b1[i] != b2[i] { ident = 0; i = n1 } else { i = i + 1 } } }
109
110 xp(" measured: posA=" as *u8); xn(posA); xp(" posR=" as *u8); xn(posR); xp(" posW=" as *u8); xn(posW)
111 xp(" Alice.count=" as *u8); xn(a_count); xp(" Alice.first=" as *u8); xn(a_first); xp(" det_identical=" as *u8); xn(ident); xp("\n" as *u8)
112
113 var pass: i64 = 0; var fail: i64 = 0
114 // correctness
115 if posA >= 0 { pass=pass+1 } else { fail=fail+1; xp(" FAIL alice-absent\n" as *u8) }
116 if a_count == 6 { pass=pass+1 } else { fail=fail+1; xp(" FAIL alice-count!=6\n" as *u8) }
117 if a_first == 0 { pass=pass+1 } else { fail=fail+1; xp(" FAIL alice-first!=0\n" as *u8) }
118 if posW >= 0 { pass=pass+1 } else { fail=fail+1; xp(" FAIL white-rabbit-bigram-absent\n" as *u8) }
119 if posR >= 0 { pass=pass+1 } else { fail=fail+1; xp(" FAIL standalone-rabbit-absent\n" as *u8) }
120 // ranking: Alice (count 6) must be FIRST -> appear before Rabbit and White Rabbit
121 var rank_ok: i64 = 0
122 if posA >= 0 { if posA < posR { if posA < posW { rank_ok = 1 } } }
123 if rank_ok == 1 { pass=pass+1 } else { fail=fail+1; xp(" FAIL alice-not-ranked-first\n" as *u8) }
124 if xhas(b1, n1, "\"nterms\":3" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; xp(" FAIL nterms!=3\n" as *u8) }
125 // concordance: Alice's per-chapter distribution must be exactly ch0:3 ch1:2 ch2:1 (deterministic)
126 if xhas(b1, n1, "\"by\":[0,3,1,2,2,1]" as *u8) == 1 { pass=pass+1 } else { fail=fail+1; xp(" FAIL alice-chapter-distribution-wrong\n" as *u8) }
127 // determinism
128 if ident == 1 { pass=pass+1 } else { fail=fail+1; xp(" FAIL not-deterministic\n" as *u8) }
129 // LIAR-KILL: title noise must NOT appear (proves title-skip)
130 if xhas(b1, n1, "\"name\":\"Chapter\"" as *u8) == 0 { pass=pass+1 } else { fail=fail+1; xp(" FAIL title-noise-Chapter-leaked\n" as *u8) }
131 // LIAR-KILL: mid-sentence stopword "I" must NOT appear
132 if xhas(b1, n1, "\"name\":\"I\"" as *u8) == 0 { pass=pass+1 } else { fail=fail+1; xp(" FAIL stopword-I-leaked\n" as *u8) }
133 // LIAR-KILL: sentence openers must NOT appear
134 if xhas(b1, n1, "\"name\":\"She\"" as *u8) == 0 { pass=pass+1 } else { fail=fail+1; xp(" FAIL opener-She-leaked\n" as *u8) }
135 if xhas(b1, n1, "\"name\":\"There\"" as *u8) == 0 { pass=pass+1 } else { fail=fail+1; xp(" FAIL opener-There-leaked\n" as *u8) }
136 // LIAR-KILL: below-threshold one-off must NOT appear (MINOCC filter has teeth)
137 if xhas(b1, n1, "\"name\":\"DRINK ME\"" as *u8) == 0 { pass=pass+1 } else { fail=fail+1; xp(" FAIL below-threshold-DRINK-ME-leaked\n" as *u8) }
138
139 xp("READER-XRAY-GATE pass=" as *u8); xn(pass); xp(" fail=" as *u8); xn(fail)
140 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
141 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
142 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
143 let ctr__dry: *i64 = gv_ctr()
144 ctr__dry[0] = pass
145 ctr__dry[1] = pass + fail
146 let rc__dry: i64 = gv_verdict("READER-XRAY-GATE" as *u8, ctr__dry, "X-Ray correct + deterministic + noise-free; book-intrinsic, derived from text, 0 external data)" as *u8)
147 sys_exit(rc__dry)
148 return rc__dry
149}