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 (<script>), 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(<script)" as *u8, g_contains(out, n5, "<script>" 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 — 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 →" 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, "← 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}