code wiki / _hdl_build / _wiki_discovery_gate.nx
_wiki_discovery_gate.nx source
↩ module page · 165 lines · 8775 B
1// _wiki_discovery_gate.nx -- unit gate for the wiki content loader's
2// V+1 AUTO-DISCOVERY (nx_wcl_discover_dir).
3//
4// NO mocks, NO HTTP daemon: drives the real loader functions against
5// the REAL wiki content dir (/mnt/c/Users/elder/nishi-silicon), then
6// renders a discovered page via the real nx_wiki_doc_render, then
7// builds the real inverted index and runs a POSITIVE + NEGATIVE search
8// control. Judged by the printed WIKIDISCOVERY marker (verdict=GREEN
9// only if EVERY assertion holds), NOT by $? -- mirrors the gate
10// convention in runtime/_hdl_build (e.g. _eoe_gate.nx).
11//
12// PROVES the V+1 TODO is closed: a new .md dropped into the content
13// dir becomes a page + search hit with ZERO code edit, because the
14// getdents64 walk enumerates the dir at load time.
15//
16// Import set mirrors the PROVEN-SAFE composition already shipping in
17// wiki/nx_wiki_doc_handler.nx (nx_syscalls + index_builder[->search] +
18// doc_render): import each module exactly ONCE to avoid the
19// double-import nxasm rc6 trap. nx_wiki_content_loader transitively
20// pulls nx_wiki_index_builder (doc store + inverted index).
21//
22// Evidence -> knowledge/status/wiki_discovery_gate.log + stdout.
23// license_tier: ORIGINAL
24import "nx_syscalls.nx"
25import "wiki/nx_wiki_content_loader.nx"
26import "wiki/nx_wiki_doc_render.nx"
27
28// ----- tiny io helpers (write to a fd; mirror the _eoe_gate shape) -----
29func wg_fp(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 }
30func wg_fn(fd: i64, v: i64) -> i64 {
31 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) }
32 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 }
33 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
34 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
35 sys_write(fd, bb, k); return 0
36}
37// write to BOTH stdout and the durable log fd (lfd<0 = stdout only)
38func wg_w2(lfd: i64, s: *u8) -> i64 { wg_fp(1, s); if lfd >= 0 { wg_fp(lfd, s) } return 0 }
39func wg_n2(lfd: i64, v: i64) -> i64 { wg_fn(1, v); if lfd >= 0 { wg_fn(lfd, v) } return 0 }
40
41// does NUL-terminated haystack contain counted-length needle? (substring)
42func wg_contains(hay: *u8, hay_n: i64, needle: *u8, needle_n: i64) -> i64 {
43 if needle_n <= 0 { return 0 }
44 if hay_n < needle_n { return 0 }
45 var i: i64 = 0
46 while i + needle_n <= hay_n {
47 var k: i64 = 0
48 var hit: i64 = 1
49 while k < needle_n { if hay[i + k] != needle[k] { hit = 0; k = needle_n } else { k = k + 1 } }
50 if hit == 1 { return 1 }
51 i = i + 1
52 }
53 return 0
54}
55
56const WG_K_MIN: i64 = 10 // assert: discovered at least this many .md pages
57const WG_OUT_CAP: i64 = 1048576 // 1 MiB render output buffer
58const WG_SCRATCH_CAP: i64 = 1048576 // 1 MiB wikilink-preprocess scratch
59
60func main() -> i64 {
61 wg_fp(1, "WIKIDISCOVERY-GATE: start (real getdents64 walk of the wiki content dir)\n" as *u8)
62
63 // ===== 1. AUTO-DISCOVER over the REAL content dir =====
64 let doc_store: *NxWikiDocStore = (sys_mmap(256)) as *NxWikiDocStore
65 let store_rc: i64 = nx_wiki_doc_store_init(doc_store, 1000, 65536, 65536, 4194304)
66 if store_rc != NX_WIB_OK {
67 wg_fp(1, "WIKIDISCOVERY pages=0 rendered_ok=0 search_hit=0 search_neg=0 verdict=RED (store init failed)\n" as *u8)
68 sys_exit(1); return 1
69 }
70 let builder: *NxWikiIndexBuilder = (sys_mmap(64)) as *NxWikiIndexBuilder
71 let builder_rc: i64 = nx_wiki_index_builder_init(builder, doc_store, 1000)
72 if builder_rc != NX_WIB_OK {
73 wg_fp(1, "WIKIDISCOVERY pages=0 rendered_ok=0 search_hit=0 search_neg=0 verdict=RED (builder init failed)\n" as *u8)
74 sys_exit(1); return 1
75 }
76
77 // THE FEATURE UNDER TEST: walk the dir + index every *.md page.
78 let dir: *u8 = "/mnt/c/Users/elder/nishi-silicon/" as *u8
79 let pages: i64 = nx_wcl_discover_dir(builder, dir)
80 wg_fp(1, " nx_wcl_discover_dir -> pages=" as *u8); wg_fn(1, pages); wg_fp(1, "\n" as *u8)
81 let dstore_n: i64 = nx_wiki_doc_store_count(doc_store)
82 wg_fp(1, " doc_store_count=" as *u8); wg_fn(1, dstore_n); wg_fp(1, "\n" as *u8)
83
84 // finalize the inverted index (PASS 2) so search works
85 let fin_rc: i64 = nx_wiki_index_builder_finalize(builder)
86 if fin_rc != NX_WIB_OK { wg_fp(1, " WARN finalize rc=" as *u8); wg_fn(1, fin_rc); wg_fp(1, "\n" as *u8) }
87
88 // Assert on the doc-store ground truth (docs actually indexed by the
89 // walk); the returned `pages` is reported in the marker. They agree.
90 var assert_pages: i64 = 0
91 if dstore_n >= WG_K_MIN { assert_pages = 1 }
92
93 // ===== 2. RENDER one discovered page + assert non-empty + known substring =====
94 // Read a KNOWN page that discovery indexed (NISHI_WIKI_CHARTER.md, whose
95 // first heading is "# Nishi wiki charter ...") and render it.
96 var rendered_ok: i64 = 0
97 let known_path: *u8 = "/mnt/c/Users/elder/nishi-silicon/NISHI_WIKI_CHARTER.md" as *u8
98 let blen: *i64 = (sys_mmap(8)) as *i64
99 blen[0] = 0
100 let src: *u8 = sys_read_file(known_path, blen)
101 if (src as i64) != 0 {
102 let src_n: i64 = blen[0]
103 if src_n > 0 {
104 let out_buf: *u8 = sys_mmap(WG_OUT_CAP)
105 let scratch: *u8 = sys_mmap(WG_SCRATCH_CAP)
106 let ctx: *NxWikiDocCtx = (sys_mmap(512)) as *NxWikiDocCtx
107 // no doc-name table needed for this assertion (0 entries -> wikilinks render broken, fine)
108 let ci_rc: i64 = nx_wiki_doc_ctx_init(ctx, out_buf, WG_OUT_CAP, src, src_n, 0 as *u8, 0, 0, scratch, WG_SCRATCH_CAP)
109 if ci_rc == NX_WIKI_DOC_OK {
110 let r_rc: i64 = nx_wiki_doc_render(ctx, "Nishi wiki charter" as *u8, 18)
111 if r_rc == NX_WIKI_DOC_OK {
112 let html_n: i64 = ctx.out_off
113 // non-empty AND contains the chrome marker "<main>" (proves
114 // render ran) AND the word "charter" from this page's body.
115 var has_main: i64 = wg_contains(out_buf, html_n, "<main>" as *u8, 6)
116 var has_word: i64 = wg_contains(out_buf, html_n, "charter" as *u8, 7)
117 if html_n > 0 { if has_main == 1 { if has_word == 1 { rendered_ok = 1 } } }
118 wg_fp(1, " render html_bytes=" as *u8); wg_fn(1, html_n)
119 wg_fp(1, " has<main>=" as *u8); wg_fn(1, has_main)
120 wg_fp(1, " has'charter'=" as *u8); wg_fn(1, has_word); wg_fp(1, "\n" as *u8)
121 } else { wg_fp(1, " render rc=" as *u8); wg_fn(1, r_rc); wg_fp(1, "\n" as *u8) }
122 }
123 }
124 }
125
126 // ===== 3. SEARCH controls: positive term hits, bogus term misses =====
127 let idx: *NxInvIndex = nx_wiki_index_builder_get_index(builder)
128 var search_hit: i64 = 0
129 var search_neg: i64 = 0
130 if (idx as i64) != 0 {
131 let rowids: *i64 = (sys_mmap(8 * 256)) as *i64
132 let qr: *NxInvQueryResult = (sys_mmap(64)) as *NxInvQueryResult
133 // POSITIVE: "sovereign" appears across the charter corpus.
134 let qrc_pos: i64 = nx_inv_query_term(idx, "sovereign" as *u8, 9, rowids, 256, qr)
135 let hits_pos: i64 = qr.n_rowids_filled
136 if qrc_pos == NX_INV_OK { if hits_pos >= 1 { search_hit = 1 } }
137 wg_fp(1, " search 'sovereign' verdict=" as *u8); wg_fn(1, qrc_pos)
138 wg_fp(1, " hits=" as *u8); wg_fn(1, hits_pos); wg_fp(1, "\n" as *u8)
139 // NEGATIVE: a bogus token must return zero hits (liar-kill).
140 let qr2: *NxInvQueryResult = (sys_mmap(64)) as *NxInvQueryResult
141 let qrc_neg: i64 = nx_inv_query_term(idx, "zzqxnonexistentterm" as *u8, 19, rowids, 256, qr2)
142 let hits_neg: i64 = qr2.n_rowids_filled
143 if hits_neg == 0 { search_neg = 1 }
144 wg_fp(1, " search 'zzqxnonexistentterm' verdict=" as *u8); wg_fn(1, qrc_neg)
145 wg_fp(1, " hits=" as *u8); wg_fn(1, hits_neg); wg_fp(1, "\n" as *u8)
146 }
147
148 // ===== 4. VERDICT (all four assertions) =====
149 var green: i64 = 1
150 if assert_pages != 1 { green = 0 }
151 if rendered_ok != 1 { green = 0 }
152 if search_hit != 1 { green = 0 }
153 if search_neg != 1 { green = 0 }
154
155 let lfd: i64 = sys_openat_append("knowledge/status/wiki_discovery_gate.log" as *u8, 420)
156 wg_w2(lfd, "WIKIDISCOVERY pages=" as *u8); wg_n2(lfd, dstore_n)
157 wg_w2(lfd, " rendered_ok=" as *u8); wg_n2(lfd, rendered_ok)
158 wg_w2(lfd, " search_hit=" as *u8); wg_n2(lfd, search_hit)
159 wg_w2(lfd, " search_neg=" as *u8); wg_n2(lfd, search_neg)
160 if green == 1 { wg_w2(lfd, " verdict=GREEN\n" as *u8) } else { wg_w2(lfd, " verdict=RED\n" as *u8) }
161 if lfd >= 0 { sys_close(lfd) }
162
163 if green == 1 { sys_exit(0); return 0 }
164 sys_exit(1); return 1
165}