code wiki / _hdl_build / nx_docportal_search_serve.nx
nx_docportal_search_serve.nx source
↩ module page · 1679 lines · 95739 B
1// nx_docportal_search_serve.nx -- R2: the PUBLIC /search serve handler over the SOVEREIGN seg_store search.
2// bytes-in -> bytes-out (no socket -- the gate drives it directly, like dad_handle). Parses GET /search?q=<query>,
3// runs dss_search over the domain's PUBLIC seg_store shard (NO tsv), reads each hit's text (ss_hget) and renders a
4// branded results page with Content-Length (sites.elf's buffered reverse proxy needs the length). A stale/old-
5// format shard (-2) degrades to "0 results", never a 500. license_tier: ORIGINAL
6import "nx_docportal_search_seg.nx"
7import "nx_artifact_root.nx" // ar_resolve/ar_read: the estate's ONE artifact-root resolver (CWD-independent conf lookup)
8import "nx_textcut.nx" // tc_cut_trim/tc_start: NO title ends mid-word, NO snippet begins mid-word
9import "nx_docprose.nx" // dpr_title/dpr_content_start: skip HTTP-capture headers and markup front matter
10
11// Consts for the zero-alloc numeric emitter + timespec buffer; MUST precede their first readers.
12const DSV_ASCII_0: i64 = 48
13const DSV_DEC: i64 = 10
14const DSV_TSBUF: i64 = 16
15
16const DSV_MAGIC_1000000: i64 = 1000000
17const DSV_MAGIC_1024: i64 = 1024
18const DSV_MAGIC_80000: i64 = 80000
19
20const DSV_OUTCAP: i64 = 262144
21const DSV_BODYCAP: i64 = 786432 // uniform per-request body mmap size (>= the largest body 600000); munmap'd every request to kill the leak
22const DSV_MAXR: i64 = 30 // results per page (20->30 2026-07-24: fuller SERPs; the shrunk tf-scan cap keeps it fast)
23const DSV_ENT_FIELD_CAP: i64 = 512 // S11-b: the entity card's jp name and canonical url, copied out of the ranker's table
24const DSV_SNIP: i64 = 240 // chars of a hit's text to show
25// ---- caps that were BARE LITERALS at their cut sites until 2026-08-25 (rule 11). Naming them is not
26// cosmetic here: DSV_TITLE_CAP is the exact number that produced the live "...Database (RE" title, and a
27// reader who could not see it named could not connect the title defect to the snippet defect it caused.
28const DSV_TITLE_CAP: i64 = 72 // bytes of the title line shown
29const DSV_TITLE_FLOOR: i64 = 56 // degenerate fallback when a document has no titled line at all
30const DSV_SENT_MAX: i64 = 320 // hard cap on one "sentence" before dsv_best_sentence gives up looking for . ! ?
31const DSV_SNIPSCAN: i64 = 8000 // head window scanned for the best query-covering sentence
32const DSV_SENT_MIN: i64 = 40 // shortest span that can qualify as a sentence
33const DSV_SENT_MAXNL: i64 = 2 // newlines tolerated inside prose before it reads as a nav blob
34
35func dsv_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
36func dsv_cat(out: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { out[o] = s[i]; o = o + 1; i = i + 1 } return o }
37func dsv_catn(out: *u8, o: i64, v: i64) -> i64 {
38 if v == 0 { out[o] = 48 as u8; return o + 1 }
39 var m: i64 = v
40 if m < 0 { out[o] = 45 as u8; o = o + 1; m = 0 - m }
41 // MSB-FIRST: zero allocation (2026-07-31, debt 1785516350). Byte-identical output.
42 var pw: i64 = 1
43 while m / pw >= DSV_DEC { pw = pw * DSV_DEC }
44 while pw > 0 { out[o] = (DSV_ASCII_0 + ((m / pw) % DSV_DEC)) as u8; o = o + 1; pw = pw / DSV_DEC }
45 return o
46}
47// HTML-escape src[0..n) into out (defensive at the boundary: query echo + doc text are untrusted)
48func dsv_esc(out: *u8, o: i64, src: *u8, n: i64) -> i64 {
49 var i: i64 = 0
50 while i < n {
51 let c: u8 = src[i]
52 if c == (60 as u8) { o = dsv_cat(out, o, "<" as *u8) }
53 else { if c == (62 as u8) { o = dsv_cat(out, o, ">" as *u8) }
54 else { if c == (38 as u8) { o = dsv_cat(out, o, "&" as *u8) }
55 else { if c == (34 as u8) { o = dsv_cat(out, o, """ as *u8) }
56 else { out[o] = c; o = o + 1 } } } }
57 i = i + 1
58 }
59 return o
60}
61func dsv_hexval(c: u8) -> i64 {
62 if c >= (48 as u8) { if c <= (57 as u8) { return (c - (48 as u8)) as i64 } }
63 if c >= (97 as u8) { if c <= (102 as u8) { return ((c - (97 as u8)) as i64) + 10 } }
64 if c >= (65 as u8) { if c <= (70 as u8) { return ((c - (65 as u8)) as i64) + 10 } }
65 return 0 - 1
66}
67// url-decode src[0..n) -> out (cap outcap). %XX -> byte, '+' -> space. Returns out length.
68func dsv_urldecode(src: *u8, n: i64, out: *u8, outcap: i64) -> i64 {
69 var i: i64 = 0
70 var o: i64 = 0
71 while i < n {
72 if o >= outcap { return o }
73 let c: u8 = src[i]
74 if c == (37 as u8) {
75 var handled: i64 = 0
76 if i + 2 < n {
77 let hh: i64 = dsv_hexval(src[i + 1])
78 let ll: i64 = dsv_hexval(src[i + 2])
79 if hh >= 0 { if ll >= 0 { out[o] = (hh * 16 + ll) as u8; o = o + 1; i = i + 3; handled = 1 } }
80 }
81 if handled == 0 { out[o] = c; o = o + 1; i = i + 1 }
82 } else {
83 if c == (43 as u8) { out[o] = 32 as u8 } else { out[o] = c }
84 o = o + 1; i = i + 1
85 }
86 }
87 return o
88}
89// extract query param `name` (nlen chars) from the request line "M <url>?a=b&name=val HTTP/1.1". urldecoded -> out.
90// Returns value length, or 0 if absent.
91func dsv_qparam(req: *u8, req_n: i64, name: *u8, nlen: i64, out: *u8, outcap: i64) -> i64 {
92 var us: i64 = 0 - 1
93 var ue: i64 = req_n
94 var sp: i64 = 0
95 var i: i64 = 0
96 while i < req_n {
97 if req[i] == (32 as u8) {
98 if sp == 0 { us = i + 1; sp = 1 } else { if sp == 1 { ue = i; sp = 2 } }
99 }
100 i = i + 1
101 }
102 if us < 0 { return 0 }
103 var qs: i64 = 0 - 1
104 i = us
105 while i < ue { if req[i] == (63 as u8) { if qs < 0 { qs = i + 1 } } i = i + 1 }
106 if qs < 0 { return 0 }
107 var p: i64 = qs
108 while p < ue {
109 var m: i64 = 1
110 var x: i64 = 0
111 while x < nlen { if (p + x) >= ue { m = 0 } else { if req[p + x] != name[x] { m = 0 } } x = x + 1 }
112 if m == 1 { if (p + nlen) < ue { if req[p + nlen] == (61 as u8) {
113 let vs: i64 = p + nlen + 1
114 var vend: i64 = 0 - 1
115 var ve: i64 = vs
116 while ve < ue { if req[ve] == (38 as u8) { if vend < 0 { vend = ve } } ve = ve + 1 }
117 if vend < 0 { vend = ue }
118 return dsv_urldecode(((req as i64) + vs) as *u8, vend - vs, out, outcap)
119 } } }
120 var adv: i64 = 0 - 1
121 var y: i64 = p
122 while y < ue { if req[y] == (38 as u8) { if adv < 0 { adv = y + 1 } } y = y + 1 }
123 if adv < 0 { p = ue } else { p = adv }
124 }
125 return 0
126}
127// dsv_host: extract the Host header value (the domain) from an HTTP request -> the search shard is dp-<domain>-pub-.
128// Port stripped; empty if absent (search then finds no shard -> graceful "0 results"). Matches "Host:" and "host:".
129func dsv_host(req: *u8, req_n: i64, out: *u8, cap: i64) -> i64 {
130 var i: i64 = 0
131 var hs: i64 = 0 - 1
132 while i + 5 < req_n {
133 if req[i] == (10 as u8) {
134 var hmatch: i64 = 0
135 if req[i + 1] == (72 as u8) { hmatch = 1 }
136 if req[i + 1] == (104 as u8) { hmatch = 1 }
137 if hmatch == 1 { if req[i + 2] == (111 as u8) { if req[i + 3] == (115 as u8) { if req[i + 4] == (116 as u8) { if req[i + 5] == (58 as u8) { hs = i + 6 } } } } }
138 }
139 i = i + 1
140 }
141 if hs < 0 { out[0] = 0 as u8; return 0 }
142 var p: i64 = hs
143 var g1: i64 = 1
144 while g1 == 1 { if p < req_n { if req[p] == (32 as u8) { p = p + 1 } else { g1 = 0 } } else { g1 = 0 } }
145 var o: i64 = 0
146 var g2: i64 = 1
147 while g2 == 1 {
148 if p >= req_n { g2 = 0 } else {
149 let c: u8 = req[p]
150 if c == (13 as u8) { g2 = 0 } else { if c == (10 as u8) { g2 = 0 } else { if c == (58 as u8) { g2 = 0 } else {
151 if o < cap { out[o] = c; o = o + 1 }
152 p = p + 1
153 } } }
154 }
155 }
156 out[o] = 0 as u8
157 return o
158}
159// tokenize the query with the INDEX'S OWN tokenizer (mirrors dss_search's inline block) so highlight
160// decisions align exactly with what matched. termstore = 16x64 bytes; returns nterms.
161func dsv_tokq(q: *u8, qn: i64, termstore: *u8, termptrs: *i64, tbl: *u8) -> i64 {
162 var nterms: i64 = 0
163 let qpos: *i64 = sys_mmap(16) as *i64
164 qpos[0] = 0
165 let tb: *u8 = sys_mmap(64)
166 var qgo: i64 = 1
167 while qgo == 1 {
168 let l: i64 = ss_tok_next2(q, qn, qpos, tb, tbl)
169 if l < 0 { qgo = 0 } else {
170 if nterms < 16 {
171 let dst: *u8 = (termstore as i64 + nterms * 64) as *u8
172 var i: i64 = 0
173 while tb[i] != (0 as u8) { dst[i] = tb[i]; i = i + 1 }
174 dst[i] = 0 as u8
175 termptrs[nterms] = dst as i64
176 nterms = nterms + 1
177 }
178 }
179 }
180 return nterms
181}
182// escape src[0..n) into out while <b>-wrapping every token that matches a query term. Own scanner over the
183// SAME classifier table as the index tokenizer (lowercase alnum runs, len>=2, 32-char compare cap), with
184// explicit run offsets -- so highlights == matches and the raw bytes still pass through dsv_esc (XSS-safe).
185func dsv_hl(out: *u8, o: i64, src: *u8, n: i64, termptrs: *i64, nterms: i64, tbl: *u8) -> i64 {
186 let tok: *u8 = sys_mmap(40)
187 var i: i64 = 0
188 while i < n {
189 let m: i64 = tbl[src[i]] as i64
190 if m == 0 {
191 o = dsv_esc(out, o, ((src as i64) + i) as *u8, 1)
192 i = i + 1
193 } else {
194 var e: i64 = i
195 var l: i64 = 0
196 var run: i64 = 1
197 while run == 1 {
198 if e >= n { run = 0 } else {
199 let c: i64 = tbl[src[e]] as i64
200 if c == 0 { run = 0 } else {
201 if l < 32 { tok[l] = c as u8; l = l + 1 }
202 e = e + 1
203 }
204 }
205 }
206 tok[l] = 0 as u8
207 var hit: i64 = 0
208 if l >= 2 {
209 var t: i64 = 0
210 while t < nterms { if dss_streq(tok, termptrs[t] as *u8) == 1 { hit = 1 } t = t + 1 }
211 }
212 if hit == 1 { o = dsv_cat(out, o, "<b>" as *u8) }
213 o = dsv_esc(out, o, ((src as i64) + i) as *u8, e - i)
214 if hit == 1 { o = dsv_cat(out, o, "</b>" as *u8) }
215 i = e
216 }
217 }
218 return o
219}
220// url-encode src[0..n) -> out (alnum passthrough, else %XX) so a decoded query can ride a result href.
221func dsv_urlenc(out: *u8, o: i64, src: *u8, n: i64) -> i64 {
222 let hex: *u8 = "0123456789ABCDEF" as *u8
223 var i: i64 = 0
224 while i < n {
225 let c: i64 = src[i] as i64
226 var plain: i64 = 0
227 if c >= 48 { if c <= 57 { plain = 1 } }
228 if c >= 97 { if c <= 122 { plain = 1 } }
229 if c >= 65 { if c <= 90 { plain = 1 } }
230 if plain == 1 { out[o] = c as u8; o = o + 1 }
231 else {
232 out[o] = 37 as u8
233 out[o + 1] = hex[(c >> 4) & 15]
234 out[o + 2] = hex[c & 15]
235 o = o + 3
236 }
237 i = i + 1
238 }
239 return o
240}
241// build the source-url key "url:<cid>" -- an ingested SITE PAGE / crawled web page carries the page's real
242// location in this row, so its result links to the PAGE itself instead of the /doc text view.
243// S12: a duration in the reader's units -- seconds under a minute, then minutes, hours, days (integer, the unit that fits)
244const DSV_AGE_MIN: i64 = 60
245const DSV_AGE_HOUR: i64 = 3600
246const DSV_AGE_DAY: i64 = 86400
247func dsv_age(body: *u8, b0: i64, secs: i64) -> i64 {
248 var b: i64 = b0
249 var sv: i64 = secs
250 if sv < 0 { sv = 0 }
251 if sv < DSV_AGE_MIN { b = dsv_catn(body, b, sv); return dsv_cat(body, b, " s" as *u8) }
252 if sv < DSV_AGE_HOUR { b = dsv_catn(body, b, sv / DSV_AGE_MIN); return dsv_cat(body, b, " min" as *u8) }
253 if sv < DSV_AGE_DAY { b = dsv_catn(body, b, sv / DSV_AGE_HOUR); return dsv_cat(body, b, " h" as *u8) }
254 b = dsv_catn(body, b, sv / DSV_AGE_DAY)
255 return dsv_cat(body, b, " d" as *u8)
256}
257func dsv_mkurlkey(cid: i64, out: *u8) -> i64 {
258 out[0] = 117 as u8; out[1] = 114 as u8; out[2] = 108 as u8; out[3] = 58 as u8 // "url:"
259 var o: i64 = 4
260 if cid == 0 { out[o] = 48 as u8; o = o + 1; out[o] = 0 as u8; return o }
261 let t: *u8 = sys_mmap(24)
262 var k: i64 = 0
263 var m: i64 = cid
264 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
265 var j: i64 = 0
266 while j < k { out[o] = t[k - 1 - j]; o = o + 1; j = j + 1 }
267 out[o] = 0 as u8
268 return o
269}
270// render one result: linked title + snippet, query terms <b>-highlighted. Link target: the doc's url:<cid>
271// row when present (a real page), else the /doc?cid text view (q + web scope ride the /doc link).
272// ONE process-lifetime scratch box, replacing sys_mmap-per-call. dsv_result runs once PER RESULT and the
273// old body mmap'd two 16-byte out-boxes every time; sys_mmap rounds up to a PAGE, so a 30-result SERP
274// asked the kernel for 60 pages of scratch it never released. Whether that is a leak or merely repeated
275// waste depends on this daemon's process model, so the claim made here is only the one that is certain:
276// it removes the per-call page allocations. Same defect class as the nx_ts_lumadiff c_num body.
277const DSV_BOXBYTES: i64 = 64
278static dsv_box_g: i64
279func dsv_box() -> *i64 {
280 if dsv_box_g == 0 { dsv_box_g = sys_mmap(DSV_BOXBYTES) as i64 }
281 return dsv_box_g as *i64
282}
283// slot i of a box, as a pointer an out-param can be written through
284func dsv_slot(b: *i64, i: i64) -> *i64 { return ((b as i64) + i * 8) as *i64 }
285
286// Raw source span only: HTML highlighting and JSON escaping remain at their own boundaries.
287func dsv_snippet_span(txt: *u8, tn: i64, title_end: i64, termptrs: *i64, nterms: i64, tbl: *u8, offout: *i64, lenout: *i64, cutbox: *i64) -> i64 {
288 var scanlen: i64 = tn
289 if scanlen > DSV_SNIPSCAN { scanlen = DSV_SNIPSCAN }
290 let matched: i64 = dsv_best_sentence(txt, scanlen, termptrs, nterms, tbl, offout, lenout)
291 if matched == 0 {
292 var start: i64 = tc_start(txt, tn, title_end)
293 if start >= tn { start = tc_skip_ws(txt, tn, 0) }
294 offout[0] = start
295 lenout[0] = tc_cut_trim(((txt as i64) + start) as *u8, tn - start, DSV_SNIP, cutbox)
296 }
297 return matched
298}
299
300func dsv_result(body: *u8, b: i64, txt: *u8, tn: i64, cid: i64, q: *u8, qn: i64, termptrs: *i64, nterms: i64, tbl: *u8, url: *u8, ul: i64, webscope: i64) -> i64 {
301 // ---- TITLE. WAS: "the first non-empty LINE, up to 72 bytes". That comment claimed it avoided nav
302 // chrome, and it did skip blank lines -- but it then served whatever the first line WAS, and on this
303 // corpus that is routinely an HTTP status line or a raw markup tag, because evidence-mirror captures
304 // are indexed with their wire bytes intact. It also cut at a fixed 72 bytes, mid-token.
305 // NOW: nx_docprose steps past capture headers and markup-only front matter, and nx_textcut cuts on a
306 // TOKEN boundary. That second half also repairs the SNIPPET, because the snippet fallback below starts
307 // exactly where the title ended -- one cap, two visible defects.
308 let tbox: *i64 = dsv_box()
309 var ts: i64 = 0
310 var te: i64 = 0
311 if dpr_title(txt, tn, DSV_TITLE_CAP, dsv_slot(tbox, 0), dsv_slot(tbox, 1), dsv_slot(tbox, 2)) == 1 {
312 ts = tbox[0]
313 te = ts + tbox[1]
314 } else {
315 // No titled line in the scan window. Fall back to the document head, STILL cut on a token
316 // boundary: an honest degenerate case, never a fabricated title.
317 ts = tc_skip_ws(txt, tn, 0)
318 te = ts + tc_cut_trim(((txt as i64) + ts) as *u8, tn - ts, DSV_TITLE_FLOOR, dsv_slot(tbox, 2))
319 }
320 if te <= ts { ts = 0; te = tn; if te > DSV_TITLE_FLOOR { te = DSV_TITLE_FLOOR } }
321 // semantic result: <article><h3><a> -- real structure, query terms bolded in the title
322 var o: i64 = dsv_cat(body, b, "<article class=r><h3 class=t><a href=\"" as *u8)
323 if ul > 0 {
324 o = dsv_esc(body, o, url, ul)
325 } else {
326 o = dsv_cat(body, o, "/doc?cid=" as *u8)
327 o = dsv_catn(body, o, cid)
328 if qn > 0 { o = dsv_cat(body, o, "&q=" as *u8); o = dsv_urlenc(body, o, q, qn) }
329 o = dsv_scope_link(body, o, webscope)
330 }
331 o = dsv_cat(body, o, "\">" as *u8)
332 o = dsv_hl(body, o, ((txt as i64) + ts) as *u8, te - ts, termptrs, nterms, tbl)
333 o = dsv_cat(body, o, "</a></h3>" as *u8)
334 if ul > 0 {
335 o = dsv_cat(body, o, "<div class=u>" as *u8)
336 o = dsv_esc(body, o, url, ul)
337 o = dsv_cat(body, o, "</div>" as *u8)
338 }
339 // ---- query-biased SNIPPET (the SOTA fix): show the best query-COVERING sentence (Google/Mojeek style),
340 // NOT the page's leading nav chrome. Fall back to content just past the title only when the query isn't
341 // found in prose. dsv_best_sentence already filters newline-dense nav blobs, so snippets read like content. ----
342 o = dsv_cat(body, o, "<div class=s>" as *u8)
343 let aoff: *i64 = dsv_slot(tbox, 5)
344 let alen: *i64 = dsv_slot(tbox, 6)
345 dsv_snippet_span(txt, tn, te, termptrs, nterms, tbl, aoff, alen, dsv_slot(tbox, 4))
346 o = dsv_hl(body, o, ((txt as i64) + aoff[0]) as *u8, alen[0], termptrs, nterms, tbl)
347 o = dsv_cat(body, o, "</div></article>" as *u8)
348 return o
349}
350// shared page style (search + doc views render as one system). MOBILE-FIRST by measured markers:
351// 16px inputs (iOS never auto-zooms), >=44px touch targets (button + tabs), text-size-adjust locked,
352// prefers-color-scheme dark palette, overflow-wrap on urls -- the serve gate asserts each marker.
353func dsv_style(body: *u8, b: i64) -> i64 {
354 var o: i64 = dsv_cat(body, b, "<style>html{-webkit-text-size-adjust:100%;text-size-adjust:100%}body{font-family:-apple-system,Segoe UI,sans-serif;max-width:680px;margin:3vh auto;padding:0 16px;color:#1c1c1e}header{margin:0 0 1rem}.brand{font-size:1.15rem;font-weight:700;color:#1c1c1e;text-decoration:none;letter-spacing:-.02em}.brand span{color:#0a6}form{display:flex;gap:8px}input[name=q]{flex:1;min-width:0;padding:12px;border:1px solid #ccc;border-radius:10px;font-size:16px}button{min-height:44px;padding:10px 20px;border:0;border-radius:10px;background:#0a6;color:#fff;font-size:16px}.meta{color:#666;font-size:.9rem;margin:1rem 0}.meta a{color:#0a6;text-decoration:none}.tabs{margin:.6rem 0 0}.tabs a{display:inline-block;min-height:44px;line-height:24px;color:#666;text-decoration:none;font-size:.95rem;padding:10px 14px;border-radius:8px}.tabs a.on{background:#e6f6ef;color:#064;font-weight:600}.ans{border:1px solid #bfe8d4;background:#f3fbf7;border-radius:12px;padding:14px 16px;margin:0 0 .4rem}.anstxt{font-size:1.02rem;line-height:1.5}.anssrc{color:#666;font-size:.8rem;margin-top:6px}.r{padding:.9rem 0;border-top:1px solid #eee;margin:0}.t{font-weight:600;font-size:1rem;margin:0}.t a{color:inherit;text-decoration:none}.t a:hover{text-decoration:underline;color:#0a6}.u{color:#0a6;font-size:.82rem;overflow-wrap:anywhere}.s{color:#444;font-size:.94rem}b{background:#e6f6ef}.doc{white-space:pre-wrap;line-height:1.55;overflow-wrap:anywhere}.pager{padding:1rem 0;border-top:1px solid #eee}.pager a{display:inline-block;min-height:44px;line-height:24px;padding:10px 14px;color:#0a6;text-decoration:none;font-weight:600}.credo{color:#8e8e93;font-size:.78rem;padding:1.4rem 0 2rem;border-top:1px solid #eee;margin-top:1rem}" as *u8)
355 o = dsv_cat(body, o, "@media (prefers-color-scheme:dark){body{background:#111214;color:#e8e8ea}.brand{color:#e8e8ea}input[name=q]{background:#1c1c1e;color:#e8e8ea;border-color:#3a3a3c}.s{color:#a8a8ad}.meta{color:#8e8e93}.r,.pager,.credo{border-top-color:#2c2c2e}b{background:#0f3d2e;color:#b7f0d4}.tabs a{color:#a8a8ad}.tabs a.on{background:#0f3d2e;color:#7fd4ae}.t a:hover{color:#3fbf8f}.u{color:#3fbf8f}.meta a{color:#3fbf8f}.ans{background:#12241c;border-color:#1d4a36}.anssrc{color:#8e8e93}.pager a{color:#3fbf8f}}</style>" as *u8)
356 return o
357}
358// JSON string escaper (API-first boundary: title/snippet/text are untrusted bytes -> \" \\ and controls)
359// R-UTF8 (2026-09-04): length of the VALID UTF-8 sequence starting at src[i], or 0 if the bytes there are
360// not valid UTF-8. Rejects stray continuations (0x80-0xBF), the overlong C0/C1 leads, and anything above
361// the U+10FFFF lead (0xF5+), and requires every continuation byte to be 0x80-0xBF. Bounded by n, so a
362// truncated sequence at the tail reports 0 rather than reading past the buffer.
363func dsv_u8seq(src: *u8, n: i64, i: i64) -> i64 {
364 let c: i64 = src[i] as i64
365 if c < 128 { return 1 }
366 if c < 194 { return 0 }
367 var need: i64 = 0
368 if c < 224 { need = 1 } else { if c < 240 { need = 2 } else { if c < 245 { need = 3 } else { need = 0 } } }
369 if need == 0 { return 0 }
370 if i + need > n - 1 { return 0 }
371 var ok: i64 = 1
372 var k: i64 = 1
373 while k <= need {
374 let cc: i64 = src[i + k] as i64
375 if cc < 128 { ok = 0 }
376 if cc > 191 { ok = 0 }
377 k = k + 1
378 }
379 if ok == 0 { return 0 }
380 return need + 1
381}
382func dsv_jesc(out: *u8, o: i64, src: *u8, n: i64) -> i64 {
383 let hex: *u8 = "0123456789abcdef" as *u8
384 var i: i64 = 0
385 while i < n {
386 let c: i64 = src[i] as i64
387 if c == 34 { o = dsv_cat(out, o, "\\\"" as *u8) }
388 else { if c == 92 { o = dsv_cat(out, o, "\\\\" as *u8) }
389 else { if c == 10 { o = dsv_cat(out, o, "\\n" as *u8) }
390 else { if c == 13 { o = dsv_cat(out, o, "\\r" as *u8) }
391 else { if c == 9 { o = dsv_cat(out, o, "\\t" as *u8) }
392 else { if c < 32 {
393 o = dsv_cat(out, o, "\\u00" as *u8)
394 out[o] = hex[(c >> 4) & 15]; o = o + 1
395 out[o] = hex[c & 15]; o = o + 1
396 } else {
397 // R-UTF8 (2026-09-04): EMIT ONLY VALID UTF-8. The old line copied every byte >= 32 verbatim,
398 // so raw Latin-1/CP1252 crawl bytes -- and a gzip magic header stored as a document title --
399 // went straight into a body declared `charset=utf-8`. MEASURED: 3 of 30 sampled queries could
400 // not be decoded by a standards-compliant JSON client at all. A public API must never emit a
401 // document its own Content-Type says is impossible.
402 let sl: i64 = dsv_u8seq(src, n, i)
403 if sl > 0 {
404 // already valid UTF-8 (ASCII included): copy the WHOLE sequence, never split it
405 var z: i64 = 0
406 while z < sl { out[o] = src[i + z]; o = o + 1; z = z + 1 }
407 i = i + (sl - 1)
408 } else { if c > 159 {
409 // invalid UTF-8 in the Latin-1 printable range: the crawler stored an undecoded
410 // ISO-8859-1 / CP1252 page. Transcode it, so "f\xfcr" serves as "fuer"-with-umlaut --
411 // the information is RECOVERED rather than destroyed, and the output is valid UTF-8.
412 out[o] = (192 + (c >> 6)) as u8; o = o + 1
413 out[o] = (128 + (c & 63)) as u8; o = o + 1
414 } else {
415 // a C1 control, or a byte of binary content (a gzip stream indexed as text): there is no
416 // text meaning to recover, so emit U+FFFD REPLACEMENT CHARACTER as raw UTF-8 (EF BF BD).
417 out[o] = 239 as u8; o = o + 1
418 out[o] = 191 as u8; o = o + 1
419 out[o] = 189 as u8; o = o + 1
420 } }
421 } } } } } }
422 i = i + 1
423 }
424 return o
425}
426// wrap a finished JSON body in a response with CORS (a PUBLIC read API any site/app may call)
427// wrap a JSON body + FREE it. EVERY per-request body is mmap'd at DSV_BODYCAP (uniform) so munmap of that
428// size is always exact. This eliminates the ~256-586KB/request leak that forced the daemon to recycle every
429// 5000 requests -- the ~15s respawn gap was the "takes forever" the operator hit (2026-07-03). With the leak
430// gone the daemon runs a high budget without growing RSS. rule 16/21.
431func dsv_respond_json(out: *u8, status: *u8, body: *u8, b: i64) -> i64 {
432 var o: i64 = 0
433 o = dsv_cat(out, o, "HTTP/1.1 " as *u8)
434 o = dsv_cat(out, o, status)
435 o = dsv_cat(out, o, "\r\nContent-Type: application/json; charset=utf-8\r\nAccess-Control-Allow-Origin: *\r\nCache-Control: no-store\r\nConnection: close\r\nContent-Length: " as *u8)
436 o = dsv_catn(out, o, b)
437 o = dsv_cat(out, o, "\r\n\r\n" as *u8)
438 var z: i64 = 0
439 while z < b { out[o] = body[z]; o = o + 1; z = z + 1 }
440 sys_munmap(body, DSV_BODYCAP)
441 return o
442}
443// wrap an HTML body + FREE it (Content-Length for the buffered proxy).
444func dsv_respond(out: *u8, status: *u8, body: *u8, b: i64) -> i64 {
445 var o: i64 = 0
446 o = dsv_cat(out, o, "HTTP/1.1 " as *u8)
447 o = dsv_cat(out, o, status)
448 o = dsv_cat(out, o, "\r\nContent-Type: text/html; charset=utf-8\r\nConnection: close\r\nContent-Length: " as *u8)
449 o = dsv_catn(out, o, b)
450 o = dsv_cat(out, o, "\r\n\r\n" as *u8)
451 var z: i64 = 0
452 while z < b { out[o] = body[z]; o = o + 1; z = z + 1 }
453 sys_munmap(body, DSV_BODYCAP)
454 return o
455}
456// scope resolution: THREE scopes (the operator's model 2026-07-04) -> 0 SITE (this Host domain's own shard),
457// 1 WEB (the broad crawled-everything corpus "web"), 2 TRUSTED (client-flagged good resources "trusted").
458// effdom = the resolved shard name. The return value drives the tabs + all scope-preserving links.
459// THE DEFAULT SEARCH SCOPE IS DATA, NOT A CONSTANT (rules 11 + 17). Measured 2026-08-22: the default was
460// hardcoded `var scope = 1` (WEB) on 2026-07-24 with a rationale naming nishifamily.com ONLY -- but ONE
461// daemon serves every domain, so it silently turned every CLIENT site's own search into an open-web search
462// (andelinwest.com, a law firm: /search?q=probate returned recipe blogs and auction lots, ZERO firm pages).
463// A change justified for one subject was applied to all subjects. Now sourced from search_default_scope.conf.
464const DSV_SCOPE_SITE: i64 = 0
465const DSV_SCOPE_WEB: i64 = 1
466const DSV_SCOPE_TRUSTED: i64 = 2
467const DSV_SCOPE_CONF_CAP: i64 = 4096
468const DSV_PATHCAP: i64 = 1024
469const DSV_CH_LF: i64 = 10
470const DSV_CH_CR: i64 = 13
471const DSV_CH_SP: i64 = 32
472const DSV_CH_HASH: i64 = 35
473static dsv_sc_buf: *u8
474static dsv_sc_n: i64
475static dsv_sc_loaded: i64
476// Loaded ONCE into a static (the conf is config, not per-request state): dsv_scope runs on EVERY request
477// and this file already munmaps its body buffer per request to kill a leak -- an mmap per call here would
478// reintroduce exactly that. Same static-cache shape as nx_artifact_root's own ar_buf/ar_n/ar_loaded.
479func dsv_scope_conf_load() -> i64 {
480 if dsv_sc_loaded == 1 { return dsv_sc_n }
481 dsv_sc_loaded = 1
482 dsv_sc_n = 0
483 dsv_sc_buf = sys_mmap(DSV_SCOPE_CONF_CAP)
484 let p: *u8 = sys_mmap(DSV_PATHCAP)
485 if ar_resolve("knowledge/hosting/search_default_scope.conf" as *u8, p) == 1 {
486 let rn: i64 = ar_read(p, dsv_sc_buf, DSV_SCOPE_CONF_CAP - 1)
487 if rn > 0 { dsv_sc_n = rn }
488 }
489 return dsv_sc_n
490}
491// compare a conf token against a NAMED literal -- never against character codes: a string spelled as
492// numbers is the same defect as a magic number and no grep can find it.
493func dsv_tok_eq(off: i64, len: i64, lit: *u8) -> i64 {
494 if dsv_slen(lit) != len { return 0 }
495 var i: i64 = 0
496 while i < len { if dsv_sc_buf[off+i] != lit[i] { return 0 } i = i + 1 }
497 return 1
498}
499// Rows: "<domain> <site|web|trusted>". A domain with NO row returns SITE deliberately -- the miss
500// direction fails SAFE: a site's own search searching its own site is never harmful, whereas
501// web-by-default publishes unrelated third-party content onto someone else's site.
502func dsv_default_scope(domain: *u8) -> i64 {
503 let n: i64 = dsv_scope_conf_load()
504 if n <= 0 { return DSV_SCOPE_SITE }
505 let dn: i64 = dsv_slen(domain)
506 var ls: i64 = 0
507 var i: i64 = 0
508 while i <= n {
509 var eol: i64 = 0
510 if i == n { eol = 1 } else { if dsv_sc_buf[i] == (DSV_CH_LF as u8) { eol = 1 } }
511 if eol == 1 {
512 var le: i64 = i
513 if le > ls { if dsv_sc_buf[le-1] == (DSV_CH_CR as u8) { le = le - 1 } }
514 if le > ls { if dsv_sc_buf[ls] != (DSV_CH_HASH as u8) {
515 var same: i64 = 1
516 var k: i64 = 0
517 while k < dn {
518 if ls + k >= le { same = 0; k = dn }
519 else { if dsv_sc_buf[ls+k] != domain[k] { same = 0; k = dn } else { k = k + 1 } }
520 }
521 if same == 1 {
522 let vs: i64 = ls + dn + 1
523 if vs < le { if dsv_sc_buf[ls+dn] == (DSV_CH_SP as u8) {
524 let vl: i64 = le - vs
525 if dsv_tok_eq(vs, vl, "web" as *u8) == 1 { return DSV_SCOPE_WEB }
526 if dsv_tok_eq(vs, vl, "site" as *u8) == 1 { return DSV_SCOPE_SITE }
527 if dsv_tok_eq(vs, vl, "trusted" as *u8) == 1 { return DSV_SCOPE_TRUSTED }
528 } }
529 }
530 } }
531 ls = i + 1
532 }
533 i = i + 1
534 }
535 return DSV_SCOPE_SITE
536}
537// E4 CORPUS SCOPES (2026-09-14): knowledge/search_scopes.conf rows word|domain|urlprefix|surface map a scope word to
538// the shard it searches and the url PREFIX every hit must carry (dss_scope_filter in the scorer, the same candidate
539// pipeline as site: and inurl:). surface=public rows may be honoured by this daemon; surface=mcp rows only by the
540// cap-gated estate door (nx_estate_search), so the estate corpus never reaches the public surface -- the E1 boundary
541// as data. Loaded ONCE into a static like the default-scope conf, sized from the file (ss_readall) rather than a cap;
542// a gate points dsv_scopes_conf_set at its own fixture conf.
543const DSV_SCOPE_CORPUS: i64 = 3
544const DSV_SCOPE_WORDCAP: i64 = 32 // a scope word is short; a longer param is no scope (the lookup misses, never truncates a match)
545const DSV_SCOPE_PARAM: *u8 = "scope"
546const DSV_CH_PIPE: i64 = 124
547const DSV_SURFACE_PUBLIC: *u8 = "public"
548static dsv_scx_buf: *u8
549static dsv_scx_n: i64
550static dsv_scx_loaded: i64
551static dsv_scopes_conf_path: *u8
552static dsv_scope_wordbuf: *u8 // the corpus scope word of the current request, NUL-terminated (links, the JSON scope name)
553static dsv_scope_pfxbuf: *u8 // the prefix handed to the scorer; owned here so it outlives the request parse
554func dsv_scopes_conf_set(path: *u8) -> i64 { dsv_scopes_conf_path = path; dsv_scx_loaded = 0; return 0 }
555func dsv_scopes_conf_load() -> i64 {
556 if dsv_scx_loaded == 1 { return dsv_scx_n }
557 dsv_scx_loaded = 1
558 dsv_scx_n = 0
559 let p: *u8 = sys_mmap(DSV_PATHCAP)
560 var have: i64 = 0
561 if (dsv_scopes_conf_path as i64) != 0 {
562 var c: i64 = 0
563 while dsv_scopes_conf_path[c] != (0 as u8) { p[c] = dsv_scopes_conf_path[c]; c = c + 1 }
564 p[c] = 0 as u8
565 have = 1
566 } else { if ar_resolve("knowledge/search_scopes.conf" as *u8, p) == 1 { have = 1 } }
567 if have == 1 {
568 let szp: *i64 = dsv_box()
569 let b: *u8 = ss_readall(p, szp)
570 if szp[0] > 0 { dsv_scx_buf = b; dsv_scx_n = szp[0] }
571 }
572 // the prefix buffer is bounded by the conf itself: no field is longer than the file that holds it
573 dsv_scope_pfxbuf = sys_mmap(dsv_scx_n + 1)
574 dsv_scope_wordbuf = sys_mmap(DSV_SCOPE_WORDCAP)
575 return dsv_scx_n
576}
577func dsv_scx_tok_eq(off: i64, len: i64, lit: *u8) -> i64 {
578 if dsv_slen(lit) != len { return 0 }
579 var i: i64 = 0
580 while i < len { if dsv_scx_buf[off+i] != lit[i] { return 0 } i = i + 1 }
581 return 1
582}
583// a request parameter against a NAMED literal (the old scope parse compared character codes: a string spelled as
584// numbers is the same defect as a magic number and no grep can find it)
585func dsv_word_eq(w: *u8, wn: i64, lit: *u8) -> i64 {
586 if dsv_slen(lit) != wn { return 0 }
587 var i: i64 = 0
588 while i < wn { if w[i] != lit[i] { return 0 } i = i + 1 }
589 return 1
590}
591// the row whose word is w[0..wn): copies its domain into domout and its prefix into pfxout (both NUL-terminated),
592// sets surface_out[0] = 1 for a public row and 0 for an mcp row, returns 1; 0 when no row carries the word
593func dsv_scope_lookup(w: *u8, wn: i64, domout: *u8, pfxout: *u8, surface_out: *i64) -> i64 {
594 let n: i64 = dsv_scopes_conf_load()
595 if n <= 0 { return 0 }
596 var ls: i64 = 0
597 var i: i64 = 0
598 while i <= n {
599 var eol: i64 = 0
600 if i == n { eol = 1 } else { if dsv_scx_buf[i] == (DSV_CH_LF as u8) { eol = 1 } }
601 if eol == 1 {
602 var le: i64 = i
603 if le > ls { if dsv_scx_buf[le-1] == (DSV_CH_CR as u8) { le = le - 1 } }
604 if le > ls { if dsv_scx_buf[ls] != (DSV_CH_HASH as u8) {
605 var f: i64 = 0
606 var fs: i64 = ls
607 var k: i64 = ls
608 var hit: i64 = 0
609 var surf_public: i64 = 0
610 while k <= le {
611 var fend: i64 = 0
612 if k == le { fend = 1 } else { if dsv_scx_buf[k] == (DSV_CH_PIPE as u8) { fend = 1 } }
613 if fend == 1 {
614 let fl: i64 = k - fs
615 if f == 0 { if fl == wn {
616 var same: i64 = 1
617 var m: i64 = 0
618 while m < wn { if dsv_scx_buf[fs + m] != w[m] { same = 0; m = wn } else { m = m + 1 } }
619 if same == 1 { hit = 1 }
620 } }
621 if hit == 1 {
622 if f == 1 { var m1: i64 = 0; while m1 < fl { domout[m1] = dsv_scx_buf[fs + m1]; m1 = m1 + 1 } domout[fl] = 0 as u8 }
623 if f == 2 { var m2: i64 = 0; while m2 < fl { pfxout[m2] = dsv_scx_buf[fs + m2]; m2 = m2 + 1 } pfxout[fl] = 0 as u8 }
624 if f == 3 { surf_public = dsv_scx_tok_eq(fs, fl, DSV_SURFACE_PUBLIC) }
625 }
626 f = f + 1
627 fs = k + 1
628 }
629 k = k + 1
630 }
631 if hit == 1 { if f >= 4 { surface_out[0] = surf_public; return 1 } }
632 } }
633 ls = i + 1
634 }
635 i = i + 1
636 }
637 return 0
638}
639func dsv_scope(req: *u8, req_n: i64, domain: *u8, effdom: *u8) -> i64 {
640 let sc: *u8 = sys_mmap(DSV_SCOPE_WORDCAP)
641 let sn: i64 = dsv_qparam(req, req_n, DSV_SCOPE_PARAM, dsv_slen(DSV_SCOPE_PARAM), sc, DSV_SCOPE_WORDCAP - 1)
642 dss_set_scope_prefix(0 as *u8, 0) // E4: no corpus scope unless a public row below says so -- cleared per request
643 if (dsv_scope_wordbuf as i64) != 0 { dsv_scope_wordbuf[0] = 0 as u8 }
644 var scope: i64 = dsv_default_scope(domain) // PER-DOMAIN default from search_default_scope.conf (2026-08-22).
645 // The hardcoded WEB default was right for nishifamily.com and WRONG for every CLIENT site
646 // this same daemon serves. Explicit ?scope= below still overrides. WAS (2026-07-24): nishifamily.com/search IS a web search engine; the site
647 // corpus + trusted are opt-in tabs. Was 0/site -> users landed on a tiny site-search and
648 // never saw the CC/entity web index or any ranking work. Explicit ?scope=site selects site.
649 // the three built-in words, compared against NAMED literals (they were character codes until 2026-09-14)
650 if dsv_word_eq(sc, sn, "site" as *u8) == 1 { scope = DSV_SCOPE_SITE }
651 if dsv_word_eq(sc, sn, "web" as *u8) == 1 { scope = DSV_SCOPE_WEB }
652 if dsv_word_eq(sc, sn, "trusted" as *u8) == 1 { scope = DSV_SCOPE_TRUSTED }
653 if scope == DSV_SCOPE_WEB {
654 let wn0: *u8 = "web" as *u8
655 var wi: i64 = 0
656 while wn0[wi] != (0 as u8) { effdom[wi] = wn0[wi]; wi = wi + 1 }
657 effdom[wi] = 0 as u8
658 return DSV_SCOPE_WEB
659 }
660 if scope == DSV_SCOPE_TRUSTED {
661 let tn0: *u8 = "trusted" as *u8
662 var t: i64 = 0
663 while tn0[t] != (0 as u8) { effdom[t] = tn0[t]; t = t + 1 }
664 effdom[t] = 0 as u8
665 return DSV_SCOPE_TRUSTED
666 }
667 // E4: a corpus scope word from knowledge/search_scopes.conf, honoured on this surface only when its row says
668 // public; an mcp-only word falls through to the domain's default exactly as an unknown word does (no leak, no error)
669 if sn > 0 {
670 let surf: *i64 = dsv_box()
671 dsv_scopes_conf_load()
672 if dsv_scope_lookup(sc, sn, effdom, dsv_scope_pfxbuf, surf) == 1 { if surf[0] == 1 {
673 var wc: i64 = 0
674 while wc < sn { dsv_scope_wordbuf[wc] = sc[wc]; wc = wc + 1 }
675 dsv_scope_wordbuf[wc] = 0 as u8
676 dss_set_scope_prefix(dsv_scope_pfxbuf, dsv_slen(dsv_scope_pfxbuf))
677 return DSV_SCOPE_CORPUS
678 } }
679 }
680 var i: i64 = 0
681 while domain[i] != (0 as u8) { effdom[i] = domain[i]; i = i + 1 }
682 effdom[i] = 0 as u8
683 return DSV_SCOPE_SITE
684}
685// append the scope-preserving query param for a link (nothing for site, &scope=web, &scope=trusted)
686func dsv_scope_link(body: *u8, b: i64, scope: i64) -> i64 {
687 if scope == DSV_SCOPE_CORPUS { if (dsv_scope_wordbuf as i64) != 0 { let o: i64 = dsv_cat(body, b, "&scope=" as *u8); return dsv_cat(body, o, dsv_scope_wordbuf) } }
688 if scope == 1 { return dsv_cat(body, b, "&scope=web" as *u8) }
689 if scope == 2 { return dsv_cat(body, b, "&scope=trusted" as *u8) }
690 return dsv_cat(body, b, "&scope=site" as *u8) // web is the default now -> site links MUST be explicit
691}
692// the JSON scope name (site/web/trusted)
693func dsv_scope_name(body: *u8, b: i64, scope: i64) -> i64 {
694 if scope == DSV_SCOPE_CORPUS { if (dsv_scope_wordbuf as i64) != 0 { return dsv_cat(body, b, dsv_scope_wordbuf) } }
695 if scope == 1 { return dsv_cat(body, b, "web" as *u8) }
696 if scope == 2 { return dsv_cat(body, b, "trusted" as *u8) }
697 return dsv_cat(body, b, "site" as *u8)
698}
699// the scope tabs: [This site] [Trusted] [Web] -- each preserves the current query, active one highlighted
700func dsv_tabs(body: *u8, b: i64, q: *u8, qn: i64, scope: i64) -> i64 {
701 var o: i64 = dsv_cat(body, b, "<p class=tabs><a " as *u8)
702 if scope == 1 { o = dsv_cat(body, o, "class=on " as *u8) }
703 o = dsv_cat(body, o, "href=\"/search?scope=web" as *u8)
704 if qn > 0 { o = dsv_cat(body, o, "&q=" as *u8); o = dsv_urlenc(body, o, q, qn) }
705 o = dsv_cat(body, o, "\">Web</a> <a " as *u8)
706 if scope == 0 { o = dsv_cat(body, o, "class=on " as *u8) }
707 o = dsv_cat(body, o, "href=\"/search?scope=site" as *u8)
708 if qn > 0 { o = dsv_cat(body, o, "&q=" as *u8); o = dsv_urlenc(body, o, q, qn) }
709 o = dsv_cat(body, o, "\">This site</a> <a " as *u8)
710 if scope == 2 { o = dsv_cat(body, o, "class=on " as *u8) }
711 o = dsv_cat(body, o, "href=\"/search?scope=trusted" as *u8)
712 if qn > 0 { o = dsv_cat(body, o, "&q=" as *u8); o = dsv_urlenc(body, o, q, qn) }
713 o = dsv_cat(body, o, "\">Trusted</a></p>" as *u8)
714 return o
715}
716// monotonic microseconds (integer; the SERP shows real measured query latency like the big engines --
717// except ours is TRUE per-request wall time, not a cached estimate)
718func dsv_now_us() -> i64 {
719 let ts: *i64 = sys_mmap(DSV_TSBUF) as *i64
720 sys_clock_gettime_mono(ts)
721 // read BOTH fields out before releasing -- computing after the munmap would be a use-after-free.
722 let sec: i64 = ts[0]
723 let nsec: i64 = ts[1]
724 sys_munmap(ts as *u8, DSV_TSBUF)
725 return sec * DSV_MAGIC_1000000 + nsec / 1000
726}
727// FEATURED ANSWER (our own featured-snippet, extracted not asserted): scan the text's sentences
728// (. ! ? boundaries; 40..320 bytes) and return the one matching the MOST distinct query terms via the
729// index's own tokenizer. offout/lenout = the winning sentence; returns distinct terms matched (0 = none).
730func dsv_best_sentence(txt: *u8, tn: i64, termptrs: *i64, nterms: i64, tbl: *u8, offout: *i64, lenout: *i64) -> i64 {
731 let tok: *u8 = sys_mmap(40)
732 var best: i64 = 0
733 offout[0] = 0
734 lenout[0] = 0
735 var s: i64 = 0
736 while s < tn {
737 // sentence end: next . ! ? or hard cap
738 var e: i64 = s
739 var run: i64 = 1
740 while run == 1 {
741 if e >= tn { run = 0 } else {
742 let c: i64 = txt[e] as i64
743 if c == 46 { run = 0 } else { if c == 33 { run = 0 } else { if c == 63 { run = 0 } else {
744 if e - s >= DSV_SENT_MAX { run = 0 } else { e = e + 1 }
745 } } }
746 }
747 }
748 let slen: i64 = e - s
749 // PROSE filter: extracted-page nav chrome ("Jump to content\nMain menu\n...") arrives as newline-
750 // dense blobs between real periods -- a genuine sentence carries at most a stray wrap. >2 newlines
751 // = not prose, never an answer (the okapi live catch, 2026-07-03).
752 var nlcount: i64 = 0
753 var nz: i64 = s
754 while nz < e { if txt[nz] == (10 as u8) { nlcount = nlcount + 1 } nz = nz + 1 }
755 if slen >= DSV_SENT_MIN { if nlcount <= DSV_SENT_MAXNL {
756 // count distinct query terms present in [s, e)
757 var matched: i64 = 0
758 var t: i64 = 0
759 while t < nterms {
760 var hit: i64 = 0
761 var i: i64 = s
762 while i < e {
763 let m: i64 = tbl[txt[i]] as i64
764 if m == 0 { i = i + 1 } else {
765 var e2: i64 = i
766 var l: i64 = 0
767 var r2: i64 = 1
768 while r2 == 1 {
769 if e2 >= e { r2 = 0 } else {
770 let c2: i64 = tbl[txt[e2]] as i64
771 if c2 == 0 { r2 = 0 } else {
772 if l < 32 { tok[l] = c2 as u8; l = l + 1 }
773 e2 = e2 + 1
774 }
775 }
776 }
777 tok[l] = 0 as u8
778 if l >= 2 { if dss_streq(tok, termptrs[t] as *u8) == 1 { hit = 1; i = e } }
779 if i < e { i = e2 }
780 }
781 }
782 matched = matched + hit
783 t = t + 1
784 }
785 if matched > best {
786 best = matched
787 offout[0] = s
788 lenout[0] = slen
789 }
790 } }
791 s = e + 1
792 }
793 // ---- NORMALISE BOTH ENDS OF THE CHOSEN SPAN (2026-08-25). The segmentation above ends a sentence at
794 // . ! ? OR at DSV_SENT_MAX, and that second arm cuts MID-TOKEN -- so the FOLLOWING span begins mid-word.
795 // That is how a live snippet came to read "FPROP) Version 9", and another "dia, the free encyclopedia".
796 // Repairing the segmenter alone would not be enough: whichever span WINS must be sound at both ends, so
797 // it is normalised once here rather than at each of the three call sites (result snippet, featured
798 // answer, JSON api) -- one fix, and no call site can forget it.
799 if best > 0 {
800 let s0: i64 = tc_start(txt, tn, offout[0])
801 var l0: i64 = (offout[0] + lenout[0]) - s0
802 if l0 < 0 { l0 = 0 }
803 // cap = l0 measured against the REAL remaining length (tn - s0), which is what makes tc_cut walk
804 // the END back to a boundary instead of returning the span unchanged.
805 offout[0] = s0
806 lenout[0] = tc_cut_trim(((txt as i64) + s0) as *u8, tn - s0, l0, dsv_slot(dsv_box(), 3))
807 }
808 return best
809}
810// THE SERVE: (domain, request bytes) -> branded HTTP results page bytes into out. Returns out length.
811// ---- THE SERP IN TWO HALVES (search L2, 2026-09-14). The PRELUDE is everything the page shows before the results
812// (doctype, style, header, form, tabs) and none of it depends on the search; the REST is the search and everything
813// after it. dss_serve composes both into the Content-Length page its 49-tooth gate drives, byte for byte as before;
814// the daemon's early-bytes path (dad_serve_early) emits the prelude on the wire BEFORE the search runs, so the edge's
815// per-read window restarts on real bytes and a slow query is a slow page instead of a 503.
816func dsv_serp_parse(domain: *u8, req: *u8, req_n: i64, q: *u8, effdom: *u8, box: *i64) -> i64 {
817 let qn: i64 = dsv_qparam(req, req_n, "q" as *u8, 1, q, 1023)
818 let webscope: i64 = dsv_scope(req, req_n, domain, effdom)
819 // page param (digits; junk -> page 0)
820 let pbuf: *u8 = sys_mmap(32)
821 let pbn: i64 = dsv_qparam(req, req_n, "p" as *u8, 1, pbuf, 15)
822 let pok: *i64 = sys_mmap(16) as *i64
823 var page: i64 = dsv_atoin(pbuf, pbn, pok)
824 if pok[0] == 0 { page = 0 }
825 if page > 25 { page = 25 }
826 box[0] = qn
827 box[1] = webscope
828 box[2] = page
829 return qn
830}
831func dsv_serp_prelude(body: *u8, q: *u8, qn: i64, webscope: i64) -> i64 {
832 var b: i64 = 0
833 b = dsv_cat(body, b, "<!DOCTYPE html><meta charset=utf-8><meta name=viewport content=\"width=device-width,initial-scale=1\"><title>" as *u8)
834 if qn > 0 { b = dsv_esc(body, b, q, qn); b = dsv_cat(body, b, " — " as *u8) }
835 b = dsv_cat(body, b, "Nishi Search</title>" as *u8)
836 b = dsv_style(body, b)
837 b = dsv_cat(body, b, "<header><a class=brand href=\"/search\">Nishi<span>Search</span></a></header><main>" as *u8)
838 b = dsv_cat(body, b, "<form action=/search method=get role=search>" as *u8)
839 if webscope == 1 { b = dsv_cat(body, b, "<input type=hidden name=scope value=web>" as *u8) }
840 if webscope == 2 { b = dsv_cat(body, b, "<input type=hidden name=scope value=trusted>" as *u8) }
841 b = dsv_cat(body, b, "<input name=q value=\"" as *u8)
842 b = dsv_esc(body, b, q, qn)
843 b = dsv_cat(body, b, "\" placeholder=\"Search\" autofocus aria-label=\"Search query\"><button>Search</button></form>" as *u8)
844 b = dsv_tabs(body, b, q, qn, webscope)
845 return b
846}
847func dsv_serp_rest(effdom: *u8, q: *u8, qn: i64, webscope: i64, page: i64, body: *u8, b0: i64, t0: i64) -> i64 {
848 let cids: *i64 = sys_mmap(DSV_MAXR * 8) as *i64
849 let scores: *i64 = sys_mmap(DSV_MAXR * 8) as *i64
850 let totalbox: *i64 = sys_mmap(16) as *i64
851 var nres: i64 = 0
852 if qn > 0 { nres = dss_search_off(effdom, q, qn, cids, scores, DSV_MAXR, page * DSV_MAXR, totalbox) }
853 if nres < 0 { nres = 0 }
854 let total: i64 = totalbox[0]
855 let qus: i64 = dsv_now_us() - t0
856 // INDEX-UNAVAILABLE MARKER (2026-08-22). Web scope + zero results + no/empty cached web handle => say
857 // "index unavailable" instead of "0 result(s)". nres==0 is in the predicate ON PURPOSE: dss_search_off can
858 // answer from the shared query memo without opening anything in this child, so a memo hit carries results
859 // while dsc_handle is still NULL -- a "withheld" header over a rendered list would be a lie. Site/trusted
860 // shards open per request and are not cached: 0 there means nothing published, and "0 result(s)" stays true.
861 var idxdown: i64 = 0
862 if webscope == 1 { if nres == 0 { if dss_web_index_segments() <= 0 { idxdown = 1 } } }
863 // query terms + classifier table, once per request: dsv_result highlights with the index's own tokens
864 let tbl: *u8 = sys_mmap(272)
865 ss_tok_table(tbl)
866 let termstore: *u8 = sys_mmap(16 * 64)
867 let termptrs: *i64 = sys_mmap(16 * 8) as *i64
868 var nterms: i64 = 0
869 if qn > 0 { nterms = dsv_tokq(q, qn, termstore, termptrs, tbl) }
870 var b: i64 = b0
871 if qn == 0 {
872 b = dsv_cat(body, b, "<p class=meta>Enter a search term.</p>" as *u8)
873 } else {
874 if idxdown == 1 { b = dsv_cat(body, b, "<p class=meta><b>index unavailable — results withheld</b> for “" as *u8) } else { b = dsv_cat(body, b, "<p class=meta>" as *u8); b = dsv_catn(body, b, nres); b = dsv_cat(body, b, " result(s) for “" as *u8) }
875 b = dsv_esc(body, b, q, qn); b = dsv_cat(body, b, "”" as *u8)
876 // SAY WHEN THE TOTAL IS AN ESTIMATE (2026-08-25). Once candidacy saturates at DSS_MAXCAND the
877 // total stops being an enumeration and becomes a df-derived LOWER BOUND -- and it was printed in
878 // byte-identical form to an exact count, so "of 372317 matched" read as more precise than the
879 // "of 201 matched" beside it when it was strictly less so. "about" is the whole fix: it costs five
880 // characters and it stops the page asserting a precision the engine never had.
881 if total > nres {
882 b = dsv_cat(body, b, " of " as *u8)
883 if dss_last_estimated() == 1 { b = dsv_cat(body, b, "about " as *u8) }
884 b = dsv_catn(body, b, total)
885 b = dsv_cat(body, b, " matched" as *u8)
886 }
887 if page > 0 { b = dsv_cat(body, b, " · page " as *u8); b = dsv_catn(body, b, page + 1) }
888 b = dsv_cat(body, b, " · " as *u8)
889 if qus < 1000 { b = dsv_cat(body, b, "<1" as *u8) } else { b = dsv_catn(body, b, qus / 1000) }
890 b = dsv_cat(body, b, " ms" as *u8)
891 if totalbox[1] == 0 { b = dsv_cat(body, b, " · phrase matched loosely (index upgrading)" as *u8) }
892 b = dsv_cat(body, b, "</p>" as *u8)
893 // S11-b ENTITY CARD (2026-09-17): when the query's canonical page is pinned first, the page says so above the
894 // results -- the resolved name, the canonical page and its title count, from the served entity table.
895 let ecs: *i64 = sys_mmap(8 * DSS_ENT_BOX_SLOTS) as *i64
896 dss_entity_stats(ecs)
897 if ecs[0] == 1 {
898 let cjp: *u8 = sys_mmap(DSV_ENT_FIELD_CAP)
899 let curl: *u8 = sys_mmap(DSV_ENT_FIELD_CAP)
900 let cjn: i64 = dss_entity_field(DSS_ENT_FIELD_JP, cjp, DSV_ENT_FIELD_CAP)
901 let cun: i64 = dss_entity_field(DSS_ENT_FIELD_URL, curl, DSV_ENT_FIELD_CAP)
902 b = dsv_cat(body, b, "<p class=meta id=entity><b>Entity:</b> " as *u8)
903 if cjn > 0 { b = dsv_esc(body, b, cjp, cjn) } else { b = dsv_esc(body, b, q, qn) }
904 if cun > 0 {
905 b = dsv_cat(body, b, " · canonical page <a href=\"" as *u8)
906 b = dsv_esc(body, b, curl, cun)
907 b = dsv_cat(body, b, "\">" as *u8)
908 b = dsv_esc(body, b, curl, cun)
909 b = dsv_cat(body, b, "</a>" as *u8)
910 }
911 let ctt: i64 = dss_entity_titles()
912 if ctt > 0 { b = dsv_cat(body, b, " · " as *u8); b = dsv_catn(body, b, ctt); b = dsv_cat(body, b, " titles" as *u8) }
913 b = dsv_cat(body, b, " · resolved by the entity dossier and pinned first</p>" as *u8)
914 }
915 // ★COVERAGE HONESTY (operator 2026-07-04: "we dont want partial results thinking we return full
916 // results"): the web scope is NISHI'S OWN INDEX (our crawl + Common Crawl), NOT the whole live web.
917 // This line appears on EVERY web result set so N results is never mistaken for "all the web has".
918 if webscope == 1 { b = dsv_cat(body, b, "<p class=meta style=\"color:#666;font-size:.85rem\">Scope: Nishi’s own index (our crawl + Common Crawl) — not the whole live web. Some sites block all automated crawlers (anti-bot walls), so their pages may be absent here even though we never filter lawful content.</p>" as *u8) }
919 // DID-YOU-MEAN (search rung F4, 2026-09-18): offered on EVERY answer when a word of the query is rare in the index
920 // and a one-edit neighbour of it is common (dss_spell_suggest); a query that finds nothing and is offered nothing
921 // there still asks the zero-hit two-edit corrector (dss_correct), exactly as before. Text and a link: zero JS.
922 let fix: *u8 = sys_mmap(DSV_MAGIC_1024)
923 var fl: i64 = dss_spell_suggest(effdom, q, qn, fix, 1023)
924 if fl <= 0 { if nres == 0 { fl = dss_correct(effdom, q, qn, fix, 1023) } }
925 if fl > 0 {
926 b = dsv_cat(body, b, "<p class=meta>Did you mean <a href=\"/search?q=" as *u8)
927 b = dsv_urlenc(body, b, fix, fl)
928 b = dsv_scope_link(body, b, webscope)
929 b = dsv_cat(body, b, "\"><b>" as *u8)
930 b = dsv_esc(body, b, fix, fl)
931 b = dsv_cat(body, b, "</b></a>?</p>" as *u8)
932 }
933 if nres == 0 {
934 // HONEST scope empty states: our "web" is a sovereign crawl (a bounded index), NOT the live
935 // internet; "trusted" is the client-curated good-resources set (small by design).
936 if webscope == 1 { b = dsv_cat(body, b, "<p class=meta>The Web tab searches Nishi’s own sovereign crawl — a growing index of pages we’ve fetched, not the whole live internet. Try a broad topic, or search <a href=\"/search?q=" as *u8); b = dsv_urlenc(body, b, q, qn); b = dsv_cat(body, b, "\">this site</a>.</p>" as *u8) }
937 if webscope == 2 { b = dsv_cat(body, b, "<p class=meta>The Trusted tab searches resources clients have flagged as good references. Nothing matched yet — try the <a href=\"/search?scope=web&q=" as *u8); b = dsv_urlenc(body, b, q, qn); b = dsv_cat(body, b, "\">Web</a> tab.</p>" as *u8) }
938 }
939 let prefix: *u8 = sys_mmap(512); dss_prefix(effdom, prefix)
940 let h: *i64 = dss_open_maybe_cached(prefix)
941 let key: *u8 = sys_mmap(64)
942 let ukey: *u8 = sys_mmap(64)
943 let dptr: *i64 = sys_mmap(16) as *i64; let dlen: *i64 = sys_mmap(16) as *i64
944 let uptr: *i64 = sys_mmap(16) as *i64; let ulen2: *i64 = sys_mmap(16) as *i64
945 // host FACET accumulator (the faceted rung): distinct hosts among this page's results
946 let fhosts: *u8 = sys_mmap(256 * 12)
947 let fcnt: *i64 = sys_mmap(8 * 12) as *i64
948 var nfh: i64 = 0
949 let hbuf: *u8 = sys_mmap(256)
950 // S12 FRESHNESS CARD (2026-09-17): every result knows when its bytes were fetched, so the page says how old they are
951 let fea: *i64 = sys_mmap(8 * DSS_FRESH_MAX) as *i64
952 var fen: i64 = nres
953 if fen > DSS_FRESH_MAX { fen = DSS_FRESH_MAX }
954 var fi: i64 = 0
955 while fi < fen { fea[fi] = dss_doc_fetch_epoch(h, cids[fi]); fi = fi + 1 }
956 let fst: *i64 = sys_mmap(8 * DSS_FRESH_SLOTS) as *i64
957 let fnow: i64 = sys_now_realtime_sec()
958 dss_fresh_stats(fea, fen, fnow, fst)
959 if nres > 0 {
960 b = dsv_cat(body, b, "<p class=meta id=fresh><b>Freshness:</b> " as *u8)
961 if fst[0] > 0 {
962 b = dsv_cat(body, b, "newest result fetched " as *u8)
963 b = dsv_age(body, b, fnow - fst[1])
964 b = dsv_cat(body, b, " ago · median age of these results " as *u8)
965 b = dsv_age(body, b, fst[2])
966 b = dsv_cat(body, b, " · " as *u8)
967 b = dsv_catn(body, b, fst[0]); b = dsv_cat(body, b, " of " as *u8); b = dsv_catn(body, b, fen)
968 b = dsv_cat(body, b, " carry a fetch time" as *u8)
969 } else {
970 b = dsv_cat(body, b, "no result on this page carries a fetch time yet (indexed before the fetch epoch was stored beside the doc)" as *u8)
971 }
972 b = dsv_cat(body, b, "</p>" as *u8)
973 }
974 var i: i64 = 0
975 while i < nres {
976 dss_mkkey(cids[i], key)
977 if (h as i64) != 0 { if ss_hget(h, key, dptr, dlen) == 1 {
978 dsv_mkurlkey(cids[i], ukey)
979 var up: i64 = 0
980 var ul: i64 = 0
981 if ss_hget(h, ukey, uptr, ulen2) == 1 { up = uptr[0]; ul = ulen2[0] }
982 if ul > 0 {
983 let hl9: i64 = dss_url_host(up as *u8, ul, hbuf)
984 if hl9 > 0 {
985 var ff: i64 = 0 - 1
986 var fz: i64 = 0
987 while fz < nfh {
988 let fp9: *u8 = (fhosts as i64 + fz * 256) as *u8
989 var feq: i64 = 1
990 var fx: i64 = 0
991 var fgo: i64 = 1
992 while fgo == 1 { if fp9[fx] != hbuf[fx] { feq = 0; fgo = 0 } else { if hbuf[fx] == (0 as u8) { fgo = 0 } else { fx = fx + 1 } } }
993 if feq == 1 { ff = fz; fz = nfh } else { fz = fz + 1 }
994 }
995 if ff >= 0 { fcnt[ff] = fcnt[ff] + 1 } else { if nfh < 12 {
996 let fd9: *u8 = (fhosts as i64 + nfh * 256) as *u8
997 var fc9: i64 = 0
998 var fgo2: i64 = 1
999 while fgo2 == 1 { fd9[fc9] = hbuf[fc9]; if hbuf[fc9] == (0 as u8) { fgo2 = 0 } else { fc9 = fc9 + 1 } }
1000 fcnt[nfh] = 1
1001 nfh = nfh + 1
1002 } }
1003 }
1004 }
1005 // FEATURED ANSWER on the top hit of page 0: the best sentence, only when it actually
1006 // covers the query (all terms, or 2+ of a multi-term query) -- extracted, never asserted
1007 if i == 0 { if page == 0 {
1008 let aoff: *i64 = sys_mmap(16) as *i64
1009 let alen: *i64 = sys_mmap(16) as *i64
1010 let am: i64 = dsv_best_sentence(dptr[0] as *u8, dlen[0], termptrs, nterms, tbl, aoff, alen)
1011 var show: i64 = 0
1012 if am >= nterms { if nterms > 0 { show = 1 } }
1013 if nterms >= 3 { if am >= 2 { show = 1 } }
1014 if show == 1 {
1015 b = dsv_cat(body, b, "<div class=ans><div class=anstxt>" as *u8)
1016 b = dsv_hl(body, b, ((dptr[0] as i64) + aoff[0]) as *u8, alen[0], termptrs, nterms, tbl)
1017 b = dsv_cat(body, b, "</div><div class=anssrc>from the top result below</div></div>" as *u8)
1018 }
1019 } }
1020 b = dsv_result(body, b, dptr[0] as *u8, dlen[0], cids[i], q, qn, termptrs, nterms, tbl, up as *u8, ul, webscope)
1021 } }
1022 i = i + 1
1023 }
1024 // host FACETS (zero-JS): when this page's results span 2+ sites, offer one-click site: narrowing.
1025 // Skipped when the query already carries a site: clause (narrowing twice is noise).
1026 var hassite: i64 = 0
1027 var hz: i64 = 0
1028 while hz + 5 <= qn {
1029 if q[hz] == (115 as u8) { if q[hz+1] == (105 as u8) { if q[hz+2] == (116 as u8) { if q[hz+3] == (101 as u8) { if q[hz+4] == (58 as u8) { hassite = 1 } } } } }
1030 hz = hz + 1
1031 }
1032 if nfh >= 2 { if hassite == 0 {
1033 b = dsv_cat(body, b, "<p class=meta>Sites: " as *u8)
1034 // top 4 hosts by count (selection)
1035 let fused: *i64 = sys_mmap(8 * 12) as *i64
1036 var fu: i64 = 0
1037 while fu < nfh { fused[fu] = 0; fu = fu + 1 }
1038 var fshown: i64 = 0
1039 var frank: i64 = 0
1040 while frank < 4 {
1041 var fbest: i64 = 0 - 1
1042 var fk: i64 = 0
1043 while fk < nfh {
1044 if fused[fk] == 0 { if fbest < 0 { fbest = fk } else { if fcnt[fk] > fcnt[fbest] { fbest = fk } } }
1045 fk = fk + 1
1046 }
1047 if fbest < 0 { frank = 4 } else {
1048 fused[fbest] = 1
1049 let fh9: *u8 = (fhosts as i64 + fbest * 256) as *u8
1050 if fshown > 0 { b = dsv_cat(body, b, " · " as *u8) }
1051 b = dsv_cat(body, b, "<a href=\"/search?q=" as *u8)
1052 b = dsv_urlenc(body, b, q, qn)
1053 b = dsv_cat(body, b, "+site%3A" as *u8)
1054 b = dsv_cat(body, b, fh9)
1055 b = dsv_scope_link(body, b, webscope)
1056 b = dsv_cat(body, b, "\">" as *u8)
1057 b = dsv_cat(body, b, fh9)
1058 b = dsv_cat(body, b, "</a> (" as *u8)
1059 b = dsv_catn(body, b, fcnt[fbest])
1060 b = dsv_cat(body, b, ")" as *u8)
1061 fshown = fshown + 1
1062 frank = frank + 1
1063 }
1064 }
1065 b = dsv_cat(body, b, "</p>" as *u8)
1066 } }
1067 // pager: Prev when past page 0; Next while ranked matches remain (total is the truth)
1068 if qn > 0 { if total > DSV_MAXR {
1069 b = dsv_cat(body, b, "<nav class=pager>" as *u8)
1070 if page > 0 {
1071 b = dsv_cat(body, b, "<a href=\"/search?q=" as *u8)
1072 b = dsv_urlenc(body, b, q, qn)
1073 b = dsv_scope_link(body, b, webscope)
1074 b = dsv_cat(body, b, "&p=" as *u8); b = dsv_catn(body, b, page - 1)
1075 b = dsv_cat(body, b, "\">← Prev</a> " as *u8)
1076 }
1077 if (page + 1) * DSV_MAXR < total {
1078 b = dsv_cat(body, b, "<a href=\"/search?q=" as *u8)
1079 b = dsv_urlenc(body, b, q, qn)
1080 b = dsv_scope_link(body, b, webscope)
1081 b = dsv_cat(body, b, "&p=" as *u8); b = dsv_catn(body, b, page + 1)
1082 b = dsv_cat(body, b, "\">Next →</a>" as *u8)
1083 }
1084 b = dsv_cat(body, b, "</nav>" as *u8)
1085 } }
1086 }
1087 // the credo footer: MEASURED page facts the big engines cannot print (their SERPs ship megabytes of
1088 // script and ad/tracker payloads; this page is what it says it is)
1089 b = dsv_cat(body, b, "</main><footer class=credo>~" as *u8)
1090 b = dsv_catn(body, b, (b + 400 + 1023) / DSV_MAGIC_1024)
1091 b = dsv_cat(body, b, " KB · 0 JavaScript · 0 ads · 0 trackers · sovereign nishi search · <a href=\"/api/openapi.json\">API</a></footer></body></html>" as *u8)
1092 return b
1093}
1094// the Content-Length page, byte for byte as before the split: the prelude, then the search and the rest
1095func dss_serve(domain: *u8, req: *u8, req_n: i64, out: *u8) -> i64 {
1096 let t0: i64 = dsv_now_us()
1097 let q: *u8 = sys_mmap(DSV_MAGIC_1024)
1098 let effdom: *u8 = sys_mmap(256)
1099 let box: *i64 = sys_mmap(32) as *i64
1100 let qn: i64 = dsv_serp_parse(domain, req, req_n, q, effdom, box)
1101 let body: *u8 = sys_mmap(DSV_BODYCAP)
1102 var b: i64 = dsv_serp_prelude(body, q, qn, box[1])
1103 b = dsv_serp_rest(effdom, q, qn, box[1], box[2], body, b, t0)
1104 return dsv_respond(out, "200 OK" as *u8, body, b)
1105}
1106// ---- EARLY-BYTES FRAMING (L2). The length is unknown when the status line goes out, so the body is chunked: the head
1107// carries the REAL status line and headers plus the prelude as the first chunk, dsv_chunk frames every later piece,
1108// dsv_chunk_end closes the body. Pure bytes-out, so the gate drives them without a socket.
1109const DSV_HEX_BASE: i64 = 16
1110const DSV_HEX_ALPHA_GAP: i64 = 87 // 'a' minus 10, so the digits 10..15 render as a..f
1111const DSV_DIGIT0: i64 = 48
1112const DSV_DIGIT9: i64 = 57
1113func dsv_cathex(out: *u8, o: i64, v: i64) -> i64 {
1114 let t: *u8 = sys_mmap(32)
1115 var m: i64 = v
1116 var k: i64 = 0
1117 if m == 0 { t[0] = DSV_DIGIT0 as u8; k = 1 }
1118 while m > 0 { let d: i64 = m % DSV_HEX_BASE; if d < 10 { t[k] = (DSV_DIGIT0 + d) as u8 } else { t[k] = (DSV_HEX_ALPHA_GAP + d) as u8 } m = m / DSV_HEX_BASE; k = k + 1 }
1119 var oo: i64 = o
1120 var i: i64 = 0
1121 while i < k { out[oo] = t[k - 1 - i]; oo = oo + 1; i = i + 1 }
1122 sys_munmap(t, 32)
1123 return oo
1124}
1125func dsv_chunk(out: *u8, o0: i64, body: *u8, s: i64, e: i64) -> i64 {
1126 if e <= s { return o0 }
1127 var o: i64 = dsv_cathex(out, o0, e - s)
1128 o = dsv_cat(out, o, "\r\n" as *u8)
1129 var z: i64 = s
1130 while z < e { out[o] = body[z]; o = o + 1; z = z + 1 }
1131 o = dsv_cat(out, o, "\r\n" as *u8)
1132 return o
1133}
1134func dsv_chunk_end(out: *u8, o0: i64) -> i64 { return dsv_cat(out, o0, "0\r\n\r\n" as *u8) }
1135func dsv_respond_early(out: *u8, body: *u8, b: i64) -> i64 {
1136 var o: i64 = dsv_cat(out, 0, "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n" as *u8)
1137 o = dsv_chunk(out, o, body, 0, b)
1138 return o
1139}
1140// THE SLOW PROBE KNOB (L2 done-rule: a deliberately slowed backend must not 503 at the edge). slowms= on a request is
1141// honoured ONLY while the conf at confpath exists and carries a ceiling in ms; without the conf the parameter is inert,
1142// so no visitor can sleep a search process. The gate plants its own conf under /tmp; production carries none.
1143func dss_serve_slow_ms(req: *u8, req_n: i64, confpath: *u8) -> i64 {
1144 let sb: *u8 = sys_mmap(32)
1145 let sn: i64 = dsv_qparam(req, req_n, "slowms" as *u8, 6, sb, 15) // 6 = the name's length (the gate caught a 1 here: the knob read nothing and stayed inert)
1146 if sn <= 0 { return 0 }
1147 let ok: *i64 = sys_mmap(16) as *i64
1148 let want: i64 = dsv_atoin(sb, sn, ok)
1149 if ok[0] == 0 { return 0 }
1150 let nb: *i64 = sys_mmap(16) as *i64
1151 let cf: *u8 = sys_read_file(confpath, nb)
1152 if (cf as i64) == 0 { return 0 }
1153 var mx: i64 = 0
1154 var any: i64 = 0
1155 var i: i64 = 0
1156 while i < nb[0] {
1157 let c: i64 = cf[i] as i64
1158 if c >= DSV_DIGIT0 { if c <= DSV_DIGIT9 { mx = mx * 10 + (c - DSV_DIGIT0); any = 1; i = i + 1 } else { i = nb[0] } } else { i = nb[0] }
1159 }
1160 if any == 0 { return 0 }
1161 if want > mx { return mx }
1162 return want
1163}
1164
1165// digits-only parse of s[0..n); okbox[0]=1 iff every byte was a digit and n>0 (defensive: a cid is ONLY digits)
1166func dsv_atoin(s: *u8, n: i64, okbox: *i64) -> i64 {
1167 okbox[0] = 0
1168 if n <= 0 { return 0 }
1169 if n > 19 { return 0 }
1170 var v: i64 = 0
1171 var i: i64 = 0
1172 while i < n {
1173 let c: i64 = s[i] as i64
1174 if c < 48 { return 0 }
1175 if c > 57 { return 0 }
1176 v = v * 10 + (c - 48)
1177 i = i + 1
1178 }
1179 okbox[0] = 1
1180 return v
1181}
1182// /doc?cid=<cid>[&q=<query>] -- the PUBLIC document view that completes the search loop (result -> readable
1183// doc). Serves ONLY the -pub- shard (dss_prefix); the -prv- shard is physically never opened. Visibility is
1184// the owner's public/private choice at upload; the SEARCH flag governs indexing consent, not public
1185// readability, so /doc serves any public doc by cid. q (if present) re-highlights + links back to results.
1186func dsv_doc_serve(domain: *u8, req: *u8, req_n: i64, out: *u8) -> i64 {
1187 let tbl: *u8 = sys_mmap(272)
1188 ss_tok_table(tbl)
1189 let q: *u8 = sys_mmap(DSV_MAGIC_1024)
1190 let qn: i64 = dsv_qparam(req, req_n, "q" as *u8, 1, q, 1023)
1191 let effdom: *u8 = sys_mmap(256)
1192 let webscope: i64 = dsv_scope(req, req_n, domain, effdom)
1193 let termstore: *u8 = sys_mmap(16 * 64)
1194 let termptrs: *i64 = sys_mmap(16 * 8) as *i64
1195 var nterms: i64 = 0
1196 if qn > 0 { nterms = dsv_tokq(q, qn, termstore, termptrs, tbl) }
1197 let cidbuf: *u8 = sys_mmap(64)
1198 let cn: i64 = dsv_qparam(req, req_n, "cid" as *u8, 3, cidbuf, 31)
1199 let okbox: *i64 = sys_mmap(16) as *i64
1200 let cid: i64 = dsv_atoin(cidbuf, cn, okbox)
1201 var found: i64 = 0
1202 let dptr: *i64 = sys_mmap(16) as *i64
1203 let dlen: *i64 = sys_mmap(16) as *i64
1204 if okbox[0] == 1 {
1205 let prefix: *u8 = sys_mmap(512); dss_prefix(effdom, prefix)
1206 let h: *i64 = dss_open_maybe_cached(prefix)
1207 if (h as i64) != 0 {
1208 let key: *u8 = sys_mmap(64); dss_mkkey(cid, key)
1209 if ss_hget(h, key, dptr, dlen) == 1 { found = 1 }
1210 }
1211 }
1212 let body: *u8 = sys_mmap(DSV_BODYCAP)
1213 var b: i64 = 0
1214 b = dsv_cat(body, b, "<!DOCTYPE html><meta charset=utf-8><meta name=viewport content=\"width=device-width,initial-scale=1\"><title>Document</title>" as *u8)
1215 b = dsv_style(body, b)
1216 b = dsv_cat(body, b, "<p class=meta><a href=\"/search" as *u8)
1217 if qn > 0 { b = dsv_cat(body, b, "?q=" as *u8); b = dsv_urlenc(body, b, q, qn) }
1218 if webscope == 1 {
1219 if qn > 0 { b = dsv_cat(body, b, "&scope=web" as *u8) } else { b = dsv_cat(body, b, "?scope=web" as *u8) }
1220 }
1221 b = dsv_cat(body, b, "\">← " as *u8)
1222 if qn > 0 { b = dsv_cat(body, b, "Back to results" as *u8) } else { b = dsv_cat(body, b, "Search" as *u8) }
1223 b = dsv_cat(body, b, "</a></p>" as *u8)
1224 if found == 0 {
1225 b = dsv_cat(body, b, "<div class=t>Document not found</div><p class=s>No public document has that id.</p></body></html>" as *u8)
1226 return dsv_respond(out, "404 Not Found" as *u8, body, b)
1227 }
1228 let txt: *u8 = dptr[0] as *u8
1229 var tn: i64 = dlen[0]
1230 // bounded BY CONSTRUCTION: html-escape expands up to 6x ("""), and the daemon's out buffer is
1231 // 512KB -- 80000 * 6 + page chrome stays safely inside it. Longer docs render truncated, marked.
1232 var trunc: i64 = 0
1233 if tn > DSV_MAGIC_80000 { tn = DSV_MAGIC_80000; trunc = 1 }
1234 // title = the same leading-sentence rule the results page uses
1235 var dot: i64 = 0 - 1
1236 var i: i64 = 0
1237 while i < tn { if i < 80 { if txt[i] == (46 as u8) { if dot < 0 { dot = i } } } i = i + 1 }
1238 var tt: i64 = dot
1239 if tt < 0 { tt = 56 }
1240 if tt > tn { tt = tn }
1241 b = dsv_cat(body, b, "<div class=t>" as *u8)
1242 b = dsv_hl(body, b, txt, tt, termptrs, nterms, tbl)
1243 b = dsv_cat(body, b, "</div><p class=\"s doc\">" as *u8)
1244 if tt < tn { b = dsv_hl(body, b, ((txt as i64) + tt) as *u8, tn - tt, termptrs, nterms, tbl) }
1245 if trunc == 1 { b = dsv_cat(body, b, " … [truncated]" as *u8) }
1246 b = dsv_cat(body, b, "</p></body></html>" as *u8)
1247 return dsv_respond(out, "200 OK" as *u8, body, b)
1248}
1249
1250// ================= API-FIRST SURFACE (versioned JSON; the HTML SERP is just one client) =================
1251// GET /api/openapi.json -> the machine-readable OpenAPI 3.1 contract for the search API (enterprise-grade:
1252// client codegen, Swagger UI, contract testing all consume this). CORS-open like the data endpoints. The
1253// spec is generated in code (SSOT = this file) so it can never drift from the handlers. `srv` = the Host
1254// so the served spec names the caller's own domain in the servers[] block.
1255func dss_api_openapi(srv: *u8, out: *u8) -> i64 {
1256 let body: *u8 = sys_mmap(DSV_BODYCAP)
1257 var b: i64 = 0
1258 b = dsv_cat(body, b, "{\"openapi\":\"3.1.0\",\"info\":{\"title\":\"Nishi Search API\",\"version\":\"1.0.0\",\"description\":\"Sovereign full-text search: a domain's docs + site pages, the nishi library, and the crawled open web. Integer BM25 (b=0.75), stemmed recall, phrase/boolean queries, did-you-mean. Zero third-party dependencies.\",\"x-notes\":\"cid is a STRING: 63-bit content ids exceed JSON 2^53 safe-integer range.\"}," as *u8)
1259 b = dsv_cat(body, b, "\"servers\":[{\"url\":\"https://" as *u8)
1260 b = dsv_jesc(body, b, srv, dsv_slen(srv))
1261 b = dsv_cat(body, b, "\"}]," as *u8)
1262 b = dsv_cat(body, b, "\"paths\":{" as *u8)
1263 // /api/search
1264 b = dsv_cat(body, b, "\"/api/search\":{\"get\":{\"operationId\":\"search\",\"summary\":\"Ranked full-text search\",\"parameters\":[" as *u8)
1265 b = dsv_cat(body, b, "{\"name\":\"q\",\"in\":\"query\",\"required\":true,\"schema\":{\"type\":\"string\"},\"description\":\"Query. Supports OR (default), +required, -excluded, \\\"quoted phrase\\\", and site:host field scoping (dot-suffix match); terms are stemmed for recall.\"}," as *u8)
1266 b = dsv_cat(body, b, "{\"name\":\"scope\",\"in\":\"query\",\"required\":false,\"schema\":{\"type\":\"string\",\"enum\":[\"web\",\"trusted\"]},\"description\":\"web = the broad crawled open-web corpus; trusted = resources clients flagged as good references; omit = this site's own corpus.\"}," as *u8)
1267 b = dsv_cat(body, b, "{\"name\":\"page\",\"in\":\"query\",\"required\":false,\"schema\":{\"type\":\"integer\",\"minimum\":0},\"description\":\"0-based results page, 20 per page.\"}]," as *u8)
1268 b = dsv_cat(body, b, "\"responses\":{\"200\":{\"description\":\"Ranked results\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/SearchResponse\"}}}}}}}," as *u8)
1269 // /api/doc
1270 b = dsv_cat(body, b, "\"/api/doc\":{\"get\":{\"operationId\":\"getDoc\",\"summary\":\"Fetch a document by content id\",\"parameters\":[" as *u8)
1271 b = dsv_cat(body, b, "{\"name\":\"cid\",\"in\":\"query\",\"required\":true,\"schema\":{\"type\":\"string\"},\"description\":\"Decimal content id (string).\"}," as *u8)
1272 b = dsv_cat(body, b, "{\"name\":\"scope\",\"in\":\"query\",\"required\":false,\"schema\":{\"type\":\"string\",\"enum\":[\"web\"]}}]," as *u8)
1273 b = dsv_cat(body, b, "\"responses\":{\"200\":{\"description\":\"The document\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/Doc\"}}}},\"400\":{\"description\":\"bad_cid\"},\"404\":{\"description\":\"not_found\"}}}}," as *u8)
1274 // /api/suggest
1275 b = dsv_cat(body, b, "\"/api/suggest\":{\"get\":{\"operationId\":\"suggest\",\"summary\":\"Autocomplete term completions\",\"parameters\":[" as *u8)
1276 b = dsv_cat(body, b, "{\"name\":\"q\",\"in\":\"query\",\"required\":true,\"schema\":{\"type\":\"string\"},\"description\":\"Term prefix.\"}," as *u8)
1277 b = dsv_cat(body, b, "{\"name\":\"scope\",\"in\":\"query\",\"required\":false,\"schema\":{\"type\":\"string\",\"enum\":[\"web\"]}}]," as *u8)
1278 b = dsv_cat(body, b, "\"responses\":{\"200\":{\"description\":\"Completions\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/components/schemas/Suggest\"}}}}}}}" as *u8)
1279 b = dsv_cat(body, b, "}," as *u8)
1280 // components
1281 b = dsv_cat(body, b, "\"components\":{\"schemas\":{" as *u8)
1282 b = dsv_cat(body, b, "\"Result\":{\"type\":\"object\",\"properties\":{\"cid\":{\"type\":\"string\"},\"score\":{\"type\":\"integer\"},\"title\":{\"type\":\"string\"},\"snippet\":{\"type\":\"string\"},\"doc\":{\"type\":\"string\"},\"url\":{\"type\":\"string\"},\"host\":{\"type\":\"string\"}},\"required\":[\"cid\",\"score\",\"title\"]}," as *u8)
1283 b = dsv_cat(body, b, "\"SearchResponse\":{\"type\":\"object\",\"properties\":{\"v\":{\"type\":\"integer\"},\"query\":{\"type\":\"string\"},\"scope\":{\"type\":\"string\"},\"page\":{\"type\":\"integer\"},\"total\":{\"type\":\"integer\"},\"nresults\":{\"type\":\"integer\"},\"did_you_mean\":{\"type\":\"string\"},\"phrase_exact\":{\"type\":\"boolean\"},\"results\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/components/schemas/Result\"}}},\"required\":[\"v\",\"nresults\",\"results\"]}," as *u8)
1284 b = dsv_cat(body, b, "\"Doc\":{\"type\":\"object\",\"properties\":{\"v\":{\"type\":\"integer\"},\"found\":{\"type\":\"boolean\"},\"cid\":{\"type\":\"string\"},\"url\":{\"type\":\"string\"},\"truncated\":{\"type\":\"boolean\"},\"text\":{\"type\":\"string\"}}}," as *u8)
1285 b = dsv_cat(body, b, "\"Suggest\":{\"type\":\"object\",\"properties\":{\"v\":{\"type\":\"integer\"},\"prefix\":{\"type\":\"string\"},\"suggestions\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}}" as *u8)
1286 b = dsv_cat(body, b, "}}}" as *u8)
1287 return dsv_respond_json(out, "200 OK" as *u8, body, b)
1288}
1289// GET /api/search?q=<terms>[&scope=web] -> {"v":1,"query","scope","nresults","results":[{cid,score,title,
1290// snippet,doc[,url]}]}. cid is a STRING on purpose (63-bit content ids exceed JSON's 2^53 safe-integer
1291// range -- an enterprise client must never receive a silently-rounded id). No q -> a 200 self-describing
1292// usage document (the endpoint documents itself); structured errors carry machine-readable codes (rule 6).
1293func dss_api_search(domain: *u8, req: *u8, req_n: i64, out: *u8) -> i64 {
1294 let q: *u8 = sys_mmap(DSV_MAGIC_1024)
1295 let qn: i64 = dsv_qparam(req, req_n, "q" as *u8, 1, q, 1023)
1296 let effdom: *u8 = sys_mmap(256)
1297 let webscope: i64 = dsv_scope(req, req_n, domain, effdom)
1298 let body: *u8 = sys_mmap(DSV_BODYCAP)
1299 var b: i64 = 0
1300 if qn == 0 {
1301 b = dsv_cat(body, b, "{\"v\":1,\"endpoint\":\"/api/search\",\"params\":{\"q\":\"required: search terms\",\"scope\":\"optional: web = the sovereign-crawled open-web corpus; default = this site's corpus\",\"page\":\"optional: 0-based results page (20/page)\"},\"results_cap\":20,\"doc_endpoint\":\"/api/doc?cid=<cid>[&scope=web]\"}" as *u8)
1302 return dsv_respond_json(out, "200 OK" as *u8, body, b)
1303 }
1304 let pgbuf: *u8 = sys_mmap(32)
1305 let pgn: i64 = dsv_qparam(req, req_n, "page" as *u8, 4, pgbuf, 15)
1306 let pgok: *i64 = sys_mmap(16) as *i64
1307 var page: i64 = dsv_atoin(pgbuf, pgn, pgok)
1308 if pgok[0] == 0 { page = 0 }
1309 if page > 25 { page = 25 }
1310 let cids: *i64 = sys_mmap(DSV_MAXR * 8) as *i64
1311 let scores: *i64 = sys_mmap(DSV_MAXR * 8) as *i64
1312 let totalbox: *i64 = sys_mmap(16) as *i64
1313 let rc: i64 = dss_search_off(effdom, q, qn, cids, scores, DSV_MAXR, page * DSV_MAXR, totalbox)
1314 var nres: i64 = rc
1315 if nres < 0 { nres = 0 }
1316 b = dsv_cat(body, b, "{\"v\":1,\"query\":\"" as *u8)
1317 b = dsv_jesc(body, b, q, qn)
1318 b = dsv_cat(body, b, "\",\"scope\":\"" as *u8)
1319 b = dsv_scope_name(body, b, webscope)
1320 b = dsv_cat(body, b, "\",\"page\":" as *u8)
1321 b = dsv_catn(body, b, page)
1322 b = dsv_cat(body, b, ",\"total\":" as *u8)
1323 b = dsv_catn(body, b, totalbox[0])
1324 // ADDITIVE contract field (rule 19: adding is safe, renaming is not). A machine consumer had no way
1325 // to know that `total` silently changes meaning from an exact enumeration to a df-derived LOWER BOUND
1326 // once candidacy saturates -- so any client computing pagination or coverage from it was doing
1327 // arithmetic on an estimate it believed was a count.
1328 b = dsv_cat(body, b, ",\"total_is_estimate\":" as *u8)
1329 if dss_last_estimated() == 1 { b = dsv_cat(body, b, "true" as *u8) } else { b = dsv_cat(body, b, "false" as *u8) }
1330 b = dsv_cat(body, b, ",\"nresults\":" as *u8)
1331 b = dsv_catn(body, b, nres)
1332 if rc == (0 - 2) { b = dsv_cat(body, b, ",\"degraded\":true" as *u8) }
1333 if totalbox[1] != 2 {
1334 b = dsv_cat(body, b, ",\"phrase_exact\":" as *u8)
1335 if totalbox[1] == 1 { b = dsv_cat(body, b, "true" as *u8) } else { b = dsv_cat(body, b, "false" as *u8) }
1336 }
1337 // DID-YOU-MEAN (search rung F4, 2026-09-18): did_you_mean is now offered on any answer, not only an empty one
1338 // (ADDITIVE, rule 19: the field keeps its name and its meaning -- a suggested query -- and simply appears more often).
1339 // The spell object announces how the answer was reached, on EVERY answer: which path answered (edit1 =
1340 // dss_spell_suggest, zero_hit = the incumbent two-edit corrector, none), the live document count and the df at which a
1341 // word counts as common (the midpoint of the ranker's idf scale), the words examined, how many were rare, the one-edit
1342 // lookups they cost and how many of those the dictionary held, the words replaced, the df of the last rare word and of
1343 // its commonest neighbour, whether it abstained, the microseconds of the one-edit path (us) and of the whole phase
1344 // including any zero-hit fallback (phase_us).
1345 let sp_t0: i64 = dsv_now_us()
1346 let fixj: *u8 = sys_mmap(DSV_MAGIC_1024)
1347 var flj: i64 = dss_spell_suggest(effdom, q, qn, fixj, 1023)
1348 let spj: *i64 = sys_mmap(8 * DYM_ST_SLOTS) as *i64
1349 dss_spell_stats(spj)
1350 var spsrc: *u8 = "none" as *u8
1351 if flj > 0 { spsrc = "edit1" as *u8 }
1352 if flj <= 0 { if nres == 0 {
1353 flj = dss_correct(effdom, q, qn, fixj, 1023)
1354 if flj > 0 { spsrc = "zero_hit" as *u8 }
1355 } }
1356 let sp_us: i64 = dsv_now_us() - sp_t0
1357 if flj > 0 {
1358 b = dsv_cat(body, b, ",\"did_you_mean\":\"" as *u8)
1359 b = dsv_jesc(body, b, fixj, flj)
1360 b = dsv_cat(body, b, "\"" as *u8)
1361 }
1362 b = dsv_cat(body, b, ",\"spell\":{\"source\":\"" as *u8)
1363 b = dsv_cat(body, b, spsrc)
1364 b = dsv_cat(body, b, "\",\"docs\":" as *u8)
1365 b = dsv_catn(body, b, spj[DYM_ST_DOCS])
1366 b = dsv_cat(body, b, ",\"common_df\":" as *u8)
1367 b = dsv_catn(body, b, spj[DYM_ST_MID])
1368 b = dsv_cat(body, b, ",\"words\":" as *u8)
1369 b = dsv_catn(body, b, spj[DYM_ST_WORDS])
1370 b = dsv_cat(body, b, ",\"rare\":" as *u8)
1371 b = dsv_catn(body, b, spj[DYM_ST_RARE])
1372 b = dsv_cat(body, b, ",\"lookups\":" as *u8)
1373 b = dsv_catn(body, b, spj[DYM_ST_LOOKUPS])
1374 b = dsv_cat(body, b, ",\"held\":" as *u8)
1375 b = dsv_catn(body, b, spj[DYM_ST_HELD])
1376 b = dsv_cat(body, b, ",\"fixed\":" as *u8)
1377 b = dsv_catn(body, b, spj[DYM_ST_FIXED])
1378 b = dsv_cat(body, b, ",\"typed_df\":" as *u8)
1379 b = dsv_catn(body, b, spj[DYM_ST_TDF])
1380 b = dsv_cat(body, b, ",\"neighbour_df\":" as *u8)
1381 b = dsv_catn(body, b, spj[DYM_ST_CDF])
1382 b = dsv_cat(body, b, ",\"abstain\":" as *u8)
1383 b = dsv_catn(body, b, spj[DYM_ST_ABSTAIN])
1384 b = dsv_cat(body, b, ",\"us\":" as *u8)
1385 b = dsv_catn(body, b, spj[DYM_ST_US])
1386 b = dsv_cat(body, b, ",\"phase_us\":" as *u8)
1387 b = dsv_catn(body, b, sp_us)
1388 b = dsv_cat(body, b, "}" as *u8)
1389 // COVERAGE HONESTY (operator 2026-07-04): the web scope is our own index, NOT the whole web -- the
1390 // machine-readable contract flag so a client never treats partial coverage as complete.
1391 if webscope == 1 { b = dsv_cat(body, b, ",\"coverage\":{\"index\":\"nishi\",\"complete\":false,\"note\":\"Nishi's own index (crawl + Common Crawl); not the whole live web. Some sites block all crawlers; lawful content is never filtered.\"}" as *u8) }
1392 b = dsv_cat(body, b, ",\"results\":[" as *u8)
1393 let prefix: *u8 = sys_mmap(512); dss_prefix(effdom, prefix)
1394 let h: *i64 = dss_open_maybe_cached(prefix)
1395 let key: *u8 = sys_mmap(64)
1396 let ukey: *u8 = sys_mmap(64)
1397 let dptr: *i64 = sys_mmap(16) as *i64; let dlen: *i64 = sys_mmap(16) as *i64
1398 let uptr: *i64 = sys_mmap(16) as *i64; let ulen2: *i64 = sys_mmap(16) as *i64
1399 let snip_tbl: *u8 = sys_mmap(272)
1400 ss_tok_table(snip_tbl)
1401 let snip_terms: *u8 = sys_mmap(DSS_MAXTERMS * 64)
1402 let snip_ptrs: *i64 = sys_mmap(DSS_MAXTERMS * 8) as *i64
1403 let snip_nterms: i64 = dsv_tokq(q, qn, snip_terms, snip_ptrs, snip_tbl)
1404 var emitted: i64 = 0
1405 var i: i64 = 0
1406 while i < nres {
1407 dss_mkkey(cids[i], key)
1408 if (h as i64) != 0 { if ss_hget(h, key, dptr, dlen) == 1 {
1409 if emitted > 0 { b = dsv_cat(body, b, "," as *u8) }
1410 emitted = emitted + 1
1411 let txt: *u8 = dptr[0] as *u8
1412 let dn2: i64 = dlen[0]
1413 // ONE TITLE RULER FOR THE WHOLE FILE (2026-08-25). This block derived the title as "everything
1414 // up to the first '.' within 80 bytes, else 56 bytes" -- a THIRD rule, agreeing with neither the
1415 // HTML SERP's nor anything else. MEASURED LIVE on the deployed binary: it emitted the title
1416 // "HTTP/1" (the dot inside "HTTP/1.1"), the title "<p align=..." for a markup document, and
1417 // 56-byte titles cut mid-word whose snippet then began "ain menu move to sidebar".
1418 // A FIX THAT LIVES IN ONE ORGAN AND NOT ITS SIBLING IS HALF A FIX, AND THE HALF LEFT UNDONE IS
1419 // THE ONE THAT SHIPS: the HTML path was repaired and this one went out broken in the SAME
1420 // binary, invisible to anyone not calling the JSON API. Both now share dpr_title + nx_textcut,
1421 // so the two surfaces cannot drift apart again -- there is only one of it.
1422 let abox: *i64 = dsv_box()
1423 var ats: i64 = 0
1424 var atl: i64 = 0
1425 if dpr_title(txt, dn2, DSV_TITLE_CAP, dsv_slot(abox, 0), dsv_slot(abox, 1), dsv_slot(abox, 2)) == 1 {
1426 ats = abox[0]
1427 atl = abox[1]
1428 } else {
1429 ats = tc_skip_ws(txt, dn2, 0)
1430 atl = tc_cut_trim(((txt as i64) + ats) as *u8, dn2 - ats, DSV_TITLE_FLOOR, dsv_slot(abox, 2))
1431 }
1432 dsv_snippet_span(txt, dn2, ats + atl, snip_ptrs, snip_nterms, snip_tbl, dsv_slot(abox, 5), dsv_slot(abox, 6), dsv_slot(abox, 4))
1433 let asn: i64 = abox[5]
1434 // Preserve the API's existing byte cap even when HTML selects a longer sentence.
1435 var asl: i64 = abox[6]
1436 if asl > DSV_SNIP { asl = tc_cut_trim(((txt as i64) + asn) as *u8, dn2 - asn, DSV_SNIP, dsv_slot(abox, 3)) }
1437 b = dsv_cat(body, b, "{\"cid\":\"" as *u8)
1438 b = dsv_catn(body, b, cids[i])
1439 b = dsv_cat(body, b, "\",\"score\":" as *u8)
1440 b = dsv_catn(body, b, scores[i])
1441 b = dsv_cat(body, b, ",\"title\":\"" as *u8)
1442 b = dsv_jesc(body, b, ((txt as i64) + ats) as *u8, atl)
1443 b = dsv_cat(body, b, "\",\"snippet\":\"" as *u8)
1444 b = dsv_jesc(body, b, ((txt as i64) + asn) as *u8, asl)
1445 b = dsv_cat(body, b, "\",\"doc\":\"/doc?cid=" as *u8)
1446 b = dsv_catn(body, b, cids[i])
1447 if webscope == 1 { b = dsv_cat(body, b, "&scope=web" as *u8) }
1448 b = dsv_cat(body, b, "\"" as *u8)
1449 dsv_mkurlkey(cids[i], ukey)
1450 if ss_hget(h, ukey, uptr, ulen2) == 1 {
1451 if ulen2[0] > 0 {
1452 b = dsv_cat(body, b, ",\"url\":\"" as *u8)
1453 b = dsv_jesc(body, b, uptr[0] as *u8, ulen2[0])
1454 b = dsv_cat(body, b, "\"" as *u8)
1455 // host: the site: filter/facet key, parsed from the url (additive contract field)
1456 let hostb: *u8 = sys_mmap(256)
1457 let hostl: i64 = dss_url_host(uptr[0] as *u8, ulen2[0], hostb)
1458 if hostl > 0 {
1459 b = dsv_cat(body, b, ",\"host\":\"" as *u8)
1460 b = dsv_jesc(body, b, hostb, hostl)
1461 b = dsv_cat(body, b, "\"" as *u8)
1462 }
1463 }
1464 }
1465 b = dsv_cat(body, b, "}" as *u8)
1466 } }
1467 i = i + 1
1468 }
1469 b = dsv_cat(body, b, "]" as *u8)
1470 // INDEX STATE (2026-08-22, ADDITIVE, rule 19). Unconditional on purpose (coverage above is web-only and an
1471 // abstain signal absent where it matters is no signal). segments = h[0] of the handle THIS response rendered
1472 // from (web: the parent-cached one; site/trusted: this request's own open) -- MEASURED per scope. state: ok(>0)
1473 // | unavailable(web,0 = OUTAGE, never no-results) | empty(site/trusted,0 = nothing published, not an outage)
1474 // | unopened(-1). A stale memo hit can ship as ok for <= one refresh window. HTTP status UNCHANGED on purpose:
1475 // a 503 reads as daemon-down to every health probe (the amplifying failure). Body only.
1476 var iseg: i64 = 0 - 1
1477 if (h as i64) != 0 { iseg = h[0] }
1478 b = dsv_cat(body, b, ",\"index\":{\"segments\":" as *u8)
1479 b = dsv_catn(body, b, iseg)
1480 b = dsv_cat(body, b, ",\"state\":\"" as *u8)
1481 if iseg > 0 { b = dsv_cat(body, b, "ok" as *u8) }
1482 if iseg == 0 { if webscope == 1 { b = dsv_cat(body, b, "unavailable" as *u8) } else { b = dsv_cat(body, b, "empty" as *u8) } }
1483 if iseg < 0 { b = dsv_cat(body, b, "unopened" as *u8) }
1484 // L0 (2026-09-14): the response announces which stage-2 path scored it -- covered = candidates scored from the
1485 // postings (no .docs page touched), walked = candidates that fell back to the head scan, nopos = segments that
1486 // lack a .pos sidecar. A feature that only prints on error is indistinguishable from one never compiled in.
1487 let l0s: *i64 = sys_mmap(32) as *i64
1488 dss_l0_stats(l0s)
1489 b = dsv_cat(body, b, "\"},\"l0\":{\"covered\":" as *u8)
1490 b = dsv_catn(body, b, l0s[0])
1491 b = dsv_cat(body, b, ",\"walked\":" as *u8)
1492 b = dsv_catn(body, b, l0s[1])
1493 b = dsv_cat(body, b, ",\"nopos\":" as *u8)
1494 b = dsv_catn(body, b, l0s[2])
1495 // S7 (2026-09-16): the served BM25Q fusion announces itself on every answer -- repeats = distinct typed terms that
1496 // occur more than once (0 means the fusion was the identity by construction), moved = candidates whose rank the
1497 // reciprocal-rank fusion changed before coordination (dss_bm25q_stats; the memo path resets both to 0). A feature
1498 // that only prints on error is indistinguishable from one never compiled in.
1499 let bqs: *i64 = sys_mmap(16) as *i64
1500 dss_bm25q_stats(bqs)
1501 b = dsv_cat(body, b, "},\"bm25q\":{\"repeats\":" as *u8)
1502 b = dsv_catn(body, b, bqs[0])
1503 b = dsv_cat(body, b, ",\"moved\":" as *u8)
1504 b = dsv_catn(body, b, bqs[1])
1505 // S11 (2026-09-17): the entity pin announces itself on every answer -- pinned=1 when the query's resolved canonical
1506 // page was a candidate and took the top band, cid = the resolved page (0 = no row for this query in
1507 // knowledge/status/entitypin.tsv), rows = the served table's size. The memo serves an earlier order until it expires.
1508 let ens: *i64 = sys_mmap(8 * DSS_ENT_BOX_SLOTS) as *i64
1509 dss_entity_stats(ens)
1510 b = dsv_cat(body, b, "},\"entity\":{\"pinned\":" as *u8)
1511 b = dsv_catn(body, b, ens[0])
1512 b = dsv_cat(body, b, ",\"cid\":\"" as *u8)
1513 b = dsv_catn(body, b, ens[1])
1514 b = dsv_cat(body, b, "\",\"rows\":" as *u8)
1515 b = dsv_catn(body, b, ens[2])
1516 // S11-b: the card's fields ride the same object (empty and 0 when nothing is pinned, the shape never changes)
1517 let ejp: *u8 = sys_mmap(DSV_ENT_FIELD_CAP)
1518 let eurl: *u8 = sys_mmap(DSV_ENT_FIELD_CAP)
1519 let ejn: i64 = dss_entity_field(DSS_ENT_FIELD_JP, ejp, DSV_ENT_FIELD_CAP)
1520 let eun: i64 = dss_entity_field(DSS_ENT_FIELD_URL, eurl, DSV_ENT_FIELD_CAP)
1521 b = dsv_cat(body, b, ",\"jp\":\"" as *u8)
1522 b = dsv_jesc(body, b, ejp, ejn)
1523 b = dsv_cat(body, b, "\",\"url\":\"" as *u8)
1524 b = dsv_jesc(body, b, eurl, eun)
1525 b = dsv_cat(body, b, "\",\"titles\":" as *u8)
1526 b = dsv_catn(body, b, dss_entity_titles())
1527 // PHASE TIMERS (2026-09-14, ADDITIVE, rule 19): microseconds per stage of THIS query from dss_phase_stats, so
1528 // a slow answer names its own phase instead of inviting a story (the L3 instrument). memo=1 means the result
1529 // cache answered and no phase ran; every other field is then 0. cand = candidates after stage 1.
1530 let phs: *i64 = sys_mmap(8 * DSS_PH_SLOTS) as *i64
1531 dss_phase_stats(phs)
1532 // S12: the same three freshness numbers ride the API (observed of the page, newest epoch, median age, the clock read)
1533 let jfea: *i64 = sys_mmap(8 * DSS_FRESH_MAX) as *i64
1534 var jfen: i64 = nres
1535 if jfen > DSS_FRESH_MAX { jfen = DSS_FRESH_MAX }
1536 var jfi: i64 = 0
1537 while jfi < jfen { jfea[jfi] = dss_doc_fetch_epoch(h, cids[jfi]); jfi = jfi + 1 }
1538 let jfst: *i64 = sys_mmap(8 * DSS_FRESH_SLOTS) as *i64
1539 let jnow: i64 = sys_now_realtime_sec()
1540 dss_fresh_stats(jfea, jfen, jnow, jfst)
1541 b = dsv_cat(body, b, "},\"freshness\":{\"observed\":" as *u8)
1542 b = dsv_catn(body, b, jfst[0])
1543 b = dsv_cat(body, b, ",\"of\":" as *u8)
1544 b = dsv_catn(body, b, jfen)
1545 b = dsv_cat(body, b, ",\"newest_epoch\":" as *u8)
1546 b = dsv_catn(body, b, jfst[1])
1547 b = dsv_cat(body, b, ",\"median_age_s\":" as *u8)
1548 b = dsv_catn(body, b, jfst[2])
1549 b = dsv_cat(body, b, ",\"now\":" as *u8)
1550 b = dsv_catn(body, b, jnow)
1551 b = dsv_cat(body, b, "},\"phase_us\":{\"prep\":" as *u8)
1552 b = dsv_catn(body, b, phs[0])
1553 b = dsv_cat(body, b, ",\"s1\":" as *u8)
1554 b = dsv_catn(body, b, phs[1])
1555 b = dsv_cat(body, b, ",\"filt\":" as *u8)
1556 b = dsv_catn(body, b, phs[2])
1557 b = dsv_cat(body, b, ",\"short\":" as *u8)
1558 b = dsv_catn(body, b, phs[3])
1559 b = dsv_cat(body, b, ",\"l0loc\":" as *u8)
1560 b = dsv_catn(body, b, phs[4])
1561 b = dsv_cat(body, b, ",\"l0dec\":" as *u8)
1562 b = dsv_catn(body, b, phs[5])
1563 b = dsv_cat(body, b, ",\"walk\":" as *u8)
1564 b = dsv_catn(body, b, phs[6])
1565 b = dsv_cat(body, b, ",\"score\":" as *u8)
1566 b = dsv_catn(body, b, phs[7])
1567 b = dsv_cat(body, b, ",\"auth\":" as *u8)
1568 b = dsv_catn(body, b, phs[8])
1569 b = dsv_cat(body, b, ",\"div\":" as *u8)
1570 b = dsv_catn(body, b, phs[9])
1571 b = dsv_cat(body, b, ",\"sel\":" as *u8)
1572 b = dsv_catn(body, b, phs[10])
1573 b = dsv_cat(body, b, ",\"total\":" as *u8)
1574 b = dsv_catn(body, b, phs[11])
1575 b = dsv_cat(body, b, ",\"cand\":" as *u8)
1576 b = dsv_catn(body, b, phs[12])
1577 b = dsv_cat(body, b, ",\"memo\":" as *u8)
1578 b = dsv_catn(body, b, phs[13])
1579 // prep sub-phases (L5 instrument, 2026-09-14): expand = stem expansion, doccount = the per-query .keys walk
1580 b = dsv_cat(body, b, ",\"expand\":" as *u8)
1581 b = dsv_catn(body, b, phs[14])
1582 b = dsv_cat(body, b, ",\"doccount\":" as *u8)
1583 b = dsv_catn(body, b, phs[15])
1584 b = dsv_cat(body, b, "}}" as *u8)
1585 sys_munmap(phs as *u8, 8 * DSS_PH_SLOTS)
1586 return dsv_respond_json(out, "200 OK" as *u8, body, b)
1587}
1588// GET /api/suggest?q=<prefix>[&scope=web] -> ranked completions from the index's OWN term dictionary
1589// (API-first autocomplete: apps/clients wire the keystroke loop; the HTML SERP stays zero-JS by design)
1590func dss_api_suggest(domain: *u8, req: *u8, req_n: i64, out: *u8) -> i64 {
1591 let q: *u8 = sys_mmap(256)
1592 let qn: i64 = dsv_qparam(req, req_n, "q" as *u8, 1, q, 63)
1593 let effdom: *u8 = sys_mmap(256)
1594 let webscope: i64 = dsv_scope(req, req_n, domain, effdom)
1595 let body: *u8 = sys_mmap(DSV_BODYCAP)
1596 var b: i64 = 0
1597 if qn == 0 {
1598 b = dsv_cat(body, b, "{\"v\":1,\"endpoint\":\"/api/suggest\",\"params\":{\"q\":\"required: term prefix\",\"scope\":\"optional: web\"},\"max\":8}" as *u8)
1599 return dsv_respond_json(out, "200 OK" as *u8, body, b)
1600 }
1601 // normalize the prefix with the index's own classifier (lowercase alnum)
1602 let tbl: *u8 = sys_mmap(272)
1603 ss_tok_table(tbl)
1604 let pfx: *u8 = sys_mmap(64)
1605 var pn: i64 = 0
1606 var i: i64 = 0
1607 while i < qn { if pn < 32 { let m: i64 = tbl[q[i]] as i64; if m != 0 { pfx[pn] = m as u8; pn = pn + 1 } } i = i + 1 }
1608 let sg: *u8 = sys_mmap(8 * 64)
1609 var n: i64 = 0
1610 if pn >= 1 { n = dss_suggest(effdom, pfx, pn, sg, 8) }
1611 b = dsv_cat(body, b, "{\"v\":1,\"prefix\":\"" as *u8)
1612 b = dsv_jesc(body, b, pfx, pn)
1613 b = dsv_cat(body, b, "\",\"scope\":\"" as *u8)
1614 b = dsv_scope_name(body, b, webscope)
1615 b = dsv_cat(body, b, "\",\"suggestions\":[" as *u8)
1616 var k: i64 = 0
1617 while k < n {
1618 if k > 0 { b = dsv_cat(body, b, "," as *u8) }
1619 b = dsv_cat(body, b, "\"" as *u8)
1620 let sp: *u8 = (sg as i64 + k * 64) as *u8
1621 var sl: i64 = 0
1622 while sp[sl] != (0 as u8) { sl = sl + 1 }
1623 b = dsv_jesc(body, b, sp, sl)
1624 b = dsv_cat(body, b, "\"" as *u8)
1625 k = k + 1
1626 }
1627 b = dsv_cat(body, b, "]}" as *u8)
1628 return dsv_respond_json(out, "200 OK" as *u8, body, b)
1629}
1630// GET /api/doc?cid=<cid>[&scope=web] -> the full public document as JSON (text bounded like the HTML view)
1631func dss_api_doc(domain: *u8, req: *u8, req_n: i64, out: *u8) -> i64 {
1632 let effdom: *u8 = sys_mmap(256)
1633 let webscope: i64 = dsv_scope(req, req_n, domain, effdom)
1634 let cidbuf: *u8 = sys_mmap(64)
1635 let cn: i64 = dsv_qparam(req, req_n, "cid" as *u8, 3, cidbuf, 31)
1636 let okbox: *i64 = sys_mmap(16) as *i64
1637 let cid: i64 = dsv_atoin(cidbuf, cn, okbox)
1638 let body: *u8 = sys_mmap(DSV_BODYCAP)
1639 var b: i64 = 0
1640 if okbox[0] == 0 {
1641 b = dsv_cat(body, b, "{\"v\":1,\"error\":{\"code\":\"bad_cid\",\"message\":\"cid must be a decimal content id\"}}" as *u8)
1642 return dsv_respond_json(out, "400 Bad Request" as *u8, body, b)
1643 }
1644 let dptr: *i64 = sys_mmap(16) as *i64
1645 let dlen: *i64 = sys_mmap(16) as *i64
1646 var found: i64 = 0
1647 let prefix: *u8 = sys_mmap(512); dss_prefix(effdom, prefix)
1648 let h: *i64 = dss_open_maybe_cached(prefix)
1649 let key: *u8 = sys_mmap(64)
1650 if (h as i64) != 0 {
1651 dss_mkkey(cid, key)
1652 if ss_hget(h, key, dptr, dlen) == 1 { found = 1 }
1653 }
1654 if found == 0 {
1655 b = dsv_cat(body, b, "{\"v\":1,\"error\":{\"code\":\"not_found\",\"message\":\"no public document with that cid\"}}" as *u8)
1656 return dsv_respond_json(out, "404 Not Found" as *u8, body, b)
1657 }
1658 var tn: i64 = dlen[0]
1659 var trunc: i64 = 0
1660 if tn > DSV_MAGIC_80000 { tn = DSV_MAGIC_80000; trunc = 1 }
1661 b = dsv_cat(body, b, "{\"v\":1,\"found\":true,\"cid\":\"" as *u8)
1662 b = dsv_catn(body, b, cid)
1663 b = dsv_cat(body, b, "\",\"scope\":\"" as *u8)
1664 b = dsv_scope_name(body, b, webscope)
1665 b = dsv_cat(body, b, "\",\"truncated\":" as *u8)
1666 if trunc == 1 { b = dsv_cat(body, b, "true" as *u8) } else { b = dsv_cat(body, b, "false" as *u8) }
1667 let ukey: *u8 = sys_mmap(64)
1668 let uptr: *i64 = sys_mmap(16) as *i64; let ulen2: *i64 = sys_mmap(16) as *i64
1669 dsv_mkurlkey(cid, ukey)
1670 if ss_hget(h, ukey, uptr, ulen2) == 1 {
1671 b = dsv_cat(body, b, ",\"url\":\"" as *u8)
1672 b = dsv_jesc(body, b, uptr[0] as *u8, ulen2[0])
1673 b = dsv_cat(body, b, "\"" as *u8)
1674 }
1675 b = dsv_cat(body, b, ",\"text\":\"" as *u8)
1676 b = dsv_jesc(body, b, dptr[0] as *u8, tn)
1677 b = dsv_cat(body, b, "\"}" as *u8)
1678 return dsv_respond_json(out, "200 OK" as *u8, body, b)
1679}