code wiki / _hdl_build / nx_docportal_search_serve_gate.nx

nx_docportal_search_serve_gate.nx source

↩ module page · 538 lines · 39671 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 55const G_SCOPE_US_BAR: i64 = 10000 // E4 done-rule: the scope filter costs under ten milliseconds (measured, never asserted) 56func main(argc: i64, argv: *i64) -> i64 { 57 g_puts("=== nx_docportal_search_serve gate (R2 /search serve, sovereign) ===\n") 58 let d1: *u8 = "Estate Planning wills living trusts probate inheritance executor" as *u8 59 // zzqservetest = an INVENTED shard-marker token: T16 proves scope=web switches shards by querying it 60 // (present here, absent from any real crawled web page BY CONSTRUCTION -- "probate" stopped working 61 // as the isolation probe the moment the real web corpus ingested wikipedia's estate-planning page) 62 let d2: *u8 = "Family Law divorce child custody support alimony parenting zzqservetest" as *u8 63 let d3: *u8 = "Criminal defense practice page felonies misdemeanors expungement" as *u8 64 let w: *i64 = ss_begin() 65 ss_add(w, 1, "doc:201" as *u8, d1, g_strlen(d1)) 66 ss_add(w, 1, "doc:202" as *u8, d2, g_strlen(d2)) 67 // 203 = an ingested SITE PAGE: carries a url:<cid> row -> its result must link to the PAGE, not /doc 68 ss_add(w, 1, "doc:203" as *u8, d3, g_strlen(d3)) 69 ss_add(w, 1, "url:203" as *u8, "/practice/criminal.html" as *u8, 23) 70 // facet fixture (T45): two docs sharing facterm on DIFFERENT hosts -> the SERP offers site: narrowing 71 let df1: *u8 = "facterm alpha article body" as *u8 72 let df2: *u8 = "facterm beta article body text" as *u8 73 ss_add(w, 1, "doc:211" as *u8, df1, g_strlen(df1)) 74 ss_add(w, 1, "url:211" as *u8, "https://en.wikipedia.org/wiki/Alpha" as *u8, 35) 75 ss_add(w, 1, "doc:212" as *u8, df2, g_strlen(df2)) 76 ss_add(w, 1, "url:212" as *u8, "https://docs.example.org/beta" as *u8, 29) 77 // pager fixture: DSV_MAXR + 2 pgterm docs, DERIVED so it always exceeds the page cap by exactly 78 // enough to force a second page. 79 // ★★★★★★IT WAS THE LITERAL 22 AGAINST A "20/page cap", AND THE CAP MOVED TO 30 ON 2026-07-24 80 // (same day dsv_scope's default flipped -- both changes broke this gate together). The fixture then 81 // fit on ONE page, no pager rendered, and T35 reported a product bug that did not exist. 82 // A FIXTURE SIZED BY A LITERAL AGAINST A CONSTANT THAT CAN MOVE IS A TEST WITH AN EXPIRY DATE 83 // NOBODY WROTE DOWN. Derived from DSV_MAXR, it cannot go stale when the cap moves again. 84 let pg_docs: i64 = DSV_MAXR + 2 85 let dpg: *u8 = "pgterm pagination fixture entry for the serve pager" as *u8 86 let pgkey: *u8 = sys_mmap(24) 87 var pgi: i64 = 301 88 while pgi <= 300 + pg_docs { 89 var ko: i64 = 0 90 let kp: *u8 = "doc:" as *u8 91 while kp[ko] != (0 as u8) { pgkey[ko] = kp[ko]; ko = ko + 1 } 92 pgkey[ko] = (48 + (pgi / 100)) as u8 93 pgkey[ko + 1] = (48 + ((pgi / 10) % 10)) as u8 94 pgkey[ko + 2] = (48 + (pgi % 10)) as u8 95 pgkey[ko + 3] = 0 as u8 96 ss_add(w, 1, pgkey, dpg, g_strlen(dpg)) 97 pgi = pgi + 1 98 } 99 // E4 scope fixture (T60): two docs sharing scopeterm under DIFFERENT url prefixes; a public scope word keeps one, 100 // an mcp-only word is not honoured on this surface (falls through to the default), no scope keeps both 101 let ds1: *u8 = "scopeterm document under the first corpus prefix" as *u8 102 let ds2: *u8 = "scopeterm document under the second corpus prefix" as *u8 103 ss_add(w, 1, "doc:221" as *u8, ds1, g_strlen(ds1)) 104 ss_add(w, 1, "url:221" as *u8, "estate://fxa/one" as *u8, g_strlen("estate://fxa/one" as *u8)) 105 ss_add(w, 1, "doc:222" as *u8, ds2, g_strlen(ds2)) 106 ss_add(w, 1, "url:222" as *u8, "estate://fxb/two" as *u8, g_strlen("estate://fxb/two" as *u8)) 107 // ⚠FIXTURE MOVED OUT OF knowledge/store/ 2026-08-15 -- IT HAD ACCUMULATED AND CORRUPTED. 108 // This gate wrote its fixture into the SHARED production store path and never cleaned it, so every 109 // run appended another segment to the same place. MEASURED: buildroot/knowledge/store/ 110 // dp-ssservetest-pub-manifest.txt read `seg-1 / seg-1 / seg-2` -- a DUPLICATE segment row, which 111 // makes ss_open2 mount the same segment twice and the shadow logic treat the older index as 112 // superseded by a newer copy of ITSELF. Symptom: every structural tooth passed (headers, XSS 113 // escaping, mobile markers, zero-JS, title) while every CONTENT tooth failed (1-result, hit-text, 114 // highlight, /doc, pager, facets) -- the shape of a shard that mounts but yields nothing. 115 // ★★★★★★A GATE THAT WRITES ITS FIXTURE TO A FIXED SHARED PATH AND NEVER CLEANS IT EVENTUALLY 116 // TESTS GARBAGE, AND ITS FAILURES LOOK LIKE PRODUCT BUGS. This is the estate's own recorded rule 117 // (gate scratch belongs in /tmp/<gate>/, created by sys_mkdir at SETUP because a teardown does not 118 // run when a run crashes) and this gate predates it. Two stale copies of the old fixture remain -- 119 // knowledge/store/ and buildroot/knowledge/store/ -- and are now unreferenced; adjudicate them with 120 // nx_retire_path rather than deleting, since they are evidence of this defect. 121 // ⚠DIAGNOSIS OF THE DUPLICATE, stated as a lead not a conclusion: ss_commit re-derives its segid 122 // under the plane lock as max_segid+1, so a duplicate seg-1 implies ss_max_segid returned -1 while 123 // seg-1 existed. That is worth chasing in ss_max_segid itself -- a manifest reader that reports 124 // "no segments" on a readable non-empty store would corrupt ANY store, not just a fixture. 125 // The fixture must stay where dss_prefix points -- it builds knowledge/store/dp-<domain>-pub- 126 // from the domain the gate serves, so moving the WRITE to /tmp would simply never be read back 127 // (checked before building; that would have turned a corrupt fixture into an absent one). 128 // Instead: START CLEAN. Unlinking the manifest makes ss_max_segid report an empty store, so 129 // ss_commit writes seg-1 and publishes a manifest naming exactly this run's segment -- stale 130 // segment FILES are simply overwritten or orphaned, never mounted, because mounting is driven by 131 // the manifest. Setup-time, not teardown-time, deliberately: A TEARDOWN DOES NOT RUN WHEN A RUN 132 // CRASHES, and this fixture was corrupted by exactly the runs that did not finish tidily. 133 // ★DOMAIN RENAMED ssservetest -> ssgatetest 2026-08-15. The old name contained the substring 134 // `serve`, which is a PROTECTED TOKEN in nx_retire_path -- so every orphaned copy of this fixture 135 // was permanently unretirable (RETIRE-REFUSED code=4 token=serve, on all five files). The guard is 136 // RIGHT: it stops a live/serving artifact being moved out from under a running service and is 137 // deliberately wrong in the direction of doing nothing. THE FIX IS THE NAME, NOT THE GUARD -- 138 // relaxing a substring match on `serve` to tidy test files would put every genuinely serving 139 // artifact one rename away from being retirable. ★★★★★★WHEN A PROTECTION REFUSES SOMETHING 140 // HARMLESS, MOVE THE HARMLESS THING OUT OF ITS PATH; DO NOT WIDEN THE PROTECTION. 141 // (The five pre-existing orphans keep the old name and stay unretirable-by-design; they are inert 142 // and stand as the evidence for the accumulation defect that produced them.) 143 sys_unlinkat("knowledge/store/dp-ssgatetest-pub-manifest.txt\x00" as *u8) 144 ss_commit("knowledge/store/dp-ssgatetest-pub-" as *u8, w, 1) 145 146 let ctr: *i64 = gv_ctr() 147 gv_head("nx_docportal_search_serve -- /search + /doc + /api serve contract over a per-run fixture" as *u8) 148 let out: *u8 = sys_mmap(DSV_OUTCAP) 149 let dom: *u8 = "ssgatetest" as *u8 150 151 // T1: q=probate -> 200 + Content-Length + "1 result" + the estate text 152 // ⚠SCOPE MUST BE EXPLICIT (2026-08-15). dsv_scope's DEFAULT flipped site->web on 2026-07-24 153 // ("nishifamily.com/search IS a web search engine; the site corpus is an opt-in tab"), so every 154 // request in this gate that omits scope= has since been querying the REAL WEB SHARD instead of the 155 // fixture committed above. That is why the store is provably correct -- probed directly: bign=27, 156 // dcnt1=1 for probate, tf1=1 on cid 201 -- while every CONTENT tooth fails and every STRUCTURAL one 157 // passes. ★★★★★★A GATE THAT RELIES ON A DEFAULT TESTS WHATEVER THE DEFAULT LATER BECOMES; the 158 // product change was deliberate and correct, and it silently redirected this gate's subject. 159 let r1: *u8 = "GET /search?q=probate&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 160 let n1: i64 = dss_serve(dom, r1, g_strlen(r1), out) 161 g_check("T1 200-header" as *u8, g_contains(out, n1, "HTTP/1.1 200 OK" as *u8), ctr) 162 g_check("T1 content-length" as *u8, g_contains(out, n1, "Content-Length: " as *u8), ctr) 163 g_check("T1 1-result" as *u8, g_contains(out, n1, "1 result(s)" as *u8), ctr) 164 g_check("T1 hit-text(Estate)" as *u8, g_contains(out, n1, "Estate Planning" as *u8), ctr) 165 166 // T2: q=divorce -> the family-law doc 167 let r2: *u8 = "GET /search?q=divorce&scope=site HTTP/1.1\r\n\r\n" as *u8 168 let n2: i64 = dss_serve(dom, r2, g_strlen(r2), out) 169 g_check("T2 hit-text(Family)" as *u8, g_contains(out, n2, "Family Law" as *u8), ctr) 170 171 // T3: empty query -> prompt, no crash 172 let r3: *u8 = "GET /search HTTP/1.1\r\n\r\n" as *u8 173 let n3: i64 = dss_serve(dom, r3, g_strlen(r3), out) 174 g_check("T3 empty-prompt" as *u8, g_contains(out, n3, "Enter a search term" as *u8), ctr) 175 176 // T4 NEG: no match -> "0 result(s)" 177 let r4: *u8 = "GET /search?q=zzznotpresent HTTP/1.1\r\n\r\n" as *u8 178 let n4: i64 = dss_serve(dom, r4, g_strlen(r4), out) 179 g_check("T4 NEG 0-results" as *u8, g_contains(out, n4, "0 result(s)" as *u8), ctr) 180 181 // T5 SECURITY: %3Cscript%3E in q -> echoed ESCAPED (&lt;script&gt;), never raw <script> 182 let r5: *u8 = "GET /search?q=%3Cscript%3E HTTP/1.1\r\n\r\n" as *u8 183 let n5: i64 = dss_serve(dom, r5, g_strlen(r5), out) 184 g_check("T5 xss-escaped(&lt;script)" as *u8, g_contains(out, n5, "&lt;script&gt;" as *u8), ctr) 185 var raw: i64 = 0 186 if g_contains(out, n5, "<script>" as *u8) == 1 { raw = 1 } 187 g_check("T5 xss no-raw-script" as *u8, (1 - raw), ctr) 188 189 // T6: urldecode '+' -> space (q=child+custody decodes to two terms; both in family-law doc) 190 let r6: *u8 = "GET /search?q=child+custody&scope=site HTTP/1.1\r\n\r\n" as *u8 191 let n6: i64 = dss_serve(dom, r6, g_strlen(r6), out) 192 g_check("T6 urldecode-plus(Family)" as *u8, g_contains(out, n6, "Family Law" as *u8), ctr) 193 194 // T10: results are LINKS -> /doc?cid=<cid>&q=<query> (the SERP click-through) 195 let na: i64 = dss_serve(dom, r1, g_strlen(r1), out) 196 // Links are SCOPE-PRESERVING, so the rendered href carries the scope the request was made in. 197 // Read off the live SERP before rewriting this: /doc?cid=<cid>&q=<q>&scope=site. 198 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) 199 200 // T11: the matched query term is <b>-highlighted in the rendered result (index-tokenizer-aligned) 201 g_check("T11 highlight(<b>probate</b>)" as *u8, g_contains(out, na, "<b>probate</b>" as *u8), ctr) 202 203 // T12: /doc?cid=201&q=probate -> 200 + the FULL doc text + highlight + back-to-results link 204 let rd1: *u8 = "GET /doc?cid=201&q=probate&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 205 let nd1: i64 = dsv_doc_serve(dom, rd1, g_strlen(rd1), out) 206 var d1ok: i64 = 0 207 // "inheritance"/"executor" straddle the title/body split, so assert each side + highlight + back-link 208 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 } } } } } 209 g_check("T12 /doc 200 + full text + highlight + back-link" as *u8, d1ok, ctr) 210 211 // T13 NEG: absent cid -> branded 404, never a 500/crash 212 let rd2: *u8 = "GET /doc?cid=99999 HTTP/1.1\r\n\r\n" as *u8 213 let nd2: i64 = dsv_doc_serve(dom, rd2, g_strlen(rd2), out) 214 var d2ok: i64 = 0 215 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 } } 216 g_check("T13 NEG /doc absent-cid -> 404" as *u8, d2ok, ctr) 217 218 // T14 NEG: malformed cid (digit-guard boundary) -> 404, not a crash / not a store probe with garbage 219 let rd3: *u8 = "GET /doc?cid=12abc HTTP/1.1\r\n\r\n" as *u8 220 let nd3: i64 = dsv_doc_serve(dom, rd3, g_strlen(rd3), out) 221 g_check("T14 NEG /doc malformed-cid -> 404" as *u8, g_contains(out, nd3, "HTTP/1.1 404" as *u8), ctr) 222 223 // T15: a doc WITH a url:<cid> row links to the REAL page (href = the url value, no /doc) 224 let r15: *u8 = "GET /search?q=expungement&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 225 let n15: i64 = dss_serve(dom, r15, g_strlen(r15), out) 226 var t15: i64 = 0 227 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 } } 228 g_check("T15 url-row result links to the page" as *u8, t15, ctr) 229 230 // T16: scope=web SWITCHES the shard away from the Host domain (a ssservetest-only term must yield 0 231 // under web scope -- isolation proves the switch without touching the real web corpus) + Web tab active 232 let r16: *u8 = "GET /search?q=zzqservetest&scope=web HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 233 let n16: i64 = dss_serve(dom, r16, g_strlen(r16), out) 234 // DECOMPOSED 2026-08-25. This was ONE tooth asserting THREE independent facts, so when it went RED it 235 // named none of them and the reader is left to guess -- and the guess is always the alarming one here 236 // ("the shard switch broke"), never "a hidden input moved". Measured cost of the compound form: it 237 // failed, and separating my own change from a pre-existing regression was impossible from the verdict 238 // alone. Three named teeth; gv_ctr moves the denominator by itself, which is why the count is not 239 // hand-maintained anywhere. 240 // T16a NEEDS THE WEB SHARD TO EXIST. PROVEN 2026-08-25: under the buildroot build/run CWD there is no 241 // dp-web-pub-manifest at all (nx_shelltool glob over buildroot/knowledge/store: matches=0, 242 // corpus_complete=1 across 12,464 files), so dss_open_maybe_cached gets an empty handle, the serve 243 // takes its DEGRADED path, and the exact "0 result(s)" prose this tooth greps for is never emitted. 244 // The product is behaving correctly -- it cannot search a shard that is not there. The gate simply 245 // COULD NOT LOOK, and "I could not look" must never share a word with "it is broken": that is how a 246 // false RED trains everyone to ignore a real one. gv_need is the estate's third state for exactly 247 // this, so the run reports SKIP -- never a false RED, and never a false pass either. 248 var webshard: i64 = 0 249 let wfd: i64 = sys_openat_rd("knowledge/store/dp-web-pub-manifest.txt" as *u8) 250 if wfd >= 0 { sys_close(wfd); webshard = 1 } 251 if gv_need("T16a precondition: web shard present in this CWD" as *u8, webshard, ctr) == 1 { 252 g_check("T16a scope=web shard ISOLATION (marker term yields 0 results)" as *u8, g_contains(out, n16, "0 result(s)" as *u8), ctr) 253 } 254 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) 255 g_check("T16c form CARRIES scope=web forward" as *u8, g_contains(out, n16, "name=scope value=web" as *u8), ctr) 256 257 // T17: default scope renders the tabs with This-site active 258 let n17: i64 = dss_serve(dom, r1, g_strlen(r1), out) 259 var t17: i64 = 0 260 if g_contains(out, n17, ">This site</a>" as *u8) == 1 { if g_contains(out, n17, ">Web</a>" as *u8) == 1 { t17 = 1 } } 261 g_check("T17 scope tabs render (This site / Web)" as *u8, t17, ctr) 262 263 // ---- API-FIRST surface (versioned JSON; enterprise contract) ---- 264 // T18: /api/search JSON shape -- v1, count, cid AS STRING, escaped title, CORS + content-type headers 265 let ra1: *u8 = "GET /api/search?q=probate&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 266 let na1: i64 = dss_api_search(dom, ra1, g_strlen(ra1), out) 267 var a1: i64 = 0 268 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 } } } } } 269 g_check("T18 /api/search JSON v1 + cid-as-string + CORS" as *u8, a1, ctr) 270 271 // T19: self-describing endpoint (no q -> 200 usage document, still structured) 272 let ra2: *u8 = "GET /api/search HTTP/1.1\r\n\r\n" as *u8 273 let na2: i64 = dss_api_search(dom, ra2, g_strlen(ra2), out) 274 var a2: i64 = 0 275 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 } } 276 g_check("T19 /api/search self-describes without q" as *u8, a2, ctr) 277 278 // T20: /api/doc found -> JSON text; T21: absent -> 404 not_found; T22: malformed -> 400 bad_cid 279 let ra3: *u8 = "GET /api/doc?cid=201&scope=site HTTP/1.1\r\n\r\n" as *u8 280 let na3: i64 = dss_api_doc(dom, ra3, g_strlen(ra3), out) 281 var a3: i64 = 0 282 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 } } } 283 g_check("T20 /api/doc found -> JSON text" as *u8, a3, ctr) 284 let ra4: *u8 = "GET /api/doc?cid=99999 HTTP/1.1\r\n\r\n" as *u8 285 let na4: i64 = dss_api_doc(dom, ra4, g_strlen(ra4), out) 286 var a4: i64 = 0 287 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 } } 288 g_check("T21 /api/doc absent -> 404 not_found" as *u8, a4, ctr) 289 let ra5: *u8 = "GET /api/doc?cid=12abc HTTP/1.1\r\n\r\n" as *u8 290 let na5: i64 = dss_api_doc(dom, ra5, g_strlen(ra5), out) 291 var a5: i64 = 0 292 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 } } 293 g_check("T22 /api/doc malformed -> 400 bad_cid" as *u8, a5, ctr) 294 295 // T23: url row rides the API too (site pages / web results carry their real location) 296 let ra6: *u8 = "GET /api/search?q=expungement&scope=site HTTP/1.1\r\n\r\n" as *u8 297 let na6: i64 = dss_api_search(dom, ra6, g_strlen(ra6), out) 298 g_check("T23 /api/search carries url for page-backed docs" as *u8, g_contains(out, na6, "\"url\":\"/practice/criminal.html\"" as *u8), ctr) 299 300 // ---- MOBILE-FIRST markers (measured mechanically, not vibes) ---- 301 let nm: i64 = dss_serve(dom, r1, g_strlen(r1), out) 302 var mm: i64 = 0 303 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 } } } } 304 g_check("T24 mobile-first markers (16px input, 44px targets, dark scheme, size-adjust lock)" as *u8, mm, ctr) 305 306 // ---- S-CLASS SERP DISPLAY rows (the beat-Google/Bing result-page bar, measured mechanically) ---- 307 // T30 the tab title carries the query (multi-tab usability) 308 let n30: i64 = dss_serve(dom, r1, g_strlen(r1), out) 309 g_check("T30 <title> = query + Nishi Search" as *u8, g_contains(out, n30, "<title>probate &mdash; Nishi Search</title>" as *u8), ctr) 310 // T31 ZERO JavaScript on the whole page (Google's SERP won't even render without JS) 311 var t31: i64 = 0 312 if g_contains(out, n30, "<script" as *u8) == 0 { t31 = 1 } 313 g_check("T31 zero-JS page (no <script anywhere)" as *u8, t31, ctr) 314 // T32 semantic structure + the measured credo footer 315 var t32: i64 = 0 316 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 } } } } } 317 g_check("T32 semantic article/h3/main + credo footer" as *u8, t32, ctr) 318 // T33 measured query latency in the meta line 319 g_check("T33 meta line shows measured ms" as *u8, g_contains(out, n30, " ms</p>" as *u8), ctr) 320 // T34 FEATURED ANSWER: a full-coverage sentence gets the answer panel, highlighted 321 let r34: *u8 = "GET /search?q=probate+inheritance&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 322 let n34: i64 = dss_serve(dom, r34, g_strlen(r34), out) 323 var t34: i64 = 0 324 if g_contains(out, n34, "class=ans" as *u8) == 1 { if g_contains(out, n34, "<b>probate</b>" as *u8) == 1 { t34 = 1 } } 325 g_check("T34 featured-answer panel (full term coverage, highlighted)" as *u8, t34, ctr) 326 // T35 pager: 22 matches -> Next on page 0; Prev + page 2 marker on p=1 327 let r35a: *u8 = "GET /search?q=pgterm&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 328 let n35a: i64 = dss_serve(dom, r35a, g_strlen(r35a), out) 329 var t35: i64 = 0 330 if g_contains(out, n35a, "Next &rarr;" as *u8) == 1 { if g_contains(out, n35a, "&p=1" as *u8) == 1 { 331 let r35b: *u8 = "GET /search?q=pgterm&p=1&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 332 let n35b: i64 = dss_serve(dom, r35b, g_strlen(r35b), out) 333 // Expected total is DERIVED from the same pg_docs the fixture was seeded with, so the count 334 // assertion cannot drift from the fixture the way the literal 22 drifted from DSV_MAXR. 335 // ⚠DOCUMENTED BOUND: this formats exactly two digits, which covers any DSV_MAXR from 8 to 97. 336 // If the cap ever leaves that range this must grow a real integer formatter -- stated here so 337 // the next reader is not surprised by a silently wrong expectation. 338 let expm: *u8 = sys_mmap(32) 339 var xo: i64 = 0 340 let ex1: *u8 = "of " as *u8 341 while ex1[xo] != (0 as u8) { expm[xo] = ex1[xo]; xo = xo + 1 } 342 expm[xo] = (48 + (pg_docs / 10)) as u8; xo = xo + 1 343 expm[xo] = (48 + (pg_docs % 10)) as u8; xo = xo + 1 344 let ex2: *u8 = " matched" as *u8 345 var xj: i64 = 0 346 while ex2[xj] != (0 as u8) { expm[xo] = ex2[xj]; xo = xo + 1; xj = xj + 1 } 347 expm[xo] = 0 as u8 348 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 } } } 349 } } 350 g_check("T35 pager Next/Prev + page marker + total matched" as *u8, t35, ctr) 351 352 // T36 DID-YOU-MEAN: a typo'd query renders the dictionary's correction as a link 353 let r36: *u8 = "GET /search?q=probete&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 354 let n36: i64 = dss_serve(dom, r36, g_strlen(r36), out) 355 var t36: i64 = 0 356 // scope-preserving link again -- the correction keeps the user in the scope they searched 357 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 } } 358 g_check("T36 did-you-mean line (probete -> probate link)" as *u8, t36, ctr) 359 360 // T37 /api/suggest: dictionary completions as versioned JSON 361 let r37: *u8 = "GET /api/suggest?q=prob&scope=site HTTP/1.1\r\n\r\n" as *u8 362 let n37: i64 = dss_api_suggest(dom, r37, g_strlen(r37), out) 363 var t37: i64 = 0 364 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 } } } 365 g_check("T37 /api/suggest JSON completions" as *u8, t37, ctr) 366 367 // T38 /api/search zero-hit carries did_you_mean 368 let r38: *u8 = "GET /api/search?q=probete&scope=site HTTP/1.1\r\n\r\n" as *u8 369 let n38: i64 = dss_api_search(dom, r38, g_strlen(r38), out) 370 var t38: i64 = 0 371 if g_contains(out, n38, "\"nresults\":0" as *u8) == 1 { if g_contains(out, n38, "\"did_you_mean\":\"probate\"" as *u8) == 1 { t38 = 1 } } 372 g_check("T38 /api/search did_you_mean field" as *u8, t38, ctr) 373 374 // T39 +term AND through the serve layer: "probate +custody" -- OR would return BOTH docs; the 375 // required term keeps only the custody-bearing one (distinguishing fixture) 376 let r39: *u8 = "GET /search?q=probate+%2Bcustody&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 377 let n39: i64 = dss_serve(dom, r39, g_strlen(r39), out) 378 var t39: i64 = 0 379 if g_contains(out, n39, "1 result(s)" as *u8) == 1 { if g_contains(out, n39, "Family Law" as *u8) == 1 { t39 = 1 } } 380 g_check("T39 +term AND via serve (OR=2 -> AND=1, custody doc only)" as *u8, t39, ctr) 381 382 // T40/T41 PHRASE through the serve layer: quoted adjacency matches; reversed order does not 383 let r40: *u8 = "GET /search?q=%22living+trusts%22&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 384 let n40: i64 = dss_serve(dom, r40, g_strlen(r40), out) 385 g_check("T40 phrase [living trusts] via serve -> 1 result" as *u8, g_contains(out, n40, "1 result(s)" as *u8), ctr) 386 // scope=site here too: a NEGATIVE that passes only because it queried the wrong shard is not a 387 // negative control at all -- it would report 0 results for a corpus it never searched. 388 let r41: *u8 = "GET /search?q=%22trusts+living%22&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 389 let n41: i64 = dss_serve(dom, r41, g_strlen(r41), out) 390 g_check("T41 NEG reversed phrase -> 0 results" as *u8, g_contains(out, n41, "0 result(s)" as *u8), ctr) 391 // T42 API carries the exactness contract for quoted queries 392 let r42: *u8 = "GET /api/search?q=%22living+trusts%22&scope=site HTTP/1.1\r\n\r\n" as *u8 393 let n42: i64 = dss_api_search(dom, r42, g_strlen(r42), out) 394 var t42: i64 = 0 395 if g_contains(out, n42, "\"phrase_exact\":true" as *u8) == 1 { if g_contains(out, n42, "\"nresults\":1" as *u8) == 1 { t42 = 1 } } 396 g_check("T42 /api/search phrase_exact:true for a quoted query" as *u8, t42, ctr) 397 398 // T43 OpenAPI 3.1 contract: valid structure, all 3 paths, servers names the Host, cid-as-string note 399 let n43: i64 = dss_api_openapi("andelinwest.com" as *u8, out) 400 var t43: i64 = 0 401 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 } } } } } } } 402 g_check("T43 /api/openapi.json valid 3.1 spec (paths+schemas+server+CORS)" as *u8, t43, ctr) 403 // T44 the SERP footer links the API spec (discoverability) 404 let r44: *u8 = "GET /search?q=probate HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 405 let n44: i64 = dss_serve(dom, r44, g_strlen(r44), out) 406 g_check("T44 SERP footer links /api/openapi.json" as *u8, g_contains(out, n44, "href=\"/api/openapi.json\"" as *u8), ctr) 407 408 // T48-T50 THREE SCOPES (operator's 2026-07-04 model): the SERP shows This site / Trusted / Web tabs, 409 // each scope-preserving; the API scope name resolves web/trusted/site. 410 let r48: *u8 = "GET /search?q=probate HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 411 let n48: i64 = dss_serve(dom, r48, g_strlen(r48), out) 412 var t48: i64 = 0 413 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 } } } 414 g_check("T48 three scope tabs (This site / Trusted / Web)" as *u8, t48, ctr) 415 let r49: *u8 = "GET /api/search?q=probate&scope=trusted HTTP/1.1\r\n\r\n" as *u8 416 let n49: i64 = dss_api_search(dom, r49, g_strlen(r49), out) 417 g_check("T49 /api/search scope=trusted -> \"scope\":\"trusted\"" as *u8, g_contains(out, n49, "\"scope\":\"trusted\"" as *u8), ctr) 418 let r50: *u8 = "GET /api/search?q=probate&scope=web HTTP/1.1\r\n\r\n" as *u8 419 let n50: i64 = dss_api_search(dom, r50, g_strlen(r50), out) 420 g_check("T50 /api/search scope=web -> \"scope\":\"web\"" as *u8, g_contains(out, n50, "\"scope\":\"web\"" as *u8), ctr) 421 422 // T45 host FACETS: facterm spans 2 hosts -> the SERP offers one-click site: narrowing 423 let r45: *u8 = "GET /search?q=facterm&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 424 let n45: i64 = dss_serve(dom, r45, g_strlen(r45), out) 425 var t45: i64 = 0 426 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 } } } 427 g_check("T45 SERP host facets (Sites: line + site: links)" as *u8, t45, ctr) 428 // T46 the site: OPERATOR through the serve layer narrows to one host + facet line suppressed 429 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 430 let n46: i64 = dss_serve(dom, r46, g_strlen(r46), out) 431 var t46: i64 = 0 432 if g_contains(out, n46, "1 result(s)" as *u8) == 1 { if g_contains(out, n46, "Sites: " as *u8) == 0 { t46 = 1 } } 433 g_check("T46 site: operator via serve (1 result, facets suppressed)" as *u8, t46, ctr) 434 // T47 API carries the host field 435 let r47: *u8 = "GET /api/search?q=facterm&scope=site HTTP/1.1\r\n\r\n" as *u8 436 let n47: i64 = dss_api_search(dom, r47, g_strlen(r47), out) 437 g_check("T47 /api/search result carries host" as *u8, g_contains(out, n47, "\"host\":\"en.wikipedia.org\"" as *u8), ctr) 438 439 // T7-T9: dsv_host (Host-header -> domain; the daemon's /search route feeds this to dss_serve) 440 let hbuf: *u8 = sys_mmap(256) 441 let rh1: *u8 = "GET /search?q=x HTTP/1.1\r\nHost: andelinwest.com:443\r\n\r\n" as *u8 442 dsv_host(rh1, g_strlen(rh1), hbuf, 255) 443 g_check("T7 host(andelinwest.com,port-stripped)" as *u8, g_streq(hbuf, "andelinwest.com" as *u8), ctr) 444 let rh2: *u8 = "GET / HTTP/1.1\r\nhost: bradrwest.com\r\n\r\n" as *u8 445 dsv_host(rh2, g_strlen(rh2), hbuf, 255) 446 g_check("T8 host(lowercase)" as *u8, g_streq(hbuf, "bradrwest.com" as *u8), ctr) 447 let rh3: *u8 = "GET / HTTP/1.1\r\n\r\n" as *u8 448 dsv_host(rh3, g_strlen(rh3), hbuf, 255) 449 var t9ok: i64 = 0 450 if hbuf[0] == (0 as u8) { t9ok = 1 } 451 g_check("T9 host-absent-empty" as *u8, t9ok, ctr) 452 453 // L2 (2026-09-14): the SERP split into prelude + rest, the early-bytes framing, and the slow probe knob 454 let r50: *u8 = "GET /search?q=facterm&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 455 let n50s: i64 = dss_serve(dom, r50, g_strlen(r50), out) 456 let pq: *u8 = sys_mmap(1024) 457 let pe: *u8 = sys_mmap(256) 458 let pbox: *i64 = sys_mmap(32) as *i64 459 let pqn: i64 = dsv_serp_parse(dom, r50, g_strlen(r50), pq, pe, pbox) 460 let pbody: *u8 = sys_mmap(DSV_BODYCAP) 461 let pb1: i64 = dsv_serp_prelude(pbody, pq, pqn, pbox[1]) 462 let pb2: i64 = dsv_serp_rest(pe, pq, pqn, pbox[1], pbox[2], pbody, pb1, dsv_now_us()) 463 var t50: i64 = 0 464 if g_contains(pbody, pb1, "<form action=/search" as *u8) == 1 { if g_contains(pbody, pb1, "result(s)" as *u8) == 0 { t50 = 1 } } 465 g_check("T50 L2 the prelude carries the page shell and no result line (it goes out before the search)" as *u8, t50, ctr) 466 var t51: i64 = 0 467 if pb2 > pb1 { if g_contains(pbody, pb2, "result(s)" as *u8) == 1 { t51 = 1 } } 468 g_check("T51 L2 the rest carries the results" as *u8, t51, ctr) 469 var t52: i64 = 0 470 var hb: i64 = 0 471 var gh: i64 = 1 472 while gh == 1 { if hb + 4 > n50s { gh = 0 } else { if out[hb] == (13 as u8) { if out[hb+1] == (10 as u8) { if out[hb+2] == (13 as u8) { if out[hb+3] == (10 as u8) { gh = 0 } } } } if gh == 1 { hb = hb + 1 } } } 473 let bs: i64 = hb + 4 474 if bs + pb1 <= n50s { var eq: i64 = 1; var z: i64 = 0; while z < pb1 { if out[bs + z] != pbody[z] { eq = 0; z = pb1 } else { z = z + 1 } } t52 = eq } 475 g_check("T52 L2 dss_serve's page begins with exactly the prelude bytes (the split is a split, not a rewrite)" as *u8, t52, ctr) 476 let eb: *u8 = sys_mmap(DSV_BODYCAP + 4096) 477 let eo: i64 = dsv_respond_early(eb, pbody, pb1) 478 var t53: i64 = 0 479 if g_contains(eb, eo, "HTTP/1.1 200 OK\r\n" as *u8) == 1 { if g_contains(eb, eo, "Transfer-Encoding: chunked\r\n\r\n" as *u8) == 1 { if g_contains(eb, eo, "Content-Length" as *u8) == 0 { t53 = 1 } } } 480 g_check("T53 L2 the early bytes are the real status line and headers, chunked, with no Content-Length" as *u8, t53, ctr) 481 let hx: *u8 = sys_mmap(32) 482 let hxn: i64 = dsv_cathex(hx, 0, pb1) 483 hx[hxn] = 0 as u8 484 let want: *u8 = sys_mmap(64) 485 var wo: i64 = dsv_cat(want, 0, "\r\n\r\n" as *u8) 486 wo = dsv_cat(want, wo, hx) 487 wo = dsv_cat(want, wo, "\r\n" as *u8) 488 want[wo] = 0 as u8 489 g_check("T54 L2 the first chunk announces exactly the prelude's length in hex" as *u8, g_contains(eb, eo, want), ctr) 490 let ce: i64 = dsv_chunk_end(eb, 0) 491 var t55: i64 = 0 492 if ce == 5 { if eb[0] == (48 as u8) { if eb[1] == (13 as u8) { if eb[4] == (10 as u8) { t55 = 1 } } } } 493 g_check("T55 L2 the terminating chunk is 0 CRLF CRLF" as *u8, t55, ctr) 494 let rs: *u8 = "GET /search?q=x&slowms=5000 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 495 g_check("T56 neg-control-slowms-without-its-conf is inert (no visitor can sleep a search process)" as *u8, (dss_serve_slow_ms(rs, g_strlen(rs), "/tmp/nx_dss_gate_no_such.conf" as *u8) == 0) as i64, ctr) 496 let scp: *u8 = "/tmp/nx_dss_gate_slow.conf" as *u8 497 let sfd: i64 = sys_openat_wr(scp, 420) 498 if sfd >= 0 { sys_write(sfd, "1500\n" as *u8, 5); sys_close(sfd) } 499 g_check("T57 L2 slowms is honoured only up to the conf's ceiling (5000 asked, 1500 allowed)" as *u8, (dss_serve_slow_ms(rs, g_strlen(rs), scp) == 1500) as i64, ctr) 500 let rs2: *u8 = "GET /search?q=x&slowms=700 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 501 g_check("T58 L2 slowms under the ceiling passes through (700)" as *u8, (dss_serve_slow_ms(rs2, g_strlen(rs2), scp) == 700) as i64, ctr) 502 sys_unlinkat(scp) 503 504 // T60 (E4 corpus scope): a scope word from the scopes conf keeps only the hits under its url prefix on the 505 // public surface when its row says public; an mcp-only row is NOT honoured here (the default scope answers, 506 // exactly as for an unknown word); no scope keeps both; and the filter's cost is measured under the bar. 507 let sxp: *u8 = "/tmp/nx_dss_gate_scopes.conf" as *u8 508 let sxfd: i64 = sys_openat_wr(sxp, 420) 509 let sxrows: *u8 = "# gate scopes\nfxa|ssgatetest|estate://fxa/|public\nfxb|ssgatetest|estate://fxb/|public\nfxm|ssgatetest|estate://fxa/|mcp\n" as *u8 510 if sxfd >= 0 { sys_write(sxfd, sxrows, g_strlen(sxrows)); sys_close(sxfd) } 511 dsv_scopes_conf_set(sxp) 512 let r60: *u8 = "GET /search?q=scopeterm&scope=fxa HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 513 let n60: i64 = dss_serve(dom, r60, g_strlen(r60), out) 514 let scope_us60: i64 = dss_scope_stats() 515 g_check("T60 a public scope word keeps only the hit under its prefix (1 result, the first)" as *u8, g_contains(out, n60, "1 result(s)" as *u8) * g_contains(out, n60, "first corpus prefix" as *u8), ctr) 516 var leak60: i64 = 0 517 if g_contains(out, n60, "second corpus prefix" as *u8) == 1 { leak60 = 1 } 518 g_check("T60a neg-control-no-cross-scope-leak: the second prefix is absent under the first scope" as *u8, (1 - leak60), ctr) 519 let r60b: *u8 = "GET /search?q=scopeterm&scope=fxb HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 520 let n60b: i64 = dss_serve(dom, r60b, g_strlen(r60b), out) 521 g_check("T60b the other scope word keeps the other hit" as *u8, g_contains(out, n60b, "1 result(s)" as *u8) * g_contains(out, n60b, "second corpus prefix" as *u8), ctr) 522 let r60c: *u8 = "GET /search?q=scopeterm&scope=fxm HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 523 let n60c: i64 = dss_serve(dom, r60c, g_strlen(r60c), out) 524 g_check("T60c neg-control-an-mcp-only-scope-is-not-honoured-on-the-public-surface: the default answers both" as *u8, g_contains(out, n60c, "2 result(s)" as *u8), ctr) 525 let r60d: *u8 = "GET /search?q=scopeterm&scope=site HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 526 let n60d: i64 = dss_serve(dom, r60d, g_strlen(r60d), out) 527 g_check("T60d no corpus scope keeps both hits" as *u8, g_contains(out, n60d, "2 result(s)" as *u8), ctr) 528 g_check("T60e the scope filter's cost is measured and under the ten-millisecond bar" as *u8, ((scope_us60 > 0) as i64) * ((scope_us60 < G_SCOPE_US_BAR) as i64), ctr) 529 let ed60: *u8 = sys_mmap(DSV_PATHCAP) 530 g_check("T60f dsv_scope resolves a public word to CORPUS and an mcp word to the default" as *u8, ((dsv_scope(r60, g_strlen(r60), dom, ed60) == DSV_SCOPE_CORPUS) as i64) * ((dsv_scope(r60c, g_strlen(r60c), dom, ed60) == DSV_SCOPE_SITE) as i64), ctr) 531 sys_unlinkat(sxp) 532 533 // Exit code comes FROM the verdict: /api/gate_run and nx_swcompare_evidence both derive GREEN/RED 534 // from the exit status, so printing a verdict beside a bare `return 0` blesses every failure found. 535 let rc: i64 = gv_verdict("DSSSERVE" as *u8, ctr, "/search + /doc + /api serve contract" as *u8) 536 sys_exit(rc) 537 return rc 538}