code wiki / _hdl_build / nx_search_snip_base_20260912.nx

nx_search_snip_base_20260912.nx source

↩ module page · 485 lines · 36914 B

1// nx_docportal_search_serve_gate.nx -- GATE for R2 (dss_serve). Writes a test PUBLIC shard, then feeds crafted 2// GET /search requests to dss_serve and asserts the rendered branded page: 200 + Content-Length, result count, 3// the hit's text present, empty-query prompt, no-match=0, and XSS-escaping of the echoed query (defensive at the 4// boundary). All over the REAL sovereign seg_store path, no tsv. license_tier: ORIGINAL 5import "nx_docportal_search_serve.nx" 6import "nx_g_puts_lib.nx" 7// MIGRATED TO THE SHARED VERDICT MACHINERY 2026-08-15, same reason as nx_editdist_gate: this gate 8// hand-rolled pass/total and printed `=== dss_serve gate: 49/49 GREEN`, which nx_swcompare_evidence 9// cannot parse -- once wired it reported [GREEN] pass=0/0, so the verdict travelled on the exit code 10// while the EVIDENCE did not. ★A GATE WHOSE COUNT THE ROLLUP CANNOT READ IS HALF-WIRED, and a partial 11// regression in 49 teeth would have surfaced only as a binary flip. gv_ctr/gv_check make 12// declared-equals-executed BY CONSTRUCTION -- with 49 teeth a hand-maintained denominator is exactly 13// the thing that silently drifts when a tooth stops running. 14import "nx_gate_verdict.nx" 15 16func g_strlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 17func g_num(v: i64) -> i64 { 18 let bb: *u8 = sys_mmap(28); var m: i64 = v 19 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 20 let t: *u8 = sys_mmap(28); var k: i64 = 0 21 if m == 0 { t[0] = 48 as u8; k = 1 } 22 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 23 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 24 sys_write(1, bb, k); return 0 25} 26// does hay[0..hn) contain the null-terminated needle? 27func g_contains(hay: *u8, hn: i64, needle: *u8) -> i64 { 28 let nl: i64 = g_strlen(needle) 29 if nl == 0 { return 1 } 30 var i: i64 = 0 31 while i + nl <= hn { 32 var m: i64 = 1 33 var j: i64 = 0 34 while j < nl { if hay[i + j] != needle[j] { m = 0 } j = j + 1 } 35 if m == 1 { return 1 } 36 i = i + 1 37 } 38 return 0 39} 40func g_streq(a: *u8, b: *u8) -> i64 { 41 var i: i64 = 0 42 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } 43 if b[i] != (0 as u8) { return 0 } 44 return 1 45} 46// Thin delegate so all 49 call sites read unchanged while the COUNTING is the shared one. 47func g_check(name: *u8, cond: i64, ctr: *i64) -> i64 { return gv_check(name, cond, ctr) } 48func g_check_unused(name: *u8, cond: i64, pass: *i64, total: *i64) -> i64 { 49 total[0] = total[0] + 1 50 g_puts(name) 51 if cond == 1 { pass[0] = pass[0] + 1; g_puts(" PASS\n") } else { g_puts(" FAIL\n") } 52 return 0 53} 54 55func main(argc: i64, argv: *i64) -> i64 { 56 g_puts("=== nx_docportal_search_serve gate (R2 /search serve, sovereign) ===\n") 57 let d1: *u8 = "Estate Planning wills living trusts probate inheritance executor" as *u8 58 // zzqservetest = an INVENTED shard-marker token: T16 proves scope=web switches shards by querying it 59 // (present here, absent from any real crawled web page BY CONSTRUCTION -- "probate" stopped working 60 // as the isolation probe the moment the real web corpus ingested wikipedia's estate-planning page) 61 let d2: *u8 = "Family Law divorce child custody support alimony parenting zzqservetest" as *u8 62 let d3: *u8 = "Criminal defense practice page felonies misdemeanors expungement" as *u8 63 let w: *i64 = ss_begin() 64 ss_add(w, 1, "doc:201" as *u8, d1, g_strlen(d1)) 65 ss_add(w, 1, "doc:202" as *u8, d2, g_strlen(d2)) 66 // 203 = an ingested SITE PAGE: carries a url:<cid> row -> its result must link to the PAGE, not /doc 67 ss_add(w, 1, "doc:203" as *u8, d3, g_strlen(d3)) 68 ss_add(w, 1, "url:203" as *u8, "/practice/criminal.html" as *u8, 23) 69 // facet fixture (T45): two docs sharing facterm on DIFFERENT hosts -> the SERP offers site: narrowing 70 let df1: *u8 = "facterm alpha article body" as *u8 71 let df2: *u8 = "facterm beta article body text" as *u8 72 ss_add(w, 1, "doc:211" as *u8, df1, g_strlen(df1)) 73 ss_add(w, 1, "url:211" as *u8, "https://en.wikipedia.org/wiki/Alpha" as *u8, 35) 74 ss_add(w, 1, "doc:212" as *u8, df2, g_strlen(df2)) 75 ss_add(w, 1, "url:212" as *u8, "https://docs.example.org/beta" as *u8, 29) 76 let snip_doc0: *u8 = "Wine Reference\nMain menu\nContents\nAccount\nMore navigation and tool links for visitors.\nRed wine carries a distinct aroma, and this sentence explains the color and flavor clearly." as *u8 77 ss_add(w, 1, "doc:981" as *u8, snip_doc0, g_strlen(snip_doc0)) 78 let snip_doc1: *u8 = "Snippet Boundary\nMain menu\nContents\nAccount\nMore navigation and tool links for visitors.\nEscapeterm describes \"quoted\" text with a backslash \\ and caf\xC3\xA9 in a complete useful sentence." as *u8 79 ss_add(w, 1, "doc:982" as *u8, snip_doc1, g_strlen(snip_doc1)) 80 let snip_doc2: *u8 = "Fallbackterm\nTiny body." as *u8 81 ss_add(w, 1, "doc:983" as *u8, snip_doc2, g_strlen(snip_doc2)) 82 let snip_doc3: *u8 = "Caps Reference\nMain menu\nContents\nAccount\nMore navigation and tool links for visitors.\nCapsterm describes bounded output with complete words describes bounded output with complete words describes bounded output with complete words describes bounded output with complete words describes bounded output with complete words describes bounded output with complete words ." as *u8 83 ss_add(w, 1, "doc:984" as *u8, snip_doc3, g_strlen(snip_doc3)) 84 let snip_doc4: *u8 = "Word Reference\nMain menu\nContents\nAccount\nMore navigation and tool links for visitors.\nDogmatic terms appear in this irrelevant sentence with enough prose to qualify.\nA dog needs daily exercise, and this sentence describes that specific animal accurately." as *u8 85 ss_add(w, 1, "doc:985" as *u8, snip_doc4, g_strlen(snip_doc4)) 86 // pager fixture: DSV_MAXR + 2 pgterm docs, DERIVED so it always exceeds the page cap by exactly 87 // enough to force a second page. 88 // ★★★★★★IT WAS THE LITERAL 22 AGAINST A "20/page cap", AND THE CAP MOVED TO 30 ON 2026-07-24 89 // (same day dsv_scope's default flipped -- both changes broke this gate together). The fixture then 90 // fit on ONE page, no pager rendered, and T35 reported a product bug that did not exist. 91 // A FIXTURE SIZED BY A LITERAL AGAINST A CONSTANT THAT CAN MOVE IS A TEST WITH AN EXPIRY DATE 92 // NOBODY WROTE DOWN. Derived from DSV_MAXR, it cannot go stale when the cap moves again. 93 let pg_docs: i64 = DSV_MAXR + 2 94 let dpg: *u8 = "pgterm pagination fixture entry for the serve pager" as *u8 95 let pgkey: *u8 = sys_mmap(24) 96 var pgi: i64 = 301 97 while pgi <= 300 + pg_docs { 98 var ko: i64 = 0 99 let kp: *u8 = "doc:" as *u8 100 while kp[ko] != (0 as u8) { pgkey[ko] = kp[ko]; ko = ko + 1 } 101 pgkey[ko] = (48 + (pgi / 100)) as u8 102 pgkey[ko + 1] = (48 + ((pgi / 10) % 10)) as u8 103 pgkey[ko + 2] = (48 + (pgi % 10)) as u8 104 pgkey[ko + 3] = 0 as u8 105 ss_add(w, 1, pgkey, dpg, g_strlen(dpg)) 106 pgi = pgi + 1 107 } 108 // ⚠FIXTURE MOVED OUT OF knowledge/store/ 2026-08-15 -- IT HAD ACCUMULATED AND CORRUPTED. 109 // This gate wrote its fixture into the SHARED production store path and never cleaned it, so every 110 // run appended another segment to the same place. MEASURED: buildroot/knowledge/store/ 111 // dp-ssservetest-pub-manifest.txt read `seg-1 / seg-1 / seg-2` -- a DUPLICATE segment row, which 112 // makes ss_open2 mount the same segment twice and the shadow logic treat the older index as 113 // superseded by a newer copy of ITSELF. Symptom: every structural tooth passed (headers, XSS 114 // escaping, mobile markers, zero-JS, title) while every CONTENT tooth failed (1-result, hit-text, 115 // highlight, /doc, pager, facets) -- the shape of a shard that mounts but yields nothing. 116 // ★★★★★★A GATE THAT WRITES ITS FIXTURE TO A FIXED SHARED PATH AND NEVER CLEANS IT EVENTUALLY 117 // TESTS GARBAGE, AND ITS FAILURES LOOK LIKE PRODUCT BUGS. This is the estate's own recorded rule 118 // (gate scratch belongs in /tmp/<gate>/, created by sys_mkdir at SETUP because a teardown does not 119 // run when a run crashes) and this gate predates it. Two stale copies of the old fixture remain -- 120 // knowledge/store/ and buildroot/knowledge/store/ -- and are now unreferenced; adjudicate them with 121 // nx_retire_path rather than deleting, since they are evidence of this defect. 122 // ⚠DIAGNOSIS OF THE DUPLICATE, stated as a lead not a conclusion: ss_commit re-derives its segid 123 // under the plane lock as max_segid+1, so a duplicate seg-1 implies ss_max_segid returned -1 while 124 // seg-1 existed. That is worth chasing in ss_max_segid itself -- a manifest reader that reports 125 // "no segments" on a readable non-empty store would corrupt ANY store, not just a fixture. 126 // The fixture must stay where dss_prefix points -- it builds knowledge/store/dp-<domain>-pub- 127 // from the domain the gate serves, so moving the WRITE to /tmp would simply never be read back 128 // (checked before building; that would have turned a corrupt fixture into an absent one). 129 // Instead: START CLEAN. Unlinking the manifest makes ss_max_segid report an empty store, so 130 // ss_commit writes seg-1 and publishes a manifest naming exactly this run's segment -- stale 131 // segment FILES are simply overwritten or orphaned, never mounted, because mounting is driven by 132 // the manifest. Setup-time, not teardown-time, deliberately: A TEARDOWN DOES NOT RUN WHEN A RUN 133 // CRASHES, and this fixture was corrupted by exactly the runs that did not finish tidily. 134 // ★DOMAIN RENAMED ssservetest -> ssgatesnipbase20260912 2026-08-15. The old name contained the substring 135 // `serve`, which is a PROTECTED TOKEN in nx_retire_path -- so every orphaned copy of this fixture 136 // was permanently unretirable (RETIRE-REFUSED code=4 token=serve, on all five files). The guard is 137 // RIGHT: it stops a live/serving artifact being moved out from under a running service and is 138 // deliberately wrong in the direction of doing nothing. THE FIX IS THE NAME, NOT THE GUARD -- 139 // relaxing a substring match on `serve` to tidy test files would put every genuinely serving 140 // artifact one rename away from being retirable. ★★★★★★WHEN A PROTECTION REFUSES SOMETHING 141 // HARMLESS, MOVE THE HARMLESS THING OUT OF ITS PATH; DO NOT WIDEN THE PROTECTION. 142 // (The five pre-existing orphans keep the old name and stay unretirable-by-design; they are inert 143 // and stand as the evidence for the accumulation defect that produced them.) 144 sys_unlinkat("knowledge/store/dp-ssgatesnipbase20260912-pub-manifest.txt\x00" as *u8) 145 ss_commit("knowledge/store/dp-ssgatesnipbase20260912-pub-" as *u8, w, 1) 146 147 let ctr: *i64 = gv_ctr() 148 gv_head("nx_docportal_search_serve -- /search + /doc + /api serve contract over a per-run fixture" as *u8) 149 let out: *u8 = sys_mmap(DSV_OUTCAP) 150 let dom: *u8 = "ssgatesnipbase20260912" as *u8 151 152 // T1: q=probate -> 200 + Content-Length + "1 result" + the estate text 153 // ⚠SCOPE MUST BE EXPLICIT (2026-08-15). dsv_scope's DEFAULT flipped site->web on 2026-07-24 154 // ("nishifamily.com/search IS a web search engine; the site corpus is an opt-in tab"), so every 155 // request in this gate that omits scope= has since been querying the REAL WEB SHARD instead of the 156 // fixture committed above. That is why the store is provably correct -- probed directly: bign=27, 157 // dcnt1=1 for probate, tf1=1 on cid 201 -- while every CONTENT tooth fails and every STRUCTURAL one 158 // passes. ★★★★★★A GATE THAT RELIES ON A DEFAULT TESTS WHATEVER THE DEFAULT LATER BECOMES; the 159 // product change was deliberate and correct, and it silently redirected this gate's subject. 160 let r1: *u8 = "GET /search?q=probate&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 161 let n1: i64 = dss_serve(dom, r1, g_strlen(r1), out) 162 g_check("T1 200-header" as *u8, g_contains(out, n1, "HTTP/1.1 200 OK" as *u8), ctr) 163 g_check("T1 content-length" as *u8, g_contains(out, n1, "Content-Length: " as *u8), ctr) 164 g_check("T1 1-result" as *u8, g_contains(out, n1, "1 result(s)" as *u8), ctr) 165 g_check("T1 hit-text(Estate)" as *u8, g_contains(out, n1, "Estate Planning" as *u8), ctr) 166 167 // T2: q=divorce -> the family-law doc 168 let r2: *u8 = "GET /search?q=divorce&scope=site HTTP/1.1\r\n\r\n" as *u8 169 let n2: i64 = dss_serve(dom, r2, g_strlen(r2), out) 170 g_check("T2 hit-text(Family)" as *u8, g_contains(out, n2, "Family Law" as *u8), ctr) 171 172 // T3: empty query -> prompt, no crash 173 let r3: *u8 = "GET /search HTTP/1.1\r\n\r\n" as *u8 174 let n3: i64 = dss_serve(dom, r3, g_strlen(r3), out) 175 g_check("T3 empty-prompt" as *u8, g_contains(out, n3, "Enter a search term" as *u8), ctr) 176 177 // T4 NEG: no match -> "0 result(s)" 178 let r4: *u8 = "GET /search?q=zzznotpresent HTTP/1.1\r\n\r\n" as *u8 179 let n4: i64 = dss_serve(dom, r4, g_strlen(r4), out) 180 g_check("T4 NEG 0-results" as *u8, g_contains(out, n4, "0 result(s)" as *u8), ctr) 181 182 // T5 SECURITY: %3Cscript%3E in q -> echoed ESCAPED (&lt;script&gt;), never raw <script> 183 let r5: *u8 = "GET /search?q=%3Cscript%3E HTTP/1.1\r\n\r\n" as *u8 184 let n5: i64 = dss_serve(dom, r5, g_strlen(r5), out) 185 g_check("T5 xss-escaped(&lt;script)" as *u8, g_contains(out, n5, "&lt;script&gt;" as *u8), ctr) 186 var raw: i64 = 0 187 if g_contains(out, n5, "<script>" as *u8) == 1 { raw = 1 } 188 g_check("T5 xss no-raw-script" as *u8, (1 - raw), ctr) 189 190 // T6: urldecode '+' -> space (q=child+custody decodes to two terms; both in family-law doc) 191 let r6: *u8 = "GET /search?q=child+custody&scope=site HTTP/1.1\r\n\r\n" as *u8 192 let n6: i64 = dss_serve(dom, r6, g_strlen(r6), out) 193 g_check("T6 urldecode-plus(Family)" as *u8, g_contains(out, n6, "Family Law" as *u8), ctr) 194 195 // T10: results are LINKS -> /doc?cid=<cid>&q=<query> (the SERP click-through) 196 let na: i64 = dss_serve(dom, r1, g_strlen(r1), out) 197 // Links are SCOPE-PRESERVING, so the rendered href carries the scope the request was made in. 198 // Read off the live SERP before rewriting this: /doc?cid=<cid>&q=<q>&scope=site. 199 g_check("T10 result-link(href /doc?cid=201&q=probate&scope=site)" as *u8, g_contains(out, na, "href=\"/doc?cid=201&q=probate&scope=site\"" as *u8), ctr) 200 201 // T11: the matched query term is <b>-highlighted in the rendered result (index-tokenizer-aligned) 202 g_check("T11 highlight(<b>probate</b>)" as *u8, g_contains(out, na, "<b>probate</b>" as *u8), ctr) 203 204 // T12: /doc?cid=201&q=probate -> 200 + the FULL doc text + highlight + back-to-results link 205 let rd1: *u8 = "GET /doc?cid=201&q=probate&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 206 let nd1: i64 = dsv_doc_serve(dom, rd1, g_strlen(rd1), out) 207 var d1ok: i64 = 0 208 // "inheritance"/"executor" straddle the title/body split, so assert each side + highlight + back-link 209 if g_contains(out, nd1, "HTTP/1.1 200 OK" as *u8) == 1 { if g_contains(out, nd1, "inheritance" as *u8) == 1 { if g_contains(out, nd1, "executor" as *u8) == 1 { if g_contains(out, nd1, "<b>probate</b>" as *u8) == 1 { if g_contains(out, nd1, "href=\"/search?q=probate\"" as *u8) == 1 { d1ok = 1 } } } } } 210 g_check("T12 /doc 200 + full text + highlight + back-link" as *u8, d1ok, ctr) 211 212 // T13 NEG: absent cid -> branded 404, never a 500/crash 213 let rd2: *u8 = "GET /doc?cid=99999 HTTP/1.1\r\n\r\n" as *u8 214 let nd2: i64 = dsv_doc_serve(dom, rd2, g_strlen(rd2), out) 215 var d2ok: i64 = 0 216 if g_contains(out, nd2, "HTTP/1.1 404" as *u8) == 1 { if g_contains(out, nd2, "Document not found" as *u8) == 1 { d2ok = 1 } } 217 g_check("T13 NEG /doc absent-cid -> 404" as *u8, d2ok, ctr) 218 219 // T14 NEG: malformed cid (digit-guard boundary) -> 404, not a crash / not a store probe with garbage 220 let rd3: *u8 = "GET /doc?cid=12abc HTTP/1.1\r\n\r\n" as *u8 221 let nd3: i64 = dsv_doc_serve(dom, rd3, g_strlen(rd3), out) 222 g_check("T14 NEG /doc malformed-cid -> 404" as *u8, g_contains(out, nd3, "HTTP/1.1 404" as *u8), ctr) 223 224 // T15: a doc WITH a url:<cid> row links to the REAL page (href = the url value, no /doc) 225 let r15: *u8 = "GET /search?q=expungement&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 226 let n15: i64 = dss_serve(dom, r15, g_strlen(r15), out) 227 var t15: i64 = 0 228 if g_contains(out, n15, "href=\"/practice/criminal.html\"" as *u8) == 1 { if g_contains(out, n15, "/doc?cid=203" as *u8) == 0 { t15 = 1 } } 229 g_check("T15 url-row result links to the page" as *u8, t15, ctr) 230 231 // T16: scope=web SWITCHES the shard away from the Host domain (a ssservetest-only term must yield 0 232 // under web scope -- isolation proves the switch without touching the real web corpus) + Web tab active 233 let r16: *u8 = "GET /search?q=zzqservetest&scope=web HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 234 let n16: i64 = dss_serve(dom, r16, g_strlen(r16), out) 235 // DECOMPOSED 2026-08-25. This was ONE tooth asserting THREE independent facts, so when it went RED it 236 // named none of them and the reader is left to guess -- and the guess is always the alarming one here 237 // ("the shard switch broke"), never "a hidden input moved". Measured cost of the compound form: it 238 // failed, and separating my own change from a pre-existing regression was impossible from the verdict 239 // alone. Three named teeth; gv_ctr moves the denominator by itself, which is why the count is not 240 // hand-maintained anywhere. 241 // T16a NEEDS THE WEB SHARD TO EXIST. PROVEN 2026-08-25: under the buildroot build/run CWD there is no 242 // dp-web-pub-manifest at all (nx_shelltool glob over buildroot/knowledge/store: matches=0, 243 // corpus_complete=1 across 12,464 files), so dss_open_maybe_cached gets an empty handle, the serve 244 // takes its DEGRADED path, and the exact "0 result(s)" prose this tooth greps for is never emitted. 245 // The product is behaving correctly -- it cannot search a shard that is not there. The gate simply 246 // COULD NOT LOOK, and "I could not look" must never share a word with "it is broken": that is how a 247 // false RED trains everyone to ignore a real one. gv_need is the estate's third state for exactly 248 // this, so the run reports SKIP -- never a false RED, and never a false pass either. 249 var webshard: i64 = 0 250 let wfd: i64 = sys_openat_rd("knowledge/store/dp-web-pub-manifest.txt" as *u8) 251 if wfd >= 0 { sys_close(wfd); webshard = 1 } 252 if gv_need("T16a precondition: web shard present in this CWD" as *u8, webshard, ctr) == 1 { 253 g_check("T16a scope=web shard ISOLATION (marker term yields 0 results)" as *u8, g_contains(out, n16, "0 result(s)" as *u8), ctr) 254 } 255 g_check("T16b scope=web tab is the ACTIVE one" as *u8, g_contains(out, n16, "class=on href=\"/search?scope=web" as *u8), ctr) 256 g_check("T16c form CARRIES scope=web forward" as *u8, g_contains(out, n16, "name=scope value=web" as *u8), ctr) 257 258 // T17: default scope renders the tabs with This-site active 259 let n17: i64 = dss_serve(dom, r1, g_strlen(r1), out) 260 var t17: i64 = 0 261 if g_contains(out, n17, ">This site</a>" as *u8) == 1 { if g_contains(out, n17, ">Web</a>" as *u8) == 1 { t17 = 1 } } 262 g_check("T17 scope tabs render (This site / Web)" as *u8, t17, ctr) 263 264 // ---- API-FIRST surface (versioned JSON; enterprise contract) ---- 265 // T18: /api/search JSON shape -- v1, count, cid AS STRING, escaped title, CORS + content-type headers 266 let ra1: *u8 = "GET /api/search?q=probate&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 267 let na1: i64 = dss_api_search(dom, ra1, g_strlen(ra1), out) 268 var a1: i64 = 0 269 if g_contains(out, na1, "\"v\":1" as *u8) == 1 { if g_contains(out, na1, "\"nresults\":1" as *u8) == 1 { if g_contains(out, na1, "\"cid\":\"201\"" as *u8) == 1 { if g_contains(out, na1, "application/json" as *u8) == 1 { if g_contains(out, na1, "Access-Control-Allow-Origin: *" as *u8) == 1 { a1 = 1 } } } } } 270 g_check("T18 /api/search JSON v1 + cid-as-string + CORS" as *u8, a1, ctr) 271 272 // T19: self-describing endpoint (no q -> 200 usage document, still structured) 273 let ra2: *u8 = "GET /api/search HTTP/1.1\r\n\r\n" as *u8 274 let na2: i64 = dss_api_search(dom, ra2, g_strlen(ra2), out) 275 var a2: i64 = 0 276 if g_contains(out, na2, "HTTP/1.1 200" as *u8) == 1 { if g_contains(out, na2, "\"endpoint\":\"/api/search\"" as *u8) == 1 { a2 = 1 } } 277 g_check("T19 /api/search self-describes without q" as *u8, a2, ctr) 278 279 // T20: /api/doc found -> JSON text; T21: absent -> 404 not_found; T22: malformed -> 400 bad_cid 280 let ra3: *u8 = "GET /api/doc?cid=201&scope=site HTTP/1.1\r\n\r\n" as *u8 281 let na3: i64 = dss_api_doc(dom, ra3, g_strlen(ra3), out) 282 var a3: i64 = 0 283 if g_contains(out, na3, "\"found\":true" as *u8) == 1 { if g_contains(out, na3, "Estate Planning" as *u8) == 1 { if g_contains(out, na3, "\"truncated\":false" as *u8) == 1 { a3 = 1 } } } 284 g_check("T20 /api/doc found -> JSON text" as *u8, a3, ctr) 285 let ra4: *u8 = "GET /api/doc?cid=99999 HTTP/1.1\r\n\r\n" as *u8 286 let na4: i64 = dss_api_doc(dom, ra4, g_strlen(ra4), out) 287 var a4: i64 = 0 288 if g_contains(out, na4, "HTTP/1.1 404" as *u8) == 1 { if g_contains(out, na4, "\"code\":\"not_found\"" as *u8) == 1 { a4 = 1 } } 289 g_check("T21 /api/doc absent -> 404 not_found" as *u8, a4, ctr) 290 let ra5: *u8 = "GET /api/doc?cid=12abc HTTP/1.1\r\n\r\n" as *u8 291 let na5: i64 = dss_api_doc(dom, ra5, g_strlen(ra5), out) 292 var a5: i64 = 0 293 if g_contains(out, na5, "HTTP/1.1 400" as *u8) == 1 { if g_contains(out, na5, "\"code\":\"bad_cid\"" as *u8) == 1 { a5 = 1 } } 294 g_check("T22 /api/doc malformed -> 400 bad_cid" as *u8, a5, ctr) 295 296 // T23: url row rides the API too (site pages / web results carry their real location) 297 let ra6: *u8 = "GET /api/search?q=expungement&scope=site HTTP/1.1\r\n\r\n" as *u8 298 let na6: i64 = dss_api_search(dom, ra6, g_strlen(ra6), out) 299 g_check("T23 /api/search carries url for page-backed docs" as *u8, g_contains(out, na6, "\"url\":\"/practice/criminal.html\"" as *u8), ctr) 300 301 // ---- MOBILE-FIRST markers (measured mechanically, not vibes) ---- 302 let nm: i64 = dss_serve(dom, r1, g_strlen(r1), out) 303 var mm: i64 = 0 304 if g_contains(out, nm, "font-size:16px" as *u8) == 1 { if g_contains(out, nm, "min-height:44px" as *u8) == 1 { if g_contains(out, nm, "prefers-color-scheme" as *u8) == 1 { if g_contains(out, nm, "text-size-adjust" as *u8) == 1 { mm = 1 } } } } 305 g_check("T24 mobile-first markers (16px input, 44px targets, dark scheme, size-adjust lock)" as *u8, mm, ctr) 306 307 // ---- S-CLASS SERP DISPLAY rows (the beat-Google/Bing result-page bar, measured mechanically) ---- 308 // T30 the tab title carries the query (multi-tab usability) 309 let n30: i64 = dss_serve(dom, r1, g_strlen(r1), out) 310 g_check("T30 <title> = query + Nishi Search" as *u8, g_contains(out, n30, "<title>probate &mdash; Nishi Search</title>" as *u8), ctr) 311 // T31 ZERO JavaScript on the whole page (Google's SERP won't even render without JS) 312 var t31: i64 = 0 313 if g_contains(out, n30, "<script" as *u8) == 0 { t31 = 1 } 314 g_check("T31 zero-JS page (no <script anywhere)" as *u8, t31, ctr) 315 // T32 semantic structure + the measured credo footer 316 var t32: i64 = 0 317 if g_contains(out, n30, "<article class=r" as *u8) == 1 { if g_contains(out, n30, "<h3 class=t" as *u8) == 1 { if g_contains(out, n30, "<footer class=credo" as *u8) == 1 { if g_contains(out, n30, "0 JavaScript" as *u8) == 1 { if g_contains(out, n30, "<main>" as *u8) == 1 { t32 = 1 } } } } } 318 g_check("T32 semantic article/h3/main + credo footer" as *u8, t32, ctr) 319 // T33 measured query latency in the meta line 320 g_check("T33 meta line shows measured ms" as *u8, g_contains(out, n30, " ms</p>" as *u8), ctr) 321 // T34 FEATURED ANSWER: a full-coverage sentence gets the answer panel, highlighted 322 let r34: *u8 = "GET /search?q=probate+inheritance&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 323 let n34: i64 = dss_serve(dom, r34, g_strlen(r34), out) 324 var t34: i64 = 0 325 if g_contains(out, n34, "class=ans" as *u8) == 1 { if g_contains(out, n34, "<b>probate</b>" as *u8) == 1 { t34 = 1 } } 326 g_check("T34 featured-answer panel (full term coverage, highlighted)" as *u8, t34, ctr) 327 // T35 pager: 22 matches -> Next on page 0; Prev + page 2 marker on p=1 328 let r35a: *u8 = "GET /search?q=pgterm&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 329 let n35a: i64 = dss_serve(dom, r35a, g_strlen(r35a), out) 330 var t35: i64 = 0 331 if g_contains(out, n35a, "Next &rarr;" as *u8) == 1 { if g_contains(out, n35a, "&p=1" as *u8) == 1 { 332 let r35b: *u8 = "GET /search?q=pgterm&p=1&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 333 let n35b: i64 = dss_serve(dom, r35b, g_strlen(r35b), out) 334 // Expected total is DERIVED from the same pg_docs the fixture was seeded with, so the count 335 // assertion cannot drift from the fixture the way the literal 22 drifted from DSV_MAXR. 336 // ⚠DOCUMENTED BOUND: this formats exactly two digits, which covers any DSV_MAXR from 8 to 97. 337 // If the cap ever leaves that range this must grow a real integer formatter -- stated here so 338 // the next reader is not surprised by a silently wrong expectation. 339 let expm: *u8 = sys_mmap(32) 340 var xo: i64 = 0 341 let ex1: *u8 = "of " as *u8 342 while ex1[xo] != (0 as u8) { expm[xo] = ex1[xo]; xo = xo + 1 } 343 expm[xo] = (48 + (pg_docs / 10)) as u8; xo = xo + 1 344 expm[xo] = (48 + (pg_docs % 10)) as u8; xo = xo + 1 345 let ex2: *u8 = " matched" as *u8 346 var xj: i64 = 0 347 while ex2[xj] != (0 as u8) { expm[xo] = ex2[xj]; xo = xo + 1; xj = xj + 1 } 348 expm[xo] = 0 as u8 349 if g_contains(out, n35b, "&larr; Prev" as *u8) == 1 { if g_contains(out, n35b, "page 2" as *u8) == 1 { if g_contains(out, n35b, expm) == 1 { t35 = 1 } } } 350 } } 351 g_check("T35 pager Next/Prev + page marker + total matched" as *u8, t35, ctr) 352 353 // T36 DID-YOU-MEAN: a typo'd query renders the dictionary's correction as a link 354 let r36: *u8 = "GET /search?q=probete&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 355 let n36: i64 = dss_serve(dom, r36, g_strlen(r36), out) 356 var t36: i64 = 0 357 // scope-preserving link again -- the correction keeps the user in the scope they searched 358 if g_contains(out, n36, "Did you mean" as *u8) == 1 { if g_contains(out, n36, "href=\"/search?q=probate&scope=site\"" as *u8) == 1 { t36 = 1 } } 359 g_check("T36 did-you-mean line (probete -> probate link)" as *u8, t36, ctr) 360 361 // T37 /api/suggest: dictionary completions as versioned JSON 362 let r37: *u8 = "GET /api/suggest?q=prob&scope=site HTTP/1.1\r\n\r\n" as *u8 363 let n37: i64 = dss_api_suggest(dom, r37, g_strlen(r37), out) 364 var t37: i64 = 0 365 if g_contains(out, n37, "\"v\":1" as *u8) == 1 { if g_contains(out, n37, "\"suggestions\":[\"probate\"" as *u8) == 1 { if g_contains(out, n37, "application/json" as *u8) == 1 { t37 = 1 } } } 366 g_check("T37 /api/suggest JSON completions" as *u8, t37, ctr) 367 368 // T38 /api/search zero-hit carries did_you_mean 369 let r38: *u8 = "GET /api/search?q=probete&scope=site HTTP/1.1\r\n\r\n" as *u8 370 let n38: i64 = dss_api_search(dom, r38, g_strlen(r38), out) 371 var t38: i64 = 0 372 if g_contains(out, n38, "\"nresults\":0" as *u8) == 1 { if g_contains(out, n38, "\"did_you_mean\":\"probate\"" as *u8) == 1 { t38 = 1 } } 373 g_check("T38 /api/search did_you_mean field" as *u8, t38, ctr) 374 375 // T39 +term AND through the serve layer: "probate +custody" -- OR would return BOTH docs; the 376 // required term keeps only the custody-bearing one (distinguishing fixture) 377 let r39: *u8 = "GET /search?q=probate+%2Bcustody&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 378 let n39: i64 = dss_serve(dom, r39, g_strlen(r39), out) 379 var t39: i64 = 0 380 if g_contains(out, n39, "1 result(s)" as *u8) == 1 { if g_contains(out, n39, "Family Law" as *u8) == 1 { t39 = 1 } } 381 g_check("T39 +term AND via serve (OR=2 -> AND=1, custody doc only)" as *u8, t39, ctr) 382 383 // T40/T41 PHRASE through the serve layer: quoted adjacency matches; reversed order does not 384 let r40: *u8 = "GET /search?q=%22living+trusts%22&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 385 let n40: i64 = dss_serve(dom, r40, g_strlen(r40), out) 386 g_check("T40 phrase [living trusts] via serve -> 1 result" as *u8, g_contains(out, n40, "1 result(s)" as *u8), ctr) 387 // scope=site here too: a NEGATIVE that passes only because it queried the wrong shard is not a 388 // negative control at all -- it would report 0 results for a corpus it never searched. 389 let r41: *u8 = "GET /search?q=%22trusts+living%22&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 390 let n41: i64 = dss_serve(dom, r41, g_strlen(r41), out) 391 g_check("T41 NEG reversed phrase -> 0 results" as *u8, g_contains(out, n41, "0 result(s)" as *u8), ctr) 392 // T42 API carries the exactness contract for quoted queries 393 let r42: *u8 = "GET /api/search?q=%22living+trusts%22&scope=site HTTP/1.1\r\n\r\n" as *u8 394 let n42: i64 = dss_api_search(dom, r42, g_strlen(r42), out) 395 var t42: i64 = 0 396 if g_contains(out, n42, "\"phrase_exact\":true" as *u8) == 1 { if g_contains(out, n42, "\"nresults\":1" as *u8) == 1 { t42 = 1 } } 397 g_check("T42 /api/search phrase_exact:true for a quoted query" as *u8, t42, ctr) 398 399 // T43 OpenAPI 3.1 contract: valid structure, all 3 paths, servers names the Host, cid-as-string note 400 let n43: i64 = dss_api_openapi("andelinwest.com" as *u8, out) 401 var t43: i64 = 0 402 if g_contains(out, n43, "\"openapi\":\"3.1.0\"" as *u8) == 1 { if g_contains(out, n43, "\"/api/search\":" as *u8) == 1 { if g_contains(out, n43, "\"/api/doc\":" as *u8) == 1 { if g_contains(out, n43, "\"/api/suggest\":" as *u8) == 1 { if g_contains(out, n43, "https://andelinwest.com" as *u8) == 1 { if g_contains(out, n43, "SearchResponse" as *u8) == 1 { if g_contains(out, n43, "application/json" as *u8) == 1 { t43 = 1 } } } } } } } 403 g_check("T43 /api/openapi.json valid 3.1 spec (paths+schemas+server+CORS)" as *u8, t43, ctr) 404 // T44 the SERP footer links the API spec (discoverability) 405 let r44: *u8 = "GET /search?q=probate HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 406 let n44: i64 = dss_serve(dom, r44, g_strlen(r44), out) 407 g_check("T44 SERP footer links /api/openapi.json" as *u8, g_contains(out, n44, "href=\"/api/openapi.json\"" as *u8), ctr) 408 409 // T48-T50 THREE SCOPES (operator's 2026-07-04 model): the SERP shows This site / Trusted / Web tabs, 410 // each scope-preserving; the API scope name resolves web/trusted/site. 411 let r48: *u8 = "GET /search?q=probate HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 412 let n48: i64 = dss_serve(dom, r48, g_strlen(r48), out) 413 var t48: i64 = 0 414 if g_contains(out, n48, ">This site</a>" as *u8) == 1 { if g_contains(out, n48, ">Trusted</a>" as *u8) == 1 { if g_contains(out, n48, ">Web</a>" as *u8) == 1 { t48 = 1 } } } 415 g_check("T48 three scope tabs (This site / Trusted / Web)" as *u8, t48, ctr) 416 let r49: *u8 = "GET /api/search?q=probate&scope=trusted HTTP/1.1\r\n\r\n" as *u8 417 let n49: i64 = dss_api_search(dom, r49, g_strlen(r49), out) 418 g_check("T49 /api/search scope=trusted -> \"scope\":\"trusted\"" as *u8, g_contains(out, n49, "\"scope\":\"trusted\"" as *u8), ctr) 419 let r50: *u8 = "GET /api/search?q=probate&scope=web HTTP/1.1\r\n\r\n" as *u8 420 let n50: i64 = dss_api_search(dom, r50, g_strlen(r50), out) 421 g_check("T50 /api/search scope=web -> \"scope\":\"web\"" as *u8, g_contains(out, n50, "\"scope\":\"web\"" as *u8), ctr) 422 423 // T45 host FACETS: facterm spans 2 hosts -> the SERP offers one-click site: narrowing 424 let r45: *u8 = "GET /search?q=facterm&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 425 let n45: i64 = dss_serve(dom, r45, g_strlen(r45), out) 426 var t45: i64 = 0 427 if g_contains(out, n45, "Sites: " as *u8) == 1 { if g_contains(out, n45, "site%3Aen.wikipedia.org" as *u8) == 1 { if g_contains(out, n45, "site%3Adocs.example.org" as *u8) == 1 { t45 = 1 } } } 428 g_check("T45 SERP host facets (Sites: line + site: links)" as *u8, t45, ctr) 429 // T46 the site: OPERATOR through the serve layer narrows to one host + facet line suppressed 430 let r46: *u8 = "GET /search?q=facterm+site%3Adocs.example.org&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 431 let n46: i64 = dss_serve(dom, r46, g_strlen(r46), out) 432 var t46: i64 = 0 433 if g_contains(out, n46, "1 result(s)" as *u8) == 1 { if g_contains(out, n46, "Sites: " as *u8) == 0 { t46 = 1 } } 434 g_check("T46 site: operator via serve (1 result, facets suppressed)" as *u8, t46, ctr) 435 // T47 API carries the host field 436 let r47: *u8 = "GET /api/search?q=facterm&scope=site HTTP/1.1\r\n\r\n" as *u8 437 let n47: i64 = dss_api_search(dom, r47, g_strlen(r47), out) 438 g_check("T47 /api/search result carries host" as *u8, g_contains(out, n47, "\"host\":\"en.wikipedia.org\"" as *u8), ctr) 439 440 // T7-T9: dsv_host (Host-header -> domain; the daemon's /search route feeds this to dss_serve) 441 let hbuf: *u8 = sys_mmap(256) 442 let rh1: *u8 = "GET /search?q=x HTTP/1.1\r\nHost: andelinwest.com:443\r\n\r\n" as *u8 443 dsv_host(rh1, g_strlen(rh1), hbuf, 255) 444 g_check("T7 host(andelinwest.com,port-stripped)" as *u8, g_streq(hbuf, "andelinwest.com" as *u8), ctr) 445 let rh2: *u8 = "GET / HTTP/1.1\r\nhost: bradrwest.com\r\n\r\n" as *u8 446 dsv_host(rh2, g_strlen(rh2), hbuf, 255) 447 g_check("T8 host(lowercase)" as *u8, g_streq(hbuf, "bradrwest.com" as *u8), ctr) 448 let rh3: *u8 = "GET / HTTP/1.1\r\n\r\n" as *u8 449 dsv_host(rh3, g_strlen(rh3), hbuf, 255) 450 var t9ok: i64 = 0 451 if hbuf[0] == (0 as u8) { t9ok = 1 } 452 g_check("T9 host-absent-empty" as *u8, t9ok, ctr) 453 454 let snip_req0: *u8 = "GET /api/search?q=red+wine&scope=site HTTP/1.1\r\n\r\n" as *u8 455 let snip_n0: i64 = dss_api_search(dom, snip_req0, g_strlen(snip_req0), out) 456 g_check("API selects relevant prose after navigation" as *u8, g_contains(out, snip_n0, "\"snippet\":\"Red wine carries a distinct aroma, and this sentence explains the color and flavor clearly\"" as *u8), ctr) 457 g_puts("SNIP-API-0 BEGIN\n"); sys_write(1, out, snip_n0); g_puts("\nSNIP-API-0 END\n") 458 let snip_req1: *u8 = "GET /api/search?q=escapeterm&scope=site HTTP/1.1\r\n\r\n" as *u8 459 let snip_n1: i64 = dss_api_search(dom, snip_req1, g_strlen(snip_req1), out) 460 g_check("API escapes JSON without HTML entities or highlighting" as *u8, g_contains(out, snip_n1, "\"snippet\":\"Escapeterm describes \\\"quoted\\\" text with a backslash \\\\ and caf\xC3\xA9 in a complete useful sentence\"" as *u8), ctr) 461 g_puts("SNIP-API-1 BEGIN\n"); sys_write(1, out, snip_n1); g_puts("\nSNIP-API-1 END\n") 462 let snip_req2: *u8 = "GET /api/search?q=fallbackterm&scope=site HTTP/1.1\r\n\r\n" as *u8 463 let snip_n2: i64 = dss_api_search(dom, snip_req2, g_strlen(snip_req2), out) 464 g_check("API fallback unchanged without qualifying prose" as *u8, g_contains(out, snip_n2, "\"snippet\":\"Tiny body.\"" as *u8), ctr) 465 g_puts("SNIP-API-2 BEGIN\n"); sys_write(1, out, snip_n2); g_puts("\nSNIP-API-2 END\n") 466 let snip_req3: *u8 = "GET /api/search?q=dog&scope=site HTTP/1.1\r\n\r\n" as *u8 467 let snip_n3: i64 = dss_api_search(dom, snip_req3, g_strlen(snip_req3), out) 468 g_check("API chooses whole-word match over dogmatic decoy" as *u8, g_contains(out, snip_n3, "\"snippet\":\"A dog needs daily exercise, and this sentence describes that specific animal accurately\"" as *u8), ctr) 469 g_puts("SNIP-API-3 BEGIN\n"); sys_write(1, out, snip_n3); g_puts("\nSNIP-API-3 END\n") 470 let snip_html_req: *u8 = "GET /search?q=red+wine&scope=site HTTP/1.1\r\n\r\n" as *u8 471 let snip_html_n: i64 = dss_serve(dom, snip_html_req, g_strlen(snip_html_req), out) 472 g_check("HTML keeps same selected prose and highlighting" as *u8, g_contains(out, snip_html_n, "<div class=s><b>Red</b> <b>wine</b> carries a distinct aroma, and this sentence explains the color and flavor clearly</div>" as *u8), ctr) 473 let snip_cap_req: *u8 = "GET /api/search?q=capsterm&scope=site HTTP/1.1\r\n\r\n" as *u8 474 let snip_cap_n: i64 = dss_api_search(dom, snip_cap_req, g_strlen(snip_cap_req), out) 475 g_puts("SNIP-CAP BEGIN\n"); sys_write(1, out, snip_cap_n); g_puts("\nSNIP-CAP END\n") 476 477 let snip_multi_req: *u8 = "GET /api/search?q=wine+escapeterm+dog&scope=site HTTP/1.1\r\n\r\n" as *u8 478 let snip_multi_n: i64 = dss_api_search(dom, snip_multi_req, g_strlen(snip_multi_req), out) 479 g_puts("SNIP-API-4 BEGIN\n"); sys_write(1, out, snip_multi_n); g_puts("\nSNIP-API-4 END\n") 480 // Exit code comes FROM the verdict: /api/gate_run and nx_swcompare_evidence both derive GREEN/RED 481 // from the exit status, so printing a verdict beside a bare `return 0` blesses every failure found. 482 let rc: i64 = gv_verdict("DSSSERVE" as *u8, ctr, "/search + /doc + /api serve contract" as *u8) 483 sys_exit(rc) 484 return rc 485}