code wiki / _hdl_build / nx_beir_eval.nx
nx_beir_eval.nx source
↩ module page · 2118 lines · 118813 B
1// nx_beir_eval.nx -- SOVEREIGN BEIR harness: real external ground truth (BEIR/nfcorpus) scored by our own
2// integer BM25 -> mean nDCG@10 (the standard BEIR metric). The HONEST external row the maturity ladder is
3// gated on (F236): real 3633-doc corpus + 323 test queries + 12335 graded qrels, vs the published BEIR BM25
4// baseline (nfcorpus nDCG@10 ~0.32, Anserini). BM25 k1=0.9 b=0.4 (BEIR defaults). IDF=log2 (ranking-invariant
5// vs ln -> identical nDCG). Integer/fixed-point throughout (no float) = bit-reproducible. Forward index
6// (per-doc sorted term,tf). Tokenizer = lowercase [a-z0-9] runs -> PORTER STEM via nx_stem_lib (2026-08-13), NO stopwords (the stemming rung LANDED -- was the
7// named gap to the stemmed 0.32 Anserini baseline).
8//
9// R0d be_bright (2026-09-14): `--set <root>` scores ANY BEIR-shaped set root (<root>/corpus.tsv, queries.tsv,
10// qrels/test.tsv and, when present, excluded.tsv: BRIGHT lists each query's own source documents there and the benchmark
11// removes them from that query's ranking, so this harness marks them unrankable for that query and counts them). Every
12// capacity is now DERIVED from the files (sys_read_file sizes the buffer, newline counts size the tables, the longest line
13// sizes the token scratch): the old 64 MiB file cap and 4096-document cap would have dropped 99 percent of BRIGHT's
14// leetcode split in silence, which is the cap class this estate refuses. `--bm25-only` skips the rerank arms (their models
15// were trained on the web corpus; BRIGHT's published floor is plain BM25, 14.5 average nDCG at 10 on the leaderboard page
16// read 2026-09-14, search.refs bright). `--bright <root>` is be_bright: this binary runs itself once per split through
17// tr_run_capture_to (one hour each, the largest split bounds it), prints one JSON row per split, the average over twelve of
18// twelve (never over a partial set), and writes the estate's row into search.leaderboard beside the published rows with
19// its rank DERIVED from their scores. The positional grammar is unchanged: [model.safetensors config.json vocab.txt
20// [max_len [depth [workers]]]] after the flags; workers is the cross-encoder pool width (0 = serial).
21// expect_exit: 0 license_tier: ORIGINAL
22import "nx_qabench_engine.nx"
23import "nx_ppmi_lib.nx"
24import "nx_stem.nx"
25import "nx_ltr_lib.nx" // R0 learned rerank arm: coordinate-ascent LTR (Metzler-Croft), 5-fold CV over the stored candidates
26import "nx_dr_densejudge.nx" // R0 trained-dense representation (embed_v1.bin via dj_maxsim*) -- the lever DR-13 named after learned fusion over PPMI was measured a dead end
27import "nx_wordpiece_lib.nx" // R0 cross-encoder arm: WordPiece over the model's own vocab
28import "nx_bert_ce_lib.nx" // R0 cross-encoder arm: the sovereign BERT encoder over a licensed data asset
29import "nx_thread_pool.nx"
30import "nx_tool_run.nx" // be_bright: this binary runs itself once per split and captures the JSON
31import "nx_timefmt.nx" // the leaderboard row's date (civil_from_days, Hinnant)
32import "nx_intlog.nx" // S5 BM25Q (2026-09-15): idf_bm25q, THE ONE query-side saturation -- composed here, never a second copy
33import "nx_beir_arms_lib.nx" // R0f (2026-09-16): THE ONE CHOOSER of the arm the BRIGHT sweep writes to the leaderboard
34const BE_ASCII_ZERO: i64 = 48
35const BE_ASCII_NINE: i64 = 57
36const BE_DECIMAL: i64 = 10
37const BE_MAGIC_1024: i64 = 1024
38const BE_MAGIC_1000000: i64 = 1000000
39// seq1494 RERANK ARM: BM25 retrieves a shortlist, the PPMI late-interaction model re-orders it, and BOTH
40// nDCG@10 values are printed FROM THE SAME RUN so the delta cannot be confounded by corpus/qrel/tokeniser
41// drift. The BM25 arm is untouched: top[0..9] keeps its exact BM25 order, we merely widen the candidate
42// selection past 10 so the reranker has something to re-order.
43// derived: 50 candidates is the standard first-stage depth for late-interaction reranking -- deep enough
44// that recall@50 >> recall@10 (so the reranker CAN win) and shallow enough to stay O(50) maxsim per query.
45const BE_KCAND: i64 = 50
46// sized: query/doc PPMI id buffers; nfcorpus docs are abstracts, far under this
47const BE_IDCAP: i64 = 4096
48const K_MAGIC_1024: i64 = 1024
49const K_MAGIC_4096: i64 = 4096
50const K_MAGIC_1900: i64 = 1900
51// ---- R0d: set roots, flags, derived capacities, the twelve splits, the leaderboard row ----
52const BE_FLAG_SET: *u8 = "--set"
53const BE_FLAG_BRIGHT: *u8 = "--bright"
54const BE_CE_POOL_WORKERS_DEFAULT: i64 = 0 // 0 = every forward on the calling thread; the 6th positional sets the pool width, and since 2026-09-15 the pool's unit of work is ONE WHOLE PAIR (a forward), never a band of one matmul: the forward inside a task is the serial path, so a pooled run scores every pair identically to a serial run and only the wall clock moves (per-matmul banding was measured as NO speedup, search.plan row 1789456036)
55const BE_CE_TASK_BYTES: i64 = 96 // BeCeTask: 12 i64 fields; one task record and one scratch set PER CANDIDATE so no two tasks ever share a buffer
56// the progress stamp is DERIVED from the run's own queries path (2026-09-15): two concurrent runs (a BRIGHT sweep and an
57// nfcorpus arm) wrote one constant path over each other, and a constant stamp path is the forgeable-heartbeat class this
58// estate already named -- every run stamps a path only its own arguments can produce
59const BE_PROGRESS_DIR: *u8 = "knowledge/status/beir_eval."
60const BE_PROGRESS_SFX: *u8 = ".progress"
61const BE_PROGRESS_SFX_TMP: *u8 = ".progress.tmp"
62const BE_SLASH: i64 = 47
63const BE_DOT: i64 = 46
64const BE_USCORE: i64 = 95
65const BE_PROGRESS_BYTES: i64 = 640
66const BE_FLAG_BM25ONLY: *u8 = "--bm25-only"
67// R0h (2026-09-16): an ALTERNATE query file inside each set root (the dataset's published reasoning-query sets). A run on an
68// alternate query set is a REFEREE REPLAY: its receipt names the file and the sweep never writes the estate's leaderboard row
69// from it, because a query another model wrote is not the estate's system.
70const BE_FLAG_QUERIES: *u8 = "--queries"
71const BE_ROOT_DEFAULT: *u8 = "knowledge/beir/nfcorpus"
72const BE_ROOT_DEFAULT_TMP: *u8 = "/tmp/beir/nfcorpus"
73const BE_DATASET_DEFAULT: *u8 = "BEIR/nfcorpus"
74const BE_F_CORPUS: *u8 = "/corpus.tsv"
75const BE_F_QRELS: *u8 = "/qrels/test.tsv"
76const BE_F_QUERIES: *u8 = "/queries.tsv"
77const BE_F_EXCLUDED: *u8 = "/excluded.tsv"
78const BE_SEP: *u8 = "/"
79const BE_PATH_CAP: i64 = 1024
80const BE_POS_CAP: i64 = 16
81const BE_NL: i64 = 10
82const BE_TAB: i64 = 9
83const BE_PIPE: i64 = 124
84const BE_DOT: i64 = 46
85const BE_MINUS: i64 = 45
86const BE_I64: i64 = 8
87const BE_G_SLOTS: i64 = 8
88const BE_TOK_BYTES: i64 = 2 // a token needs one byte and a separator, so tokens <= bytes / 2 + lines
89const BE_PERMIL_DIGITS: i64 = 10 // the board writes nDCG x 100 with one decimal; permil / 10 . permil % 10
90const BE_BRIGHT_N: i64 = 12
91const BE_PT_TF_MOD: i64 = 1048576 // posting word radix (2^20): doc * radix + tf; a tf at or past it is clamped and COUNTED, never silently wrapped
92const BE_BRIGHT_BM25_PUBLISHED_PERMIL: i64 = 145 // the leaderboard page's plain BM25 row, read 2026-09-14 (search.refs bright)
93// S5: the per-split receipt keys the sweep reads back (each is the FIRST occurrence in that split's JSON; the two
94// ndcg keys are prefixed by the field that precedes them so the plain arm's key is never mistaken for them)
95const BE_JSON_BQ_KEY: *u8 = "k_q10\":1228,\"ndcg_at_10_permil\":"
96const BE_JSON_FQ_KEY: *u8 = "bm25q-rank, same 50 candidates\",\"ndcg_at_10_permil\":"
97const BE_JSON_LONGN_KEY: *u8 = "\"long_n\":"
98const BE_JSON_LONGD_KEY: *u8 = "\"long_bm25_permil\":"
99const BE_JSON_LONGQ_KEY: *u8 = "\"long_bm25q_permil\":"
100const BE_JSON_LONGF_KEY: *u8 = "\"long_fusion_permil\":"
101const BE_JSON_NOREP_KEY: *u8 = "\"norepeat_n\":"
102const BE_JSON_NOREPSAME_KEY: *u8 = "\"norepeat_top10_identical\":"
103const BE_JSON_REP_KEY: *u8 = "\"queries_with_repeated_term\":"
104// R0f: the reranker keys the sweep reads back (each spelled once in a split receipt)
105const BE_JSON_CEM_KEY: *u8 = "\"ce_measured\":"
106const BE_JSON_CE_KEY: *u8 = "\"ce_ndcg_at_10_permil\":"
107const BE_JSON_CEF_KEY: *u8 = "\"cefusion_ndcg_at_10_permil\":"
108const BE_JSON_PRF_KEY: *u8 = "\"prf_ndcg_at_10_permil\":"
109// R0g PRF ARM (2026-09-16): RM3-style pseudo-relevance feedback. The three parameters are Anserini's RM3 defaults
110// (fbDocs 10, fbTerms 10, originalQueryWeight 0.5), named here so the receipt can print them; the top cut is the nDCG cutoff.
111const BE_PRF_FB_DOCS: i64 = 10
112const BE_PRF_FB_TERMS: i64 = 10
113const BE_PRF_ORIG_PERMIL: i64 = 500
114const BE_PRF_TOP: i64 = 10
115const BE_JSON_CAP: i64 = 65536 // a per-split JSON receipt is a few KB; a capture that fills this is REFUSED, never averaged
116const BE_SPLIT_TIMEOUT_MS: i64 = 3600000 // one hour per split: leetcode (413932 documents) bounds it
117const BE_LB_A: *u8 = "buildroot/knowledge/compare/search.leaderboard"
118const BE_LB_B: *u8 = "knowledge/compare/search.leaderboard"
119const BE_LB_TMP: *u8 = ".tmp"
120const BE_LB_ROW: *u8 = "lb|bright|"
121const BE_LB_SYSTEM: *u8 = "nishi-search"
122// S5: the row names the arm it scores. The fused arm is written only when its own pre-declared rule held in the SAME
123// sweep (fusion beat plain on the long subset, no-repeat queries identical) and its twelve-split average is at least
124// the plain arm's -- the measuring organ chooses from its own receipt, never a hand.
125const BE_LB_URL: *u8 = "https://nishifamily.com/compare/search"
126const BE_LB_F_SYSTEM: i64 = 3
127const BE_LB_F_SCORE: i64 = 5
128const BE_LB_SLACK: i64 = 512
129const BE_JSON_NDCG_KEY: *u8 = "\"ndcg_at_10_permil\":"
130const BE_JSON_NQ_KEY: *u8 = "\"test_queries_scored\":"
131const BE_JSON_DOCS_KEY: *u8 = "\"docs\":"
132const BE_SECS_PER_DAY: i64 = 86400
133const BE_CLOCK_WORDS: i64 = 2
134const BE_DATE_LEN: i64 = 10
135const BE_SPLIT_0: *u8 = "biology"
136const BE_SPLIT_1: *u8 = "earth_science"
137const BE_SPLIT_2: *u8 = "economics"
138const BE_SPLIT_3: *u8 = "psychology"
139const BE_SPLIT_4: *u8 = "robotics"
140const BE_SPLIT_5: *u8 = "stackoverflow"
141const BE_SPLIT_6: *u8 = "sustainable_living"
142const BE_SPLIT_7: *u8 = "leetcode"
143const BE_SPLIT_8: *u8 = "pony"
144const BE_SPLIT_9: *u8 = "aops"
145const BE_SPLIT_10: *u8 = "theoremqa_questions"
146const BE_SPLIT_11: *u8 = "theoremqa_theorems"
147
148// read a whole file, sized from the file itself (sys_read_file cannot short-read); returns bytes or -1 when absent
149func be_read(path: *u8, slot: *i64) -> i64 {
150 let lenp: *i64 = sys_mmap(BE_I64) as *i64
151 lenp[0] = 0
152 let buf: *u8 = sys_read_file(path, lenp)
153 if (buf as i64) == 0 { return 0 - 1 }
154 if lenp[0] <= 0 { return 0 - 1 }
155 slot[0] = buf as i64
156 return lenp[0]
157}
158
159// read pathA, else fall back to pathB (NAS stable path first, local /tmp second)
160func be_read_fb(pa: *u8, pb: *u8, slot: *i64) -> i64 {
161 let n: i64 = be_read(pa, slot)
162 if n > 0 { return n }
163 return be_read(pb, slot)
164}
165
166func be_slen(s: *u8) -> i64 {
167 var n: i64 = 0
168 while (s[n] & 0xff) as i64 != 0 { n = n + 1 }
169 return n
170}
171func be_streq(a: *u8, b: *u8) -> i64 {
172 var i: i64 = 0
173 var go: i64 = 1
174 while go == 1 {
175 let ca: i64 = (a[i] & 0xff) as i64
176 let cb: i64 = (b[i] & 0xff) as i64
177 if ca != cb { return 0 }
178 if ca == 0 { go = 0 }
179 i = i + 1
180 }
181 return 1
182}
183func be_count_byte(buf: *u8, n: i64, ch: i64) -> i64 {
184 var c: i64 = 0
185 var i: i64 = 0
186 while i < n { if (buf[i] & 0xff) as i64 == ch { c = c + 1 } i = i + 1 }
187 return c
188}
189// the longest line in buf (bytes between newlines)
190func be_maxline(buf: *u8, n: i64) -> i64 {
191 var best: i64 = 0
192 var cur: i64 = 0
193 var i: i64 = 0
194 while i < n {
195 if (buf[i] & 0xff) as i64 == BE_NL { if cur > best { best = cur } cur = 0 } else { cur = cur + 1 }
196 i = i + 1
197 }
198 if cur > best { best = cur }
199 return best
200}
201// dst = a + b (+ c when c is not null), NUL-terminated; returns the length or -1 when it would not fit
202// R0h: the queries path of a set root: the default queries.tsv, or root / qfile when an alternate query file is named
203func be_qpath(dst: *u8, root: *u8, qfile: *u8) -> i64 {
204 if (qfile as i64) == 0 { return be_path(dst, root, BE_F_QUERIES) }
205 return be_path3(dst, root, BE_SEP, qfile)
206}
207func be_path3(dst: *u8, a: *u8, b: *u8, c: *u8) -> i64 {
208 let la: i64 = be_slen(a)
209 let lb: i64 = be_slen(b)
210 var lc: i64 = 0
211 if (c as i64) != 0 { lc = be_slen(c) }
212 if la + lb + lc + 1 > BE_PATH_CAP { return 0 - 1 }
213 var i: i64 = 0
214 while i < la { dst[i] = a[i]; i = i + 1 }
215 var j: i64 = 0
216 while j < lb { dst[la + j] = b[j]; j = j + 1 }
217 var k: i64 = 0
218 while k < lc { dst[la + lb + k] = c[k]; k = k + 1 }
219 dst[la + lb + lc] = 0 as u8
220 return la + lb + lc
221}
222func be_path(dst: *u8, a: *u8, b: *u8) -> i64 { return be_path3(dst, a, b, 0 as *u8) }
223// the integer after the FIRST occurrence of key in buf[0..n), or -1 when the key is absent
224func be_json_int(buf: *u8, n: i64, key: *u8) -> i64 {
225 let m: i64 = be_slen(key)
226 var i: i64 = 0
227 while i + m <= n {
228 var j: i64 = 0
229 var ok: i64 = 1
230 while j < m { if (buf[i + j] & 0xff) as i64 != (key[j] & 0xff) as i64 { ok = 0; j = m } else { j = j + 1 } }
231 if ok == 1 {
232 var p: i64 = i + m
233 var neg: i64 = 0
234 if p < n { if (buf[p] & 0xff) as i64 == BE_MINUS { neg = 1; p = p + 1 } }
235 var v: i64 = 0
236 var any: i64 = 0
237 var go: i64 = 1
238 while go == 1 {
239 if p >= n { go = 0 } else {
240 let ch: i64 = (buf[p] & 0xff) as i64
241 if ch >= BE_ASCII_ZERO { if ch <= BE_ASCII_NINE { v = v * BE_DECIMAL + (ch - BE_ASCII_ZERO); any = 1; p = p + 1 } else { go = 0 } } else { go = 0 }
242 }
243 }
244 if any == 0 { return 0 - 1 }
245 if neg == 1 { return 0 - v }
246 return v
247 }
248 i = i + 1
249 }
250 return 0 - 1
251}
252func be_split_name(i: i64) -> *u8 {
253 if i == 0 { return BE_SPLIT_0 }
254 if i == 1 { return BE_SPLIT_1 }
255 if i == 2 { return BE_SPLIT_2 }
256 if i == 3 { return BE_SPLIT_3 }
257 if i == 4 { return BE_SPLIT_4 }
258 if i == 5 { return BE_SPLIT_5 }
259 if i == 6 { return BE_SPLIT_6 }
260 if i == 7 { return BE_SPLIT_7 }
261 if i == 8 { return BE_SPLIT_8 }
262 if i == 9 { return BE_SPLIT_9 }
263 if i == 10 { return BE_SPLIT_10 }
264 return BE_SPLIT_11
265}
266// two decimal digits, zero-padded, into dst at off
267func be_put2(dst: *u8, off: i64, v: i64) -> i64 {
268 dst[off] = (BE_ASCII_ZERO + (v / BE_DECIMAL) % BE_DECIMAL) as u8
269 dst[off + 1] = (BE_ASCII_ZERO + v % BE_DECIMAL) as u8
270 return off + 2
271}
272// today's civil date as YYYY-MM-DD (UTC) from the clock, NUL-terminated
273func be_today(dst: *u8) -> i64 {
274 let ts: *i64 = sys_mmap(BE_CLOCK_WORDS * BE_I64) as *i64
275 ts[0] = 0
276 sys_clock_gettime_real(ts)
277 let y: *i64 = sys_mmap(BE_I64) as *i64
278 let m: *i64 = sys_mmap(BE_I64) as *i64
279 let d: *i64 = sys_mmap(BE_I64) as *i64
280 civil_from_days(ts[0] / BE_SECS_PER_DAY, y, m, d)
281 var o: i64 = be_put2(dst, 0, y[0] / 100)
282 o = be_put2(dst, o, y[0] % 100)
283 dst[o] = BE_MINUS as u8
284 o = be_put2(dst, o + 1, m[0])
285 dst[o] = BE_MINUS as u8
286 o = be_put2(dst, o + 1, d[0])
287 dst[o] = 0 as u8
288 return o
289}
290// the k-th pipe field of the line buf[s..e) -> start offset (len in lenp), or -1
291func be_field(buf: *u8, s: i64, e: i64, k: i64, lenp: *i64) -> i64 {
292 var f: i64 = 0
293 var p: i64 = s
294 var st: i64 = s
295 while p <= e {
296 var atsep: i64 = 0
297 if p == e { atsep = 1 } else { if (buf[p] & 0xff) as i64 == BE_PIPE { atsep = 1 } }
298 if atsep == 1 {
299 if f == k { lenp[0] = p - st; return st }
300 f = f + 1
301 st = p + 1
302 }
303 p = p + 1
304 }
305 return 0 - 1
306}
307// a board score like 66.9 -> 669 permil (whole x 10 + first decimal); -1 when it does not parse
308func be_score_permil(buf: *u8, s: i64, n: i64) -> i64 {
309 var v: i64 = 0
310 var i: i64 = 0
311 var any: i64 = 0
312 while i < n {
313 let ch: i64 = (buf[s + i] & 0xff) as i64
314 if ch >= BE_ASCII_ZERO && ch <= BE_ASCII_NINE { v = v * BE_DECIMAL + (ch - BE_ASCII_ZERO); any = 1; i = i + 1 } else {
315 if ch == BE_DOT { i = i + 1; if i < n { let dch: i64 = (buf[s + i] & 0xff) as i64; if dch >= BE_ASCII_ZERO && dch <= BE_ASCII_NINE { return v * BE_PERMIL_DIGITS + (dch - BE_ASCII_ZERO) } } return v * BE_PERMIL_DIGITS }
316 i = n
317 }
318 }
319 if any == 0 { return 0 - 1 }
320 return v * BE_PERMIL_DIGITS
321}
322func be_starts_at(buf: *u8, s: i64, e: i64, pre: *u8) -> i64 {
323 let m: i64 = be_slen(pre)
324 if e - s < m { return 0 }
325 var i: i64 = 0
326 while i < m { if (buf[s + i] & 0xff) as i64 != (pre[i] & 0xff) as i64 { return 0 } i = i + 1 }
327 return 1
328}
329func be_field_is(buf: *u8, s: i64, e: i64, k: i64, want: *u8) -> i64 {
330 let lp: *i64 = sys_mmap(BE_I64) as *i64
331 let fs: i64 = be_field(buf, s, e, k, lp)
332 if fs < 0 { return 0 }
333 if lp[0] != be_slen(want) { return 0 }
334 return be_starts_at(buf, fs, fs + lp[0], want)
335}
336// write the estate's row into search.leaderboard: rank derived from the published rows' scores, the old
337// nishi-search row dropped, the file rewritten through .tmp + rename. Returns the rank, or a negative refusal.
338func be_lb_write(permil: i64, today: *u8, org: *u8) -> i64 {
339 let slot: *i64 = sys_mmap(BE_I64) as *i64
340 var path: *u8 = BE_LB_A
341 var n: i64 = be_read(path, slot)
342 if n < 0 { path = BE_LB_B; n = be_read(path, slot) }
343 if n < 0 { return 0 - 1 }
344 let buf: *u8 = slot[0] as *u8
345 let out: *u8 = sys_mmap(n + BE_LB_SLACK + be_slen(org) + be_slen(BE_LB_URL))
346 var o: i64 = 0
347 var rank: i64 = 1
348 let lp: *i64 = sys_mmap(BE_I64) as *i64
349 var p: i64 = 0
350 while p < n {
351 let e: i64 = be_find(buf, p, n, BE_NL)
352 var keep: i64 = 1
353 if be_starts_at(buf, p, e, BE_LB_ROW) == 1 {
354 if be_field_is(buf, p, e, BE_LB_F_SYSTEM, BE_LB_SYSTEM) == 1 { keep = 0 } else {
355 let fs: i64 = be_field(buf, p, e, BE_LB_F_SCORE, lp)
356 if fs >= 0 { if be_score_permil(buf, fs, lp[0]) > permil { rank = rank + 1 } }
357 }
358 }
359 if keep == 1 {
360 var i: i64 = p
361 while i < e { out[o] = buf[i]; o = o + 1; i = i + 1 }
362 if e < n { out[o] = BE_NL as u8; o = o + 1 }
363 }
364 p = e + 1
365 }
366 if o > 0 { if (out[o - 1] & 0xff) as i64 != BE_NL { out[o] = BE_NL as u8; o = o + 1 } }
367 // lb|bright|<rank>|nishi-search|<org>|<score>|<date>|<url>
368 var i2: i64 = 0
369 let row: *u8 = BE_LB_ROW
370 while i2 < be_slen(row) { out[o] = row[i2]; o = o + 1; i2 = i2 + 1 }
371 let numb: *u8 = sys_mmap(BE_DATE_LEN + BE_DATE_LEN)
372 var nn: i64 = 0
373 var rv: i64 = rank
374 if rv == 0 { numb[0] = BE_ASCII_ZERO as u8; nn = 1 }
375 while rv > 0 { numb[nn] = (BE_ASCII_ZERO + rv % BE_DECIMAL) as u8; rv = rv / BE_DECIMAL; nn = nn + 1 }
376 while nn > 0 { nn = nn - 1; out[o] = numb[nn]; o = o + 1 }
377 out[o] = BE_PIPE as u8
378 o = o + 1
379 var i3: i64 = 0
380 while i3 < be_slen(BE_LB_SYSTEM) { out[o] = BE_LB_SYSTEM[i3]; o = o + 1; i3 = i3 + 1 }
381 out[o] = BE_PIPE as u8
382 o = o + 1
383 var i4: i64 = 0
384 while i4 < be_slen(org) { out[o] = org[i4]; o = o + 1; i4 = i4 + 1 }
385 out[o] = BE_PIPE as u8
386 o = o + 1
387 // the score: permil -> whole.decimal
388 let whole: i64 = permil / BE_PERMIL_DIGITS
389 nn = 0
390 rv = whole
391 if rv == 0 { numb[0] = BE_ASCII_ZERO as u8; nn = 1 }
392 while rv > 0 { numb[nn] = (BE_ASCII_ZERO + rv % BE_DECIMAL) as u8; rv = rv / BE_DECIMAL; nn = nn + 1 }
393 while nn > 0 { nn = nn - 1; out[o] = numb[nn]; o = o + 1 }
394 out[o] = BE_DOT as u8
395 o = o + 1
396 out[o] = (BE_ASCII_ZERO + permil % BE_PERMIL_DIGITS) as u8
397 o = o + 1
398 out[o] = BE_PIPE as u8
399 o = o + 1
400 var i5: i64 = 0
401 while i5 < be_slen(today) { out[o] = today[i5]; o = o + 1; i5 = i5 + 1 }
402 out[o] = BE_PIPE as u8
403 o = o + 1
404 var i6: i64 = 0
405 while i6 < be_slen(BE_LB_URL) { out[o] = BE_LB_URL[i6]; o = o + 1; i6 = i6 + 1 }
406 out[o] = BE_NL as u8
407 o = o + 1
408 let tmp: *u8 = sys_mmap(BE_PATH_CAP)
409 if be_path(tmp, path, BE_LB_TMP) < 0 { return 0 - 2 }
410 let fd: i64 = sys_openat_wr(tmp, MODE_0644)
411 if fd < 0 { return 0 - 3 }
412 var off: i64 = 0
413 while off < o {
414 let w: i64 = sys_write(fd, ((out as i64) + off) as *u8, o - off)
415 if w <= 0 { sys_close(fd); return 0 - 4 }
416 off = off + w
417 }
418 sys_close(fd)
419 if sys_renameat(tmp, path) != 0 { return 0 - 5 }
420 return rank
421}
422// R0e (2026-09-16): the per-split deadline. The bm25 hour bounds the plain arm (leetcode, 413,932 documents); a rerank sweep
423// adds the split's PAIRS (queries x depth) times the slowest MEASURED full-length forward over the pool width, so a slow
424// box is never killed mid-split while a hung child still is -- a hang guard, never a speed bar. queries are counted from the
425// split's own queries.tsv; a split whose queries cannot be read keeps the bm25 hour and the child reports the miss itself.
426const BE_CE_PAIR_CEILING_MS: i64 = 134000 // T11 nx_bert_ce_gate 2026-09-15: one 512-position pair, SERIAL, on the loaded NAS = 133,787,252 us
427func be_split_deadline_ms(setp: *u8, bm25_only: i64, pos: *i64, npos: i64, qfile: *u8) -> i64 {
428 if bm25_only == 1 { return BE_SPLIT_TIMEOUT_MS }
429 var depth: i64 = BE_KCAND
430 if npos >= 5 { depth = be_atoi(pos[4] as *u8) }
431 if depth > BE_KCAND { depth = BE_KCAND }
432 var workers: i64 = BE_CE_POOL_WORKERS_DEFAULT
433 if npos >= 6 { workers = be_atoi(pos[5] as *u8) }
434 if workers < 1 { workers = 1 }
435 let pq: *u8 = sys_mmap(BE_PATH_CAP)
436 be_qpath(pq, setp, qfile)
437 let sz: *i64 = sys_mmap(BE_I64) as *i64
438 let buf: *u8 = sys_read_file(pq, sz)
439 var nq: i64 = 0
440 if (buf as i64) != 0 { if sz[0] > 0 { nq = be_count_byte(buf, sz[0], BE_NL) } }
441 return BE_SPLIT_TIMEOUT_MS + nq * depth * BE_CE_PAIR_CEILING_MS / workers
442}
443// be_bright: this binary once per split, the twelve receipts, the average over twelve of twelve, the board row
444func be_bright(root: *u8, self: *u8, bm25_only: i64, pos: *i64, npos: i64, qfile: *u8) -> i64 {
445 let out: *u8 = sys_mmap(BE_JSON_CAP)
446 let outlen: *i64 = sys_mmap(BE_I64) as *i64
447 let av: *i64 = sys_mmap((BE_G_SLOTS + BE_POS_CAP) * BE_I64) as *i64 // R0e: the flag slots plus every forwarded positional
448 let setp: *u8 = sys_mmap(BE_PATH_CAP)
449 let corp: *u8 = sys_mmap(BE_PATH_CAP)
450 let today: *u8 = sys_mmap(BE_DATE_LEN + BE_DATE_LEN)
451 be_today(today)
452 var scored: i64 = 0
453 var missing: i64 = 0
454 var refused: i64 = 0
455 var sum: i64 = 0
456 var qsum: i64 = 0
457 var dsum: i64 = 0
458 // S5 BM25Q across the sweep (2026-09-15): every split's own bm25q block is read back from its captured receipt and the
459 // long-query subset is aggregated WEIGHTED by each split's long_n, so the sweep-level verdict is the same rule the
460 // per-set receipt declares, over the twelve reasoning-query sets the rung was written for
461 var bq_sum: i64 = 0
462 var fq_sum: i64 = 0
463 var ce_n: i64 = 0 // R0f: splits whose receipt measured the reranker
464 var ce_sum: i64 = 0
465 var cef_sum: i64 = 0
466 var prf_n: i64 = 0 // R0g: splits whose receipt carried the PRF arm
467 var prf_sum: i64 = 0
468 var lq_n: i64 = 0
469 var lq_d: i64 = 0
470 var lq_q: i64 = 0
471 var lq_f: i64 = 0
472 var nr_n: i64 = 0
473 var nr_s: i64 = 0
474 var rep_sum: i64 = 0
475 db_w("{\"tool\":\"nx_beir_eval\",\"mode\":\"be_bright\",\"root\":\"" as *u8); db_w(root)
476 db_w("\",\"self\":\"" as *u8); db_w(self)
477 db_w("\",\"bm25_only\":" as *u8); db_n(bm25_only)
478 db_w(",\"forwarded_positionals\":" as *u8); db_n(npos)
479 db_w(",\"queries_file\":\"" as *u8); if (qfile as i64) == 0 { db_w("queries.tsv" as *u8) } else { db_w(qfile) } db_w("\"" as *u8)
480 db_w(",\"date\":\"" as *u8); db_w(today)
481 db_w("\",\"splits\":[" as *u8)
482 var i: i64 = 0
483 while i < BE_BRIGHT_N {
484 let name: *u8 = be_split_name(i)
485 be_path3(setp, root, BE_SEP, name)
486 be_path(corp, setp, BE_F_CORPUS)
487 if i > 0 { db_w("," as *u8) }
488 db_w("{\"split\":\"" as *u8); db_w(name); db_w("\"" as *u8)
489 let fd: i64 = sys_openat_rd(corp)
490 if fd < 0 { missing = missing + 1; db_w(",\"state\":\"MISSING (no corpus.tsv under the split; run nx_bright_prep)\"}" as *u8) } else {
491 sys_close(fd)
492 av[0] = self as i64
493 av[1] = BE_FLAG_SET as i64
494 av[2] = setp as i64
495 var an: i64 = 3
496 if bm25_only == 1 { av[an] = BE_FLAG_BM25ONLY as i64; an = an + 1 }
497 if (qfile as i64) != 0 { av[an] = BE_FLAG_QUERIES as i64; an = an + 1; av[an] = qfile as i64; an = an + 1 }
498 // R0e (2026-09-16): every positional the caller gave (model, config, vocab, max_len, depth, workers) is forwarded
499 // to the split child. The sweep used to launch each split BARE, so a cross-encoder sweep ran every split at the
500 // defaults -- SERIAL, whatever pool width the caller asked for -- and nothing in its receipt said so.
501 var ap: i64 = 0
502 while ap < npos { av[an] = pos[ap]; an = an + 1; ap = ap + 1 }
503 av[an] = 0
504 outlen[0] = 0
505 let rc: i64 = tr_run_capture_to(self, av, out, BE_JSON_CAP, outlen, be_split_deadline_ms(setp, bm25_only, pos, npos, qfile))
506 let n: i64 = outlen[0]
507 db_w(",\"rc\":" as *u8); db_n(rc)
508 db_w(",\"capture_bytes\":" as *u8); db_n(n)
509 if n >= BE_JSON_CAP { refused = refused + 1; db_w(",\"state\":\"REFUSED (the capture filled BE_JSON_CAP; nothing averaged from a truncated receipt)\"}" as *u8) } else {
510 let nd: i64 = be_json_int(out, n, BE_JSON_NDCG_KEY)
511 let nq: i64 = be_json_int(out, n, BE_JSON_NQ_KEY)
512 let docs: i64 = be_json_int(out, n, BE_JSON_DOCS_KEY)
513 db_w(",\"docs\":" as *u8); db_n(docs)
514 db_w(",\"queries\":" as *u8); db_n(nq)
515 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(nd)
516 let bq: i64 = be_json_int(out, n, BE_JSON_BQ_KEY)
517 let fq: i64 = be_json_int(out, n, BE_JSON_FQ_KEY)
518 let ln: i64 = be_json_int(out, n, BE_JSON_LONGN_KEY)
519 let ld: i64 = be_json_int(out, n, BE_JSON_LONGD_KEY)
520 let lq: i64 = be_json_int(out, n, BE_JSON_LONGQ_KEY)
521 let lf: i64 = be_json_int(out, n, BE_JSON_LONGF_KEY)
522 let nrn: i64 = be_json_int(out, n, BE_JSON_NOREP_KEY)
523 let nrs: i64 = be_json_int(out, n, BE_JSON_NOREPSAME_KEY)
524 let rpn: i64 = be_json_int(out, n, BE_JSON_REP_KEY)
525 let cem: i64 = be_json_int(out, n, BE_JSON_CEM_KEY)
526 let cen: i64 = be_json_int(out, n, BE_JSON_CE_KEY)
527 let cefv: i64 = be_json_int(out, n, BE_JSON_CEF_KEY)
528 let prfv: i64 = be_json_int(out, n, BE_JSON_PRF_KEY)
529 if rc == 0 && nd >= 0 && nq > 0 { if prfv >= 0 { prf_n = prf_n + 1; prf_sum = prf_sum + prfv } }
530 if rc == 0 && nd >= 0 && nq > 0 { if cem == 1 { ce_n = ce_n + 1; ce_sum = ce_sum + cen; cef_sum = cef_sum + cefv } }
531 db_w(",\"bm25q_permil\":" as *u8); db_n(bq)
532 db_w(",\"bm25q_fusion_permil\":" as *u8); db_n(fq)
533 db_w(",\"prf_permil\":" as *u8); db_n(prfv)
534 db_w(",\"crossenc_permil\":" as *u8); db_n(cen)
535 db_w(",\"cefusion_permil\":" as *u8); db_n(cefv)
536 db_w(",\"long_n\":" as *u8); db_n(ln)
537 db_w(",\"long_bm25_permil\":" as *u8); db_n(ld)
538 db_w(",\"long_bm25q_permil\":" as *u8); db_n(lq)
539 db_w(",\"long_fusion_permil\":" as *u8); db_n(lf)
540 db_w(",\"norepeat_n\":" as *u8); db_n(nrn)
541 db_w(",\"norepeat_identical\":" as *u8); db_n(nrs)
542 db_w(",\"queries_with_repeated_term\":" as *u8); db_n(rpn)
543 if rc == 0 && nd >= 0 && nq > 0 { if ln > 0 { lq_n = lq_n + ln; lq_d = lq_d + ld * ln; lq_q = lq_q + lq * ln; lq_f = lq_f + lf * ln } if bq >= 0 { bq_sum = bq_sum + bq } if fq >= 0 { fq_sum = fq_sum + fq } if nrn > 0 { nr_n = nr_n + nrn; nr_s = nr_s + nrs } if rpn > 0 { rep_sum = rep_sum + rpn } }
544 if rc == 0 && nd >= 0 && nq > 0 { scored = scored + 1; sum = sum + nd; qsum = qsum + nq; dsum = dsum + docs; db_w(",\"state\":\"SCORED\"}" as *u8) } else { refused = refused + 1; db_w(",\"state\":\"REFUSED (non-zero exit or no score in the receipt)\"}" as *u8) }
545 }
546 }
547 i = i + 1
548 }
549 db_w("],\"splits_declared\":" as *u8); db_n(BE_BRIGHT_N)
550 db_w(",\"scored\":" as *u8); db_n(scored)
551 db_w(",\"missing\":" as *u8); db_n(missing)
552 db_w(",\"refused\":" as *u8); db_n(refused)
553 db_w(",\"queries_total\":" as *u8); db_n(qsum)
554 db_w(",\"docs_total\":" as *u8); db_n(dsum)
555 var avg: i64 = 0 - 1
556 if scored == BE_BRIGHT_N { avg = sum / BE_BRIGHT_N }
557 db_w(",\"average_ndcg_at_10_permil\":" as *u8); db_n(avg)
558 db_w(",\"published_bm25_average_permil\":" as *u8); db_n(BE_BRIGHT_BM25_PUBLISHED_PERMIL)
559 var bq_avg: i64 = 0 - 1
560 var fq_avg: i64 = 0 - 1
561 if scored == BE_BRIGHT_N { bq_avg = bq_sum / BE_BRIGHT_N; fq_avg = fq_sum / BE_BRIGHT_N }
562 var ce_avg: i64 = 0 - 1
563 var cef_avg: i64 = 0 - 1
564 if ce_n == BE_BRIGHT_N { ce_avg = ce_sum / BE_BRIGHT_N; cef_avg = cef_sum / BE_BRIGHT_N }
565 var prf_avg: i64 = 0 - 1
566 if prf_n == BE_BRIGHT_N { prf_avg = prf_sum / BE_BRIGHT_N }
567 var lqd: i64 = 0
568 var lqq: i64 = 0
569 var lqf: i64 = 0
570 if lq_n > 0 { lqd = lq_d / lq_n; lqq = lq_q / lq_n; lqf = lq_f / lq_n }
571 db_w(",\"bm25q\":{\"average_ndcg_at_10_permil\":" as *u8); db_n(bq_avg)
572 db_w(",\"fusion_average_ndcg_at_10_permil\":" as *u8); db_n(fq_avg)
573 db_w(",\"crossenc_splits_measured\":" as *u8); db_n(ce_n)
574 db_w(",\"crossenc_average_ndcg_at_10_permil\":" as *u8); db_n(ce_avg)
575 db_w(",\"cefusion_average_ndcg_at_10_permil\":" as *u8); db_n(cef_avg)
576 db_w(",\"prf_splits_measured\":" as *u8); db_n(prf_n)
577 db_w(",\"prf_average_ndcg_at_10_permil\":" as *u8); db_n(prf_avg)
578 db_w(",\"long_rule\":\"per split, query tokens above that split's mean; aggregated weighted by long_n\",\"long_n_total\":" as *u8); db_n(lq_n)
579 db_w(",\"long_bm25_permil\":" as *u8); db_n(lqd)
580 db_w(",\"long_bm25q_permil\":" as *u8); db_n(lqq)
581 db_w(",\"long_fusion_permil\":" as *u8); db_n(lqf)
582 db_w(",\"queries_with_repeated_term\":" as *u8); db_n(rep_sum)
583 db_w(",\"norepeat_n\":" as *u8); db_n(nr_n)
584 db_w(",\"norepeat_identical\":" as *u8); db_n(nr_s)
585 db_w(",\"accept_rule\":\"declared 2026-09-04 (search S5): the FUSED arm must EXCEED plain BM25 on the long-query subset by nDCG at 10, and every no-repeat query must rank IDENTICALLY under both\",\"verdict\":\"" as *u8)
586 if lq_n > 0 { if lqf > lqd { if nr_s == nr_n { db_w("FUSION-BEATS-BM25-ON-LONG" as *u8) } else { db_w("IDENTITY-CONTROL-FAILED" as *u8) } } else { db_w("FUSION-DOES-NOT-BEAT-BM25-ON-LONG" as *u8) } } else { db_w("NO-LONG-QUERIES" as *u8) }
587 db_w("\"}" as *u8)
588 db_w(",\"delta_vs_published_bm25_permil\":" as *u8); if avg >= 0 { db_n(avg - BE_BRIGHT_BM25_PUBLISHED_PERMIL) } else { db_n(0 - 1) }
589 if avg >= 0 {
590 // S5: the row carries the BEST sovereign lexical arm this sweep measured, named on the row (see nx_beir_arms_lib, R0f)
591 // R0f: the arm is chosen by nx_beir_arms_lib from this sweep's own averages (plain, BM25Q fusion under its rule, the
592 // cross-encoder rerank and its RRF fusion when every split measured them and they exceed plain)
593 var fusion_ok: i64 = 0
594 if lq_n > 0 { if lqf > lqd { if nr_s == nr_n { fusion_ok = 1 } } }
595 let arm: i64 = be_lb_choose(avg, fq_avg, fusion_ok, prf_n, prf_avg, ce_n, ce_avg, cef_avg, BE_BRIGHT_N)
596 let lb_score: i64 = be_lb_arm_score(arm, avg, fq_avg, prf_avg, ce_avg, cef_avg)
597 let lb_org: *u8 = be_lb_arm_org(arm)
598 let lb_arm: *u8 = be_lb_arm_label(arm)
599 db_w(",\"leaderboard_arm\":\"" as *u8); db_w(lb_arm); db_w("\",\"leaderboard_score_permil\":" as *u8); db_n(lb_score)
600 if (qfile as i64) != 0 {
601 db_w(",\"leaderboard_row\":\"NOT-WRITTEN (a referee replay on an alternate query set; a query another model wrote is not the estate's system)\"" as *u8)
602 } else {
603 let rank: i64 = be_lb_write(lb_score, today, lb_org)
604 db_w(",\"leaderboard_row\":" as *u8)
605 if rank > 0 { db_w("\"WRITTEN rank=" as *u8); db_n(rank); db_w(" system=nishi-search\"" as *u8) } else { db_w("\"NOT-WRITTEN (leaderboard file refused, rc=" as *u8); db_n(rank); db_w(")\"" as *u8) }
606 }
607 } else { db_w(",\"leaderboard_row\":\"NOT-WRITTEN (twelve of twelve splits must score; a partial average is not a placement)\"" as *u8) }
608 db_w(",\"accept_rule\":\"declared BEFORE the run: every split scored, the partition scored+missing+refused = 12 printed, the average within its own tolerance of the published plain-BM25 average (14.5) before any arm above BM25 is claimed on this board\"}" as *u8)
609 db_w("\n" as *u8)
610 if scored == BE_BRIGHT_N { return 0 }
611 return 1
612}
613
614// index of byte ch in buf[from,limit), else limit
615func be_find(buf: *u8, from: i64, limit: i64, ch: i64) -> i64 {
616 var i: i64 = from
617 var res: i64 = limit
618 var go: i64 = 1
619 while go == 1 {
620 if i >= limit { go = 0 } else {
621 if buf[i] == (ch as u8) { res = i; go = 0 } else { i = i + 1 }
622 }
623 }
624 return res
625}
626
627// lowercase+hash [a-z0-9] tokens in buf[start,end); append hashes to out at noff[0]; return token count
628func be_tok(buf: *u8, start: i64, end: i64, out: *i64, noff: *i64, scr: *u8) -> i64 {
629 var i: i64 = start
630 var cnt: i64 = 0
631 var sl: i64 = 0
632 while i <= end {
633 var c: i64 = 0
634 if i < end { c = buf[i] as i64 }
635 var isc: i64 = 0
636 var lc: i64 = c
637 if c >= 65 { if c <= 90 { lc = c + 32; isc = 1 } }
638 if c >= 97 { if c <= 122 { isc = 1 } }
639 if c >= 48 { if c <= 57 { isc = 1 } }
640 if isc == 1 {
641 if sl < 500 { scr[sl] = lc as u8; sl = sl + 1 }
642 } else {
643 if sl > 0 {
644 sl = pst_stem(scr, sl)
645 out[noff[0]] = db_semhash(scr, 0, sl)
646 noff[0] = noff[0] + 1
647 cnt = cnt + 1
648 sl = 0
649 }
650 }
651 i = i + 1
652 }
653 return cnt
654}
655
656func be_qs1(a: *i64, lo: i64, hi: i64) -> i64 {
657 if lo >= hi { return 0 }
658 var i: i64 = lo
659 var j: i64 = hi
660 let p: i64 = a[(lo + hi) / 2]
661 while i <= j {
662 while a[i] < p { i = i + 1 }
663 while a[j] > p { j = j - 1 }
664 if i <= j {
665 let t: i64 = a[i]; a[i] = a[j]; a[j] = t
666 i = i + 1; j = j - 1
667 }
668 }
669 be_qs1(a, lo, j)
670 be_qs1(a, i, hi)
671 return 0
672}
673
674func be_qs2(key: *i64, pay: *i64, lo: i64, hi: i64) -> i64 {
675 if lo >= hi { return 0 }
676 var i: i64 = lo
677 var j: i64 = hi
678 let p: i64 = key[(lo + hi) / 2]
679 while i <= j {
680 while key[i] < p { i = i + 1 }
681 while key[j] > p { j = j - 1 }
682 if i <= j {
683 let t: i64 = key[i]; key[i] = key[j]; key[j] = t
684 let u: i64 = pay[i]; pay[i] = pay[j]; pay[j] = u
685 i = i + 1; j = j - 1
686 }
687 }
688 be_qs2(key, pay, lo, j)
689 be_qs2(key, pay, i, hi)
690 return 0
691}
692
693// log2(q) in 1/1024ths for q>=1
694func be_log2_1024(q: i64) -> i64 {
695 if q <= 1 { return 0 }
696 var bl: i64 = 0
697 var t: i64 = q
698 while t > 1 { t = t / 2; bl = bl + 1 }
699 var frac: i64 = 0
700 if bl >= 6 { frac = (q / (1 << (bl - 6))) - 64 }
701 if bl < 6 { frac = (q << (6 - bl)) - 64 }
702 if frac < 0 { frac = 0 }
703 return bl * K_MAGIC_1024 + frac * 16
704}
705
706func be_disc(r: i64) -> i64 {
707 if r == 1 { return 1000 }
708 if r == 2 { return 631 }
709 if r == 3 { return 500 }
710 if r == 4 { return 431 }
711 if r == 5 { return 387 }
712 if r == 6 { return 356 }
713 if r == 7 { return 333 }
714 if r == 8 { return 315 }
715 if r == 9 { return 301 }
716 if r == 10 { return 289 }
717 return 0
718}
719
720// R0 PROXIMITY FEATURES: tokenise a candidate doc's raw span and measure how TIGHTLY the query terms co-occur --
721// the signal a bag-of-words BM25 cannot see. out[0] = the smallest token window covering every DISTINCT query term
722// present in the doc (-1 when fewer than two are present); out[1] = adjacent query-term pairs (phrase-ness).
723// bp = scratch box mmapped once by main and sized from the corpus: [0]=doc hashes [1]=match slot per token
724// [2]=present flag per query slot [3]=window counts per query slot [4]=count box. No per-call allocation.
725func be_prox(cbuf: *u8, ts: i64, te: i64, qh: *i64, nqh: i64, scr: *u8, bp: *i64, out: *i64) -> i64 {
726 let dh: *i64 = bp[0] as *i64
727 let mt: *i64 = bp[1] as *i64
728 let pr: *u8 = bp[2] as *u8
729 let cn: *i64 = bp[3] as *i64
730 let no: *i64 = bp[4] as *i64
731 no[0] = 0
732 be_tok(cbuf, ts, te, dh, no, scr)
733 let dn: i64 = no[0]
734 var j: i64 = 0
735 while j < nqh { pr[j] = 0 as u8; cn[j] = 0; j = j + 1 }
736 var i: i64 = 0
737 while i < dn {
738 var mj: i64 = 0 - 1
739 var jj: i64 = 0
740 while jj < nqh { if dh[i] == qh[jj] { mj = jj; jj = nqh } else { jj = jj + 1 } }
741 if mj >= 0 { pr[mj] = 1 as u8 }
742 mt[i] = mj
743 i = i + 1
744 }
745 var npres: i64 = 0
746 j = 0
747 while j < nqh { if pr[j] == (1 as u8) { npres = npres + 1 } j = j + 1 }
748 var big: i64 = 0
749 i = 0
750 while i + 1 < dn { if mt[i] >= 0 { if mt[i + 1] >= 0 { if mt[i + 1] != mt[i] { big = big + 1 } } } i = i + 1 }
751 var minwin: i64 = 0 - 1
752 if npres >= 2 {
753 var have: i64 = 0
754 var l: i64 = 0
755 var r: i64 = 0
756 minwin = dn
757 while r < dn {
758 let mr: i64 = mt[r]
759 if mr >= 0 { if cn[mr] == 0 { have = have + 1 } cn[mr] = cn[mr] + 1 }
760 while have == npres {
761 let wlen: i64 = r - l + 1
762 if wlen < minwin { minwin = wlen }
763 let ml: i64 = mt[l]
764 if ml >= 0 { cn[ml] = cn[ml] - 1; if cn[ml] == 0 { have = have - 1 } }
765 l = l + 1
766 }
767 r = r + 1
768 }
769 }
770 out[0] = minwin
771 out[1] = big
772 return 0
773}
774
775// decimal argv parse; stops at the first non-digit
776func be_atoi(s: *u8) -> i64 {
777 var v: i64 = 0
778 var i: i64 = 0
779 var go: i64 = 1
780 while go == 1 {
781 let c: i64 = s[i] as i64
782 if c >= BE_ASCII_ZERO { if c <= BE_ASCII_NINE { v = v * BE_DECIMAL + (c - BE_ASCII_ZERO); i = i + 1 } else { go = 0 } } else { go = 0 }
783 }
784 return v
785}
786
787// ONE CROSS-ENCODER PAIR AS ONE POOL TASK (2026-09-15). The pool's unit of work is the whole forward, never a band of
788// one matmul: per-matmul banding pays a submit and a wait for every one of the ~40 matmuls inside a forward and was
789// measured as no speedup (search.plan row 1789456036), while a pair-level task pays ONE sync per forward. The forward
790// inside stays the serial path (the encoder handle carries no pool), so a pooled run and a serial run produce the same
791// score for every pair BY CONSTRUCTION and only the wall clock moves. Every task owns its scratch (ids, types, doc
792// pieces); the encoder weights and the wordpiece table are read-only after load (neither wp_tokenize/wp_pair nor
793// bc_forward writes its table -- checked 2026-09-15), and bc_forward mmaps and unmaps its own activations per call.
794struct BeCeTask {
795 cg: i64, // *i64 the loaded encoder (read-only)
796 wg: i64, // *i64 the wordpiece table (read-only)
797 cbuf: i64, // *u8 the corpus bytes
798 ts: i64, // document span start
799 te: i64, // document span end
800 qtok: i64, // *i64 the query pieces (read-only, shared by the burst)
801 nqx: i64,
802 maxlen: i64,
803 dtok: i64, // *i64 THIS task's document-piece scratch
804 ids: i64, // *i64 THIS task's pair ids
805 types: i64, // *i64 THIS task's pair types
806 score: i64, // OUT: the relevance logit in micro units
807}
808func be_ce_task_at(tasks: *u8, i: i64) -> *BeCeTask { return ((tasks as i64) + i * BE_CE_TASK_BYTES) as *BeCeTask }
809func _be_ce_task(ctx_i: i64) -> i64 {
810 let t: *BeCeTask = ctx_i as *BeCeTask
811 let ndx: i64 = wp_tokenize(t.wg as *i64, t.cbuf as *u8, t.ts, t.te - t.ts, t.dtok as *i64)
812 let tx: i64 = wp_pair(t.wg as *i64, t.qtok as *i64, t.nqx, t.dtok as *i64, ndx, t.maxlen, t.ids as *i64, t.types as *i64)
813 t.score = bc_f32_micro(bc_forward(t.cg as *i64, t.ids as *i64, t.types as *i64, tx))
814 return 0
815}
816// a decimal into dst at off (returns the new offset); a bare string copy without the terminator
817func be_dec(dst: *u8, off: i64, v: i64) -> i64 {
818 var o: i64 = off
819 var x: i64 = v
820 if x < 0 { dst[o] = 45 as u8; o = o + 1; x = 0 - x }
821 let t: *u8 = sys_mmap(24)
822 var n: i64 = 0
823 if x == 0 { t[0] = 48 as u8; n = 1 }
824 while x > 0 { t[n] = (48 + x % 10) as u8; x = x / 10; n = n + 1 }
825 while n > 0 { n = n - 1; dst[o] = t[n]; o = o + 1 }
826 sys_munmap(t, 24)
827 return o
828}
829func be_scat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64 = off; var i: i64 = 0; while s[i] != (0 as u8) { dst[o] = s[i]; o = o + 1; i = i + 1 } return o }
830// THE PROGRESS ROW (2026-09-15): truncate-written (tmp + rename, so a reader never sees a torn row) after every query.
831// A run that prints only its final JSON is silent for hours, and a silent run is indistinguishable from a dead one: the
832// depth-50 NAS run of this date burned 23 CPU-hours with nobody able to say whether it was a third or nine tenths done.
833// Negative on any failure so the caller can COUNT the rows that did not land; it never refuses the run.
834// the stamp path for a queries path: knowledge/status/beir_eval.<queries path with / and . folded to _>.progress
835func be_progress_path(dst: *u8, qpath: *u8, tmp: i64) -> i64 {
836 var o: i64 = be_scat(dst, 0, BE_PROGRESS_DIR)
837 var qi: i64 = 0
838 while qpath[qi] != (0 as u8) {
839 if qi < BE_PATH_CAP {
840 var c: i64 = qpath[qi] as i64
841 if c == BE_SLASH { c = BE_USCORE }
842 if c == BE_DOT { c = BE_USCORE }
843 dst[o] = c as u8
844 o = o + 1
845 }
846 qi = qi + 1
847 }
848 if tmp == 1 { o = be_scat(dst, o, BE_PROGRESS_SFX_TMP) } else { o = be_scat(dst, o, BE_PROGRESS_SFX) }
849 dst[o] = 0 as u8
850 return o
851}
852func be_progress(qpath: *u8, done: i64, pairs: i64, workers: i64, depth: i64) -> i64 {
853 let cap: i64 = BE_PROGRESS_BYTES + BE_PATH_CAP
854 let b: *u8 = sys_mmap(cap)
855 var o: i64 = be_scat(b, 0, "ts=" as *u8); o = be_dec(b, o, sys_now_realtime_sec())
856 o = be_scat(b, o, " queries_done=" as *u8); o = be_dec(b, o, done)
857 o = be_scat(b, o, " ce_pairs=" as *u8); o = be_dec(b, o, pairs)
858 o = be_scat(b, o, " ce_depth=" as *u8); o = be_dec(b, o, depth)
859 o = be_scat(b, o, " pool_workers=" as *u8); o = be_dec(b, o, workers)
860 o = be_scat(b, o, " queries=" as *u8)
861 var qi: i64 = 0
862 while qpath[qi] != (0 as u8) { if qi < BE_PATH_CAP { b[o] = qpath[qi]; o = o + 1 } qi = qi + 1 }
863 o = be_scat(b, o, " -- truncate-written by nx_beir_eval after every query; a ts that stops moving while the process lives is a hung run, not a slow one\n" as *u8)
864 let pp: *u8 = sys_mmap(BE_PATH_CAP * 2)
865 let pt: *u8 = sys_mmap(BE_PATH_CAP * 2)
866 be_progress_path(pp, qpath, 0)
867 be_progress_path(pt, qpath, 1)
868 let fd: i64 = sys_openat_wr(pt, MODE_0644)
869 if fd < 0 { sys_munmap(b, cap); return 0 - 1 }
870 var off: i64 = 0
871 while off < o {
872 let wv: i64 = sys_write(fd, ((b as i64) + off) as *u8, o - off)
873 if wv <= 0 { sys_close(fd); sys_munmap(b, cap); return 0 - 2 }
874 off = off + wv
875 }
876 sys_close(fd)
877 sys_munmap(b, cap)
878 if sys_renameat(pt, pp) != 0 { return 0 - 3 }
879 return 0
880}
881func main(argc: i64, argv: *i64) -> i64 {
882 let G: *i64 = sys_mmap(BE_G_SLOTS * BE_I64) as *i64
883 let scr: *u8 = sys_mmap(K_MAGIC_1024)
884
885 // ---------- flags (R0d): --set <root>, --bright <root>, --bm25-only; the rest stay positional ----------
886 let pos: *i64 = sys_mmap(BE_POS_CAP * BE_I64) as *i64
887 var npos: i64 = 0
888 var root: *u8 = 0 as *u8
889 var bright_root: *u8 = 0 as *u8
890 var bm25_only: i64 = 0
891 var qfile: *u8 = 0 as *u8
892 var ai: i64 = 1
893 while ai < argc {
894 let a: *u8 = argv[ai] as *u8
895 var used_flag: i64 = 0
896 if be_streq(a, BE_FLAG_SET) == 1 { if ai + 1 < argc { root = argv[ai + 1] as *u8; ai = ai + 1 } used_flag = 1 }
897 if be_streq(a, BE_FLAG_BRIGHT) == 1 { if ai + 1 < argc { bright_root = argv[ai + 1] as *u8; ai = ai + 1 } used_flag = 1 }
898 if be_streq(a, BE_FLAG_BM25ONLY) == 1 { bm25_only = 1; used_flag = 1 }
899 // dash-less twins of the three flags: nx_sov_build_run's qualify lane treats ANY forwarded argument that starts
900 // with -- as one of its own build-lane flags and refuses the run (measured 2026-09-14), so a qualification run
901 // spells them set=<root>, bright=<root>, bm25only. Same parser, same variables, one spelling per lane.
902 let kv_set: *u8 = "set=" as *u8
903 let kv_bright: *u8 = "bright=" as *u8
904 let kv_bm25: *u8 = "bm25only" as *u8
905 if be_starts_at(a, 0, be_slen(a), kv_set) == 1 { root = ((a as i64) + be_slen(kv_set)) as *u8; used_flag = 1 }
906 if be_starts_at(a, 0, be_slen(a), kv_bright) == 1 { bright_root = ((a as i64) + be_slen(kv_bright)) as *u8; used_flag = 1 }
907 if be_streq(a, kv_bm25) == 1 { bm25_only = 1; used_flag = 1 }
908 if be_streq(a, BE_FLAG_QUERIES) == 1 { if ai + 1 < argc { qfile = argv[ai + 1] as *u8; ai = ai + 1 } used_flag = 1 }
909 let kv_queries: *u8 = "queries=" as *u8
910 if be_starts_at(a, 0, be_slen(a), kv_queries) == 1 { qfile = ((a as i64) + be_slen(kv_queries)) as *u8; used_flag = 1 }
911 if used_flag == 0 { if npos < BE_POS_CAP { pos[npos] = argv[ai]; npos = npos + 1 } }
912 ai = ai + 1
913 }
914 if (bright_root as i64) != 0 { return be_bright(bright_root, argv[0] as *u8, bm25_only, pos, npos, qfile) }
915 let pc: *u8 = sys_mmap(BE_PATH_CAP)
916 let pq: *u8 = sys_mmap(BE_PATH_CAP)
917 let pd: *u8 = sys_mmap(BE_PATH_CAP)
918 let px: *u8 = sys_mmap(BE_PATH_CAP)
919
920 // ---------- load corpus (the buffer is sized from the file; every table below is sized from the buffer) ----------
921 var cn: i64 = 0
922 if (root as i64) == 0 {
923 be_path(pc, BE_ROOT_DEFAULT, BE_F_CORPUS)
924 be_path(px, BE_ROOT_DEFAULT_TMP, BE_F_CORPUS)
925 cn = be_read_fb(pc, px, G)
926 } else {
927 be_path(pc, root, BE_F_CORPUS)
928 cn = be_read(pc, G)
929 }
930 if cn <= 0 { db_w("{\"error\":\"corpus.tsv missing\",\"path\":\"" as *u8); db_w(pc); db_w("\"}\n" as *u8); return 1 }
931 let cbuf: *u8 = G[0] as *u8
932 let nd_cap: i64 = be_count_byte(cbuf, cn, BE_NL) + 1
933 let tok_cap: i64 = cn / BE_TOK_BYTES + nd_cap + 1
934
935 let thash: *i64 = sys_mmap(tok_cap * BE_I64) as *i64
936 let noff: *i64 = sys_mmap(BE_I64) as *i64
937 noff[0] = 0
938 let doc_start: *i64 = sys_mmap((nd_cap + 1) * BE_I64) as *i64
939 let doc_len: *i64 = sys_mmap(nd_cap * BE_I64) as *i64
940 let doc_idh: *i64 = sys_mmap(nd_cap * BE_I64) as *i64
941 // seq1494 RERANK ARM: keep each doc's RAW TEXT SPAN in cbuf. BM25 works on this harness's own hashed
942 // vocab, but the PPMI late-interaction model has its OWN word ids, so the reranker needs the original
943 // characters. Two i64 arrays is the whole cost of making rung 2 measurable instead of asserted.
944 let doc_ts: *i64 = sys_mmap(nd_cap * BE_I64) as *i64
945 let doc_te: *i64 = sys_mmap(nd_cap * BE_I64) as *i64
946 var nd: i64 = 0
947 var maxspan: i64 = 0 // longest raw doc span, derives the proximity token scratch (no guessed cap)
948 var maxdoctok: i64 = 0 // most tokens in one doc, derives the forward-index scratch (no guessed cap)
949
950 var p: i64 = 0
951 while p < cn {
952 let eol: i64 = be_find(cbuf, p, cn, BE_NL)
953 let tab: i64 = be_find(cbuf, p, eol, BE_TAB)
954 if tab < eol { if nd < nd_cap {
955 doc_idh[nd] = db_semhash(cbuf, p, tab - p)
956 doc_start[nd] = noff[0]
957 doc_ts[nd] = tab + 1
958 doc_te[nd] = eol
959 if eol - tab - 1 > maxspan { maxspan = eol - tab - 1 }
960 doc_len[nd] = be_tok(cbuf, tab + 1, eol, thash, noff, scr)
961 if doc_len[nd] > maxdoctok { maxdoctok = doc_len[nd] }
962 nd = nd + 1
963 } }
964 p = eol + 1
965 }
966 doc_start[nd] = noff[0]
967 let ntok: i64 = noff[0]
968
969 // ---------- vocab = sort+unique ----------
970 let vocab: *i64 = sys_mmap((ntok + 1) * BE_I64) as *i64
971 var vi: i64 = 0
972 while vi < ntok { vocab[vi] = thash[vi]; vi = vi + 1 }
973 be_qs1(vocab, 0, ntok - 1)
974 var nv: i64 = 0
975 var k: i64 = 0
976 while k < ntok {
977 if nv == 0 { vocab[nv] = vocab[k]; nv = nv + 1 }
978 else { if vocab[k] != vocab[nv - 1] { vocab[nv] = vocab[k]; nv = nv + 1 } }
979 k = k + 1
980 }
981
982 // ---------- forward index + df ----------
983 let dterm: *i64 = sys_mmap((ntok + 1) * BE_I64) as *i64
984 let dtf: *i64 = sys_mmap((ntok + 1) * BE_I64) as *i64
985 let doc_off: *i64 = sys_mmap((nd_cap + 1) * BE_I64) as *i64
986 let df: *i64 = sys_mmap((nv + 1) * BE_I64) as *i64
987 var z: i64 = 0
988 while z < nv { df[z] = 0; z = z + 1 }
989 let tmpcap: i64 = maxdoctok + 1
990 let tmp: *i64 = sys_mmap(tmpcap * BE_I64) as *i64
991 var dpos: i64 = 0
992 var d: i64 = 0
993 while d < nd {
994 let s0: i64 = doc_start[d]
995 let s1: i64 = doc_start[d + 1]
996 var m: i64 = 0
997 var q: i64 = s0
998 while q < s1 {
999 if m < tmpcap { tmp[m] = db_bsearch_i64(vocab, nv, thash[q]); m = m + 1 }
1000 q = q + 1
1001 }
1002 be_qs1(tmp, 0, m - 1)
1003 doc_off[d] = dpos
1004 var a: i64 = 0
1005 while a < m {
1006 var b: i64 = a + 1
1007 var go3: i64 = 1
1008 while go3 == 1 { if b < m { if tmp[b] == tmp[a] { b = b + 1 } else { go3 = 0 } } else { go3 = 0 } }
1009 if dpos < ntok { dterm[dpos] = tmp[a]; dtf[dpos] = b - a; dpos = dpos + 1 }
1010 df[tmp[a]] = df[tmp[a]] + 1
1011 a = b
1012 }
1013 d = d + 1
1014 }
1015 doc_off[nd] = dpos
1016
1017 // ---------- inverted postings (R0d DURABLE FIX, 2026-09-15): term -> (doc, tf), built ONCE from the forward index ----------
1018 // The per-query loop used to binary-search EVERY doc for EVERY query term (O(nq * nqt * nd)): on leetcode
1019 // (413,932 docs) that outlived the per-split hour and the driver's two-hour wall, so the twelve-of-twelve
1020 // BRIGHT average could not be measured under load. df[t] is exactly the posting count of term t, so the
1021 // offsets are a prefix sum over df and the fill is one pass over the forward index in doc order -- every
1022 // term's postings come out doc-ascending, which the candidate pass relies on for identical tie order.
1023 // A posting packs doc and tf in one word (doc * BE_PT_TF_MOD + tf); a tf at or past the radix is clamped and COUNTED.
1024 let pt_off: *i64 = sys_mmap((nv + 2) * BE_I64) as *i64
1025 var pt_acc: i64 = 0
1026 var pt_t: i64 = 0
1027 while pt_t < nv { pt_off[pt_t] = pt_acc; pt_acc = pt_acc + df[pt_t]; pt_t = pt_t + 1 }
1028 pt_off[nv] = pt_acc
1029 let pt_fill: *i64 = sys_mmap((nv + 2) * BE_I64) as *i64
1030 pt_t = 0
1031 while pt_t <= nv { pt_fill[pt_t] = pt_off[pt_t]; pt_t = pt_t + 1 }
1032 let pt: *i64 = sys_mmap((pt_acc + 1) * BE_I64) as *i64
1033 var pt_clamped: i64 = 0
1034 var pt_d: i64 = 0
1035 while pt_d < nd {
1036 var pt_i: i64 = doc_off[pt_d]
1037 let pt_e: i64 = doc_off[pt_d + 1]
1038 while pt_i < pt_e {
1039 let pt_term: i64 = dterm[pt_i]
1040 var pt_tf: i64 = dtf[pt_i]
1041 if pt_tf >= BE_PT_TF_MOD { pt_tf = BE_PT_TF_MOD - 1; pt_clamped = pt_clamped + 1 }
1042 pt[pt_fill[pt_term]] = pt_d * BE_PT_TF_MOD + pt_tf
1043 pt_fill[pt_term] = pt_fill[pt_term] + 1
1044 pt_i = pt_i + 1
1045 }
1046 pt_d = pt_d + 1
1047 }
1048
1049 var totlen: i64 = 0
1050 z = 0
1051 while z < nd { totlen = totlen + doc_len[z]; z = z + 1 }
1052 var avgdl: i64 = 1
1053 if nd > 0 { avgdl = totlen / nd }
1054 if avgdl < 1 { avgdl = 1 }
1055
1056 // ---------- doc-id -> docidx (sorted idhash) ----------
1057 let sidh: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64
1058 let sidx: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64
1059 z = 0
1060 while z < nd { sidh[z] = doc_idh[z]; sidx[z] = z; z = z + 1 }
1061 be_qs2(sidh, sidx, 0, nd - 1)
1062
1063 // ---------- qrels ----------
1064 var qn: i64 = 0
1065 if (root as i64) == 0 {
1066 be_path(pq, BE_ROOT_DEFAULT, BE_F_QRELS)
1067 be_path(px, BE_ROOT_DEFAULT_TMP, BE_F_QRELS)
1068 qn = be_read_fb(pq, px, (G as i64 + BE_I64) as *i64)
1069 } else {
1070 be_path(pq, root, BE_F_QRELS)
1071 qn = be_read(pq, (G as i64 + BE_I64) as *i64)
1072 }
1073 if qn <= 0 { db_w("{\"error\":\"qrels test.tsv missing\",\"path\":\"" as *u8); db_w(pq); db_w("\"}\n" as *u8); return 1 }
1074 let qbuf: *u8 = G[1] as *u8
1075 let nj_cap: i64 = be_count_byte(qbuf, qn, BE_NL) + 1
1076 let j_qid: *i64 = sys_mmap(nj_cap * BE_I64) as *i64
1077 let j_doc: *i64 = sys_mmap(nj_cap * BE_I64) as *i64
1078 let j_scr: *i64 = sys_mmap(nj_cap * BE_I64) as *i64
1079 var nj: i64 = 0
1080 var qp: i64 = 0
1081 var hdr: i64 = 1
1082 while qp < qn {
1083 let e2: i64 = be_find(qbuf, qp, qn, BE_NL)
1084 if hdr == 1 { hdr = 0 } else {
1085 let t1: i64 = be_find(qbuf, qp, e2, BE_TAB)
1086 if t1 < e2 {
1087 let t2: i64 = be_find(qbuf, t1 + 1, e2, BE_TAB)
1088 if t2 < e2 {
1089 var sc: i64 = 0
1090 var sp: i64 = t2 + 1
1091 while sp < e2 { let dch: i64 = qbuf[sp] as i64; if dch >= 48 { if dch <= 57 { sc = sc * 10 + (dch - 48) } } sp = sp + 1 }
1092 let dh: i64 = db_semhash(qbuf, t1 + 1, t2 - t1 - 1)
1093 let dpos2: i64 = db_bsearch_i64(sidh, nd, dh)
1094 if dpos2 >= 0 { if nj < nj_cap {
1095 j_qid[nj] = db_semhash(qbuf, qp, t1 - qp)
1096 j_doc[nj] = sidx[dpos2]
1097 j_scr[nj] = sc
1098 nj = nj + 1
1099 } }
1100 }
1101 }
1102 }
1103 qp = e2 + 1
1104 }
1105 // sort judgments by qid, carrying an index permutation (so j_doc/j_scr stay addressable via jidx)
1106 let jidx: *i64 = sys_mmap((nj + 1) * BE_I64) as *i64
1107 z = 0
1108 while z < nj { jidx[z] = z; z = z + 1 }
1109 be_qs2(j_qid, jidx, 0, nj - 1)
1110
1111 // ---------- excluded (R0d): <root>/excluded.tsv, query id TAB doc id; absent for BEIR sets ----------
1112 var xn: i64 = 0
1113 if (root as i64) == 0 { be_path(px, BE_ROOT_DEFAULT, BE_F_EXCLUDED) } else { be_path(px, root, BE_F_EXCLUDED) }
1114 xn = be_read(px, (G as i64 + 3 * BE_I64) as *i64)
1115 var nx: i64 = 0
1116 var x_qid: *i64 = 0 as *i64
1117 var x_doc: *i64 = 0 as *i64
1118 var x_unknown: i64 = 0
1119 if xn > 0 {
1120 let xbuf: *u8 = G[3] as *u8
1121 let x_cap: i64 = be_count_byte(xbuf, xn, BE_NL) + 1
1122 x_qid = sys_mmap(x_cap * BE_I64) as *i64
1123 x_doc = sys_mmap(x_cap * BE_I64) as *i64
1124 var xp: i64 = 0
1125 while xp < xn {
1126 let xe: i64 = be_find(xbuf, xp, xn, BE_NL)
1127 let xt: i64 = be_find(xbuf, xp, xe, BE_TAB)
1128 if xt < xe {
1129 let xdh: i64 = db_semhash(xbuf, xt + 1, xe - xt - 1)
1130 let xdp: i64 = db_bsearch_i64(sidh, nd, xdh)
1131 if xdp >= 0 { if nx < x_cap { x_qid[nx] = db_semhash(xbuf, xp, xt - xp); x_doc[nx] = sidx[xdp]; nx = nx + 1 } } else { x_unknown = x_unknown + 1 }
1132 }
1133 xp = xe + 1
1134 }
1135 be_qs2(x_qid, x_doc, 0, nx - 1)
1136 }
1137 var excluded_applied: i64 = 0
1138
1139 // ---------- per query ----------
1140 var dqn: i64 = 0
1141 if (root as i64) == 0 {
1142 be_qpath(pd, BE_ROOT_DEFAULT, qfile)
1143 be_qpath(px, BE_ROOT_DEFAULT_TMP, qfile)
1144 dqn = be_read_fb(pd, px, (G as i64 + 2 * BE_I64) as *i64)
1145 } else {
1146 be_qpath(pd, root, qfile)
1147 dqn = be_read(pd, (G as i64 + 2 * BE_I64) as *i64)
1148 }
1149 if dqn <= 0 { db_w("{\"error\":\"queries.tsv missing\",\"path\":\"" as *u8); db_w(pd); db_w("\"}\n" as *u8); return 1 }
1150 let dbuf: *u8 = G[2] as *u8
1151 let nq_cap: i64 = be_count_byte(dbuf, dqn, BE_NL) + 1
1152 let qcap: i64 = be_maxline(dbuf, dqn) / BE_TOK_BYTES + 2 // tokens in the longest query line
1153 let score: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64
1154 let qtid: *i64 = sys_mmap(qcap * BE_I64) as *i64
1155 // S5 BM25Q ARM (2026-09-15): the query-side saturation arm shares the postings walk. Per query token: whether it is
1156 // the FIRST occurrence of its term and the term's query-term frequency; a second score array; the arm's own top-K;
1157 // the pool-fusion scratch; and one per-query record so the long-query subset and the identity control are DERIVED
1158 // after the loop from the data, never from a constant.
1159 let qfirst: *i64 = sys_mmap(qcap * BE_I64) as *i64
1160 let qcnt: *i64 = sys_mmap(qcap * BE_I64) as *i64
1161 let scoreq: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64
1162 let topq: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64
1163 let topq_s: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64
1164 let qrank: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64
1165 let fsq: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64
1166 let fqu: *u8 = sys_mmap(BE_KCAND + 1)
1167 let pq_tok: *i64 = sys_mmap(nq_cap * BE_I64) as *i64
1168 let pq_nd: *i64 = sys_mmap(nq_cap * BE_I64) as *i64
1169 let pq_ndq: *i64 = sys_mmap(nq_cap * BE_I64) as *i64
1170 let pq_ndf: *i64 = sys_mmap(nq_cap * BE_I64) as *i64
1171 let pq_rep: *i64 = sys_mmap(nq_cap * BE_I64) as *i64
1172 let pq_same: *i64 = sys_mmap(nq_cap * BE_I64) as *i64
1173 var pq_n: i64 = 0
1174 var sum_ndcg_q: i64 = 0
1175 var sum_ndcg_fq: i64 = 0
1176 let top: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 // seq1494 widened the shortlist to 50 but left this at 16 slots: top[16..49] overran 272B every query -- harmless while only WRITTEN (BM25 arm reads top[0..9]), FATAL once the rerank arm READ the trampled slots back as doc indices
1177 let goldsc: *i64 = sys_mmap((nj + 1) * BE_I64) as *i64
1178 let used: *u8 = sys_mmap(nd + 1)
1179 // R0d DURABLE FIX (2026-09-15): the candidate pass walks only the docs a query term touched (mark) and keeps the
1180 // shortlist in one bounded, index-ordered insertion (top_s) -- the 50 full-corpus scans it replaces were the
1181 // second half of the O(nq * nd) cost that kept the twelve-of-twelve BRIGHT run from finishing under load
1182 let mark: *u8 = sys_mmap(nd + 1)
1183 let top_s: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64
1184 // R0g PRF buffers: the expanded score and mark per doc, the touched-doc list, feedback term weights over the vocab
1185 let scorep: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64
1186 let pmark: *u8 = sys_mmap(nd + 1)
1187 let plist: *i64 = sys_mmap((nd + 1) * BE_I64) as *i64
1188 let tw: *i64 = sys_mmap((nv + 1) * BE_I64) as *i64
1189 let twl: *i64 = sys_mmap((nv + 1) * BE_I64) as *i64
1190 let ex_t: *i64 = sys_mmap(BE_PRF_FB_TERMS * BE_I64) as *i64
1191 let ex_w: *i64 = sys_mmap(BE_PRF_FB_TERMS * BE_I64) as *i64
1192 let ptop: *i64 = sys_mmap(BE_PRF_TOP * BE_I64) as *i64
1193 let ptop_s: *i64 = sys_mmap(BE_PRF_TOP * BE_I64) as *i64
1194 let qhbuf: *i64 = sys_mmap(qcap * BE_I64) as *i64
1195 let qnoff: *i64 = sys_mmap(BE_I64) as *i64
1196
1197 // seq1494: load the PPMI model ONCE. HONEST-ABSENT: if it is missing the rerank arm reports
1198 // UNAVAILABLE rather than silently scoring 0 -- an absent model must never read as "reranking is bad".
1199 // g-block for the PPMI lib: its contract uses slots 69..78 (byte 632), so 64 bytes was a
1200 // 560-byte arena overrun -- the seq1494 crash class (dark code, first armed 2026-08-13)
1201 let PG: *i64 = sys_mmap(BE_MAGIC_1024) as *i64
1202 var rr_ok: i64 = 0
1203 if bm25_only == 0 { rr_ok = ppl_load(PG, "knowledge/index/semppmi_v1.bin" as *u8) }
1204 // R0 TRAINED-DENSE ARM: embed_v1.bin (nx_embed_train, PPMI factorised = SGNS-class) through the SAME vocab
1205 // ids as the PPMI model; HONEST-ABSENT like it -- de_ok==0 leaves both dense slots constant (no vote).
1206 var de_ok: i64 = 0
1207 if bm25_only == 0 { de_ok = dj_load_embed(PG, "knowledge/index/embed_v1.bin" as *u8) }
1208 if de_ok == 1 { dj_build_mean(PG) }
1209 let dscore: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64
1210 let escore: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64
1211 // R0 CROSS-ENCODER ARM (2026-09-14): a pretrained cross-encoder held as a LICENSED DATA ASSET, run by the sovereign
1212 // encoder (nx_bert_ce_lib over nx_wordpiece_lib). positional: [0] model.safetensors [1] config.json [2] vocab.txt
1213 // [3] max sequence length (default the config's max_position_embeddings) [4] candidate depth (default BE_KCAND).
1214 // HONEST-ABSENT like the other arms: a model that does not load reports UNAVAILABLE, never a score of 0.
1215 var ce_model: *u8 = "knowledge/fetched/cmp_search_ce_minilm_model.safetensors" as *u8
1216 var ce_cfg: *u8 = "knowledge/fetched/cmp_search_ce_minilm_config.json" as *u8
1217 var ce_vocab: *u8 = "knowledge/fetched/cmp_search_ce_minilm_vocab.txt" as *u8
1218 if npos >= 3 { ce_model = pos[0] as *u8; ce_cfg = pos[1] as *u8; ce_vocab = pos[2] as *u8 }
1219 let CG: *i64 = sys_mmap(BC_G_BYTES) as *i64
1220 let WG: *i64 = sys_mmap(WP_G_BYTES) as *i64
1221 var ce_ok: i64 = 0
1222 if bm25_only == 0 { ce_ok = bc_load(CG, ce_model, ce_cfg) } else { CG[BC_G_MISSING] = ("skipped: --bm25-only" as *u8) as i64 }
1223 if ce_ok == 1 { if wp_load(WG, ce_vocab) != 1 { ce_ok = 0; CG[BC_G_MISSING] = ("vocab.txt" as *u8) as i64 } }
1224 var ce_maxlen: i64 = 0
1225 if ce_ok == 1 { ce_maxlen = CG[BC_G_MAXPOS] }
1226 if npos >= 4 { ce_maxlen = be_atoi(pos[3] as *u8) }
1227 if ce_ok == 1 { if ce_maxlen > CG[BC_G_MAXPOS] { ce_maxlen = CG[BC_G_MAXPOS] } }
1228 var ce_depth: i64 = BE_KCAND
1229 if npos >= 5 { ce_depth = be_atoi(pos[4] as *u8) }
1230 if ce_depth > BE_KCAND { ce_depth = BE_KCAND }
1231 var ce_workers: i64 = BE_CE_POOL_WORKERS_DEFAULT
1232 if npos >= 6 { ce_workers = be_atoi(pos[5] as *u8) }
1233 // PAIR-LEVEL FORK-JOIN (2026-09-15): ce_workers > 0 forks that many children per query burst, child w scoring the
1234 // candidates cx with cx % ce_workers == w through the SERIAL forward (CG[BC_G_POOL] stays 0, so a pair's score cannot
1235 // depend on the width), and the parent reaps them all before reading the scores. Processes, not the thread pool:
1236 // MEASURED the same day on WSL2, an 8-wide thread pool of whole forwards ran 5 s per forward against 1.6 s serial
1237 // (eight threads faulting fresh activation pages on ONE address space serialise on it), while a forked child owns its
1238 // address space and its faults. The task records live in SHARED memory so a child's score reaches the parent.
1239 let xscore: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64
1240 let xused: *u8 = sys_mmap(BE_KCAND)
1241 let xrank: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 // R0f: the cross-encoder rank of each candidate
1242 let xfsc: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64 // R0f: the RRF score over bm25-rank + crossenc-rank
1243 // one task record + one scratch set per candidate: pair ids/types bounded by max_len, document pieces by the longest span
1244 let ce_tasks: *u8 = sys_mmap_shared(BE_KCAND * BE_CE_TASK_BYTES)
1245 let ce_stp: *i64 = sys_mmap(BE_I64) as *i64
1246 var ci0: i64 = 0
1247 while ci0 < BE_KCAND {
1248 let tk0: *BeCeTask = be_ce_task_at(ce_tasks, ci0)
1249 tk0.ids = sys_mmap((ce_maxlen + 1) * BE_I64) as i64
1250 tk0.types = sys_mmap((ce_maxlen + 1) * BE_I64) as i64
1251 tk0.dtok = sys_mmap((maxspan + 1) * BE_I64) as i64
1252 tk0.score = 0
1253 ci0 = ci0 + 1
1254 }
1255 let ce_qtok: *i64 = sys_mmap((dqn + 1) * BE_I64) as *i64 // query pieces are bounded by the query file's bytes
1256 var progress_fail: i64 = 0 // progress rows that could not be written (announced in the JSON)
1257 var sum_ndcg_ce: i64 = 0
1258 var q_ce_improved: i64 = 0
1259 var q_ce_worsened: i64 = 0
1260 var sum_ndcg_cef: i64 = 0
1261 var q_cef_improved: i64 = 0
1262 var q_cef_worsened: i64 = 0
1263 var sum_ndcg_prf: i64 = 0
1264 var q_prf_improved: i64 = 0
1265 var q_prf_worsened: i64 = 0
1266 var prf_queries_expanded: i64 = 0
1267 var prf_expansions_total: i64 = 0
1268 var ce_pairs: i64 = 0
1269 let qids: *i64 = sys_mmap(BE_IDCAP * BE_I64) as *i64
1270 let dids: *i64 = sys_mmap(BE_IDCAP * BE_I64) as *i64
1271 let cscore: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64
1272 let cused: *u8 = sys_mmap(BE_KCAND)
1273 // R1b fusion-arm buffers (2026-08-13): dense ranks, rrf scores, selection flags
1274 let drank: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64
1275 let fsc: *i64 = sys_mmap(BE_KCAND * BE_I64) as *i64
1276 let fuse_u: *u8 = sys_mmap(BE_KCAND)
1277 var sum_ndcg_rr: i64 = 0
1278 var sum_ndcg_fu: i64 = 0
1279 var q_fu_improved: i64 = 0
1280 var q_fu_worsened: i64 = 0
1281 var q_improved: i64 = 0
1282 var q_worsened: i64 = 0
1283 var q_same: i64 = 0
1284 var sum_ndcg: i64 = 0
1285 var nq: i64 = 0
1286 var n_noqrel: i64 = 0
1287 var n_noterm: i64 = 0
1288 var n_noidcg: i64 = 0
1289 // R0 LEARNED ARM storage: per-candidate features + gold + idcg + fold, filled during the BM25 pass,
1290 // read once after the loop by ltr_cv. Sized from the queries file (nq_cap), never a guessed bound.
1291 let ft_feat: *i64 = sys_mmap(nq_cap * BE_KCAND * LTR_NFEAT * BE_I64) as *i64
1292 let ft_gold: *i64 = sys_mmap(nq_cap * BE_KCAND * BE_I64) as *i64
1293 let ft_ncand: *i64 = sys_mmap(nq_cap * BE_I64) as *i64
1294 let ft_idcg: *i64 = sys_mmap(nq_cap * BE_I64) as *i64
1295 let ft_fold: *i64 = sys_mmap(nq_cap * BE_I64) as *i64
1296 var ft_nq: i64 = 0
1297 // proximity scratch, sized from the corpus: a token needs a byte and a separator, so tokens <= span/2 + 1
1298 let bp_tokcap: i64 = maxspan / BE_TOK_BYTES + 2
1299 let bp: *i64 = sys_mmap(48) as *i64
1300 bp[0] = sys_mmap(bp_tokcap * BE_I64) as i64
1301 bp[1] = sys_mmap(bp_tokcap * BE_I64) as i64
1302 bp[2] = sys_mmap(qcap + 1) as i64
1303 bp[3] = sys_mmap(qcap * BE_I64) as i64
1304 bp[4] = sys_mmap(BE_I64) as i64
1305 let proxout: *i64 = sys_mmap(16) as *i64
1306 var qpp: i64 = 0
1307 while qpp < dqn {
1308 let e3: i64 = be_find(dbuf, qpp, dqn, BE_NL)
1309 let tb: i64 = be_find(dbuf, qpp, e3, BE_TAB)
1310 if tb < e3 {
1311 let qh2: i64 = db_semhash(dbuf, qpp, tb - qpp)
1312 qnoff[0] = 0
1313 be_tok(dbuf, tb + 1, e3, qhbuf, qnoff, scr)
1314 var nqt: i64 = 0
1315 var qi: i64 = 0
1316 while qi < qnoff[0] {
1317 let tid2: i64 = db_bsearch_i64(vocab, nv, qhbuf[qi])
1318 if tid2 >= 0 { if nqt < qcap { qtid[nqt] = tid2; nqt = nqt + 1 } }
1319 qi = qi + 1
1320 }
1321 let lo0: i64 = db_bsearch_i64(j_qid, nj, qh2)
1322 if lo0 < 0 { n_noqrel = n_noqrel + 1 } else {
1323 var jlo: i64 = lo0
1324 var g1: i64 = 1
1325 while g1 == 1 { if jlo > 0 { if j_qid[jlo - 1] == qh2 { jlo = jlo - 1 } else { g1 = 0 } } else { g1 = 0 } }
1326 var jhi: i64 = lo0
1327 var g2: i64 = 1
1328 while g2 == 1 { if jhi < nj - 1 { if j_qid[jhi + 1] == qh2 { jhi = jhi + 1 } else { g2 = 0 } } else { g2 = 0 } }
1329
1330 // gold + IDCG@10 FIRST (methodology: every query with relevant judgments is counted)
1331 var ng: i64 = 0
1332 var jjg: i64 = jlo
1333 while jjg <= jhi { if ng < nj { goldsc[ng] = j_scr[jidx[jjg]]; ng = ng + 1 } jjg = jjg + 1 }
1334 be_qs1(goldsc, 0, ng - 1)
1335 var idcg: i64 = 0
1336 var ri: i64 = 0
1337 while ri < 10 { if ri < ng { idcg = idcg + goldsc[ng - 1 - ri] * be_disc(ri + 1) } ri = ri + 1 }
1338
1339 if idcg <= 0 { n_noidcg = n_noidcg + 1 } else {
1340 var dcg: i64 = 0
1341 var dcg_q: i64 = 0
1342 var dcg_fq: i64 = 0
1343 var ncand_real_q: i64 = 0 // R0g: the plain arm's real candidate count, hoisted for the PRF pass
1344 // S5: a query with no term in the vocabulary ranks nothing under EITHER arm -- identical by vacuity, so the
1345 // identity control starts at 1 and the arm below overwrites it whenever it actually ranks (15 such queries
1346 // on nfcorpus read as non-identical on the first run, which was the initialiser, not the arm)
1347 var q_same10: i64 = 1
1348 var q_rep: i64 = 0
1349 if nqt <= 0 { n_noterm = n_noterm + 1 } else {
1350 z = 0
1351 while z < nd { score[z] = 0; z = z + 1 }
1352 // R0d DURABLE FIX: walk the term's postings (doc-ascending), never the corpus; the arithmetic per
1353 // (term, doc) is byte-for-byte the scan it replaces, so every score is identical
1354 // S5: first-occurrence flag and query-term frequency per token. The plain arm below stays
1355 // byte-identical (it adds once per OCCURRENCE, as it always has); the BM25Q arm adds once per
1356 // TERM with the saturated weight, so a query with no repeated term scores IDENTICALLY.
1357 var qa: i64 = 0
1358 while qa < nqt {
1359 var qcnt1: i64 = 0
1360 var firstq: i64 = 1
1361 var qb: i64 = 0
1362 while qb < nqt { if qtid[qb] == qtid[qa] { qcnt1 = qcnt1 + 1; if qb < qa { firstq = 0 } } qb = qb + 1 }
1363 qfirst[qa] = firstq
1364 qcnt[qa] = qcnt1
1365 qa = qa + 1
1366 }
1367 z = 0
1368 while z < nd { scoreq[z] = 0; z = z + 1 }
1369 var qt: i64 = 0
1370 while qt < nqt {
1371 let tid3: i64 = qtid[qt]
1372 let dfi: i64 = df[tid3]
1373 if dfi > 0 {
1374 let idf: i64 = be_log2_1024((2 * nd + 2) / (2 * dfi + 1))
1375 let idfq: i64 = idf_bm25q(idf, qcnt[qt])
1376 let addq: i64 = qfirst[qt]
1377 var pi: i64 = pt_off[tid3]
1378 let pe: i64 = pt_off[tid3 + 1]
1379 while pi < pe {
1380 let dd: i64 = pt[pi] / BE_PT_TF_MOD
1381 let tf: i64 = pt[pi] % BE_PT_TF_MOD
1382 let norm1000: i64 = 600 + (400 * doc_len[dd]) / avgdl
1383 let denom1000: i64 = tf * 1000 + (900 * norm1000) / 1000
1384 if denom1000 > 0 { score[dd] = score[dd] + (idf * tf * K_MAGIC_1900) / denom1000 }
1385 if addq == 1 { if denom1000 > 0 { scoreq[dd] = scoreq[dd] + (idfq * tf * K_MAGIC_1900) / denom1000 } }
1386 mark[dd] = 1 as u8
1387 pi = pi + 1
1388 }
1389 }
1390 qt = qt + 1
1391 }
1392 z = 0
1393 while z < nd { used[z] = 0 as u8; z = z + 1 }
1394 // R0d: the benchmark's own exclusions for this query are unrankable (BRIGHT excluded_ids)
1395 if nx > 0 {
1396 let xlo0: i64 = db_bsearch_i64(x_qid, nx, qh2)
1397 if xlo0 >= 0 {
1398 var xlo: i64 = xlo0
1399 var gx1: i64 = 1
1400 while gx1 == 1 { if xlo > 0 { if x_qid[xlo - 1] == qh2 { xlo = xlo - 1 } else { gx1 = 0 } } else { gx1 = 0 } }
1401 var xhi: i64 = xlo0
1402 var gx2: i64 = 1
1403 while gx2 == 1 { if xhi < nx - 1 { if x_qid[xhi + 1] == qh2 { xhi = xhi + 1 } else { gx2 = 0 } } else { gx2 = 0 } }
1404 var xk: i64 = xlo
1405 while xk <= xhi { used[x_doc[xk]] = 1 as u8; score[x_doc[xk]] = 0; scoreq[x_doc[xk]] = 0; excluded_applied = excluded_applied + 1; xk = xk + 1 }
1406 }
1407 }
1408 // R0d DURABLE FIX: the shortlist from ONE index-ordered pass over the touched docs (bounded, sorted
1409 // insertion; a strict compare keeps the lower index ahead on ties, exactly as the 50 full scans
1410 // did), then the zero-score fill in index order for a query touching fewer than BE_KCAND docs
1411 var ncand: i64 = 0
1412 var ncq: i64 = 0
1413 var dd2: i64 = 0
1414 while dd2 < nd {
1415 if mark[dd2] == (1 as u8) {
1416 mark[dd2] = 0 as u8
1417 // S5: the BM25Q arm's own shortlist from the same touched set, the same bounded insertion
1418 if used[dd2] == (0 as u8) {
1419 let scq2: i64 = scoreq[dd2]
1420 if scq2 > 0 {
1421 var slotq: i64 = 0 - 1
1422 if ncq < BE_KCAND { slotq = ncq; ncq = ncq + 1 } else { if scq2 > topq_s[BE_KCAND - 1] { slotq = BE_KCAND - 1 } }
1423 if slotq >= 0 {
1424 var kq: i64 = slotq
1425 while kq > 0 { if topq_s[kq - 1] < scq2 { topq[kq] = topq[kq - 1]; topq_s[kq] = topq_s[kq - 1]; kq = kq - 1 } else { break } }
1426 topq[kq] = dd2
1427 topq_s[kq] = scq2
1428 }
1429 }
1430 }
1431 if used[dd2] == (0 as u8) {
1432 let sc2: i64 = score[dd2]
1433 if sc2 > 0 {
1434 var slot: i64 = 0 - 1
1435 if ncand < BE_KCAND { slot = ncand; ncand = ncand + 1 } else { if sc2 > top_s[BE_KCAND - 1] { slot = BE_KCAND - 1 } }
1436 if slot >= 0 {
1437 var kk: i64 = slot
1438 while kk > 0 { if top_s[kk - 1] < sc2 { top[kk] = top[kk - 1]; top_s[kk] = top_s[kk - 1]; kk = kk - 1 } else { break } }
1439 top[kk] = dd2
1440 top_s[kk] = sc2
1441 }
1442 }
1443 }
1444 }
1445 dd2 = dd2 + 1
1446 }
1447 var rr: i64 = 0
1448 while rr < ncand { used[top[rr]] = 1 as u8; rr = rr + 1 }
1449 let ncand_real: i64 = ncand
1450 ncand_real_q = ncand_real
1451 var fd0: i64 = 0
1452 while ncand < BE_KCAND {
1453 if fd0 >= nd { top[ncand] = 0 - 1; ncand = ncand + 1 } else {
1454 if used[fd0] == (0 as u8) { top[ncand] = fd0; used[fd0] = 1 as u8; ncand = ncand + 1 }
1455 fd0 = fd0 + 1
1456 }
1457 }
1458 rr = 0
1459 while rr < 10 {
1460 let dpk: i64 = top[rr]
1461 var gv: i64 = 0
1462 if dpk >= 0 {
1463 var jj2: i64 = jlo
1464 while jj2 <= jhi {
1465 if j_doc[jidx[jj2]] == dpk { gv = j_scr[jidx[jj2]]; jj2 = jhi + 1 } else { jj2 = jj2 + 1 }
1466 }
1467 }
1468 dcg = dcg + gv * be_disc(rr + 1)
1469 rr = rr + 1
1470 }
1471 // S5 BM25Q ARM (pre-declared 2026-09-04, landed 2026-09-15): the same walk scored with the query-side
1472 // saturation (idf_bm25q), its own top-10 over the touched docs, and an RRF k=60 fusion of the plain
1473 // BM25 rank with the BM25Q rank over the SAME candidate pool (the R1b shape), so the delta cannot be
1474 // confounded by candidates the plain arm never saw.
1475 var rq: i64 = 0
1476 while rq < 10 {
1477 var gvq: i64 = 0
1478 if rq < ncq {
1479 let dpq: i64 = topq[rq]
1480 var jjq: i64 = jlo
1481 while jjq <= jhi { if j_doc[jidx[jjq]] == dpq { gvq = j_scr[jidx[jjq]]; jjq = jhi + 1 } else { jjq = jjq + 1 } }
1482 }
1483 dcg_q = dcg_q + gvq * be_disc(rq + 1)
1484 rq = rq + 1
1485 }
1486 var fq0: i64 = 0
1487 while fq0 < BE_KCAND { fqu[fq0] = 0 as u8; qrank[fq0] = BE_KCAND; fq0 = fq0 + 1 }
1488 var drq: i64 = 0
1489 while drq < BE_KCAND {
1490 var bq: i64 = 0 - 1
1491 var cq: i64 = 0
1492 while cq < BE_KCAND {
1493 if fqu[cq] == (0 as u8) { if top[cq] >= 0 {
1494 if bq < 0 { bq = cq } else { if scoreq[top[cq]] > scoreq[top[bq]] { bq = cq } }
1495 } }
1496 cq = cq + 1
1497 }
1498 if bq >= 0 { fqu[bq] = 1 as u8; qrank[bq] = drq }
1499 drq = drq + 1
1500 }
1501 var fq1: i64 = 0
1502 while fq1 < BE_KCAND {
1503 fsq[fq1] = 0
1504 if top[fq1] >= 0 { fsq[fq1] = BE_MAGIC_1000000 / (60 + fq1) + BE_MAGIC_1000000 / (60 + qrank[fq1]) }
1505 fq1 = fq1 + 1
1506 }
1507 var fq2: i64 = 0
1508 while fq2 < BE_KCAND { fqu[fq2] = 0 as u8; fq2 = fq2 + 1 }
1509 var rkq: i64 = 0
1510 while rkq < 10 {
1511 var bq3: i64 = 0 - 1
1512 var cq3: i64 = 0
1513 while cq3 < BE_KCAND {
1514 if fqu[cq3] == (0 as u8) { if top[cq3] >= 0 {
1515 if bq3 < 0 { bq3 = cq3 } else { if fsq[cq3] > fsq[bq3] { bq3 = cq3 } }
1516 } }
1517 cq3 = cq3 + 1
1518 }
1519 if bq3 >= 0 {
1520 fqu[bq3] = 1 as u8
1521 let dpq3: i64 = top[bq3]
1522 var gvq3: i64 = 0
1523 var jjq3: i64 = jlo
1524 while jjq3 <= jhi { if j_doc[jidx[jjq3]] == dpq3 { gvq3 = j_scr[jidx[jjq3]]; jjq3 = jhi + 1 } else { jjq3 = jjq3 + 1 } }
1525 dcg_fq = dcg_fq + gvq3 * be_disc(rkq + 1)
1526 }
1527 rkq = rkq + 1
1528 }
1529 // the anti-vacuity witness: a query with no repeated term must produce the SAME top-10 under both
1530 var same10: i64 = 1
1531 if ncand_real != ncq { same10 = 0 }
1532 var rs: i64 = 0
1533 while rs < 10 { if rs < ncq { if top[rs] != topq[rs] { same10 = 0 } } rs = rs + 1 }
1534 q_same10 = same10
1535 var qr: i64 = 0
1536 while qr < nqt { if qcnt[qr] > 1 { q_rep = 1 } qr = qr + 1 }
1537 }
1538 // ---- seq1494 RERANK ARM: re-order the SAME BM25 shortlist by PPMI late-interaction ----
1539 // Identical qrels, identical idcg, identical candidate pool -> the ONLY difference is
1540 // the ordering function, which is what makes this a controlled comparison.
1541 var dcg_rr: i64 = dcg
1542 var dcg_fu: i64 = dcg
1543 if rr_ok == 1 { if nqt > 0 {
1544 // same (buf,len) fix on the query side: the query text is dbuf[tb+1 .. e3)
1545 let nqi: i64 = ppl_tokenize_ids(PG, ((dbuf as i64) + tb + 1) as *u8, e3 - tb - 1, qids, BE_IDCAP)
1546 var ci: i64 = 0
1547 while ci < BE_KCAND {
1548 cscore[ci] = 0 - 1
1549 dscore[ci] = 0
1550 escore[ci] = 0
1551 cused[ci] = 0 as u8
1552 let dpc: i64 = top[ci]
1553 if dpc >= 0 {
1554 let dsx: i64 = doc_ts[dpc]
1555 let dex: i64 = doc_te[dpc]
1556 // BUGFIX (caught by an EMPTY result file, not by a passing test): this took
1557 // (buf, len) but was handed (cbuf, dex) -- the corpus BASE and an ABSOLUTE
1558 // END offset -- so every candidate re-tokenised the WHOLE corpus from byte 0.
1559 // 323 queries x 50 candidates x 3633 docs never finished. Pass the doc's own
1560 // span. A silent non-finish is a LOUDER bug than a wrong number.
1561 let ndi: i64 = ppl_tokenize_ids(PG, ((cbuf as i64) + dsx) as *u8, dex - dsx, dids, BE_IDCAP)
1562 cscore[ci] = ppl_maxsim_idf(PG, qids, nqi, dids, ndi)
1563 if de_ok == 1 { dscore[ci] = dj_maxsim_centered(PG, qids, nqi, dids, ndi); escore[ci] = dj_maxsim(PG, qids, nqi, dids, ndi) }
1564 }
1565 ci = ci + 1
1566 }
1567 var dcg2: i64 = 0
1568 var rk: i64 = 0
1569 while rk < 10 {
1570 var bi: i64 = 0 - 1
1571 var cj: i64 = 0
1572 while cj < BE_KCAND {
1573 if cused[cj] == (0 as u8) { if top[cj] >= 0 {
1574 if bi < 0 { bi = cj } else { if cscore[cj] > cscore[bi] { bi = cj } }
1575 } }
1576 cj = cj + 1
1577 }
1578 if bi >= 0 {
1579 cused[bi] = 1 as u8
1580 let dpk2: i64 = top[bi]
1581 var gv2: i64 = 0
1582 var jj3: i64 = jlo
1583 while jj3 <= jhi {
1584 if j_doc[jidx[jj3]] == dpk2 { gv2 = j_scr[jidx[jj3]]; jj3 = jhi + 1 } else { jj3 = jj3 + 1 }
1585 }
1586 dcg2 = dcg2 + gv2 * be_disc(rk + 1)
1587 }
1588 rk = rk + 1
1589 }
1590 dcg_rr = dcg2
1591 // R1b FUSION ARM (pre-declared 2026-08-13): RRF k=60 over the BM25 order
1592 // (top[] index IS the bm25 rank) and the dense maxsim order (cscore). A doc
1593 // must rank in BOTH signals to top the fused list -- exactly what
1594 // nx_recall_fuse ships; measured on external ground truth BEFORE wiring.
1595 var du: i64 = 0
1596 while du < BE_KCAND { fuse_u[du] = 0 as u8; du = du + 1 }
1597 var dr: i64 = 0
1598 while dr < BE_KCAND {
1599 var bj: i64 = 0 - 1
1600 var cj2: i64 = 0
1601 while cj2 < BE_KCAND {
1602 if fuse_u[cj2] == (0 as u8) { if top[cj2] >= 0 {
1603 if bj < 0 { bj = cj2 } else { if cscore[cj2] > cscore[bj] { bj = cj2 } }
1604 } }
1605 cj2 = cj2 + 1
1606 }
1607 if bj >= 0 { fuse_u[bj] = 1 as u8; drank[bj] = dr }
1608 dr = dr + 1
1609 }
1610 var fi: i64 = 0
1611 while fi < BE_KCAND {
1612 fsc[fi] = 0
1613 if top[fi] >= 0 { fsc[fi] = BE_MAGIC_1000000 / (60 + fi) + BE_MAGIC_1000000 / (60 + drank[fi]) }
1614 fi = fi + 1
1615 }
1616 var fu2: i64 = 0
1617 while fu2 < BE_KCAND { fuse_u[fu2] = 0 as u8; fu2 = fu2 + 1 }
1618 var dcg3: i64 = 0
1619 var rk3: i64 = 0
1620 while rk3 < 10 {
1621 var b3: i64 = 0 - 1
1622 var c3: i64 = 0
1623 while c3 < BE_KCAND {
1624 if fuse_u[c3] == (0 as u8) { if top[c3] >= 0 {
1625 if b3 < 0 { b3 = c3 } else { if fsc[c3] > fsc[b3] { b3 = c3 } }
1626 } }
1627 c3 = c3 + 1
1628 }
1629 if b3 >= 0 {
1630 fuse_u[b3] = 1 as u8
1631 let dpk3: i64 = top[b3]
1632 var gv3: i64 = 0
1633 var jj4: i64 = jlo
1634 while jj4 <= jhi {
1635 if j_doc[jidx[jj4]] == dpk3 { gv3 = j_scr[jidx[jj4]]; jj4 = jhi + 1 } else { jj4 = jj4 + 1 }
1636 }
1637 dcg3 = dcg3 + gv3 * be_disc(rk3 + 1)
1638 }
1639 rk3 = rk3 + 1
1640 }
1641 dcg_fu = dcg3
1642 } }
1643 // R0 CROSS-ENCODER ARM: rerank the SAME shortlist by the sovereign encoder's logit (same qrels, idcg, pool)
1644 // R0g PRF ARM (2026-09-16): RM3-style pseudo-relevance feedback, the NON-reasoning expansion control the R0c
1645 // rewriter must beat. Feedback docs = the plain arm's top BE_PRF_FB_DOCS; a candidate expansion term's weight
1646 // is the sum over those docs of tf/doclen (permil) times idf; the BE_PRF_FB_TERMS best terms NOT in the query
1647 // expand it, each weighted by its share of the best weight; the expanded score is orig_permil x plain plus
1648 // (1000 - orig_permil) x the expansion terms' BM25, over every doc either walk touches; excluded docs stay
1649 // unrankable. Anserini's RM3 defaults (fbDocs 10, fbTerms 10, originalQueryWeight 0.5) are the bar's source.
1650 var dcg_prf: i64 = dcg
1651 var prf_nex: i64 = 0
1652 if nqt > 0 { if ncand_real_q > 0 {
1653 var ntw: i64 = 0
1654 var fbi: i64 = 0
1655 while fbi < BE_PRF_FB_DOCS { if fbi < ncand_real_q {
1656 let fbd: i64 = top[fbi]
1657 if fbd >= 0 { if doc_len[fbd] > 0 {
1658 var fi2: i64 = doc_off[fbd]
1659 let fe2: i64 = doc_off[fbd + 1]
1660 while fi2 < fe2 {
1661 let ft: i64 = dterm[fi2]
1662 if tw[ft] == 0 { twl[ntw] = ft; ntw = ntw + 1 }
1663 tw[ft] = tw[ft] + (dtf[fi2] * 1000) / doc_len[fbd]
1664 fi2 = fi2 + 1
1665 }
1666 } }
1667 } fbi = fbi + 1 }
1668 // the best expansion terms by weight x idf, skipping the query's own terms
1669 var ti: i64 = 0
1670 while ti < ntw {
1671 let t2: i64 = twl[ti]
1672 var inq: i64 = 0
1673 var qq: i64 = 0
1674 while qq < nqt { if qtid[qq] == t2 { inq = 1 } qq = qq + 1 }
1675 if inq == 0 { if df[t2] > 0 {
1676 let wt: i64 = tw[t2] * be_log2_1024((2 * nd + 2) / (2 * df[t2] + 1))
1677 var slotp: i64 = 0 - 1
1678 if prf_nex < BE_PRF_FB_TERMS { slotp = prf_nex; prf_nex = prf_nex + 1 } else { if wt > ex_w[BE_PRF_FB_TERMS - 1] { slotp = BE_PRF_FB_TERMS - 1 } }
1679 if slotp >= 0 {
1680 var kp: i64 = slotp
1681 while kp > 0 { if ex_w[kp - 1] < wt { ex_t[kp] = ex_t[kp - 1]; ex_w[kp] = ex_w[kp - 1]; kp = kp - 1 } else { break } }
1682 ex_t[kp] = t2
1683 ex_w[kp] = wt
1684 }
1685 } }
1686 tw[t2] = 0
1687 ti = ti + 1
1688 }
1689 if prf_nex > 0 { if ex_w[0] > 0 {
1690 // the expanded score over every doc the original or an expansion term touches
1691 var np: i64 = 0
1692 var qo: i64 = 0
1693 while qo < nqt {
1694 let tq: i64 = qtid[qo]
1695 var po: i64 = pt_off[tq]
1696 let poe: i64 = pt_off[tq + 1]
1697 while po < poe {
1698 let dq: i64 = pt[po] / BE_PT_TF_MOD
1699 if pmark[dq] == (0 as u8) { pmark[dq] = 1 as u8; plist[np] = dq; np = np + 1; scorep[dq] = (score[dq] * BE_PRF_ORIG_PERMIL) / 1000 }
1700 po = po + 1
1701 }
1702 qo = qo + 1
1703 }
1704 var ei: i64 = 0
1705 while ei < prf_nex {
1706 let te: i64 = ex_t[ei]
1707 let wperm: i64 = (ex_w[ei] * 1000) / ex_w[0]
1708 let idfe: i64 = be_log2_1024((2 * nd + 2) / (2 * df[te] + 1))
1709 var pe2: i64 = pt_off[te]
1710 let pee: i64 = pt_off[te + 1]
1711 while pe2 < pee {
1712 let de: i64 = pt[pe2] / BE_PT_TF_MOD
1713 let tfe: i64 = pt[pe2] % BE_PT_TF_MOD
1714 if pmark[de] == (0 as u8) { pmark[de] = 1 as u8; plist[np] = de; np = np + 1; scorep[de] = (score[de] * BE_PRF_ORIG_PERMIL) / 1000 }
1715 let norme: i64 = 600 + (400 * doc_len[de]) / avgdl
1716 let denome: i64 = tfe * 1000 + (900 * norme) / 1000
1717 if denome > 0 { scorep[de] = scorep[de] + (((1000 - BE_PRF_ORIG_PERMIL) * wperm) * ((idfe * tfe * K_MAGIC_1900) / denome)) / BE_MAGIC_1000000 }
1718 pe2 = pe2 + 1
1719 }
1720 ei = ei + 1
1721 }
1722 // the benchmark's exclusions stay unrankable under this arm too
1723 if nx > 0 {
1724 let plo0: i64 = db_bsearch_i64(x_qid, nx, qh2)
1725 if plo0 >= 0 {
1726 var plo: i64 = plo0
1727 var gp1: i64 = 1
1728 while gp1 == 1 { if plo > 0 { if x_qid[plo - 1] == qh2 { plo = plo - 1 } else { gp1 = 0 } } else { gp1 = 0 } }
1729 var phi: i64 = plo0
1730 var gp2: i64 = 1
1731 while gp2 == 1 { if phi < nx - 1 { if x_qid[phi + 1] == qh2 { phi = phi + 1 } else { gp2 = 0 } } else { gp2 = 0 } }
1732 var pk: i64 = plo
1733 while pk <= phi { scorep[x_doc[pk]] = 0; pk = pk + 1 }
1734 }
1735 }
1736 // the top ten by expanded score (bounded insertion, lower index ahead on ties), then their DCG
1737 var npt: i64 = 0
1738 var pl: i64 = 0
1739 while pl < np {
1740 let dp: i64 = plist[pl]
1741 let sp: i64 = scorep[dp]
1742 if sp > 0 {
1743 var slot2: i64 = 0 - 1
1744 if npt < BE_PRF_TOP { slot2 = npt; npt = npt + 1 } else { if sp > ptop_s[BE_PRF_TOP - 1] { slot2 = BE_PRF_TOP - 1 } }
1745 if slot2 >= 0 {
1746 var k2: i64 = slot2
1747 while k2 > 0 { if ptop_s[k2 - 1] < sp { ptop[k2] = ptop[k2 - 1]; ptop_s[k2] = ptop_s[k2 - 1]; k2 = k2 - 1 } else { break } }
1748 ptop[k2] = dp
1749 ptop_s[k2] = sp
1750 }
1751 }
1752 pmark[dp] = 0 as u8
1753 pl = pl + 1
1754 }
1755 var dcgp: i64 = 0
1756 var rp: i64 = 0
1757 while rp < npt {
1758 let dpp: i64 = ptop[rp]
1759 var gvp: i64 = 0
1760 var jjp: i64 = jlo
1761 while jjp <= jhi { if j_doc[jidx[jjp]] == dpp { gvp = j_scr[jidx[jjp]]; jjp = jhi + 1 } else { jjp = jjp + 1 } }
1762 dcgp = dcgp + gvp * be_disc(rp + 1)
1763 rp = rp + 1
1764 }
1765 dcg_prf = dcgp
1766 prf_queries_expanded = prf_queries_expanded + 1
1767 prf_expansions_total = prf_expansions_total + prf_nex
1768 } }
1769 } }
1770 if dcg_prf > dcg { q_prf_improved = q_prf_improved + 1 } else { if dcg_prf < dcg { q_prf_worsened = q_prf_worsened + 1 } }
1771 sum_ndcg_prf = sum_ndcg_prf + (dcg_prf * 1000) / idcg
1772 var dcg_ce: i64 = dcg
1773 var dcg_cef: i64 = dcg
1774 if ce_ok == 1 { if nqt > 0 {
1775 let nqx: i64 = wp_tokenize(WG, dbuf, tb + 1, e3 - tb - 1, ce_qtok)
1776 // every candidate pair is ONE task: tokenise, pair, forward (serial inside), score into its own record;
1777 // a forked burst spreads the tasks over ce_workers children, a serial run calls the same task body inline
1778 var cx: i64 = 0
1779 var submitted: i64 = 0
1780 while cx < BE_KCAND {
1781 xscore[cx] = 0
1782 xused[cx] = 0 as u8
1783 let dpx: i64 = top[cx]
1784 if cx < ce_depth { if dpx >= 0 {
1785 let tk: *BeCeTask = be_ce_task_at(ce_tasks, cx)
1786 tk.cg = CG as i64
1787 tk.wg = WG as i64
1788 tk.cbuf = cbuf as i64
1789 tk.ts = doc_ts[dpx]
1790 tk.te = doc_te[dpx]
1791 tk.qtok = ce_qtok as i64
1792 tk.nqx = nqx
1793 tk.maxlen = ce_maxlen
1794 tk.score = 0
1795 if ce_workers > 0 { submitted = submitted + 1 } else { _be_ce_task(tk as i64) }
1796 ce_pairs = ce_pairs + 1
1797 } }
1798 cx = cx + 1
1799 }
1800 if submitted > 0 {
1801 var fw: i64 = 0
1802 while fw < ce_workers {
1803 let fpid: i64 = sys_fork()
1804 if fpid == 0 {
1805 var cw: i64 = 0
1806 while cw < ce_depth {
1807 if cw % ce_workers == fw { if top[cw] >= 0 { _be_ce_task(be_ce_task_at(ce_tasks, cw) as i64) } }
1808 cw = cw + 1
1809 }
1810 sys_exit(0)
1811 }
1812 fw = fw + 1
1813 }
1814 var fd0: i64 = 0
1815 while fd0 < ce_workers { sys_wait4(0 - 1, ce_stp, 0); fd0 = fd0 + 1 }
1816 }
1817 cx = 0
1818 while cx < BE_KCAND {
1819 if cx < ce_depth { if top[cx] >= 0 { let tkr: *BeCeTask = be_ce_task_at(ce_tasks, cx); xscore[cx] = tkr.score } }
1820 cx = cx + 1
1821 }
1822 var dcgx: i64 = 0
1823 var rkx: i64 = 0
1824 while rkx < 10 {
1825 var bx: i64 = 0 - 1
1826 var cj5: i64 = 0
1827 while cj5 < ce_depth {
1828 if xused[cj5] == (0 as u8) { if top[cj5] >= 0 {
1829 if bx < 0 { bx = cj5 } else { if xscore[cj5] > xscore[bx] { bx = cj5 } }
1830 } }
1831 cj5 = cj5 + 1
1832 }
1833 if bx >= 0 {
1834 xused[bx] = 1 as u8
1835 let dpk5: i64 = top[bx]
1836 var gv5: i64 = 0
1837 var jj5: i64 = jlo
1838 while jj5 <= jhi {
1839 if j_doc[jidx[jj5]] == dpk5 { gv5 = j_scr[jidx[jj5]]; jj5 = jhi + 1 } else { jj5 = jj5 + 1 }
1840 }
1841 dcgx = dcgx + gv5 * be_disc(rkx + 1)
1842 }
1843 rkx = rkx + 1
1844 }
1845 // R0f CE-FUSION ARM (2026-09-16): RRF k=RRF_K_STD over the BM25 order (top index) and the cross-encoder
1846 // order, same candidates. The MS MARCO reranker is out of domain on reasoning queries, so a rank fusion
1847 // that needs a document to stand in BOTH orders is measured beside the pure rerank; the sweep chooses
1848 // between them from its own receipt (nx_beir_arms_lib), never a hand.
1849 var xr0: i64 = 0
1850 while xr0 < BE_KCAND { xused[xr0] = 0 as u8; xrank[xr0] = ce_depth; xr0 = xr0 + 1 }
1851 var xo: i64 = 0
1852 while xo < ce_depth {
1853 var bxr: i64 = 0 - 1
1854 var cxr: i64 = 0
1855 while cxr < ce_depth {
1856 if xused[cxr] == (0 as u8) { if top[cxr] >= 0 { if bxr < 0 { bxr = cxr } else { if xscore[cxr] > xscore[bxr] { bxr = cxr } } } }
1857 cxr = cxr + 1
1858 }
1859 if bxr >= 0 { xused[bxr] = 1 as u8; xrank[bxr] = xo }
1860 xo = xo + 1
1861 }
1862 var xf: i64 = 0
1863 while xf < BE_KCAND {
1864 xfsc[xf] = 0
1865 if xf < ce_depth { if top[xf] >= 0 { xfsc[xf] = BE_MAGIC_1000000 / (RRF_K_STD + xf) + BE_MAGIC_1000000 / (RRF_K_STD + xrank[xf]) } }
1866 xf = xf + 1
1867 }
1868 var xu: i64 = 0
1869 while xu < BE_KCAND { xused[xu] = 0 as u8; xu = xu + 1 }
1870 var dcgxf: i64 = 0
1871 var rkf: i64 = 0
1872 while rkf < 10 {
1873 var bf: i64 = 0 - 1
1874 var cf: i64 = 0
1875 while cf < ce_depth {
1876 if xused[cf] == (0 as u8) { if top[cf] >= 0 { if bf < 0 { bf = cf } else { if xfsc[cf] > xfsc[bf] { bf = cf } } } }
1877 cf = cf + 1
1878 }
1879 if bf >= 0 {
1880 xused[bf] = 1 as u8
1881 let dpkf: i64 = top[bf]
1882 var gvf: i64 = 0
1883 var jjf: i64 = jlo
1884 while jjf <= jhi { if j_doc[jidx[jjf]] == dpkf { gvf = j_scr[jidx[jjf]]; jjf = jhi + 1 } else { jjf = jjf + 1 } }
1885 dcgxf = dcgxf + gvf * be_disc(rkf + 1)
1886 }
1887 rkf = rkf + 1
1888 }
1889 dcg_cef = dcgxf
1890 dcg_ce = dcgx
1891 } }
1892 if dcg_ce > dcg { q_ce_improved = q_ce_improved + 1 } else { if dcg_ce < dcg { q_ce_worsened = q_ce_worsened + 1 } }
1893 sum_ndcg_ce = sum_ndcg_ce + (dcg_ce * 1000) / idcg
1894 if dcg_cef > dcg { q_cef_improved = q_cef_improved + 1 } else { if dcg_cef < dcg { q_cef_worsened = q_cef_worsened + 1 } }
1895 sum_ndcg_cef = sum_ndcg_cef + (dcg_cef * 1000) / idcg
1896 if dcg_rr > dcg { q_improved = q_improved + 1 } else { if dcg_rr < dcg { q_worsened = q_worsened + 1 } else { q_same = q_same + 1 } }
1897 if dcg_fu > dcg { q_fu_improved = q_fu_improved + 1 } else { if dcg_fu < dcg { q_fu_worsened = q_fu_worsened + 1 } }
1898 sum_ndcg_fu = sum_ndcg_fu + (dcg_fu * 1000) / idcg
1899 sum_ndcg_rr = sum_ndcg_rr + (dcg_rr * 1000) / idcg
1900 sum_ndcg = sum_ndcg + (dcg * 1000) / idcg
1901 // S5: the BM25Q arm's per-query record; the long-query subset and the identity control are derived after the loop
1902 sum_ndcg_q = sum_ndcg_q + (dcg_q * 1000) / idcg
1903 sum_ndcg_fq = sum_ndcg_fq + (dcg_fq * 1000) / idcg
1904 if pq_n < nq_cap { pq_tok[pq_n] = qnoff[0]; pq_nd[pq_n] = (dcg * 1000) / idcg; pq_ndq[pq_n] = (dcg_q * 1000) / idcg; pq_ndf[pq_n] = (dcg_fq * 1000) / idcg; pq_rep[pq_n] = q_rep; pq_same[pq_n] = q_same10; pq_n = pq_n + 1 }
1905 // R0 LEARNED ARM: store this query's shortlist for the post-loop 5-fold CV reranker.
1906 // Same candidate pool (top[]), same gold, same idcg as the arms above -> a controlled
1907 // comparison. nqt<=0 stores zero candidates so it scores 0 exactly as the BM25 arm does.
1908 if ft_nq < nq_cap {
1909 ft_idcg[ft_nq] = idcg
1910 ft_fold[ft_nq] = ft_nq - (ft_nq / LTR_FOLDS) * LTR_FOLDS
1911 var st_nc: i64 = 0
1912 if nqt > 0 {
1913 var ci2: i64 = 0
1914 while ci2 < BE_KCAND {
1915 let cdoc: i64 = top[ci2]
1916 if cdoc >= 0 {
1917 let fb: i64 = (ft_nq * BE_KCAND + st_nc) * LTR_NFEAT
1918 ft_feat[fb + 0] = score[cdoc]
1919 if rr_ok == 1 { ft_feat[fb + 1] = cscore[ci2] } else { ft_feat[fb + 1] = 0 }
1920 var cov: i64 = 0
1921 var covidf: i64 = 0
1922 var stf: i64 = 0
1923 var qz: i64 = 0
1924 while qz < nqt {
1925 let tt: i64 = qtid[qz]
1926 let od0: i64 = doc_off[cdoc]
1927 let od1: i64 = doc_off[cdoc + 1]
1928 let ppz: i64 = db_bsearch_i64((dterm as i64 + od0 * 8) as *i64, od1 - od0, tt)
1929 if ppz >= 0 {
1930 cov = cov + 1
1931 let dfz: i64 = df[tt]
1932 covidf = covidf + be_log2_1024((2 * nd + 2) / (2 * dfz + 1))
1933 stf = stf + dtf[od0 + ppz]
1934 }
1935 qz = qz + 1
1936 }
1937 ft_feat[fb + 2] = cov
1938 ft_feat[fb + 3] = covidf
1939 ft_feat[fb + 4] = stf
1940 ft_feat[fb + 5] = doc_len[cdoc]
1941 var d6: i64 = 0
1942 var d7: i64 = 0
1943 if rr_ok == 1 { if de_ok == 1 { d6 = dscore[ci2]; d7 = escore[ci2] } }
1944 ft_feat[fb + 6] = d6
1945 ft_feat[fb + 7] = d7
1946 be_prox(cbuf, doc_ts[cdoc], doc_te[cdoc], qhbuf, qnoff[0], scr, bp, proxout)
1947 var f8: i64 = 0
1948 if proxout[0] > 0 { f8 = BE_MAGIC_1000000 / (proxout[0] + 1) }
1949 ft_feat[fb + 8] = f8
1950 ft_feat[fb + 9] = proxout[1]
1951 var gvv: i64 = 0
1952 var jz: i64 = jlo
1953 while jz <= jhi { if j_doc[jidx[jz]] == cdoc { gvv = j_scr[jidx[jz]]; jz = jhi + 1 } else { jz = jz + 1 } }
1954 ft_gold[ft_nq * BE_KCAND + st_nc] = gvv
1955 st_nc = st_nc + 1
1956 }
1957 ci2 = ci2 + 1
1958 }
1959 }
1960 ft_ncand[ft_nq] = st_nc
1961 ft_nq = ft_nq + 1
1962 }
1963 nq = nq + 1
1964 if be_progress(pd, nq, ce_pairs, ce_workers, ce_depth) < 0 { progress_fail = progress_fail + 1 }
1965 }
1966 }
1967 }
1968 qpp = e3 + 1
1969 }
1970
1971 var mean: i64 = 0
1972 if nq > 0 { mean = sum_ndcg / nq }
1973 // R0 LEARNED ARM: 5-fold cross-validated held-out nDCG over the stored candidate features. No test
1974 // label trains the weights that score it (each query is held out of its own fold's training).
1975 let ft_cnt: *i64 = sys_mmap(8) as *i64
1976 let cv_learned: i64 = ltr_cv(ft_feat, ft_gold, ft_fold, ft_nq, ft_ncand, BE_KCAND, ft_idcg, ft_cnt)
1977 let ctl_cnt: *i64 = sys_mmap(8) as *i64
1978 let cv_bm25ctrl: i64 = ltr_ndcg_single(ft_feat, ft_gold, ft_nq, ft_ncand, BE_KCAND, ft_idcg, 0, ctl_cnt)
1979 db_w("{\"tool\":\"nx_beir_eval\",\"dataset\":\"" as *u8)
1980 if (root as i64) == 0 { db_w(BE_DATASET_DEFAULT) } else { db_w(root) }
1981 db_w("\",\"queries_file\":\"" as *u8); if (qfile as i64) == 0 { db_w("queries.tsv" as *u8) } else { db_w(qfile) }
1982 db_w("\",\"docs\":" as *u8); db_n(nd)
1983 db_w(",\"vocab\":" as *u8); db_n(nv)
1984 db_w(",\"tokens\":" as *u8); db_n(ntok)
1985 db_w(",\"postings\":" as *u8); db_n(pt_acc)
1986 db_w(",\"postings_tf_clamped\":" as *u8); db_n(pt_clamped)
1987 db_w(",\"test_queries_scored\":" as *u8); db_n(nq)
1988 db_w(",\"dropped_no_qrels\":" as *u8); db_n(n_noqrel)
1989 db_w(",\"dropped_no_relevant\":" as *u8); db_n(n_noidcg)
1990 db_w(",\"counted_zero_no_query_term_match\":" as *u8); db_n(n_noterm)
1991 db_w(",\"excluded_pairs\":" as *u8); db_n(nx)
1992 db_w(",\"excluded_unknown_docs\":" as *u8); db_n(x_unknown)
1993 db_w(",\"excluded_applied\":" as *u8); db_n(excluded_applied)
1994 db_w(",\"bm25_only\":" as *u8); db_n(bm25_only)
1995 db_w(",\"avgdl\":" as *u8); db_n(avgdl)
1996 db_w(",\"bm25\":{\"k1x1000\":900,\"bx1000\":400,\"idf\":\"log2\",\"stemming\":\"porter\",\"stopwords\":false}" as *u8)
1997 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(mean)
1998 if (root as i64) == 0 { db_w(",\"published_bm25_baseline_permil\":320" as *u8) } else { db_w(",\"published_bm25_baseline\":\"per set: the board's sotabar row carries it (BRIGHT average 14.5)\"" as *u8) }
1999 // seq1494: the rerank arm, printed from the SAME run. UNAVAILABLE (not 0) when the model is absent.
2000 var mean_rr: i64 = 0
2001 if nq > 0 { mean_rr = sum_ndcg_rr / nq }
2002 db_w(",\"rerank\":{\"model\":" as *u8)
2003 if rr_ok == 1 { db_w("\"semppmi_v1 late-interaction maxsim(idf)\"" as *u8) } else { db_w("\"UNAVAILABLE -- semppmi_v1.bin did not load or --bm25-only; rerank arm NOT measured (this is not a score of 0)\"" as *u8) }
2004 db_w(",\"candidates\":" as *u8); db_n(BE_KCAND)
2005 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(mean_rr)
2006 db_w(",\"delta_permil\":" as *u8); db_n(mean_rr - mean)
2007 db_w(",\"queries_improved\":" as *u8); db_n(q_improved)
2008 db_w(",\"queries_worsened\":" as *u8); db_n(q_worsened)
2009 db_w(",\"queries_unchanged\":" as *u8); db_n(q_same)
2010 db_w(",\"accept_rule\":\"declared BEFORE the run: rerank must EXCEED the BM25 arm on these same queries or it does NOT get wired into search (seq1494)\"}" as *u8)
2011 var mean_fu: i64 = 0
2012 if nq > 0 { mean_fu = sum_ndcg_fu / nq }
2013 db_w(",\"fusion\":{\"method\":\"rrf k=60 over bm25-rank + maxsim-rank, same 50 candidates\",\"ndcg_at_10_permil\":" as *u8); db_n(mean_fu)
2014 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_fu - mean)
2015 db_w(",\"queries_improved\":" as *u8); db_n(q_fu_improved)
2016 db_w(",\"queries_worsened\":" as *u8); db_n(q_fu_worsened)
2017 db_w(",\"accept_rule\":\"declared BEFORE the run: FUSED must EXCEED the BM25 arm same-run or R1b stays unwired\"}" as *u8)
2018 // S5 BM25Q (2026-09-15): the query-side saturation arm and its pool fusion, the long-query subset DERIVED from the
2019 // set (tokens above the set's mean) and the identity control over every query with no repeated term
2020 var mean_q: i64 = 0
2021 var mean_fq: i64 = 0
2022 if nq > 0 { mean_q = sum_ndcg_q / nq; mean_fq = sum_ndcg_fq / nq }
2023 var tok_sum: i64 = 0
2024 var pi2: i64 = 0
2025 while pi2 < pq_n { tok_sum = tok_sum + pq_tok[pi2]; pi2 = pi2 + 1 }
2026 var tok_mean: i64 = 0
2027 if pq_n > 0 { tok_mean = tok_sum / pq_n }
2028 var long_n: i64 = 0
2029 var long_sd: i64 = 0
2030 var long_sq: i64 = 0
2031 var long_sf: i64 = 0
2032 var norep_n: i64 = 0
2033 var norep_same: i64 = 0
2034 var rep_n: i64 = 0
2035 pi2 = 0
2036 while pi2 < pq_n {
2037 if pq_tok[pi2] > tok_mean { long_n = long_n + 1; long_sd = long_sd + pq_nd[pi2]; long_sq = long_sq + pq_ndq[pi2]; long_sf = long_sf + pq_ndf[pi2] }
2038 if pq_rep[pi2] == 0 { norep_n = norep_n + 1; if pq_same[pi2] == 1 { norep_same = norep_same + 1 } } else { rep_n = rep_n + 1 }
2039 pi2 = pi2 + 1
2040 }
2041 var long_d: i64 = 0
2042 var long_q: i64 = 0
2043 var long_f: i64 = 0
2044 if long_n > 0 { long_d = long_sd / long_n; long_q = long_sq / long_n; long_f = long_sf / long_n }
2045 db_w(",\"bm25q\":{\"saturation\":\"robertson on query-term frequency (nx_intlog idf_bm25q, k_q10 below)\",\"k_q10\":" as *u8); db_n(BM25Q_K_Q10)
2046 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(mean_q)
2047 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_q - mean)
2048 db_w(",\"fusion\":{\"method\":\"rrf k=60 over bm25-rank + bm25q-rank, same 50 candidates\",\"ndcg_at_10_permil\":" as *u8); db_n(mean_fq)
2049 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_fq - mean); db_w("}" as *u8)
2050 db_w(",\"long_rule\":\"query tokens above the set mean\",\"mean_query_tokens\":" as *u8); db_n(tok_mean)
2051 db_w(",\"long_n\":" as *u8); db_n(long_n)
2052 db_w(",\"long_bm25_permil\":" as *u8); db_n(long_d)
2053 db_w(",\"long_bm25q_permil\":" as *u8); db_n(long_q)
2054 db_w(",\"long_fusion_permil\":" as *u8); db_n(long_f)
2055 db_w(",\"queries_with_repeated_term\":" as *u8); db_n(rep_n)
2056 db_w(",\"norepeat_n\":" as *u8); db_n(norep_n)
2057 db_w(",\"norepeat_top10_identical\":" as *u8); db_n(norep_same)
2058 db_w(",\"accept_rule\":\"declared 2026-09-04 (search S5): the FUSED arm must EXCEED plain BM25 on the long-query subset by nDCG at 10, and every no-repeat query must rank IDENTICALLY under both\",\"verdict\":\"" as *u8)
2059 if long_n > 0 { if long_f > long_d { if norep_same == norep_n { db_w("FUSION-BEATS-BM25-ON-LONG" as *u8) } else { db_w("IDENTITY-CONTROL-FAILED" as *u8) } } else { db_w("FUSION-DOES-NOT-BEAT-BM25-ON-LONG" as *u8) } } else { db_w("NO-LONG-QUERIES" as *u8) }
2060 db_w("\"}" as *u8)
2061 db_w(",\"learned\":{\"model\":\"coordinate-ascent LTR (Metzler-Croft: init bm25-only, step-halving line search on training-fold nDCG at 10), 5-fold CV\",\"features\":\"bm25 ppmi_maxsim cover covidf sumtf doclen dense_maxsim_centered dense_maxsim minwin bigram\",\"dense_model\":" as *u8)
2062 if de_ok == 1 { db_w("\"embed_v1 (nx_embed_train, PPMI-factorised; common component removed for the centered slot)\"" as *u8) } else { db_w("\"UNAVAILABLE -- embed_v1.bin did not load or --bm25-only; both dense slots constant (no vote), NOT a score of 0\"" as *u8) }
2063 db_w(",\"single_feature_controls_permil\":[" as *u8)
2064 var sfk: i64 = 0
2065 while sfk < LTR_NFEAT { if sfk > 0 { db_w("," as *u8) } db_n(ltr_ndcg_single(ft_feat, ft_gold, ft_nq, ft_ncand, BE_KCAND, ft_idcg, sfk, ctl_cnt)); sfk = sfk + 1 }
2066 db_w("],\"folds\":5,\"queries_scored\":" as *u8); db_n(ft_cnt[0])
2067 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(cv_learned)
2068 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(cv_learned - mean)
2069 db_w(",\"bm25only_control_permil\":" as *u8); db_n(cv_bm25ctrl)
2070 db_w(",\"accept_rule\":\"the 5-fold cross-validated held-out mean must EXCEED the BM25 arm on these same queries -- no test label trains the weights that score it -- or nr_rerank stays UNWIRED\"}" as *u8)
2071 var mean_ce: i64 = 0
2072 if nq > 0 { mean_ce = sum_ndcg_ce / nq }
2073 db_w(",\"crossenc\":{\"model\":" as *u8)
2074 if ce_ok == 1 { db_w("\"" as *u8); db_w(ce_model); db_w("\"" as *u8) } else { db_w("\"UNAVAILABLE -- the cross-encoder did not load (" as *u8); db_w(CG[BC_G_MISSING] as *u8); db_w("); arm NOT measured, not a score of 0\"" as *u8) }
2075 db_w(",\"hidden\":" as *u8); db_n(CG[BC_G_HID])
2076 db_w(",\"layers\":" as *u8); db_n(CG[BC_G_LAYERS])
2077 db_w(",\"max_len\":" as *u8); db_n(ce_maxlen)
2078 db_w(",\"candidates\":" as *u8); db_n(ce_depth)
2079 db_w(",\"pairs_scored\":" as *u8); db_n(ce_pairs)
2080 db_w(",\"pool_workers\":" as *u8); db_n(ce_workers)
2081 db_w(",\"pool_unit\":\"one pair per task, serial forward inside\"" as *u8)
2082 let ppr: *u8 = sys_mmap(BE_PATH_CAP * 2)
2083 be_progress_path(ppr, pd, 0)
2084 db_w(",\"progress_file\":\"" as *u8); db_w(ppr); db_w("\",\"progress_rows_unwritten\":" as *u8); db_n(progress_fail)
2085 db_w(",\"ndcg_at_10_permil\":" as *u8); db_n(mean_ce)
2086 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_ce - mean)
2087 db_w(",\"queries_improved\":" as *u8); db_n(q_ce_improved)
2088 db_w(",\"queries_worsened\":" as *u8); db_n(q_ce_worsened)
2089 db_w(",\"accept_rule\":\"declared BEFORE the run: the cross-encoder arm must EXCEED the BM25 arm on these same queries or nr_rerank stays UNWIRED; wired only after it also clears the estate judged set\"}" as *u8)
2090 // R0f (2026-09-16): the keys the BRIGHT sweep reads back per split -- each spelled ONCE in this receipt so be_json_int's
2091 // first occurrence is the value; ce_measured says whether the reranker ran at all (an UNAVAILABLE arm is 0, never a score)
2092 var mean_cef: i64 = 0
2093 if nq > 0 { mean_cef = sum_ndcg_cef / nq }
2094 db_w(",\"ce_measured\":" as *u8); db_n(ce_ok)
2095 db_w(",\"ce_ndcg_at_10_permil\":" as *u8); db_n(mean_ce)
2096 db_w(",\"cefusion\":{\"method\":\"rrf k=RRF_K_STD over bm25-rank + crossenc-rank, same candidates\",\"queries_improved\":" as *u8); db_n(q_cef_improved)
2097 db_w(",\"queries_worsened\":" as *u8); db_n(q_cef_worsened)
2098 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_cef - mean)
2099 db_w(",\"accept_rule\":\"declared BEFORE the run (R0f): the fused arm is chosen for the row only when every split measured the reranker and it EXCEEDS plain BM25 and the best other arm; a tie keeps the pure rerank\"}" as *u8)
2100 db_w(",\"cefusion_ndcg_at_10_permil\":" as *u8); db_n(mean_cef)
2101 // R0g: the PRF arm's receipt, its sweep key spelled once
2102 var mean_prf: i64 = 0
2103 if nq > 0 { mean_prf = sum_ndcg_prf / nq }
2104 db_w(",\"prf\":{\"method\":\"rm3-style pseudo-relevance feedback\",\"fb_docs\":" as *u8); db_n(BE_PRF_FB_DOCS)
2105 db_w(",\"fb_terms\":" as *u8); db_n(BE_PRF_FB_TERMS)
2106 db_w(",\"orig_weight_permil\":" as *u8); db_n(BE_PRF_ORIG_PERMIL)
2107 db_w(",\"term_weight\":\"sum over feedback docs of tf/doclen permil x idf, query terms excluded, expansion weights as a share of the best\"" as *u8)
2108 db_w(",\"queries_expanded\":" as *u8); db_n(prf_queries_expanded)
2109 db_w(",\"expansion_terms_total\":" as *u8); db_n(prf_expansions_total)
2110 db_w(",\"queries_improved\":" as *u8); db_n(q_prf_improved)
2111 db_w(",\"queries_worsened\":" as *u8); db_n(q_prf_worsened)
2112 db_w(",\"delta_vs_bm25_permil\":" as *u8); db_n(mean_prf - mean)
2113 db_w(",\"accept_rule\":\"declared BEFORE the run (R0g): the PRF arm reaches the row only when its twelve-split average EXCEEDS plain BM25 and the best other arm; it is the non-reasoning expansion control the R0c rewriter must beat\"}" as *u8)
2114 db_w(",\"prf_ndcg_at_10_permil\":" as *u8); db_n(mean_prf)
2115 db_w(",\"note\":\"real external ground truth; integer/bit-reproducible; porter-stemmed via nx_stem_lib (rung landed 2026-08-13); no stopwords; capacities derived from the set's own files (R0d, 2026-09-14)\"}" as *u8)
2116 db_w("\n" as *u8)
2117 return 0
2118}