nx_bright_reasoned_import.nx source
↩ module page · 450 lines · 22048 B
1// nx_bright_reasoned_import.nx -- REFEREE-REPLAY IMPORTER for a published reasoned-query set (search R0l, 2026-09-16).
2// A query reasoner's authors publish their rewrites as ONE JSON object keyed by the ORIGINAL BRIGHT query text with
3// the rewrite as the value (TongSearch-QR ships one file per model, MIT). This organ matches that object, split by
4// split, against the estate's own BEIR-shaped queries.tsv rows (written by nx_bright_prep, whose cells have every
5// tab, newline and carriage return replaced by a space) and writes <root>/<split>/<outname> rows `id TAB text`:
6// the alternate query file nx_beir_eval takes as `queries=<outname>`, which it scores as a REFEREE REPLAY and never
7// writes to the leaderboard (a query another model wrote is not the estate's system). Two modes: `reason` (the
8// rewrite alone is the query, the BRIGHT reasoning-query protocol the paper's Table 1 uses) and `concat` (the
9// original query, one space, the rewrite). The JSON decoder flattens \n \t \r to a space so a decoded key compares
10// BYTE-EQUAL to the prep organ's cell, encodes \uXXXX (surrogate pairs included) through the estate's utf8 encoder
11// and passes raw UTF-8 through untouched. It REFUSES (exit 1, nothing renamed into place) when any split row has no
12// rewrite, naming every missing id: a partial replay scores a different query set than the one it claims. Counts
13// print as a partition (rows = matched + missed) beside the JSON pair count, and keys reused across splits are
14// counted separately, because BRIGHT's two theoremqa splits share question texts, so a text-keyed set is SMALLER
15// than the row count by construction and the two numbers must not be read as a mismatch.
16// argv: <reasoned.json> <bright-root> <outname> [reason|concat] (the twelve splits are nx_beir_eval's)
17// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 full match, 1 refused (named), 2 usage
18import "nx_syscalls.nx"
19import "nx_utf8.nx"
20
21const RI_OK: i64 = 0
22const RI_REFUSED: i64 = 1
23const RI_USAGE: i64 = 2
24const RI_STDOUT: i64 = 1
25const RI_PATH_CAP: i64 = 1024
26const RI_BYTE: i64 = 255
27const RI_TAB: i64 = 9
28const RI_NL: i64 = 10
29const RI_CR: i64 = 13
30const RI_SPACE: i64 = 32
31const RI_QUOTE: i64 = 34
32const RI_COMMA: i64 = 44
33const RI_COLON: i64 = 58
34const RI_LBRACE: i64 = 123
35const RI_RBRACE: i64 = 125
36const RI_BACKSLASH: i64 = 92
37const RI_ESC_B: i64 = 98
38const RI_ESC_F: i64 = 102
39const RI_ESC_N: i64 = 110
40const RI_ESC_R: i64 = 114
41const RI_ESC_T: i64 = 116
42const RI_ESC_U: i64 = 117
43const RI_CTL_BS: i64 = 8
44const RI_CTL_FF: i64 = 12
45const RI_SUR_HI_LO: i64 = 0xD800
46const RI_SUR_HI_HI: i64 = 0xDBFF
47const RI_SUR_LO_LO: i64 = 0xDC00
48const RI_SUR_LO_HI: i64 = 0xDFFF
49const RI_SUR_SHIFT: i64 = 10
50const RI_SUR_BASE: i64 = 0x10000
51const RI_HEX_DIGITS: i64 = 4
52const RI_UTF8_MAX: i64 = 4
53const RI_BOM_LEN: i64 = 3
54const RI_BOM_0: i64 = 0xEF
55const RI_BOM_1: i64 = 0xBB
56const RI_BOM_2: i64 = 0xBF
57const RI_NUM_CAP: i64 = 24
58const RI_CELL: i64 = 8
59const RI_SPLITS: i64 = 12
60const RI_ARENA_SLACK: i64 = 16
61const RI_MODE_COUNT: i64 = 0
62const RI_MODE_DECODE: i64 = 1
63const RI_NONE: i64 = 0 - 1
64const RI_SLASH: *u8 = "/"
65const RI_TMP: *u8 = ".tmp"
66const RI_F_QUERIES: *u8 = "/queries.tsv"
67const RI_WORD_REASON: *u8 = "reason"
68const RI_WORD_CONCAT: *u8 = "concat"
69
70// ---- text primitives ----
71func ri_slen(s: *u8) -> i64 { var n: i64 = 0; while ((s[n] as i64) & RI_BYTE) != 0 { n = n + 1 } return n }
72func ri_puts(s: *u8) -> i64 { let n: i64 = ri_slen(s); if n > 0 { sys_write(RI_STDOUT, s, n) } return 0 }
73func ri_putn(v: i64) -> i64 {
74 let t: *u8 = sys_mmap(RI_NUM_CAP)
75 let b: *u8 = sys_mmap(RI_NUM_CAP)
76 var m: i64 = v
77 if m < 0 { sys_write(RI_STDOUT, "-" as *u8, 1); m = 0 - m }
78 var k: i64 = 0
79 if m == 0 { t[0] = 48 as u8; k = 1 }
80 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
81 var i: i64 = 0
82 while i < k { b[i] = t[k - 1 - i]; i = i + 1 }
83 sys_write(RI_STDOUT, b, k)
84 return 0
85}
86func ri_memeq(a: *u8, b: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { if a[i] != b[i] { return 0 } i = i + 1 } return 1 }
87func ri_streq(a: *u8, b: *u8) -> i64 { let n: i64 = ri_slen(a); if n != ri_slen(b) { return 0 } return ri_memeq(a, b, n) }
88// append s at dst[off..]; returns the new offset or RI_NONE past the cap
89func ri_cat(dst: *u8, off: i64, s: *u8, cap: i64) -> i64 {
90 let n: i64 = ri_slen(s)
91 if off + n + 1 > cap { return RI_NONE }
92 var i: i64 = 0
93 while i < n { dst[off + i] = s[i]; i = i + 1 }
94 dst[off + n] = 0 as u8
95 return off + n
96}
97// dst = root + "/" + split + tail
98func ri_path(dst: *u8, root: *u8, split: *u8, tail: *u8) -> i64 {
99 var o: i64 = ri_cat(dst, 0, root, RI_PATH_CAP)
100 if o < 0 { return RI_NONE }
101 o = ri_cat(dst, o, RI_SLASH, RI_PATH_CAP)
102 if o < 0 { return RI_NONE }
103 o = ri_cat(dst, o, split, RI_PATH_CAP)
104 if o < 0 { return RI_NONE }
105 return ri_cat(dst, o, tail, RI_PATH_CAP)
106}
107// the twelve BRIGHT splits in nx_beir_eval's order
108func ri_split(i: i64) -> *u8 {
109 if i == 0 { return "biology" as *u8 }
110 if i == 1 { return "earth_science" as *u8 }
111 if i == 2 { return "economics" as *u8 }
112 if i == 3 { return "psychology" as *u8 }
113 if i == 4 { return "robotics" as *u8 }
114 if i == 5 { return "stackoverflow" as *u8 }
115 if i == 6 { return "sustainable_living" as *u8 }
116 if i == 7 { return "leetcode" as *u8 }
117 if i == 8 { return "pony" as *u8 }
118 if i == 9 { return "aops" as *u8 }
119 if i == 10 { return "theoremqa_questions" as *u8 }
120 return "theoremqa_theorems" as *u8
121}
122
123// ---- JSON scanning (a top-level object of string -> string pairs; nothing else is admitted) ----
124func ri_is_ws(c: i64) -> i64 { if c == RI_SPACE { return 1 } if c == RI_TAB { return 1 } if c == RI_NL { return 1 } if c == RI_CR { return 1 } return 0 }
125func ri_skip_ws(raw: *u8, n: i64, at: i64) -> i64 { var i: i64 = at; while i < n { if ri_is_ws((raw[i] as i64) & RI_BYTE) == 0 { return i } i = i + 1 } return i }
126func ri_hex(c: i64) -> i64 {
127 if c >= 48 { if c <= 57 { return c - 48 } }
128 if c >= 97 { if c <= 102 { return c - 87 } }
129 if c >= 65 { if c <= 70 { return c - 55 } }
130 return RI_NONE
131}
132// four hex digits at raw[at..at+4) -> code unit, or RI_NONE
133func ri_hex4(raw: *u8, n: i64, at: i64) -> i64 {
134 if at + RI_HEX_DIGITS > n { return RI_NONE }
135 var v: i64 = 0
136 var k: i64 = 0
137 while k < RI_HEX_DIGITS {
138 let h: i64 = ri_hex((raw[at + k] as i64) & RI_BYTE)
139 if h < 0 { return RI_NONE }
140 v = (v << 4) | h
141 k = k + 1
142 }
143 return v
144}
145// walk a JSON string from raw[at] (just past the opening quote) without decoding; returns the index past the
146// closing quote or RI_NONE when the text ends first
147func ri_skip_string(raw: *u8, n: i64, at: i64) -> i64 {
148 var i: i64 = at
149 while i < n {
150 let c: i64 = (raw[i] as i64) & RI_BYTE
151 if c == RI_QUOTE { return i + 1 }
152 if c == RI_BACKSLASH { i = i + 2 } else { i = i + 1 }
153 }
154 return RI_NONE
155}
156// decode a JSON string from raw[at] (just past the opening quote) into out[op[0]..], advancing op[0]; \n \t \r and
157// any raw tab, newline or carriage return become ONE SPACE (the prep organ's cell rule); \uXXXX pairs are joined
158// and utf8-encoded; returns the index past the closing quote or RI_NONE when malformed
159func ri_decode_string(raw: *u8, n: i64, at: i64, out: *u8, op: *i64) -> i64 {
160 var i: i64 = at
161 let cell: *i64 = sys_mmap(RI_CELL) as *i64
162 while i < n {
163 let c: i64 = (raw[i] as i64) & RI_BYTE
164 if c == RI_QUOTE { return i + 1 }
165 if c == RI_BACKSLASH {
166 if i + 1 >= n { return RI_NONE }
167 let e: i64 = (raw[i + 1] as i64) & RI_BYTE
168 i = i + 2
169 var handled: i64 = 0
170 if e == RI_ESC_N { out[op[0]] = RI_SPACE as u8; op[0] = op[0] + 1; handled = 1 }
171 if e == RI_ESC_T { out[op[0]] = RI_SPACE as u8; op[0] = op[0] + 1; handled = 1 }
172 if e == RI_ESC_R { out[op[0]] = RI_SPACE as u8; op[0] = op[0] + 1; handled = 1 }
173 if e == RI_ESC_B { out[op[0]] = RI_CTL_BS as u8; op[0] = op[0] + 1; handled = 1 }
174 if e == RI_ESC_F { out[op[0]] = RI_CTL_FF as u8; op[0] = op[0] + 1; handled = 1 }
175 if e == RI_ESC_U {
176 var cp: i64 = ri_hex4(raw, n, i)
177 if cp < 0 { return RI_NONE }
178 i = i + RI_HEX_DIGITS
179 if cp >= RI_SUR_HI_LO { if cp <= RI_SUR_HI_HI {
180 // a high surrogate must be followed by \u + low surrogate
181 if i + 1 < n { if ((raw[i] as i64) & RI_BYTE) == RI_BACKSLASH { if ((raw[i + 1] as i64) & RI_BYTE) == RI_ESC_U {
182 let lo: i64 = ri_hex4(raw, n, i + 2)
183 if lo >= RI_SUR_LO_LO { if lo <= RI_SUR_LO_HI {
184 cp = RI_SUR_BASE + ((cp - RI_SUR_HI_LO) << RI_SUR_SHIFT) + (lo - RI_SUR_LO_LO)
185 i = i + 2 + RI_HEX_DIGITS
186 } }
187 } } }
188 } }
189 if cp == RI_TAB { cp = RI_SPACE }
190 if cp == RI_NL { cp = RI_SPACE }
191 if cp == RI_CR { cp = RI_SPACE }
192 cell[0] = op[0]
193 if utf8_encode_one(cp, out, cell) < 0 { return RI_NONE }
194 op[0] = cell[0]
195 handled = 1
196 }
197 if handled == 0 {
198 // \" \\ \/ and any other escaped byte stand for themselves
199 out[op[0]] = e as u8
200 op[0] = op[0] + 1
201 }
202 } else {
203 var v: i64 = c
204 if v == RI_TAB { v = RI_SPACE }
205 if v == RI_NL { v = RI_SPACE }
206 if v == RI_CR { v = RI_SPACE }
207 out[op[0]] = v as u8
208 op[0] = op[0] + 1
209 i = i + 1
210 }
211 }
212 return RI_NONE
213}
214// walk the whole object: mode COUNT returns the pair count; mode DECODE fills the offset/length tables and the
215// arena (each decoded string NUL-terminated) and returns the pair count; RI_NONE when malformed
216func ri_walk(raw: *u8, n: i64, mode: i64, koff: *i64, klen: *i64, voff: *i64, vlen: *i64, arena: *u8, ap: *i64) -> i64 {
217 var i: i64 = 0
218 if n >= RI_BOM_LEN { if ((raw[0] as i64) & RI_BYTE) == RI_BOM_0 { if ((raw[1] as i64) & RI_BYTE) == RI_BOM_1 { if ((raw[2] as i64) & RI_BYTE) == RI_BOM_2 { i = RI_BOM_LEN } } } }
219 i = ri_skip_ws(raw, n, i)
220 if i >= n { return RI_NONE }
221 if ((raw[i] as i64) & RI_BYTE) != RI_LBRACE { return RI_NONE }
222 i = i + 1
223 var pairs: i64 = 0
224 var go: i64 = 1
225 while go == 1 {
226 i = ri_skip_ws(raw, n, i)
227 if i >= n { return RI_NONE }
228 let c: i64 = (raw[i] as i64) & RI_BYTE
229 if c == RI_RBRACE { go = 0 }
230 if go == 1 {
231 if c != RI_QUOTE { return RI_NONE }
232 if mode == RI_MODE_COUNT {
233 i = ri_skip_string(raw, n, i + 1)
234 } else {
235 let ks: i64 = ap[0]
236 i = ri_decode_string(raw, n, i + 1, arena, ap)
237 if i < 0 { return RI_NONE }
238 koff[pairs] = ks
239 klen[pairs] = ap[0] - ks
240 arena[ap[0]] = 0 as u8
241 ap[0] = ap[0] + 1
242 }
243 if i < 0 { return RI_NONE }
244 i = ri_skip_ws(raw, n, i)
245 if i >= n { return RI_NONE }
246 if ((raw[i] as i64) & RI_BYTE) != RI_COLON { return RI_NONE }
247 i = ri_skip_ws(raw, n, i + 1)
248 if i >= n { return RI_NONE }
249 if ((raw[i] as i64) & RI_BYTE) != RI_QUOTE { return RI_NONE }
250 if mode == RI_MODE_COUNT {
251 i = ri_skip_string(raw, n, i + 1)
252 } else {
253 let vs: i64 = ap[0]
254 i = ri_decode_string(raw, n, i + 1, arena, ap)
255 if i < 0 { return RI_NONE }
256 voff[pairs] = vs
257 vlen[pairs] = ap[0] - vs
258 arena[ap[0]] = 0 as u8
259 ap[0] = ap[0] + 1
260 }
261 if i < 0 { return RI_NONE }
262 pairs = pairs + 1
263 i = ri_skip_ws(raw, n, i)
264 if i >= n { return RI_NONE }
265 let d: i64 = (raw[i] as i64) & RI_BYTE
266 if d == RI_COMMA { i = i + 1 }
267 if d == RI_RBRACE { go = 0 }
268 if d != RI_COMMA { if d != RI_RBRACE { return RI_NONE } }
269 }
270 }
271 return pairs
272}
273
274// ---- the match: a queries.tsv row's text against the decoded keys; returns the pair index or RI_NONE ----
275func ri_find(text: *u8, tl: i64, arena: *u8, koff: *i64, klen: *i64, pairs: i64) -> i64 {
276 var p: i64 = 0
277 while p < pairs {
278 if klen[p] == tl { if ri_memeq(text, ((arena as i64) + koff[p]) as *u8, tl) == 1 { return p } }
279 p = p + 1
280 }
281 return RI_NONE
282}
283// THE ONE DECISION: the exit code for a run, from its counts. A gate drives this directly so the refusal rule
284// cannot be right in main and wrong in the test: any miss or any unreadable split refuses.
285func ri_decide(missed: i64, unreadable: i64) -> i64 {
286 if missed > 0 { return RI_REFUSED }
287 if unreadable > 0 { return RI_REFUSED }
288 return RI_OK
289}
290func ri_write_all(fd: i64, buf: *u8, n: i64) -> i64 {
291 var off: i64 = 0
292 while off < n {
293 let r: i64 = sys_write(fd, ((buf as i64) + off) as *u8, n - off)
294 if r <= 0 { return RI_NONE }
295 off = off + r
296 }
297 return 0
298}
299// stage one split: read its queries.tsv, match every row, write <outpath>.tmp; st receives rows, matched, missed
300func ri_stage_split(root: *u8, split: *u8, outname: *u8, concat: i64, arena: *u8, alen: i64, koff: *i64, klen: *i64, voff: *i64, vlen: *i64, used: *i64, pairs: i64, st: *i64, tmpp: *u8, outp: *u8) -> i64 {
301 let qp: *u8 = sys_mmap(RI_PATH_CAP)
302 if ri_path(qp, root, split, RI_F_QUERIES) < 0 { return RI_NONE }
303 if ri_path(outp, root, split, RI_SLASH) < 0 { return RI_NONE }
304 if ri_cat(outp, ri_slen(outp), outname, RI_PATH_CAP) < 0 { return RI_NONE }
305 if ri_cat(tmpp, 0, outp, RI_PATH_CAP) < 0 { return RI_NONE }
306 if ri_cat(tmpp, ri_slen(tmpp), RI_TMP, RI_PATH_CAP) < 0 { return RI_NONE }
307 let lp: *i64 = sys_mmap(RI_CELL) as *i64
308 let q: *u8 = sys_read_file(qp, lp)
309 let qn: i64 = lp[0]
310 if (q as i64) == 0 { ri_puts("RI-UNREADABLE " as *u8); ri_puts(qp); ri_puts("\n" as *u8); return RI_NONE }
311 if qn <= 0 { ri_puts("RI-UNREADABLE " as *u8); ri_puts(qp); ri_puts("\n" as *u8); return RI_NONE }
312 let cap: i64 = alen + qn + qn + RI_ARENA_SLACK
313 let out: *u8 = sys_mmap(cap)
314 var o: i64 = 0
315 var rows: i64 = 0
316 var matched: i64 = 0
317 var missed: i64 = 0
318 var i: i64 = 0
319 while i < qn {
320 // one row: id TAB text NL (a trailing CR is dropped: the file may have been edited on any host)
321 var e: i64 = i
322 while e < qn { if ((q[e] as i64) & RI_BYTE) == RI_NL { e = qn + e } else { e = e + 1 } }
323 var end: i64 = e
324 if e > qn { end = e - qn }
325 var tab: i64 = RI_NONE
326 var k: i64 = i
327 while k < end { if tab < 0 { if ((q[k] as i64) & RI_BYTE) == RI_TAB { tab = k } } k = k + 1 }
328 if tab >= 0 {
329 var tend: i64 = end
330 if tend > tab + 1 { if ((q[tend - 1] as i64) & RI_BYTE) == RI_CR { tend = tend - 1 } }
331 let idl: i64 = tab - i
332 let tl: i64 = tend - (tab + 1)
333 let text: *u8 = ((q as i64) + tab + 1) as *u8
334 rows = rows + 1
335 let p: i64 = ri_find(text, tl, arena, koff, klen, pairs)
336 if p < 0 {
337 missed = missed + 1
338 ri_puts("RI-MISS split=" as *u8); ri_puts(split); ri_puts(" id=" as *u8); sys_write(RI_STDOUT, ((q as i64) + i) as *u8, idl); ri_puts("\n" as *u8)
339 } else {
340 matched = matched + 1
341 used[p] = used[p] + 1
342 var j: i64 = 0
343 while j < idl { out[o] = q[i + j]; o = o + 1; j = j + 1 }
344 out[o] = RI_TAB as u8; o = o + 1
345 if concat == 1 {
346 j = 0
347 while j < tl { out[o] = text[j]; o = o + 1; j = j + 1 }
348 out[o] = RI_SPACE as u8; o = o + 1
349 }
350 let v: *u8 = ((arena as i64) + voff[p]) as *u8
351 let vl: i64 = vlen[p]
352 j = 0
353 while j < vl { out[o] = v[j]; o = o + 1; j = j + 1 }
354 out[o] = RI_NL as u8; o = o + 1
355 }
356 }
357 i = end + 1
358 }
359 st[0] = rows
360 st[1] = matched
361 st[2] = missed
362 let fd: i64 = sys_openat_wr(tmpp, MODE_0644)
363 if fd < 0 { ri_puts("RI-CANNOT-STAGE " as *u8); ri_puts(tmpp); ri_puts("\n" as *u8); return RI_NONE }
364 let w: i64 = ri_write_all(fd, out, o)
365 sys_close(fd)
366 if w < 0 { ri_puts("RI-SHORT-WRITE " as *u8); ri_puts(tmpp); ri_puts("\n" as *u8); return RI_NONE }
367 return o
368}
369
370func main(argc: i64, argv: *i64) -> i64 {
371 if argc < 4 {
372 ri_puts("usage: nx_bright_reasoned_import <reasoned.json> <bright-root> <outname> [reason|concat]\n" as *u8)
373 return RI_USAGE
374 }
375 let jsonp: *u8 = argv[1] as *u8
376 let root: *u8 = argv[2] as *u8
377 let outname: *u8 = argv[3] as *u8
378 var concat: i64 = 0
379 if argc >= 5 {
380 let m: *u8 = argv[4] as *u8
381 if ri_streq(m, RI_WORD_CONCAT) == 1 { concat = 1 } else {
382 if ri_streq(m, RI_WORD_REASON) == 0 { ri_puts("RI-USAGE mode must be reason or concat\n" as *u8); return RI_USAGE }
383 }
384 }
385 let lp: *i64 = sys_mmap(RI_CELL) as *i64
386 let raw: *u8 = sys_read_file(jsonp, lp)
387 let n: i64 = lp[0]
388 if (raw as i64) == 0 { ri_puts("RI-REFUSED cannot read " as *u8); ri_puts(jsonp); ri_puts("\n" as *u8); return RI_REFUSED }
389 if n <= 0 { ri_puts("RI-REFUSED empty " as *u8); ri_puts(jsonp); ri_puts("\n" as *u8); return RI_REFUSED }
390 let none: *i64 = sys_mmap(RI_CELL) as *i64
391 let pairs: i64 = ri_walk(raw, n, RI_MODE_COUNT, none, none, none, none, raw, none)
392 if pairs < 0 { ri_puts("RI-REFUSED malformed: not one JSON object of string to string pairs\n" as *u8); return RI_REFUSED }
393 if pairs == 0 { ri_puts("RI-REFUSED the object holds no pairs\n" as *u8); return RI_REFUSED }
394 let koff: *i64 = sys_mmap(pairs * RI_CELL) as *i64
395 let klen: *i64 = sys_mmap(pairs * RI_CELL) as *i64
396 let voff: *i64 = sys_mmap(pairs * RI_CELL) as *i64
397 let vlen: *i64 = sys_mmap(pairs * RI_CELL) as *i64
398 let used: *i64 = sys_mmap(pairs * RI_CELL) as *i64
399 let alen: i64 = n + pairs + pairs + RI_ARENA_SLACK
400 let arena: *u8 = sys_mmap(alen)
401 let ap: *i64 = sys_mmap(RI_CELL) as *i64
402 ap[0] = 0
403 let pairs2: i64 = ri_walk(raw, n, RI_MODE_DECODE, koff, klen, voff, vlen, arena, ap)
404 if pairs2 != pairs { ri_puts("RI-REFUSED the decode pass disagrees with the count pass\n" as *u8); return RI_REFUSED }
405 ri_puts("RI-JSON " as *u8); ri_puts(jsonp); ri_puts(" bytes=" as *u8); ri_putn(n); ri_puts(" pairs=" as *u8); ri_putn(pairs); ri_puts(" decoded_bytes=" as *u8); ri_putn(ap[0]); ri_puts("\n" as *u8)
406 let st: *i64 = sys_mmap(RI_CELL * 3) as *i64
407 let tmps: *u8 = sys_mmap(RI_PATH_CAP * RI_SPLITS)
408 let outs: *u8 = sys_mmap(RI_PATH_CAP * RI_SPLITS)
409 var rows: i64 = 0
410 var matched: i64 = 0
411 var missed: i64 = 0
412 var unreadable: i64 = 0
413 var s: i64 = 0
414 while s < RI_SPLITS {
415 let tmpp: *u8 = ((tmps as i64) + s * RI_PATH_CAP) as *u8
416 let outp: *u8 = ((outs as i64) + s * RI_PATH_CAP) as *u8
417 st[0] = 0; st[1] = 0; st[2] = 0
418 let r: i64 = ri_stage_split(root, ri_split(s), outname, concat, arena, alen, koff, klen, voff, vlen, used, pairs, st, tmpp, outp)
419 if r < 0 { unreadable = unreadable + 1 }
420 rows = rows + st[0]
421 matched = matched + st[1]
422 missed = missed + st[2]
423 ri_puts("RI-SPLIT " as *u8); ri_puts(ri_split(s)); ri_puts(" rows=" as *u8); ri_putn(st[0]); ri_puts(" matched=" as *u8); ri_putn(st[1]); ri_puts(" missed=" as *u8); ri_putn(st[2])
424 if r >= 0 { ri_puts(" staged_bytes=" as *u8); ri_putn(r) } else { ri_puts(" staged=NONE" as *u8) }
425 ri_puts("\n" as *u8)
426 s = s + 1
427 }
428 var keys_used: i64 = 0
429 var keys_reused: i64 = 0
430 var p: i64 = 0
431 while p < pairs { if used[p] > 0 { keys_used = keys_used + 1 } if used[p] > 1 { keys_reused = keys_reused + 1 } p = p + 1 }
432 var mode: *u8 = RI_WORD_REASON
433 if concat == 1 { mode = RI_WORD_CONCAT }
434 ri_puts("RI-PARTITION rows=" as *u8); ri_putn(rows); ri_puts(" matched=" as *u8); ri_putn(matched); ri_puts(" missed=" as *u8); ri_putn(missed); ri_puts(" sum=" as *u8); ri_putn(matched + missed)
435 ri_puts(" pairs=" as *u8); ri_putn(pairs); ri_puts(" keys_used=" as *u8); ri_putn(keys_used); ri_puts(" keys_reused_across_splits=" as *u8); ri_putn(keys_reused); ri_puts(" keys_unused=" as *u8); ri_putn(pairs - keys_used); ri_puts(" mode=" as *u8); ri_puts(mode); ri_puts("\n" as *u8)
436 if ri_decide(missed, unreadable) != RI_OK {
437 ri_puts("RI-REFUSED missed=" as *u8); ri_putn(missed); ri_puts(" unreadable_splits=" as *u8); ri_putn(unreadable); ri_puts(" -- a partial replay would score a different query set than it claims, and every split must stage before any is renamed; nothing renamed into place, the .tmp stages are left for inspection\nverdict=RED\n" as *u8)
438 return RI_REFUSED
439 }
440 s = 0
441 while s < RI_SPLITS {
442 let tmpp: *u8 = ((tmps as i64) + s * RI_PATH_CAP) as *u8
443 let outp: *u8 = ((outs as i64) + s * RI_PATH_CAP) as *u8
444 if sys_renameat(tmpp, outp) != 0 { ri_puts("RI-REFUSED rename failed for " as *u8); ri_puts(outp); ri_puts("\nverdict=RED\n" as *u8); return RI_REFUSED }
445 ri_puts("RI-WROTE " as *u8); ri_puts(outp); ri_puts("\n" as *u8)
446 s = s + 1
447 }
448 ri_puts("RI-DONE splits=" as *u8); ri_putn(RI_SPLITS); ri_puts(" rows=" as *u8); ri_putn(rows); ri_puts(" out=" as *u8); ri_puts(outname); ri_puts(" -- run: nx_beir_eval bright=<root> bm25only queries=" as *u8); ri_puts(outname); ri_puts(" (a referee replay: the sweep names the file and never writes the leaderboard row)\nverdict=GREEN\n" as *u8)
449 return RI_OK
450}