code wiki / _hdl_build / nx_docportal_search_seg_gate.nx

nx_docportal_search_seg_gate.nx source

↩ module page · 547 lines · 34726 B

1// nx_docportal_search_seg_gate.nx -- GATE for the SOVEREIGN seg_store-native onsite search (nx_docportal_search_seg). 2// Writes 3 PUBLIC docs into a test shard through the RAW sovereign store (doc:<cid> keys, text values so 3// ss_write_seg builds .terms), then drives dss_search end-to-end over the REAL seg_store -- proving the sovereign 4// path (ss_open -> ss_term postings -> ss_hget -> rank) with NO tsv anywhere. Negative controls: absent term -> 0, 5// absent shard -> 0 (isolation, not a crash). license_tier: ORIGINAL 6import "nx_docportal_search_seg.nx" 7 8// evidence-line builders (local, so this gate stays self-contained) 9func dsg_cat(b: *u8, off: i64, s: *u8) -> i64 { var o: i64 = off; var i: i64 = 0; while s[i] != (0 as u8) { b[o] = s[i]; o = o + 1; i = i + 1 } return o } 10func dsg_catn(b: *u8, off: i64, v: i64) -> i64 { 11 var m: i64 = v 12 if m < 0 { m = 0 } 13 let t: *u8 = sys_mmap(28) 14 var k: i64 = 0 15 if m == 0 { t[0] = 48 as u8; k = 1 } 16 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 17 var o: i64 = off 18 var i: i64 = 0 19 while i < k { b[o] = t[k - 1 - i]; o = o + 1; i = i + 1 } 20 return o 21} 22 23func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 24func g_num(v: i64) -> i64 { 25 let bb: *u8 = sys_mmap(28); var m: i64 = v 26 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 27 let t: *u8 = sys_mmap(28); var k: i64 = 0 28 if m == 0 { t[0] = 48 as u8; k = 1 } 29 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 30 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 31 sys_write(1, bb, k); return 0 32} 33func g_strlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 34 35// one check: got n results with cids_out[0]==want_top (want_top<0 = don't care about top); expect_n<0 = don't care 36func g_check(name: *u8, got_n: i64, cids: *i64, expect_n: i64, want_top: i64, pass: *i64, total: *i64) -> i64 { 37 total[0] = total[0] + 1 38 var ok: i64 = 1 39 if expect_n >= 0 { if got_n != expect_n { ok = 0 } } 40 if want_top >= 0 { if got_n < 1 { ok = 0 } else { if cids[0] != want_top { ok = 0 } } } 41 g_puts(name); g_puts(" n="); g_num(got_n) 42 if ok == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 43 return 0 44} 45 46func main(argc: i64, argv: *i64) -> i64 { 47 g_puts("=== nx_docportal_search_seg gate (SOVEREIGN seg_store search, no tsv) ===\n") 48 // --- write a test PUBLIC shard through the raw sovereign store --- 49 let prefix: *u8 = "knowledge/store/dp-ssgatetest-pub-" as *u8 50 let d1: *u8 = "Estate Planning wills living trusts probate inheritance executor" as *u8 51 let d2: *u8 = "Family Law divorce child custody support alimony parenting plans" as *u8 52 let d3: *u8 = "Business Law llc corporation formation contracts operating agreement" as *u8 53 // consent rows (same segment, deterministic re-runs): 104 opted OUT of search (pol=2 = AI_BLOG only), 54 // 105 opted IN (pol=1). 101-103 stay pol-FREE = the absent-pol default-searchable path. 55 let d4: *u8 = "Adoption confidential retainer matters" as *u8 56 let d5: *u8 = "Municipal annexation ordinance guidance" as *u8 57 let w: *i64 = ss_begin() 58 ss_add(w, 1, "doc:101" as *u8, d1, g_strlen(d1)) 59 ss_add(w, 1, "doc:102" as *u8, d2, g_strlen(d2)) 60 ss_add(w, 1, "doc:103" as *u8, d3, g_strlen(d3)) 61 // url rows for the site: field-filter rows (103 deliberately has NO url = not site-attributable) 62 ss_add(w, 1, "url:101" as *u8, "https://en.wikipedia.org/wiki/Trust_law" as *u8, 39) 63 ss_add(w, 1, "url:102" as *u8, "https://law.example.com/family" as *u8, 30) 64 ss_add(w, 1, "doc:104" as *u8, d4, g_strlen(d4)) 65 ss_add(w, 1, "pol:104" as *u8, "2" as *u8, 1) 66 ss_add(w, 1, "doc:105" as *u8, d5, g_strlen(d5)) 67 ss_add(w, 1, "pol:105" as *u8, "1" as *u8, 1) 68 // IDF fixture (T9): idfrare lives in ONE doc (106); idfcommon in FOUR (107-110). Equal tf. The OLD 69 // distinct+tf scorer TIED 106 vs 107 (first candidate won = 107, postings order); only IDF ranking 70 // puts the rare-term doc on top -- this row fails on the old scorer BY CONSTRUCTION. 71 let d6: *u8 = "idfrare idfrare notice" as *u8 72 let d7: *u8 = "idfcommon idfcommon memo" as *u8 73 let d8: *u8 = "idfcommon lorem" as *u8 74 let d9: *u8 = "idfcommon ipsum" as *u8 75 let d10: *u8 = "idfcommon dolor" as *u8 76 ss_add(w, 1, "doc:106" as *u8, d6, g_strlen(d6)) 77 ss_add(w, 1, "doc:107" as *u8, d7, g_strlen(d7)) 78 ss_add(w, 1, "doc:108" as *u8, d8, g_strlen(d8)) 79 ss_add(w, 1, "doc:109" as *u8, d9, g_strlen(d9)) 80 ss_add(w, 1, "doc:110" as *u8, d10, g_strlen(d10)) 81 // length-norm fixture (T14): the LONG doc (126) is inserted FIRST -- under b=0 equal tf tied and 82 // candidate order won (126); full BM25's verbosity correction must put the SHORT doc (127) on top. 83 let dlong: *u8 = sys_mmap(4096) 84 var dlo: i64 = 0 85 var lr: i64 = 0 86 while lr < 80 { let wf: *u8 = "verbose filler prose words continue onward " as *u8; var wj: i64 = 0; while wf[wj] != (0 as u8) { dlong[dlo] = wf[wj]; dlo = dlo + 1; wj = wj + 1 } lr = lr + 1 } 87 let lm: *u8 = "lennorm appears once here" as *u8 88 var lj: i64 = 0 89 while lm[lj] != (0 as u8) { dlong[dlo] = lm[lj]; dlo = dlo + 1; lj = lj + 1 } 90 let dshort: *u8 = "lennorm short focused note" as *u8 91 ss_add(w, 1, "doc:126" as *u8, dlong, dlo) 92 ss_add(w, 1, "doc:127" as *u8, dshort, g_strlen(dshort)) 93 // stemming fixture (T18): a doc that only says the INFLECTED form -- query stem-expansion must recall it 94 let dstem: *u8 = "stemtoken indexing crawlers were ranking pages" as *u8 95 ss_add(w, 1, "doc:128" as *u8, dstem, g_strlen(dstem)) 96 // pagination fixture (T10): 15 pgseg docs -> offset/total behavior is provable (page sizes 10/5/0) 97 let dpg: *u8 = "pgseg pagination fixture entry" as *u8 98 let pgkey: *u8 = sys_mmap(24) 99 var pgi: i64 = 111 100 while pgi <= 125 { 101 var ko: i64 = 0 102 let kp: *u8 = "doc:" as *u8 103 while kp[ko] != (0 as u8) { pgkey[ko] = kp[ko]; ko = ko + 1 } 104 pgkey[ko] = (48 + (pgi / 100)) as u8 105 pgkey[ko + 1] = (48 + ((pgi / 10) % 10)) as u8 106 pgkey[ko + 2] = (48 + (pgi % 10)) as u8 107 pgkey[ko + 3] = 0 as u8 108 ss_add(w, 1, pgkey, dpg, g_strlen(dpg)) 109 pgi = pgi + 1 110 } 111 // host-diversity fixture (T22/T23): 5 docs on crowd.example.com (tf=2) + 2 on other.example.com (tf=1), 112 // all matching "diversitytest". WITHOUT the cap (webdiv=0) the 5 tf=2 crowd docs take the top 5 slots 113 // (cids[3]=304); WITH the cap (webdiv=1, DSS_HOSTCAP=3) an OTHER-host doc is promoted into slot 3 114 // (cids[3]=306) once crowd hits the cap -- distinguishing by construction (the old scorer had no cap). 115 let dcrowd: *u8 = "diversitytest diversitytest note" as *u8 116 let dother: *u8 = "diversitytest memo" as *u8 117 ss_add(w, 1, "doc:301" as *u8, dcrowd, g_strlen(dcrowd)) 118 ss_add(w, 1, "url:301" as *u8, "https://crowd.example.com/1" as *u8, 27) 119 ss_add(w, 1, "doc:302" as *u8, dcrowd, g_strlen(dcrowd)) 120 ss_add(w, 1, "url:302" as *u8, "https://crowd.example.com/2" as *u8, 27) 121 ss_add(w, 1, "doc:303" as *u8, dcrowd, g_strlen(dcrowd)) 122 ss_add(w, 1, "url:303" as *u8, "https://crowd.example.com/3" as *u8, 27) 123 ss_add(w, 1, "doc:304" as *u8, dcrowd, g_strlen(dcrowd)) 124 ss_add(w, 1, "url:304" as *u8, "https://crowd.example.com/4" as *u8, 27) 125 ss_add(w, 1, "doc:305" as *u8, dcrowd, g_strlen(dcrowd)) 126 ss_add(w, 1, "url:305" as *u8, "https://crowd.example.com/5" as *u8, 27) 127 ss_add(w, 1, "doc:306" as *u8, dother, g_strlen(dother)) 128 ss_add(w, 1, "url:306" as *u8, "https://other.example.com/6" as *u8, 27) 129 ss_add(w, 1, "doc:307" as *u8, dother, g_strlen(dother)) 130 ss_add(w, 1, "url:307" as *u8, "https://other.example.com/7" as *u8, 27) 131 // authority fusion fixture (T28/T29): two docs identical content (equal BM25), different urls; doc 601's url 132 // carries a high pr: prior, doc 600's has none. webdiv=0 -> tie broken by candidate order (600 first); 133 // webdiv=1 -> the PageRank prior lifts 601 over 600 (distinguishing: pre-fuse, webdiv=1 also gave 600). 134 let dae: *u8 = "authorityterm equalcontent alpha" as *u8 135 let u600: *u8 = "https://plain.example/b" as *u8 136 let u601: *u8 = "https://authority.example/a" as *u8 137 ss_add(w, 1, "doc:600" as *u8, dae, g_strlen(dae)) 138 ss_add(w, 1, "url:600" as *u8, u600, g_strlen(u600)) 139 ss_add(w, 1, "doc:601" as *u8, dae, g_strlen(dae)) 140 ss_add(w, 1, "url:601" as *u8, u601, g_strlen(u601)) 141 let prk: *u8 = sys_mmap(48) 142 dss_prkey(dss_urlcid(u601, g_strlen(u601)), prk) 143 let prv: *i64 = sys_mmap(16) as *i64 144 prv[0] = 500000000 145 ss_add(w, 1, prk, prv as *u8, 8) 146 // url-dedup fixture (T30/T31): docs 700+701 = two crawl SNAPSHOTS of the SAME url (identical content -> 147 // equal BM25; distinct content cids in prod, distinct doc keys here). webdiv=1 must serve ONE. 148 let ddup: *u8 = "zqduppage snapshot content for url dedup" as *u8 149 let udup: *u8 = "https://dup.example.com/page" as *u8 150 ss_add(w, 1, "doc:700" as *u8, ddup, g_strlen(ddup)) 151 ss_add(w, 1, "url:700" as *u8, udup, g_strlen(udup)) 152 ss_add(w, 1, "doc:701" as *u8, ddup, g_strlen(ddup)) 153 ss_add(w, 1, "url:701" as *u8, udup, g_strlen(udup)) 154 // proximity fixture (T-prox, R1b): 801 (scattered) + 800 (clustered) have the SAME length + SAME tf 155 // -> IDENTICAL BM25; ONLY the proximity boost distinguishes them. 801 is indexed FIRST (so a naive 156 // tie would pick 801); the CLUSTERED 800 must win via proximity. proxterma/proxtermb/zfil* are unique. 157 let dpxs: *u8 = "proxterma zfila zfilb zfilc zfild zfile zfilf proxtermb" as *u8 158 let dpxc: *u8 = "zfilg zfilh zfili zfilj proxterma proxtermb zfilk zfill" as *u8 159 ss_add(w, 1, "doc:801" as *u8, dpxs, g_strlen(dpxs)) 160 ss_add(w, 1, "doc:800" as *u8, dpxc, g_strlen(dpxc)) 161 // title-field fixture (T-title, R1c): 901 (body) + 900 (title) have SAME length + SAME tf -> IDENTICAL 162 // BM25; only the title-field boost distinguishes. 901 indexed FIRST; the TITLE-match 900 must win. 163 let dttl: *u8 = "titletok aaa1 aaa2 aaa3 aaa4 aaa5 aaa6 aaa7" as *u8 164 let dbod: *u8 = "bbb1 bbb2 bbb3 bbb4 bbb5 bbb6 titletok bbb7" as *u8 165 ss_add(w, 1, "doc:901" as *u8, dbod, g_strlen(dbod)) 166 ss_add(w, 1, "doc:900" as *u8, dttl, g_strlen(dttl)) 167 // multilingual fixture (2026-07-23, T33-T36): Russian (Cyrillic word tokens, case-folded), 168 // Japanese (Han bigrams), Korean (Hangul bigrams) -- end-to-end through the FULL dss path 169 // (query tokenize -> postings -> BM25 tf-scan re-tokenizing the doc). Unique terms, no fixture overlap. 170 let dru: *u8 = "\xD1\x81\xD1\x83\xD0\xB4 \xD0\xBF\xD0\xBE \xD0\xBD\xD0\xB0\xD1\x81\xD0\xBB\xD0\xB5\xD0\xB4\xD1\x81\xD1\x82\xD0\xB2\xD1\x83 \xD0\xB2 \xD0\xBC\xD0\xBE\xD1\x81\xD0\xBA\xD0\xB2\xD0\xB5 \xD1\x80\xD0\xB0\xD1\x81\xD1\x81\xD0\xBC\xD0\xBE\xD1\x82\xD1\x80\xD0\xB5\xD0\xBB \xD0\xB4\xD0\xB5\xD0\xBB\xD0\xBE" as *u8 171 let dja: *u8 = "\xE6\x9D\xB1\xE4\xBA\xAC\xE5\xA4\xA7\xE5\xAD\xA6 \xE7\xA0\x94\xE7\xA9\xB6" as *u8 172 let dko: *u8 = "\xED\x95\x9C\xEA\xB5\xAD \xEA\xB2\x80\xEC\x83\x89 \xEC\x97\x94\xEC\xA7\x84 \xEA\xB0\x9C\xEB\xB0\x9C" as *u8 173 ss_add(w, 1, "doc:950" as *u8, dru, g_strlen(dru)) 174 ss_add(w, 1, "doc:951" as *u8, dja, g_strlen(dja)) 175 ss_add(w, 1, "doc:952" as *u8, dko, g_strlen(dko)) 176 // R2b url-scope fixture (T37-T40, 2026-08-04): four docs share the term "subgadget"; only 960 lives 177 // under /r/gadgetlab on reddit. 963 = the SEGMENT-ANCHOR decoy (/r/gadgetlabmemes must NOT satisfy 178 // r/gadgetlab). 962 = the off-reddit control for inurl: (its url carries no "comments"). 179 let dsr1: *u8 = "subgadget review thread alpha" as *u8 180 let dsr2: *u8 = "subgadget review thread beta" as *u8 181 let dsr3: *u8 = "subgadget review blogpost" as *u8 182 let dsr4: *u8 = "subgadget meme collection" as *u8 183 ss_add(w, 1, "doc:960" as *u8, dsr1, g_strlen(dsr1)) 184 let u960: *u8 = "https://old.reddit.com/r/gadgetlab/comments/ab1/thread/" as *u8 185 ss_add(w, 1, "url:960" as *u8, u960, g_strlen(u960)) 186 ss_add(w, 1, "doc:961" as *u8, dsr2, g_strlen(dsr2)) 187 let u961: *u8 = "https://old.reddit.com/r/cooking/comments/cd2/thread/" as *u8 188 ss_add(w, 1, "url:961" as *u8, u961, g_strlen(u961)) 189 ss_add(w, 1, "doc:962" as *u8, dsr3, g_strlen(dsr3)) 190 let u962: *u8 = "https://techblog.example.com/subgadget-review" as *u8 191 ss_add(w, 1, "url:962" as *u8, u962, g_strlen(u962)) 192 ss_add(w, 1, "doc:963" as *u8, dsr4, g_strlen(dsr4)) 193 let u963: *u8 = "https://old.reddit.com/r/gadgetlabmemes/xyz" as *u8 194 ss_add(w, 1, "url:963" as *u8, u963, g_strlen(u963)) 195 ss_commit(prefix, w, 1) 196 g_puts("wrote 40 docs (+2 pol, +7 host-crowding, +2 authority +1 pr:, +2 url-dup, +4 url-scope) -> dp-ssgatetest-pub-\n") 197 198 let pass: *i64 = sys_mmap(16) as *i64; pass[0] = 0 199 let total: *i64 = sys_mmap(16) as *i64; total[0] = 0 200 let cids: *i64 = sys_mmap(64 * 8) as *i64 201 let scores: *i64 = sys_mmap(64 * 8) as *i64 202 let dom: *u8 = "ssgatetest" as *u8 203 204 // T1: "probate" -> exactly doc 101 (only estate mentions probate) 205 let q1: *u8 = "probate" as *u8 206 let n1: i64 = dss_search(dom, q1, g_strlen(q1), cids, scores, 10) 207 g_check("T1 probate->101" as *u8, n1, cids, 1, 101, pass, total) 208 209 // T2: "divorce custody" -> doc 102 top (matches BOTH terms) 210 let q2: *u8 = "divorce custody" as *u8 211 let n2: i64 = dss_search(dom, q2, g_strlen(q2), cids, scores, 10) 212 g_check("T2 divorce+custody->102" as *u8, n2, cids, 1, 102, pass, total) 213 214 // T3: "law contracts" -> doc 103 TOP (matches law+contracts=2) above 102 (law=1). 2 candidates. 215 let q3: *u8 = "law contracts" as *u8 216 let n3: i64 = dss_search(dom, q3, g_strlen(q3), cids, scores, 10) 217 g_check("T3 law+contracts->103 top" as *u8, n3, cids, 2, 103, pass, total) 218 219 // T4: "law" -> both 102 (Family Law) and 103 (Business Law); 101 has no 'law' 220 let q4: *u8 = "law" as *u8 221 let n4: i64 = dss_search(dom, q4, g_strlen(q4), cids, scores, 10) 222 g_check("T4 law->2 docs" as *u8, n4, cids, 2, 0 - 1, pass, total) 223 224 // T5 NEG: absent term -> 0 results (no false hit) 225 let q5: *u8 = "zzznotpresentanywhere" as *u8 226 let n5: i64 = dss_search(dom, q5, g_strlen(q5), cids, scores, 10) 227 g_check("T5 NEG absent-term->0" as *u8, n5, cids, 0, 0 - 1, pass, total) 228 229 // T6 NEG (isolation): a domain with NO shard -> 0, not -2, not a crash 230 let q6: *u8 = "probate" as *u8 231 let n6: i64 = dss_search("nosuchdomain" as *u8, q6, g_strlen(q6), cids, scores, 10) 232 g_check("T6 NEG absent-shard->0" as *u8, n6, cids, 0, 0 - 1, pass, total) 233 234 // T7 NEG (owner consent): doc 104 exists in the pub shard but its pol row LACKS the search bit 235 // (pol=2 = AI_BLOG only) -> query-time consent filter EXCLUDES it (the retired tsv emitter's 236 // emission-time enforcement, now live per hit) 237 let q7: *u8 = "adoption" as *u8 238 let n7: i64 = dss_search(dom, q7, g_strlen(q7), cids, scores, 10) 239 g_check("T7 NEG consent opt-out excluded" as *u8, n7, cids, 0, 0 - 1, pass, total) 240 241 // T8 (owner consent): doc 105's pol row HAS the search bit (pol=1) -> included 242 let q8: *u8 = "annexation" as *u8 243 let n8: i64 = dss_search(dom, q8, g_strlen(q8), cids, scores, 10) 244 g_check("T8 consent opt-in included" as *u8, n8, cids, 1, 105, pass, total) 245 246 // T9 (IDF ranking): query "idfcommon idfrare" -- 5 candidates; the RARE-term doc (106) must be TOP. 247 // idf(idfrare)=log2(N/1) >> idf(idfcommon)=log2(N/4); tf equal (2 each for 106/107). The retired 248 // distinct+tf scorer tied them and candidate order picked 107 -- this row is the ranking-rung proof. 249 let q9: *u8 = "idfcommon idfrare" as *u8 250 let n9: i64 = dss_search(dom, q9, g_strlen(q9), cids, scores, 10) 251 g_check("T9 IDF: rare-term doc outranks common-term doc" as *u8, n9, cids, 5, 106, pass, total) 252 253 // T10 (pagination): 15 pgseg docs -- offset windows must return 10/5/0 with total=15 and disjoint pages 254 let qp: *u8 = "pgseg" as *u8 255 let tot: *i64 = sys_mmap(16) as *i64 256 let np0: i64 = dss_search_off(dom, qp, g_strlen(qp), cids, scores, 10, 0, tot) 257 let p0top: i64 = cids[0] 258 let np1: i64 = dss_search_off(dom, qp, g_strlen(qp), cids, scores, 10, 10, tot) 259 let p1top: i64 = cids[0] 260 let np2: i64 = dss_search_off(dom, qp, g_strlen(qp), cids, scores, 10, 20, tot) 261 var t10: i64 = 0 262 if np0 == 10 { if np1 == 5 { if np2 == 0 { if tot[0] == 15 { if p0top != p1top { t10 = 1 } } } } } 263 g_puts("T10 pagination offsets 10/5/0 total=15 disjoint") 264 total[0] = total[0] + 1 265 if t10 == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 266 267 // T11 (+term AND): "law +contracts" keeps ONLY the doc that carries contracts (plain OR returned 2) 268 let q11: *u8 = "law +contracts" as *u8 269 let n11: i64 = dss_search(dom, q11, g_strlen(q11), cids, scores, 10) 270 g_check("T11 +term AND filter" as *u8, n11, cids, 1, 103, pass, total) 271 272 // T12 did-you-mean: an unknown term corrects to the closest dictionary term (probete -> probate) 273 let fix: *u8 = sys_mmap(256) 274 let fl: i64 = dss_correct(dom, "probete" as *u8, 7, fix, 255) 275 var t12: i64 = 0 276 if fl == 7 { 277 let want: *u8 = "probate" as *u8 278 var eq12: i64 = 1 279 var z12: i64 = 0 280 while z12 < 7 { if fix[z12] != want[z12] { eq12 = 0; z12 = 7 } else { z12 = z12 + 1 } } 281 t12 = eq12 282 } 283 g_puts("T12 did-you-mean probete->probate") 284 total[0] = total[0] + 1 285 if t12 == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 286 287 // T13 suggest: the dictionary completes "prob" (top completion = probate) 288 let sg: *u8 = sys_mmap(8 * 64) 289 let n13: i64 = dss_suggest(dom, "prob" as *u8, 4, sg, 8) 290 var t13: i64 = 0 291 if n13 >= 1 { 292 let w13: *u8 = "probate" as *u8 293 var eq13: i64 = 1 294 var z13: i64 = 0 295 while z13 < 8 { if sg[z13] != w13[z13] { eq13 = 0; z13 = 8 } else { z13 = z13 + 1 } } 296 t13 = eq13 297 } 298 g_puts("T13 suggest prob->probate") 299 total[0] = total[0] + 1 300 if t13 == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 301 302 // T14 (BM25 length norm): equal tf, wildly different lengths -- the SHORT doc must outrank the LONG 303 // one (b=0 tied them and insertion order picked the long 126; b=0.75 must pick 127) 304 let q14: *u8 = "lennorm" as *u8 305 let n14: i64 = dss_search(dom, q14, g_strlen(q14), cids, scores, 10) 306 g_check("T14 length-norm: short doc outranks verbose doc" as *u8, n14, cids, 2, 127, pass, total) 307 308 // T15/T16 PHRASE through dss: d1 carries "... living trusts ..." adjacent -- the quoted phrase 309 // matches; the REVERSED phrase must not (order-sensitive adjacency via the NXQ1 sidecar) 310 let q15: *u8 = "\"living trusts\"" as *u8 311 let n15: i64 = dss_search(dom, q15, g_strlen(q15), cids, scores, 10) 312 g_check("T15 phrase [living trusts] -> doc 101" as *u8, n15, cids, 1, 101, pass, total) 313 let q16: *u8 = "\"trusts living\"" as *u8 314 let n16: i64 = dss_search(dom, q16, g_strlen(q16), cids, scores, 10) 315 g_check("T16 NEG phrase [trusts living] -> 0" as *u8, n16, cids, 0, 0 - 1, pass, total) 316 317 // T17 (-term NOT): "law -contracts" -- OR gave both law docs; the exclusion drops the contracts one 318 let q17: *u8 = "law -contracts" as *u8 319 let n17: i64 = dss_search(dom, q17, g_strlen(q17), cids, scores, 10) 320 g_check("T17 -term exclusion (law -contracts -> 102 only)" as *u8, n17, cids, 1, 102, pass, total) 321 322 // T18b (NO ZERO-SCORE NOISE, operator-reported "julia kyoka" bug): doc 128 has "ranking" (matched via 323 // stem) but NOT "zznomatch". A 2-term query "ranking zznomatch" must return ONLY positively-scored docs; 324 // no doc may appear at score 0. Assert every returned score is > 0. 325 let qzs: *u8 = "ranking zznomatchword" as *u8 326 let nzs: i64 = dss_search(dom, qzs, g_strlen(qzs), cids, scores, 20) 327 var allpos: i64 = 1 328 var zi: i64 = 0 329 while zi < nzs { if scores[zi] <= 0 { allpos = 0 } zi = zi + 1 } 330 g_puts("T18b no zero-score results (n="); g_num(nzs); g_puts(")") 331 total[0] = total[0] + 1 332 if allpos == 1 { if nzs >= 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL(none)\n") } } else { g_puts(" FAIL(zero-score shown)\n") } 333 334 // T18 (STEMMING recall): the doc says "indexing"/"crawlers"/"ranking"; queries for the STEM-shared 335 // forms "index"/"crawler"/"rank" must recall it via query-time dictionary stem-expansion (no index change) 336 let q18a: *u8 = "index" as *u8 337 let n18a: i64 = dss_search(dom, q18a, g_strlen(q18a), cids, scores, 10) 338 var t18: i64 = 0 339 if n18a >= 1 { 340 // 128 must be among the results (its only 'index'-family token is 'indexing') 341 var f18: i64 = 0 342 var z18: i64 = 0 343 while z18 < n18a { if cids[z18] == 128 { f18 = 1 } z18 = z18 + 1 } 344 // and a query for "crawler" must recall 128 (which only says "crawlers") 345 let n18b: i64 = dss_search(dom, "crawler" as *u8, 7, cids, scores, 10) 346 var f18b: i64 = 0 347 var z18b: i64 = 0 348 while z18b < n18b { if cids[z18b] == 128 { f18b = 1 } z18b = z18b + 1 } 349 if f18 == 1 { if f18b == 1 { t18 = 1 } } 350 } 351 g_puts("T18 stemming recall (index->indexing, crawler->crawlers)") 352 total[0] = total[0] + 1 353 if t18 == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 354 355 // T19-T21 (site: FIELD FILTER, the faceted rung): "law" matches 102 (law.example.com) + 103 (no url). 356 // site:example.com keeps only 102 (dot-suffix host match; url-less 103 dropped as not site-attributable) 357 let q19: *u8 = "law site:example.com" as *u8 358 let n19: i64 = dss_search(dom, q19, g_strlen(q19), cids, scores, 10) 359 g_check("T19 site: filter (law site:example.com -> 102 only)" as *u8, n19, cids, 1, 102, pass, total) 360 // cross-host NEG: no "law" doc lives on wikipedia.org 361 let q20: *u8 = "law site:wikipedia.org" as *u8 362 let n20: i64 = dss_search(dom, q20, g_strlen(q20), cids, scores, 10) 363 g_check("T20 NEG site: cross-host (law site:wikipedia.org -> 0)" as *u8, n20, cids, 0, 0 - 1, pass, total) 364 // suffix-boundary NEG: kipedia.org must NOT match en.wikipedia.org (the '.' boundary rule) 365 let q21: *u8 = "trusts site:kipedia.org" as *u8 366 let n21: i64 = dss_search(dom, q21, g_strlen(q21), cids, scores, 10) 367 var t21b: i64 = 0 368 if n21 == 0 { 369 let q21b: *u8 = "trusts site:wikipedia.org" as *u8 370 let n21b: i64 = dss_search(dom, q21b, g_strlen(q21b), cids, scores, 10) 371 if n21b == 1 { if cids[0] == 101 { t21b = 1 } } 372 } 373 g_puts("T21 suffix boundary (kipedia.org->0, wikipedia.org->101)") 374 total[0] = total[0] + 1 375 if t21b == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 376 377 // T22 (host-diversity CONTROL, webdiv=0): no cap -> the 5 tf=2 crowd-host docs fill the top 5, so the 378 // 4th result (cids[3]) is a crowd-host doc (304). Non-web scopes (site/trusted) always use this path. 379 let qd: *u8 = "diversitytest" as *u8 380 let td: *i64 = sys_mmap(16) as *i64 381 let nd0: i64 = dss_search_off_div(dom, qd, g_strlen(qd), cids, scores, 10, 0, td, 0) 382 var t22: i64 = 0 383 if nd0 == 7 { if cids[3] == 304 { t22 = 1 } } 384 g_puts("T22 host-cap CONTROL (webdiv=0: crowd fills top, cids[3]=304)") 385 total[0] = total[0] + 1 386 if t22 == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL cids[3]="); g_num(cids[3]); g_puts(" n="); g_num(nd0); g_puts("\n") } 387 388 // T23 (host-diversity CAP, webdiv=1): crowd host caps at DSS_HOSTCAP=3, so an OTHER-host doc (306) is 389 // promoted into slot 3 -- and ALL 7 still return (over-cap crowd docs overflow via phase B, never 390 // deleted). Fails on the old code by construction (no cap -> cids[3]=304). 391 let nd1: i64 = dss_search_off_div(dom, qd, g_strlen(qd), cids, scores, 10, 0, td, 1) 392 var t23: i64 = 0 393 if nd1 == 7 { if cids[3] == 306 { t23 = 1 } } 394 g_puts("T23 host-cap FIRES (webdiv=1: cids[3]=306, all 7 still returned)") 395 total[0] = total[0] + 1 396 if t23 == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL cids[3]="); g_num(cids[3]); g_puts(" n="); g_num(nd1); g_puts("\n") } 397 398 // T24 (dss_is_web predicate): only the exact "web" shard triggers the cap; site domains + "trusted" + 399 // a "web"-prefixed decoy do NOT (so a customer site named web*.com is never wrongly capped). 400 var t24: i64 = 0 401 if dss_is_web("web" as *u8) == 1 { if dss_is_web("trusted" as *u8) == 0 { if dss_is_web("andelinwest.com" as *u8) == 0 { if dss_is_web("weblog.com" as *u8) == 0 { t24 = 1 } } } } 402 g_puts("T24 dss_is_web exact-match (web=1; trusted/site/web*=0)") 403 total[0] = total[0] + 1 404 if t24 == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 405 406 // T25 (dss_hosthash): same host -> same fingerprint; different host -> different; no url host -> 0. 407 let hscr2: *u8 = sys_mmap(256) 408 let hh_a: i64 = dss_hosthash("https://crowd.example.com/x" as *u8, 27, hscr2) 409 let hh_b: i64 = dss_hosthash("https://crowd.example.com/y" as *u8, 27, hscr2) 410 let hh_c: i64 = dss_hosthash("https://other.example.com/z" as *u8, 27, hscr2) 411 let hh_d: i64 = dss_hosthash("relative/path/nohost" as *u8, 20, hscr2) 412 var t25: i64 = 0 413 if hh_a == hh_b { if hh_a != hh_c { if hh_a != 0 { if hh_d == 0 { t25 = 1 } } } } 414 g_puts("T25 dss_hosthash (same-host eq, diff-host neq, no-host=0)") 415 total[0] = total[0] + 1 416 if t25 == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 417 418 // T28 (P1 authority CONTROL, webdiv=0): equal-BM25 tie -> candidate order -> doc 600 first (no pr fusion) 419 let qa: *u8 = "authorityterm" as *u8 420 let ta: *i64 = sys_mmap(16) as *i64 421 let na0: i64 = dss_search_off_div(dom, qa, g_strlen(qa), cids, scores, 10, 0, ta, 0) 422 g_check("T28 authority CONTROL (webdiv=0: tie -> 600)" as *u8, na0, cids, 2, 600, pass, total) 423 // T29 (P1 authority FUSION, webdiv=1): doc 601's PageRank prior lifts it above the equal-BM25 doc 600 424 let na1: i64 = dss_search_off_div(dom, qa, g_strlen(qa), cids, scores, 10, 0, ta, 1) 425 g_check("T29 authority FUSION (webdiv=1: pr: prior -> 601 first)" as *u8, na1, cids, 2, 601, pass, total) 426 427 // T30 URL-DEDUP CONTROL (webdiv=0): both snapshots of one url serve; site/trusted stay byte-identical 428 let qd: *u8 = "zqduppage" as *u8 429 let nd0: i64 = dss_search_off_div(dom, qd, g_strlen(qd), cids, scores, 10, 0, ta, 0) 430 g_check("T30 url-dedup CONTROL (webdiv=0: both snapshots serve)" as *u8, nd0, cids, 2, 700, pass, total) 431 // T31 URL-DEDUP (webdiv=1): ONE result per url (tie -> first candidate) and totals = DISTINCT pages 432 let nd1: i64 = dss_search_off_div(dom, qd, g_strlen(qd), cids, scores, 10, 0, ta, 1) 433 var t31: i64 = 0 434 if nd1 == 1 { if cids[0] == 700 { if ta[0] == 1 { t31 = 1 } } } 435 g_puts("T31 url-dedup (webdiv=1: 1 result, cid 700, total=1)") 436 total[0] = total[0] + 1 437 if t31 == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 438 439 // T-prox (R1b PROXIMITY): 800 (clustered) and 801 (scattered) carry IDENTICAL BM25 (same len+tf); 440 // the proximity boost must rank the CLUSTERED doc 800 first even though 801 was indexed first. This 441 // row FAILS by construction without the boost (tie -> indexed-first 801) and PASSES with it. 442 let qpx: *u8 = "proxterma proxtermb" as *u8 443 let npx: i64 = dss_search(dom, qpx, g_strlen(qpx), cids, scores, 10) 444 g_check("T-prox clustered 800 outranks scattered 801" as *u8, npx, cids, 2, 800, pass, total) 445 446 // T-title (R1c): 900 (query term in the TITLE) vs 901 (in the BODY), IDENTICAL BM25; the title-field 447 // boost must rank the TITLE-match doc 900 first even though 901 was indexed first. 448 let qtt: *u8 = "titletok" as *u8 449 let ntt: i64 = dss_search(dom, qtt, g_strlen(qtt), cids, scores, 10) 450 g_check("T-title: title-field match 900 outranks body match 901" as *u8, ntt, cids, 2, 900, pass, total) 451 452 // T33 RUSSIAN end-to-end: Cyrillic query term -> doc 950 (word tokens through the whole dss path) 453 let q33: *u8 = "\xD0\xBD\xD0\xB0\xD1\x81\xD0\xBB\xD0\xB5\xD0\xB4\xD1\x81\xD1\x82\xD0\xB2\xD1\x83" as *u8 454 let n33: i64 = dss_search(dom, q33, g_strlen(q33), cids, scores, 10) 455 g_check("T33 russian (nasledstvu)->950" as *u8, n33, cids, 1, 950, pass, total) 456 // T34 JAPANESE end-to-end: 4-char Han query -> overlapping bigrams -> doc 951 457 let q34: *u8 = "\xE6\x9D\xB1\xE4\xBA\xAC\xE5\xA4\xA7\xE5\xAD\xA6" as *u8 458 let n34: i64 = dss_search(dom, q34, g_strlen(q34), cids, scores, 10) 459 g_check("T34 japanese (toukyoudaigaku)->951" as *u8, n34, cids, 1, 951, pass, total) 460 // T35 KOREAN end-to-end: Hangul bigram query -> doc 952 461 let q35: *u8 = "\xEA\xB2\x80\xEC\x83\x89" as *u8 462 let n35: i64 = dss_search(dom, q35, g_strlen(q35), cids, scores, 10) 463 g_check("T35 korean (geomsaek)->952" as *u8, n35, cids, 1, 952, pass, total) 464 // T36 CYRILLIC CASE-FOLD: uppercase query MOSKVE matches the lowercase doc 465 let q36: *u8 = "\xD0\x9C\xD0\x9E\xD0\xA1\xD0\x9A\xD0\x92\xD0\x95" as *u8 466 let n36: i64 = dss_search(dom, q36, g_strlen(q36), cids, scores, 10) 467 g_check("T36 cyrillic case-fold (MOSKVE)->950" as *u8, n36, cids, 1, 950, pass, total) 468 469 // T37 SUBREDDIT idiom (R2b, 2026-08-04): "r/GadgetLab subgadget" implies site:reddit.com + a case- 470 // folded, segment-anchored /r/gadgetlab path -> ONLY 960. 961 = other sub, 962 = off-reddit, 963 = 471 // /r/gadgetlabmemes (the anchor decoy). The pre-rewrite engine returned all four ("r" died at the 472 // tokenizer's 2-char floor) -- this tooth fails without the fix BY CONSTRUCTION. 473 let q37: *u8 = "r/GadgetLab subgadget" as *u8 474 let n37: i64 = dss_search(dom, q37, g_strlen(q37), cids, scores, 10) 475 g_check("T37 r/<sub> scopes to the subreddit (960 only)" as *u8, n37, cids, 1, 960, pass, total) 476 // T38 inurl: general URL filter, ANY site: docs whose url carries "comments" = 960+961 exactly 477 let q38: *u8 = "inurl:comments subgadget" as *u8 478 let n38: i64 = dss_search(dom, q38, g_strlen(q38), cids, scores, 10) 479 g_check("T38 inurl:comments -> the two thread docs" as *u8, n38, cids, 2, 0 - 1, pass, total) 480 // T39 CONTROL: the bare term returns ALL FOUR docs -- queries without a url-scope clause are 481 // byte-identical to the pre-R2b engine (the ruler-safety claim, positively controlled) 482 let q39: *u8 = "subgadget" as *u8 483 let n39: i64 = dss_search(dom, q39, g_strlen(q39), cids, scores, 10) 484 g_check("T39 CONTROL bare term -> all 4 docs" as *u8, n39, cids, 4, 0 - 1, pass, total) 485 // T40 NEG: an unknown subreddit -> honest 0, never a silent fallback to unscoped results 486 let q40: *u8 = "r/nosuchsub subgadget" as *u8 487 let n40: i64 = dss_search(dom, q40, g_strlen(q40), cids, scores, 10) 488 g_check("T40 NEG r/nosuchsub -> 0" as *u8, n40, cids, 0, 0 - 1, pass, total) 489 490 // T41 (R2d stuffing penalty): KATs on the factored decision, pinned to the MEASURED live docs 491 // (nx_doc_lexstat 2026-08-04). bign=150000, common dcnt=40000 (blood/pressure class), 492 // rare dcnt=120 (entity name). Spam blogspot tf34/825 -> 512; real paper tf14/1226 -> 1024; 493 // a RARE name at profile density tf40/800 -> 1024 (the julia exemption); tiny doc + small 494 // corpus -> inert 1024 (why every fixture tooth above stays byte-identical). 495 var t41: i64 = 1 496 if dss_stuff_factor(34, 825, 40000, 150000) != 512 { t41 = 0 } 497 if dss_stuff_factor(14, 1226, 40000, 150000) != 1024 { t41 = 0 } 498 if dss_stuff_factor(40, 800, 120, 150000) != 1024 { t41 = 0 } 499 if dss_stuff_factor(30, 40, 40000, 150000) != 1024 { t41 = 0 } 500 if dss_stuff_factor(34, 825, 40000, 500) != 1024 { t41 = 0 } 501 total[0] = total[0] + 1 502 g_puts("T41 stuffing factor: spam 512 / real+rare+tiny+small-corpus 1024") 503 if t41 == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 504 505 // T42 (R2d brand-label exemption): a dense term that IS a host label of the doc's url is the 506 // term's owner, not a stuffer -- and a substring without a boundary earns NOTHING (the fix for 507 // the 368->297 navigational regression; the measured spam domain must stay penalized). 508 let t42scr: *u8 = sys_mmap(256) 509 var t42: i64 = 1 510 let u42a: *u8 = "https://github.com/features" as *u8 511 let u42b: *u8 = "https://highbloodpressure67.blogspot.com/" as *u8 512 let u42c: *u8 = "https://www.rust-lang.org/learn" as *u8 513 if dss_host_label_match(u42a, g_strlen(u42a), "github" as *u8, t42scr) != 1 { t42 = 0 } 514 if dss_host_label_match(u42b, g_strlen(u42b), "blood" as *u8, t42scr) != 0 { t42 = 0 } 515 if dss_host_label_match(u42b, g_strlen(u42b), "pressure" as *u8, t42scr) != 0 { t42 = 0 } 516 if dss_host_label_match(u42c, g_strlen(u42c), "rust" as *u8, t42scr) != 1 { t42 = 0 } 517 if dss_host_label_match(u42a, g_strlen(u42a), "hub" as *u8, t42scr) != 0 { t42 = 0 } 518 total[0] = total[0] + 1 519 g_puts("T42 brand-label: github/rust exempt, blood/pressure/hub substrings not") 520 if t42 == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 521 522 g_puts("=== dss gate: "); g_num(pass[0]); g_puts("/"); g_num(total[0]); g_puts(" ") 523 524 // EVIDENCE (2026-07-30): this gate is the SEARCH lane's only NAS-runnable witness -- 36 teeth over 525 // BM25 ranking, proximity, title-field boost and Cyrillic/CJK case-folding -- and it wrote its 526 // verdict to STDOUT ONLY, so nx_gatereg_derive could not see the lane and the maturity rollup could 527 // not grade it. Same defect that hid lab-science and the browser renderer. 528 // ★It is SAFE to publish: every tooth runs against SYNTHETIC fixture docs (800/801/900/901/950-952), 529 // never sampled production content, so no dp-*-secret / dp-*-prv material can reach this log. 530 // ★Plain verdict=GREEN|RED -- gv_is_pass accepts GREEN|PASS|VALID only, and this ecosystem has 531 // already invented four different pass-words. Do not add a fifth. 532 let lfd: i64 = sys_openat_append("knowledge/status/search_seg_gate.log\x00" as *u8, 420) 533 if lfd >= 0 { 534 let lb: *u8 = sys_mmap(256) 535 var lo: i64 = 0 536 lo = dsg_cat(lb, lo, "DSS-GATE rows=" as *u8) 537 lo = dsg_catn(lb, lo, total[0]) 538 lo = dsg_cat(lb, lo, " passed=" as *u8) 539 lo = dsg_catn(lb, lo, pass[0]) 540 if pass[0] == total[0] { lo = dsg_cat(lb, lo, " verdict=GREEN\n" as *u8) } else { lo = dsg_cat(lb, lo, " verdict=RED\n" as *u8) } 541 sys_write(lfd, lb, lo) 542 sys_close(lfd) 543 } 544 545 if pass[0] == total[0] { g_puts("GREEN\n"); return 0 } 546 g_puts("RED\n"); return 1 547}