code wiki / _hdl_build / _wiki_cite_live_gate.nx

_wiki_cite_live_gate.nx source

↩ module page · 264 lines · 14066 B

1// _wiki_cite_live_gate.nx -- THE LIVE INLINE-CITE-CARD GATE (served output). 2// 3// Re-proves, from a REAL run (never a fabricated GREEN), that the anti-pushout 4// [[cite:<cid>]] supporting-source cards render LIVE (UNESCAPED) in the SERVED 5// wiki page -- judged on the actually-served (post-markdown) HTTP bytes, driven 6// through the SAME render body the daemon forks (nx_wiki_doc_handle_cp, the 7// cite-prefix-injectable form of nx_wiki_doc_handle). 8// 9// THE BUG THIS KILLS (the SAME shape as the escaped-[[wikilink]] bug): the cite 10// pass USED to expand [[cite:<cid>]] -> <details class="nx-cite"> card HTML 11// BEFORE markdown ran, so markdown_inline html-escaped the '<','>' to &lt;,&gt; 12// and the SERVED bytes were &lt;details... (dead escaped text), NOT a real 13// expandable card. The old cite gates "passed" only because they asserted the 14// substring in the PRE-markdown cite-render buffer -- a MEASUREMENT ARTIFACT; 15// the served output was escaped. FIX (mirrors the wikilink split): leave the 16// literal [[cite:<cid>]] token in the body, render markdown, then a POST-markdown 17// cite pass replaces each token with the card HTML emitted RAW (never escaped). 18// 19// SEED a FRESH per-run content-addressed archive prefix (empty each run => 20// idempotent, Rule 10; never the production WAR_PREFIX) with: 21// S1 HOSTABLE (CC_BY) content "ALPHA-INLINE-EVIDENCE-777" 22// S2 PROPRIETARY (NOT host) content "SECRET-NOHOST-888" 23// SEED a doc store with ONE page whose body cites BOTH: 24// "... [[cite:<cid_S1>]] ... [[cite:<cid_S2>]] ..." 25// RENDER it via nx_wiki_doc_handle_cp(..., prefix) and judge the SERVED HTML: 26// 27// card_live the served HTML contains a LIVE "<details class=\"nx-cite\"" 28// (NOT "&lt;details") AND "ALPHA-INLINE-EVIDENCE-777" sits INSIDE 29// that card (after the details-open + the card body div). 30// not_escaped the served HTML does NOT contain "&lt;details" ANYWHERE (no 31// dead html-escaped card leaked through). 32// liar_kill "SECRET-NOHOST-888" appears NOWHERE in the served HTML (the 33// proprietary source's bytes are suppressed), while a link + 34// license-note for S2 IS present (nx-cite-link + the note text). 35// 36// Verdict line (stdout + knowledge/status/wiki_cite_live_gate.log): 37// WIKICITELIVE card_live=<0|1> not_escaped=<0|1> liar_kill=<0|1> verdict=GREEN|RED 38// 39// Pure NishiLang, NO SQL, NO .sh/.py/.js, no new .tsv/.conf. nx_sites_daemon 40// UNTOUCHED. Imports the served handler under test (which transitively pulls the 41// cite-render + license + archive + seg_store chain, each spliced ONCE by the 42// resolver's module-identity dedup). license_tier: ORIGINAL 43import "nx_syscalls.nx" 44import "wiki/nx_wiki_index_builder.nx" 45import "wiki/nx_wiki_doc_handler.nx" 46import "wiki/nx_wiki_cite_render.nx" 47import "wiki/nx_artifact_store.nx" 48 49const WCL_LOG: *u8 = "knowledge/status/wiki_cite_live_gate.log" 50const WCL_RESP_CAP: i64 = 2097152 // 2 MiB served-response buffer 51const WCL_SCAN_CAP: i64 = 64 // archive segment-scan cap 52 53// ===== io helpers (mirror _wiki_frontend_gate.nx) ============================ 54func wcl_w(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 } 55func wcl_n(fd: i64, v: i64) -> i64 { 56 let bb: *u8 = sys_mmap(28); var m: i64 = v 57 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) } 58 let t: *u8 = sys_mmap(28); var k: i64 = 0 59 if m == 0 { t[0] = 48 as u8; k = 1 } 60 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 61 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 62 sys_write(fd, bb, k); return 0 63} 64func wcl_w2(lfd: i64, s: *u8) -> i64 { wcl_w(1, s); if lfd >= 0 { wcl_w(lfd, s) } return 0 } 65func wcl_n2(lfd: i64, v: i64) -> i64 { wcl_n(1, v); if lfd >= 0 { wcl_n(lfd, v) } return 0 } 66func wcl_p(s: *u8) -> i64 { wcl_w(1, s); return 0 } 67func wcl_pn(v: i64) -> i64 { wcl_n(1, v); return 0 } 68func wcl_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 69 70func wcl_cat(dst: *u8, off: i64, s: *u8) -> i64 { 71 var i: i64 = 0 72 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 } 73 return off + i 74} 75func wcl_catn(dst: *u8, off: i64, v: i64) -> i64 { 76 var m: i64 = v; var o: i64 = off 77 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m } 78 let t: *u8 = sys_mmap(28); var k: i64 = 0 79 if m == 0 { t[0] = 48 as u8; k = 1 } 80 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 81 var i: i64 = 0; while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 } 82 return o + k 83} 84 85// ===== GROUND-TRUTH SUBSTRING SEARCH (judge on the SERVED HTML) ============== 86func wcl_find(hay: *u8, hn: i64, needle: *u8) -> i64 { 87 let nn: i64 = wcl_slen(needle) 88 if nn == 0 { return 0 - 1 } 89 if nn > hn { return 0 - 1 } 90 var i: i64 = 0 91 let last: i64 = hn - nn 92 while i <= last { 93 var j: i64 = 0 94 var eq: i64 = 1 95 while j < nn { 96 if eq == 1 { if hay[i + j] != needle[j] { eq = 0 } } 97 j = j + 1 98 } 99 if eq == 1 { return i } 100 i = i + 1 101 } 102 return 0 - 1 103} 104func wcl_has(hay: *u8, hn: i64, needle: *u8) -> i64 { 105 if wcl_find(hay, hn, needle) >= 0 { return 1 } 106 return 0 107} 108 109func main() -> i64 { 110 wcl_p("WIKICITELIVE-GATE: start (served [[cite]] card LIVE/unescaped + liar-kill)\n" as *u8) 111 112 // ===== FRESH per-run archive prefix => empty archive each run (idempotent) == 113 // Never the production WAR_PREFIX; the handler reads THIS prefix via the 114 // cite-prefix-injectable nx_wiki_doc_handle_cp, so we exercise the SERVED path 115 // without touching production data. 116 let prefix: *u8 = sys_mmap(256) 117 var po: i64 = 0 118 po = wcl_cat(prefix, po, "knowledge/store/wikiarchive-citelivegate-" as *u8) 119 po = wcl_catn(prefix, po, sys_now_realtime_sec()) 120 po = wcl_cat(prefix, po, "-" as *u8) 121 prefix[po] = 0 as u8 122 wcl_p(" store prefix = " as *u8); wcl_p(prefix); wcl_p("\n" as *u8) 123 124 // distinctive content strings the gate searches for in the SERVED HTML 125 let evidence: *u8 = "ALPHA-INLINE-EVIDENCE-777" as *u8 126 let secret: *u8 = "SECRET-NOHOST-888" as *u8 127 128 // ===== SEED S1 (CC-BY, hostable) ========================================== 129 let s1_slug: *u8 = "src-live1" as *u8 130 let s1_body: *u8 = "Supporting evidence: ALPHA-INLINE-EVIDENCE-777 (full text of the hostable cited source).\n" as *u8 131 let cid_s1: *u8 = sys_mmap(80) 132 let w1: *i64 = ss_begin() 133 let r1: i64 = war_archive_page(w1, s1_slug, s1_body, wcl_slen(s1_body), cid_s1) 134 let c1: i64 = ss_commit(prefix, w1, 0) 135 let lset1: i64 = nx_wiki_license_set(prefix, cid_s1, NXLIC_CC_BY, 1) 136 wcl_p(" S1 (CC-BY) archive_rc=" as *u8); wcl_pn(r1); wcl_p(" commit=" as *u8); wcl_pn(c1) 137 wcl_p(" cid=" as *u8); wcl_p(cid_s1); wcl_p(" license_get=" as *u8); wcl_pn(nx_wiki_license_get(prefix, cid_s1)); wcl_p("\n" as *u8) 138 139 // ===== SEED S2 (PROPRIETARY, NOT hostable) ================================ 140 let s2_slug: *u8 = "src-live2" as *u8 141 let s2_body: *u8 = "Confidential: SECRET-NOHOST-888 must never be inlined without a license.\n" as *u8 142 let cid_s2: *u8 = sys_mmap(80) 143 let w2: *i64 = ss_begin() 144 let r2: i64 = war_archive_page(w2, s2_slug, s2_body, wcl_slen(s2_body), cid_s2) 145 let c2: i64 = ss_commit(prefix, w2, 2) 146 let lset2: i64 = nx_wiki_license_set(prefix, cid_s2, NXLIC_PROPRIETARY, 3) 147 wcl_p(" S2 (PROPRIETARY) archive_rc=" as *u8); wcl_pn(r2); wcl_p(" commit=" as *u8); wcl_pn(c2) 148 wcl_p(" cid=" as *u8); wcl_p(cid_s2); wcl_p(" license_get=" as *u8); wcl_pn(nx_wiki_license_get(prefix, cid_s2)) 149 wcl_p(" hostable=" as *u8); wcl_pn(nx_wiki_license_hostable(nx_wiki_license_get(prefix, cid_s2))); wcl_p("\n" as *u8) 150 151 // SANITY: prove S2's secret bytes ARE retrievable from the archive, so the 152 // absence-from-HTML below is a real suppression, not an archiving miss. 153 let pps: *i64 = sys_mmap(16) as *i64 154 let s2got: i64 = war_get_by_cid(prefix, cid_s2, pps, WCL_SCAN_CAP) 155 var s2_in_store: i64 = 0 156 if s2got > 0 { if wcl_has(pps[0] as *u8, s2got, secret) == 1 { s2_in_store = 1 } } 157 wcl_p(" S2 secret-in-store=" as *u8); wcl_pn(s2_in_store); wcl_p(" (archive readback len=" as *u8); wcl_pn(s2got); wcl_p(")\n" as *u8) 158 159 // ===== SEED a doc store with ONE page citing BOTH S1 and S2 =============== 160 let store: *NxWikiDocStore = sys_mmap(2048) as *NxWikiDocStore 161 let rc_init: i64 = nx_wiki_doc_store_init(store, 16, 8192, 8192, 65536) 162 wcl_p(" store_init rc=" as *u8); wcl_pn(rc_init); wcl_p("\n" as *u8) 163 164 // body: a markdown heading + a paragraph citing S1 (hostable) and S2 (proprietary). 165 let pg: *u8 = sys_mmap(1024) 166 var g: i64 = 0 167 g = wcl_cat(pg, g, "# Cite Live Page\n\nHostable source read in place: [[cite:" as *u8) 168 g = wcl_cat(pg, g, cid_s1) 169 g = wcl_cat(pg, g, "]].\n\nProprietary source (link only): [[cite:" as *u8) 170 g = wcl_cat(pg, g, cid_s2) 171 g = wcl_cat(pg, g, "]].\n" as *u8) 172 pg[g] = 0 as u8 173 let pg_rid: i64 = nx_wiki_doc_store_add(store, 174 "Cite Live Page" as *u8, 14, "/wiki/cite-live" as *u8, 15, pg, g) 175 wcl_p(" seeded page rowid=" as *u8); wcl_pn(pg_rid); wcl_p(" body_len=" as *u8); wcl_pn(g) 176 wcl_p(" doc_count=" as *u8); wcl_pn(nx_wiki_doc_store_count(store)); wcl_p("\n" as *u8) 177 178 // ===== RENDER via the REAL served handler (cite-prefix-injectable) ======== 179 // artifact_store = 0: a null artifact store is a graceful no-op (no pipeline 180 // banner) per Cardinal 14 -- the page still renders. cite_prefix = our fresh 181 // per-run archive prefix, so the cite post-pass resolves OUR S1/S2. 182 let url: *u8 = "/wiki/cite-live" as *u8 183 let url_n: i64 = 15 184 let resp: *u8 = sys_mmap(WCL_RESP_CAP) 185 let resp_n: *i64 = (sys_mmap(8)) as *i64 186 resp_n[0] = 0 187 let h_rc: i64 = nx_wiki_doc_handle_cp(store, 0 as *NxArtifactStore, url, url_n, 188 resp, WCL_RESP_CAP, resp_n, prefix) 189 let hn: i64 = resp_n[0] 190 wcl_p(" handle rc=" as *u8); wcl_pn(h_rc); wcl_p(" resp_len=" as *u8); wcl_pn(hn); wcl_p("\n" as *u8) 191 192 // ---- card_live: a LIVE "<details class=\"nx-cite\"" present AND the evidence 193 // sits INSIDE it (after the details-open AND the card-body div). The card is 194 // emitted RAW by the POST-markdown cite pass, so it is real markup not text. 195 // NOTE: "nx-cite-body" ALSO appears in the <head> CSS (.nx-cite-body{...}), so 196 // we scope the card-body + evidence search to the region AT/AFTER the 197 // details-open (the card's OWN body div), not the whole document. 198 var card_live: i64 = 0 199 let det_at: i64 = wcl_find(resp, hn, "<details class=\"nx-cite\"" as *u8) 200 var body_at: i64 = 0 - 1 201 var ev_at: i64 = 0 - 1 202 if det_at >= 0 { 203 let tail: *u8 = (resp as i64 + det_at) as *u8 204 let tail_n: i64 = hn - det_at 205 let rb: i64 = wcl_find(tail, tail_n, "nx-cite-body" as *u8) 206 if rb >= 0 { body_at = det_at + rb } 207 let re: i64 = wcl_find(tail, tail_n, evidence) 208 if re >= 0 { ev_at = det_at + re } 209 } 210 if det_at >= 0 { if body_at > det_at { if ev_at > body_at { card_live = 1 } } } 211 wcl_p(" card_live: details@" as *u8); wcl_pn(det_at); wcl_p(" card-body@" as *u8); wcl_pn(body_at) 212 wcl_p(" evidence@" as *u8); wcl_pn(ev_at); wcl_p(" -> card_live=" as *u8); wcl_pn(card_live); wcl_p("\n" as *u8) 213 214 // ---- not_escaped: NO "&lt;details" anywhere (no dead html-escaped card) ---- 215 var not_escaped: i64 = 1 216 let esc_at: i64 = wcl_find(resp, hn, "&lt;details" as *u8) 217 if esc_at >= 0 { not_escaped = 0 } 218 wcl_p(" not_escaped: &lt;details@" as *u8); wcl_pn(esc_at) 219 wcl_p(" (-1=absent=GOOD) -> not_escaped=" as *u8); wcl_pn(not_escaped); wcl_p("\n" as *u8) 220 221 // ---- liar_kill: the proprietary secret bytes appear NOWHERE in the served 222 // HTML, AND a link + license-note for S2 IS present (suppressed, not labeled). 223 var liar_kill: i64 = 0 224 let leak_at: i64 = wcl_find(resp, hn, secret) 225 let link_at: i64 = wcl_find(resp, hn, "nx-cite-link" as *u8) 226 let note_at: i64 = wcl_find(resp, hn, "licensing restricts inline hosting" as *u8) 227 if leak_at < 0 { if link_at >= 0 { if note_at >= 0 { liar_kill = 1 } } } 228 wcl_p(" liar_kill: SECRET_LEAK@" as *u8); wcl_pn(leak_at); wcl_p(" (-1=absent=GOOD)") 229 wcl_p(" link@" as *u8); wcl_pn(link_at); wcl_p(" note@" as *u8); wcl_pn(note_at) 230 wcl_p(" -> liar_kill=" as *u8); wcl_pn(liar_kill); wcl_p("\n" as *u8) 231 232 // ===== EVIDENCE: echo a served-HTML chunk around the two cards for judging == 233 // Locate the first card and print a window from there (so the inline card + 234 // the suppressed link are both visible to the human reader). 235 wcl_p(" ---- served HTML window around the cite cards ----\n" as *u8) 236 var win_start: i64 = 0 237 if det_at >= 0 { win_start = det_at - 80 } 238 if win_start < 0 { win_start = 0 } 239 var win_len: i64 = hn - win_start 240 if win_len > 1400 { win_len = 1400 } 241 let win_ptr: *u8 = (resp as i64 + win_start) as *u8 242 sys_write(1, win_ptr, win_len) 243 wcl_p("\n ---- /served window ----\n" as *u8) 244 245 // ===== VERDICT ===== 246 var green: i64 = 1 247 if card_live != 1 { green = 0 } 248 if not_escaped != 1 { green = 0 } 249 if liar_kill != 1 { green = 0 } 250 // belt-and-suspenders: the secret must truly have been in the store, so the 251 // suppression we measured was a real liar-kill (not an archiving miss). 252 if s2_in_store != 1 { green = 0 } 253 254 let lfd: i64 = sys_openat_append(WCL_LOG, 420) 255 wcl_w2(lfd, "WIKICITELIVE card_live=" as *u8); wcl_n2(lfd, card_live) 256 wcl_w2(lfd, " not_escaped=" as *u8); wcl_n2(lfd, not_escaped) 257 wcl_w2(lfd, " liar_kill=" as *u8); wcl_n2(lfd, liar_kill) 258 if green == 1 { wcl_w2(lfd, " verdict=GREEN\n" as *u8) } else { wcl_w2(lfd, " verdict=RED\n" as *u8) } 259 if lfd >= 0 { sys_close(lfd) } 260 261 if green == 1 { sys_exit(0); return 0 } 262 sys_exit(1) 263 return 1 264}