nx_libdata.nx source
↩ module page · 1476 lines · 67181 B
1// nx_libdata.nx -- THE SELF-SUFFICIENCY DATA LIBRARY ENGINE (ws=library-datasets, 2026-07-31).
2// Operator goal: collect the datasets that were NOT coming in, ranked MOST VALUABLE to LEAST for
3// household self-sufficiency against the cost-of-living crisis (gardening, NSF, manufacturing, ...).
4//
5// WHY: the library answered 'gardening' with garden-centre shop pages, and knowledge/fetched/ held
6// 44 Wikipedia pages. Root cause (debt 1785516741/1785516905) was TRANSPORT, not a missing list:
7// every ingester called the TLS-1.3-only fetch entry point, so TLS-1.2-only hosts -- exactly where
8// US federal open data lives -- were unreachable. This organ deliberately calls the WIDE-REACH
9// nx_https_fetch_follow_best so it can never regress to the narrow path.
10//
11// DATA-DRIVEN BY CONSTRUCTION (rule 11): the source list is knowledge/registry/selfsuff_datasets.tsv
12// and the ranking weights are knowledge/status/selfsuff_axes.conf. Adding a dataset is ONE ROW and
13// zero code; re-prioritising the whole library is editing four weights. Contrast nx_supply_research_fetch,
14// which hardcodes 44 URLs in its body.
15//
16// verbs: rank | gaps | fetch [maxn] | status | selftest
17// expect_exit: 0 license_tier: ORIGINAL
18import "nx_syscalls.nx"
19import "nx_x509_trust_store.nx"
20import "nx_trust_store_load_from_certdata.nx"
21import "nx_https_fetch_follow.nx"
22import "nx_sha256.nx"
23import "nx_store_seed_lib.nx"
24import "nx_lib_openalex.nx"
25import "nx_lib_search.nx"
26import "nx_gzip_wrap.nx"
27const LD_MAGIC_2048: i64 = 2048
28const LD_MAGIC_65558: i64 = 65558
29const LD_MAGIC_4096: i64 = 4096
30
31const LD_BUF: i64 = 262144
32const LD_AXBUF: i64 = 16384
33const LD_ROWS: i64 = 256
34// 15 columns: the original 13 plus two SOTA gates carried as DATA, not code --
35// col 13 min_bytes semantic floor; a payload under it is an error envelope, not a dataset
36// col 14 max_age_days freshness; 0 = never stale. have-skip alone means a file is NEVER refreshed.
37// Rows with only 13 fields still parse: missing fields get length 0 and read as 0 (rule 19).
38const LD_NF: i64 = 15
39const LD_FETCH: i64 = 134217728
40const LD_PATH: i64 = 1024
41const LD_CERT: i64 = 4194304
42const LD_MODE_644: i64 = 420
43const LD_PERMIL: i64 = 1000
44const LD_TAB: i64 = 9
45const LD_NL: i64 = 10
46const LD_HASH: i64 = 35
47const LD_ACCESS_FULL: i64 = 10
48const LD_HOPS: i64 = 6
49// Range window. EIA truncates a single response near 258KB, so stay well under it.
50const LD_CHUNK: i64 = 131072
51const LD_MAXCHUNKS: i64 = 1100
52const LD_WINDOW_TRIES: i64 = 4
53// Backoff multiplies by attempt number: 429 is explicit rate limiting, not an error.
54const LD_BACKOFF_MS: i64 = 1500
55const LD_REFETCH_MS: i64 = 8000
56
57// field indexes into a registry row
58const F_ID: i64 = 0
59const F_DOMAIN: i64 = 1
60const F_URL: i64 = 3
61const F_SAVE: i64 = 6
62const F_BREADTH: i64 = 7
63const F_DUR: i64 = 8
64const F_UNSUB: i64 = 9
65const F_ACCESS: i64 = 10
66const F_STATUS: i64 = 11
67const F_MINBYTES: i64 = 13
68const F_MAXAGE: i64 = 14
69const LD_SECS_DAY: i64 = 86400
70// Error envelopes announce themselves in the first bytes. Scanning only the HEAD keeps a real
71// dataset that happens to contain the words "Not Found" in its body from being rejected.
72const LD_SCANHEAD: i64 = 2048
73const LD_CATALOG: *u8 = "knowledge/store/libdata-" as *u8
74const LD_REJCONF: *u8 = "knowledge/status/selfsuff_reject.conf" as *u8
75const LD_PROV: *u8 = "knowledge/status/selfsuff_provenance.tsv" as *u8
76
77// Local string helpers. nx_sovjson_lib.nx lives in runtime/_hdl_build/ and this organ lives in
78// runtime/ -- runtime CANNOT import _hdl_build (layering law), so sj_vlen/sj_puts/sj_lit_eq are
79// reimplemented here rather than reaching across the layer.
80func ld_vlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
81func ld_emit(s: *u8) -> i64 { let n: i64 = ld_vlen(s); sys_write(1, s, n); return 0 }
82func ld_lit_eq(s: *u8, off: i64, len: i64, lit: *u8) -> i64 {
83 let ll: i64 = ld_vlen(lit)
84 if ll != len { return 0 }
85 var i: i64 = 0
86 while i < ll { if s[off+i] != lit[i] { return 0 } i = i + 1 }
87 return 1
88}
89
90func ld_puts(s: *u8) -> i64 { ld_emit(s); return 0 }
91
92// CORRECT integer emit. The sibling fetcher nx_supply_research_fetch has this same helper WITHOUT
93// the reverse-and-write loop below, so every byte count and status code it prints comes out EMPTY
94// (debt 1785516650). A fetcher that cannot report a byte count cannot tell success from failure.
95func ld_putn(v: i64) -> i64 {
96 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
97 var m: i64 = v
98 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
99 let d: *u8 = sys_mmap(24)
100 var k: i64 = 0
101 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
102 var j: i64 = k - 1
103 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 }
104 return 0
105}
106
107func ld_write_n(s: *u8, n: i64) -> i64 { sys_write(1, s, n); return 0 }
108
109func ld_read(path: *u8, buf: *u8, cap: i64) -> i64 {
110 let fd: i64 = sys_openat_rd(path)
111 if fd < 0 { return -1 }
112 var n: i64 = 0
113 var go: i64 = 1
114 while go == 1 { let r: i64 = sys_read(fd, ((buf as i64)+n) as *u8, cap-n); if r <= 0 { go = 0 } else { n = n + r } if n >= cap { go = 0 } }
115 sys_close(fd)
116 return n
117}
118
119func ld_have(path: *u8) -> i64 {
120 let fd: i64 = sys_openat_rd(path)
121 if fd < 0 { return 0 }
122 sys_close(fd)
123 return 1
124}
125
126// parse a non-negative int out of buf[o..o+len)
127func ld_atoi(buf: *u8, o: i64, len: i64) -> i64 {
128 var v: i64 = 0
129 var i: i64 = 0
130 while i < len {
131 let c: i64 = buf[o+i] as i64
132 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } }
133 i = i + 1
134 }
135 return v
136}
137
138// look up an integer config value: a line "<key>\t<int>\t..."
139// End-of-line index (exclusive) for the line starting at `from`, or n if the last line is unterminated.
140// Written as an explicit scan-then-stop because terminating the loop by driving the cursor past n
141// DESTROYS the position we are trying to return -- the bug this function exists to prevent.
142func ld_eol(buf: *u8, from: i64, n: i64) -> i64 {
143 var p: i64 = from
144 var eol: i64 = -1
145 while p < n {
146 if eol < 0 {
147 if buf[p] == (LD_NL as u8) { eol = p }
148 p = p + 1
149 } else { p = n }
150 }
151 if eol < 0 { return n }
152 return eol
153}
154
155func ld_conf_int(buf: *u8, n: i64, key: *u8, dflt: i64) -> i64 {
156 let kl: i64 = ld_vlen(key)
157 var i: i64 = 0
158 while i < n {
159 let ls: i64 = i
160 let lend: i64 = ld_eol(buf, i, n)
161 // does this line start with key followed by TAB?
162 var ok: i64 = 0
163 if ls + kl + 1 <= lend {
164 var k: i64 = 0
165 ok = 1
166 while k < kl { if buf[ls+k] != key[k] { ok = 0; k = kl } else { k = k + 1 } }
167 if ok == 1 { if buf[ls+kl] != (LD_TAB as u8) { ok = 0 } }
168 }
169 if ok == 1 {
170 let vs: i64 = ls + kl + 1
171 var ve: i64 = vs
172 while ve < lend { if buf[ve] == (LD_TAB as u8) { ve = lend } else { ve = ve + 1 } }
173 return ld_atoi(buf, vs, ve - vs)
174 }
175 i = lend + 1
176 }
177 return dflt
178}
179
180// Parse the registry into parallel offset/length arrays. Returns the row count.
181func ld_parse(buf: *u8, n: i64, fo: *i64, fl: *i64) -> i64 {
182 var rows: i64 = 0
183 var i: i64 = 0
184 while i < n {
185 if rows >= LD_ROWS { i = n }
186 if i < n {
187 let e: i64 = ld_eol(buf, i, n)
188 var keep: i64 = 1
189 if e <= i { keep = 0 }
190 if keep == 1 { if buf[i] == (LD_HASH as u8) { keep = 0 } }
191 if keep == 1 {
192 // Zero every slot first so a 13-column legacy row leaves min_bytes//max_age at 0
193 // instead of inheriting whatever the previous row left in the array.
194 var z: i64 = 0
195 while z < LD_NF { fo[rows*LD_NF + z] = 0; fl[rows*LD_NF + z] = 0; z = z + 1 }
196 var c: i64 = 0
197 var fs: i64 = i
198 var p: i64 = i
199 while p <= e {
200 var cut: i64 = 0
201 if p == e { cut = 1 }
202 if cut == 0 { if buf[p] == (LD_TAB as u8) { cut = 1 } }
203 if cut == 1 {
204 if c < LD_NF {
205 fo[rows*LD_NF + c] = fs
206 fl[rows*LD_NF + c] = p - fs
207 c = c + 1
208 }
209 fs = p + 1
210 }
211 p = p + 1
212 }
213 if c >= 12 { rows = rows + 1 }
214 }
215 i = e + 1
216 }
217 }
218 return rows
219}
220
221func ld_field_i(buf: *u8, fo: *i64, fl: *i64, r: i64, f: i64) -> i64 {
222 return ld_atoi(buf, fo[r*LD_NF + f], fl[r*LD_NF + f])
223}
224
225// delivered = (w_save*save + w_breadth*breadth + w_unsub*unsub + w_dur*dur) * access / 10
226// access MULTIPLIES: a dataset we cannot retrieve delivers ZERO, however precious it is.
227func ld_score(buf: *u8, fo: *i64, fl: *i64, r: i64, ws: i64, wb: i64, wu: i64, wd: i64) -> i64 {
228 let sv: i64 = ld_field_i(buf, fo, fl, r, F_SAVE)
229 let br: i64 = ld_field_i(buf, fo, fl, r, F_BREADTH)
230 let du: i64 = ld_field_i(buf, fo, fl, r, F_DUR)
231 let un: i64 = ld_field_i(buf, fo, fl, r, F_UNSUB)
232 let ac: i64 = ld_field_i(buf, fo, fl, r, F_ACCESS)
233 let base: i64 = ws*sv + wb*br + wu*un + wd*du
234 return (base * ac) / LD_ACCESS_FULL
235}
236
237// selection sort of an index array by score desc (rows are bounded by LD_ROWS)
238func ld_order(sc: *i64, ord: *i64, rows: i64) -> i64 {
239 var i: i64 = 0
240 while i < rows { ord[i] = i; i = i + 1 }
241 var a: i64 = 0
242 while a < rows {
243 var best: i64 = a
244 var b: i64 = a + 1
245 while b < rows {
246 if sc[ord[b]] > sc[ord[best]] { best = b }
247 b = b + 1
248 }
249 let t: i64 = ord[a]
250 ord[a] = ord[best]
251 ord[best] = t
252 a = a + 1
253 }
254 return 0
255}
256
257// knowledge/fetched/ss_<id>.raw
258func ld_outpath(dst: *u8, buf: *u8, fo: *i64, fl: *i64, r: i64) -> i64 {
259 let pre: *u8 = "knowledge/fetched/ss_" as *u8
260 var k: i64 = 0
261 var i: i64 = 0
262 let pl: i64 = ld_vlen(pre)
263 while i < pl { dst[k] = pre[i]; k = k + 1; i = i + 1 }
264 let io: i64 = fo[r*LD_NF + F_ID]
265 let il: i64 = fl[r*LD_NF + F_ID]
266 i = 0
267 while i < il { dst[k] = buf[io+i]; k = k + 1; i = i + 1 }
268 let suf: *u8 = ".raw" as *u8
269 let sl: i64 = ld_vlen(suf)
270 i = 0
271 while i < sl { dst[k] = suf[i]; k = k + 1; i = i + 1 }
272 dst[k] = 0 as u8
273 return k
274}
275
276func ld_cstr(dst: *u8, buf: *u8, o: i64, len: i64) -> i64 {
277 var i: i64 = 0
278 while i < len { dst[i] = buf[o+i]; i = i + 1 }
279 dst[len] = 0 as u8
280 return len
281}
282
283func ld_load(rpath: *u8, apath: *u8, buf: *u8, ax: *u8, fo: *i64, fl: *i64, sc: *i64, ord: *i64, wout: *i64) -> i64 {
284 let n: i64 = ld_read(rpath, buf, LD_BUF)
285 if n <= 0 { return -1 }
286 let an: i64 = ld_read(apath, ax, LD_AXBUF)
287 if an <= 0 { return -2 }
288 let ws: i64 = ld_conf_int(ax, an, "w_save" as *u8, 0)
289 let wb: i64 = ld_conf_int(ax, an, "w_breadth" as *u8, 0)
290 let wu: i64 = ld_conf_int(ax, an, "w_unsub" as *u8, 0)
291 let wd: i64 = ld_conf_int(ax, an, "w_durability" as *u8, 0)
292 // FAIL-CLOSED: absent weights must not silently rank everything 0 and look like a working library.
293 if ws + wb + wu + wd <= 0 { return -3 }
294 wout[0] = ws
295 wout[1] = wb
296 wout[2] = wu
297 wout[3] = wd
298 wout[4] = ld_conf_int(ax, an, "domain_floor" as *u8, 0)
299 let rows: i64 = ld_parse(buf, n, fo, fl)
300 var r: i64 = 0
301 while r < rows { sc[r] = ld_score(buf, fo, fl, r, ws, wb, wu, wd); r = r + 1 }
302 ld_order(sc, ord, rows)
303 return rows
304}
305
306// ---- structural completeness helpers (debt 1785520161) ------------------------------------------
307// Search only the TAIL window: a terminator that appears anywhere else does not prove completeness.
308func ld_find_last(b: *u8, n: i64, lit: *u8, litlen: i64, window: i64) -> i64 {
309 var start: i64 = n - window
310 if start < 0 { start = 0 }
311 var i: i64 = start
312 var found: i64 = 0
313 while i + litlen <= n {
314 var k: i64 = 0
315 var ok: i64 = 1
316 while k < litlen { if b[i+k] != lit[k] { ok = 0; k = litlen } else { k = k + 1 } }
317 if ok == 1 { found = 1 }
318 i = i + 1
319 }
320 return found
321}
322
323// ZIP end-of-central-directory signature: PK\x05\x06. Its ABSENCE means the archive is truncated,
324// which is exactly what a server closing early produces.
325func ld_zip_eocd(b: *u8, n: i64) -> i64 {
326 var start: i64 = n - LD_MAGIC_65558
327 if start < 0 { start = 0 }
328 var i: i64 = start
329 var found: i64 = 0
330 while i + 4 <= n {
331 if b[i] == (80 as u8) { if b[i+1] == (75 as u8) { if b[i+2] == (5 as u8) { if b[i+3] == (6 as u8) { found = 1 } } } }
332 i = i + 1
333 }
334 return found
335}
336
337// A JSON document is complete when its LAST non-whitespace byte closes the root it opened.
338func ld_json_closed(b: *u8, n: i64, want: i64) -> i64 {
339 var i: i64 = n - 1
340 var res: i64 = 0
341 var go: i64 = 1
342 while go == 1 {
343 if i < 0 { go = 0 } else {
344 let c: i64 = b[i] as i64
345 if c == 32 { i = i - 1 } else {
346 if c == 10 { i = i - 1 } else {
347 if c == 13 { i = i - 1 } else {
348 if c == 9 { i = i - 1 } else {
349 if c == want { res = 1 }
350 go = 0
351 }
352 }
353 }
354 }
355 }
356 }
357 return res
358}
359
360// Structural completeness of ONE collected file: 1=complete, 0=SHORT-DELIVERY, 2=unverifiable.
361// Shared by verify AND status, deliberately: coverage that counts a truncated file as collected is
362// the same coverage-gaming failure the MIN headline exists to prevent. A short file is NOT covered.
363func ld_buf_complete(vbuf: *u8, n: i64) -> i64 {
364 if n <= 8 { return 2 }
365 if vbuf[0] == (37 as u8) { if vbuf[1] == (80 as u8) { if vbuf[2] == (68 as u8) { if vbuf[3] == (70 as u8) {
366 return ld_find_last(vbuf, n, "%%EOF" as *u8, 5, LD_MAGIC_4096)
367 } } } }
368 if vbuf[0] == (80 as u8) { if vbuf[1] == (75 as u8) { return ld_zip_eocd(vbuf, n) } }
369 if vbuf[0] == (123 as u8) { return ld_json_closed(vbuf, n, 125) }
370 if vbuf[0] == (91 as u8) { return ld_json_closed(vbuf, n, 93) }
371 return 2
372}
373
374func ld_file_complete(path: *u8, vbuf: *u8) -> i64 {
375 let n: i64 = ld_read(path, vbuf, LD_FETCH)
376 return ld_buf_complete(vbuf, n)
377}
378
379// ---- SOTA gap-closers: content hash, provenance lineage, freshness ------------------------------
380// Measured against 2026 ingestion practice, the library was missing: integrity hashing, a provenance
381// record per artifact, incremental//freshness, and semantic (not merely structural) validation.
382
383func ld_hexdig(v: i64) -> i64 {
384 if v < 10 { return 48 + v }
385 return 87 + v
386}
387
388// sha256 of a buffer, written as 64 lowercase hex chars + NUL. Integrity + change detection + dedup.
389func ld_sha_hex(b: *u8, n: i64, outhex: *u8) -> i64 {
390 let dig: *u8 = sys_mmap(64)
391 sha256_digest(b, n, dig)
392 var i: i64 = 0
393 while i < 32 {
394 let byte: i64 = dig[i] as i64
395 outhex[i*2] = ld_hexdig(byte / 16) as u8
396 outhex[i*2 + 1] = ld_hexdig(byte % 16) as u8
397 i = i + 1
398 }
399 outhex[64] = 0 as u8
400 return 64
401}
402
403func ld_app_str(d: *u8, o: i64, s2: *u8) -> i64 {
404 var i: i64 = 0
405 while s2[i] != (0 as u8) { d[o+i] = s2[i]; i = i + 1 }
406 return o + i
407}
408func ld_app_n(d: *u8, o: i64, v: i64) -> i64 {
409 if v == 0 { d[o] = 48 as u8; return o + 1 }
410 var m: i64 = v
411 var k: i64 = o
412 if m < 0 { d[k] = 45 as u8; k = k + 1; m = 0 - m }
413 let t: *u8 = sys_mmap(24)
414 var c: i64 = 0
415 while m > 0 { t[c] = (48 + (m % 10)) as u8; m = m / 10; c = c + 1 }
416 var j: i64 = c - 1
417 while j >= 0 { d[k] = t[j]; k = k + 1; j = j - 1 }
418 return k
419}
420
421// APPEND-ONLY provenance: one row per completed fetch. This is the lineage catalog the library had
422// no equivalent of -- without it there is no record of WHEN a byte arrived, from WHAT status, or
423// WHETHER it changed. Append-only so history is never rewritten.
424func ld_prov_append(idb: *u8, idlen: i64, url: *u8, status: i64, bytes: i64, hex: *u8, verdict: *u8) -> i64 {
425 let line: *u8 = sys_mmap(LD_MAGIC_2048)
426 var o: i64 = 0
427 o = ld_app_n(line, o, sys_now_realtime_sec())
428 line[o] = 9 as u8; o = o + 1
429 var i: i64 = 0
430 while i < idlen { line[o] = idb[i]; o = o + 1; i = i + 1 }
431 line[o] = 9 as u8; o = o + 1
432 o = ld_app_n(line, o, status)
433 line[o] = 9 as u8; o = o + 1
434 o = ld_app_n(line, o, bytes)
435 line[o] = 9 as u8; o = o + 1
436 o = ld_app_str(line, o, hex)
437 line[o] = 9 as u8; o = o + 1
438 o = ld_app_str(line, o, verdict)
439 line[o] = 9 as u8; o = o + 1
440 o = ld_app_str(line, o, url)
441 line[o] = 10 as u8; o = o + 1
442 let fd: i64 = sys_openat_append(LD_PROV, LD_MODE_644)
443 if fd < 0 { return 0 - 1 }
444 sys_write(fd, line, o)
445 sys_close(fd)
446 return o
447}
448
449// Newest provenance epoch for an id, or 0 if never fetched. Drives freshness WITHOUT a stat call:
450// the lineage log is already the authority on when a byte arrived.
451func ld_prov_last(idb: *u8, idlen: i64, pbuf: *u8) -> i64 {
452 let n: i64 = ld_read(LD_PROV, pbuf, LD_BUF)
453 if n <= 0 { return 0 }
454 var best: i64 = 0
455 var i: i64 = 0
456 while i < n {
457 let e: i64 = ld_eol(pbuf, i, n)
458 var ts: i64 = 0
459 var q: i64 = i
460 while q < e { if pbuf[q] == (9 as u8) { q = e } else { ts = ts * 10 + ((pbuf[q] as i64) - 48); q = q + 1 } }
461 var idstart: i64 = i
462 while idstart < e { if pbuf[idstart] == (9 as u8) { idstart = idstart + 1; q = e + 1 } else { idstart = idstart + 1 } }
463 var same: i64 = 1
464 var k: i64 = 0
465 while k < idlen { if idstart + k >= e { same = 0; k = idlen } else { if pbuf[idstart + k] != idb[k] { same = 0; k = idlen } else { k = k + 1 } } }
466 if same == 1 { if idstart + idlen < e { if pbuf[idstart + idlen] != (9 as u8) { same = 0 } } }
467 if same == 1 { if ts > best { best = ts } }
468 i = e + 1
469 }
470 return best
471}
472
473// Does the payload HEAD carry a known error-envelope marker? Markers live in a conf file, not in
474// code (rule 11), so the list is tunable without a reship. This is the guard a byte floor cannot be:
475// an evidence-derived floor protects only rows that ALREADY have an observation, which leaves the
476// FIRST fetch of a new row -- the most exposed case -- completely unguarded. Proven necessary:
477// api.bls.gov answered 200 with a 224-byte REQUEST_NOT_PROCESSED envelope and it was saved.
478func ld_has_marker(b: *u8, n: i64, conf: *u8, cn: i64) -> i64 {
479 var lim: i64 = n
480 if lim > LD_SCANHEAD { lim = LD_SCANHEAD }
481 var i: i64 = 0
482 var hit: i64 = 0
483 while i < cn {
484 let e: i64 = ld_eol(conf, i, cn)
485 var mlen: i64 = e - i
486 var skip: i64 = 0
487 if mlen <= 0 { skip = 1 }
488 if skip == 0 { if conf[i] == (35 as u8) { skip = 1 } }
489 if skip == 0 {
490 var q: i64 = 0
491 while q + mlen <= lim {
492 var k: i64 = 0
493 var same: i64 = 1
494 while k < mlen { if b[q+k] != conf[i+k] { same = 0; k = mlen } else { k = k + 1 } }
495 if same == 1 { hit = 1; q = lim }
496 q = q + 1
497 }
498 }
499 i = e + 1
500 }
501 return hit
502}
503
504// Find `needle` in b[0..n); returns index just PAST it, or -1.
505func ld_find_past(b: *u8, n: i64, needle: *u8) -> i64 {
506 let nl: i64 = ld_vlen(needle)
507 if nl <= 0 { return 0 - 1 }
508 var i: i64 = 0
509 var hit: i64 = 0 - 1
510 while i + nl <= n {
511 if hit < 0 {
512 var k: i64 = 0
513 var same: i64 = 1
514 while k < nl { if b[i+k] != needle[k] { same = 0; k = nl } else { k = k + 1 } }
515 if same == 1 { hit = i + nl }
516 }
517 i = i + 1
518 }
519 return hit
520}
521
522func ld_copy_until_quote(b: *u8, n: i64, from: i64, out: *u8) -> i64 {
523 var i: i64 = from
524 var k: i64 = 0
525 while i < n {
526 if b[i] == (34 as u8) { i = n } else { out[k] = b[i]; k = k + 1; i = i + 1 }
527 }
528 out[k] = 0 as u8
529 return k
530}
531
532// Extract OpenAlex meta.next_cursor into `out` (NUL-terminated). Returns length, 0 if absent/null.
533// The cursor is the ONLY honest signal that a harvest is finished -- page counting guesses.
534func ld_next_cursor(b: *u8, n: i64, out: *u8) -> i64 {
535 var at: i64 = ld_find_past(b, n, "\"next_cursor\"" as *u8)
536 if at < 0 { return 0 }
537 // skip ": " then require an opening quote; a null cursor means the last page.
538 while at < n { if b[at] == (34 as u8) { at = at + 1; return ld_copy_until_quote(b, n, at, out) } else { if b[at] == (110 as u8) { return 0 } else { at = at + 1 } } }
539 return 0
540}
541
542
543func ld_row_line(buf: *u8, fo: *i64, fl: *i64, r: i64, score: i64, rank: i64, have: i64) -> i64 {
544 ld_putn(rank)
545 ld_puts("\t" as *u8)
546 ld_putn(score)
547 ld_puts("\t" as *u8)
548 ld_write_n(((buf as i64) + fo[r*LD_NF + F_DOMAIN]) as *u8, fl[r*LD_NF + F_DOMAIN])
549 ld_puts("\t" as *u8)
550 ld_write_n(((buf as i64) + fo[r*LD_NF + F_ID]) as *u8, fl[r*LD_NF + F_ID])
551 ld_puts("\t" as *u8)
552 ld_write_n(((buf as i64) + fo[r*LD_NF + F_STATUS]) as *u8, fl[r*LD_NF + F_STATUS])
553 if have == 1 { ld_puts("\tON-DISK" as *u8) }
554 if have == 0 { ld_puts("\tABSENT" as *u8) }
555 ld_puts("\n" as *u8)
556 return 0
557}
558
559func main(argc: i64, argv: *i64) -> i64 {
560 if argc < 2 {
561 ld_puts("usage: nx_libdata {rank | gaps | fetch [maxn] | status | selftest} [registry] [axes]\n" as *u8)
562 sys_exit(2)
563 return 2
564 }
565 let verb: *u8 = argv[1] as *u8
566 let vl: i64 = ld_vlen(verb)
567
568 let rpath: *u8 = "knowledge/registry/selfsuff_datasets.tsv" as *u8
569 let apath: *u8 = "knowledge/status/selfsuff_axes.conf" as *u8
570
571 let buf: *u8 = sys_mmap(LD_BUF)
572 let ax: *u8 = sys_mmap(LD_AXBUF)
573 let fo: *i64 = sys_mmap(LD_ROWS*LD_NF*8) as *i64
574 let fl: *i64 = sys_mmap(LD_ROWS*LD_NF*8) as *i64
575 let sc: *i64 = sys_mmap(LD_ROWS*8) as *i64
576 let ord: *i64 = sys_mmap(LD_ROWS*8) as *i64
577 let w: *i64 = sys_mmap(64) as *i64
578 let pathbuf: *u8 = sys_mmap(LD_PATH)
579
580 let rows: i64 = ld_load(rpath, apath, buf, ax, fo, fl, sc, ord, w)
581 if rows == -1 { ld_puts("REFUSED registry unreadable: " as *u8); ld_puts(rpath); ld_puts("\n" as *u8); sys_exit(3); return 3 }
582 if rows == -2 { ld_puts("REFUSED axes conf unreadable: " as *u8); ld_puts(apath); ld_puts("\n" as *u8); sys_exit(3); return 3 }
583 if rows == -3 { ld_puts("REFUSED axes weights all zero -- refusing to emit a ranking that would look valid\n" as *u8); sys_exit(3); return 3 }
584 if rows <= 0 { ld_puts("REFUSED registry has no rows\n" as *u8); sys_exit(3); return 3 }
585
586 if ld_lit_eq(verb, 0, vl, "rank" as *u8) == 1 {
587 ld_puts("NX-LIBDATA RANK rows=" as *u8); ld_putn(rows)
588 ld_puts(" weights save/breadth/unsub/dur=" as *u8)
589 ld_putn(w[0]); ld_puts("/" as *u8); ld_putn(w[1]); ld_puts("/" as *u8); ld_putn(w[2]); ld_puts("/" as *u8); ld_putn(w[3])
590 ld_puts("\nrank\tscore\tdomain\tid\tstatus\tondisk\n" as *u8)
591 var i: i64 = 0
592 while i < rows {
593 let r: i64 = ord[i]
594 ld_outpath(pathbuf, buf, fo, fl, r)
595 ld_row_line(buf, fo, fl, r, sc[r], i+1, ld_have(pathbuf))
596 i = i + 1
597 }
598 sys_exit(0)
599 return 0
600 }
601
602 if ld_lit_eq(verb, 0, vl, "gaps" as *u8) == 1 {
603 ld_puts("NX-LIBDATA GAPS -- ranked work order, highest self-sufficiency value first\n" as *u8)
604 ld_puts("rank\tscore\tdomain\tid\tstatus\tondisk\n" as *u8)
605 var i: i64 = 0
606 var miss: i64 = 0
607 while i < rows {
608 let r: i64 = ord[i]
609 ld_outpath(pathbuf, buf, fo, fl, r)
610 if ld_have(pathbuf) == 0 {
611 ld_row_line(buf, fo, fl, r, sc[r], i+1, 0)
612 miss = miss + 1
613 }
614 i = i + 1
615 }
616 ld_puts("GAPS absent=" as *u8); ld_putn(miss)
617 ld_puts(" of " as *u8); ld_putn(rows); ld_puts("\n" as *u8)
618 sys_exit(0)
619 return 0
620 }
621
622 if ld_lit_eq(verb, 0, vl, "fetch" as *u8) == 1 {
623 var maxn: i64 = rows
624 if argc >= 3 { maxn = ld_atoi(argv[2] as *u8, 0, ld_vlen(argv[2] as *u8)) }
625 if maxn <= 0 { maxn = rows }
626 let tr: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt" as *u8, 512, LD_CERT)
627 if tr <= 0 { ld_puts("REFUSED certdata load failed -- refusing to fetch unauthenticated\n" as *u8); sys_exit(4); return 4 }
628 let store: *TrustStore = tr as *TrustStore
629 let out: *u8 = sys_mmap(LD_FETCH)
630 let status: *i64 = sys_mmap(8) as *i64
631 let urlbuf: *u8 = sys_mmap(LD_PATH)
632 let pbuf: *u8 = sys_mmap(LD_BUF)
633 let hexb: *u8 = sys_mmap(80)
634 let rconf: *u8 = sys_mmap(LD_AXBUF)
635 let rcn: i64 = ld_read(LD_REJCONF, rconf, LD_AXBUF)
636 var rejected: i64 = 0
637 var refreshed: i64 = 0
638 ld_puts("NX-LIBDATA FETCH ranked, wide-reach (1.3 -> chrome -> 1.2). CA roots=" as *u8)
639 ld_putn(trust_store_count(store)); ld_puts("\n" as *u8)
640 var i: i64 = 0
641 var done: i64 = 0
642 var okc: i64 = 0
643 var skip: i64 = 0
644 var fail: i64 = 0
645 var trunc: i64 = 0
646 var bytes_total: i64 = 0
647 while i < rows {
648 if done < maxn {
649 let r: i64 = ord[i]
650 ld_outpath(pathbuf, buf, fo, fl, r)
651 ld_write_n(((buf as i64) + fo[r*LD_NF + F_ID]) as *u8, fl[r*LD_NF + F_ID])
652 ld_puts("\t" as *u8)
653 // INCREMENTAL, NOT NEVER-AGAIN. Plain have-skip means a collected file is frozen
654 // forever; a price series or a rent table is wrong within weeks. max_age_days (col 14)
655 // turns the skip into a freshness check, using the provenance log as the authority on
656 // when the bytes actually arrived. max_age_days=0 keeps the old never-refetch behaviour.
657 var need: i64 = 1
658 if ld_have(pathbuf) == 1 {
659 need = 0
660 let maxage: i64 = ld_field_i(buf, fo, fl, r, F_MAXAGE)
661 if maxage > 0 {
662 let last: i64 = ld_prov_last(((buf as i64) + fo[r*LD_NF + F_ID]) as *u8, fl[r*LD_NF + F_ID], pbuf)
663 if last > 0 { if sys_now_realtime_sec() - last > maxage * LD_SECS_DAY { need = 1; refreshed = refreshed + 1 } }
664 }
665 }
666 if need == 0 {
667 ld_puts("[have-skip fresh]\n" as *u8)
668 skip = skip + 1
669 } else {
670 ld_cstr(urlbuf, buf, fo[r*LD_NF + F_URL], fl[r*LD_NF + F_URL])
671 status[0] = 0
672 let got: i64 = nx_https_fetch_follow_best(urlbuf, store, out, LD_FETCH, LD_HOPS, status)
673 ld_puts("status=" as *u8); ld_putn(status[0])
674 ld_puts(" bytes=" as *u8); ld_putn(got)
675 // ONLY 2xx MAY ENTER THE LIBRARY. The first pass saved a 404 page as
676 // ss_nist-mml-data.raw (70634B) and a 191B error blob as ss_fred-series.raw.
677 // A wrong answer in the library is worse than an absent row: every downstream
678 // reader then treats an error page as the dataset.
679 var ok2xx: i64 = 0
680 if status[0] >= 200 { if status[0] < 300 { ok2xx = 1 } }
681 // SEMANTIC FLOOR. 2xx + structurally-valid is NOT "the data is there": api.bls.gov
682 // answered 200 with a well-formed JSON rate-limit envelope and it was banked as a
683 // household-expenditure dataset. A global byte floor cannot work (ss_phzm-zone.raw is
684 // 105 real bytes), so the floor is PER-ROW DATA in col 13.
685 var floored: i64 = 0
686 let minb: i64 = ld_field_i(buf, fo, fl, r, F_MINBYTES)
687 // got<=0 is a TRANSPORT failure (-2 connect, -3 handshake, -4 GET), NOT a small
688 // payload. Reporting it as BELOW-FLOOR names the wrong cause and would send the
689 // next reader hunting for a data problem that does not exist.
690 if minb > 0 { if got > 0 { if got < minb { floored = 1 } } }
691 if floored == 0 { if rcn > 0 { if got > 0 {
692 if ld_has_marker(out, got, rconf, rcn) == 1 { floored = 2 }
693 } } }
694 if floored != 0 {
695 if floored == 1 {
696 ld_puts(" REJECTED-BELOW-FLOOR min=" as *u8)
697 ld_putn(minb)
698 }
699 if floored == 2 { ld_puts(" REJECTED-ERROR-ENVELOPE (marker matched in head)" as *u8) }
700 ld_puts("\n" as *u8)
701 rejected = rejected + 1
702 ld_sha_hex(out, got, hexb)
703 ld_prov_append(((buf as i64) + fo[r*LD_NF + F_ID]) as *u8, fl[r*LD_NF + F_ID], urlbuf, status[0], got, hexb, "REJECTED-BELOW-FLOOR" as *u8)
704 }
705 if got > 0 { if ok2xx == 1 { if floored == 0 {
706 let fd: i64 = sys_openat_wr(pathbuf, LD_MODE_644)
707 if fd < 0 { ld_puts(" SAVE-FAIL\n" as *u8); fail = fail + 1 } else {
708 sys_write(fd, out, got)
709 sys_close(fd)
710 ld_puts(" SAVED" as *u8)
711 okc = okc + 1
712 bytes_total = bytes_total + got
713 // integrity + lineage: hash every artifact and record how it arrived
714 ld_sha_hex(out, got, hexb)
715 ld_prov_append(((buf as i64) + fo[r*LD_NF + F_ID]) as *u8, fl[r*LD_NF + F_ID], urlbuf, status[0], got, hexb, "SAVED" as *u8)
716 ld_puts(" sha=" as *u8)
717 sys_write(1, hexb, 12)
718 // TRUNCATION IS SILENT CORRUPTION: a PDF/ZIP cut at the buffer cap is
719 // not the dataset. Say so loudly instead of banking a clean-looking row.
720 if got >= LD_FETCH { ld_puts(" ***TRUNCATED-AT-CAP INCOMPLETE***" as *u8); trunc = trunc + 1 }
721 ld_puts("\n" as *u8)
722 }
723 } } }
724 if got > 0 { if ok2xx == 0 { ld_puts(" REFUSED-NON-2XX not saved\n" as *u8); fail = fail + 1 } }
725 if got <= 0 { ld_puts(" FETCH-FAIL\n" as *u8); fail = fail + 1 }
726 done = done + 1
727 }
728 }
729 i = i + 1
730 }
731 ld_puts("FETCH saved=" as *u8); ld_putn(okc)
732 ld_puts(" skipped=" as *u8); ld_putn(skip)
733 ld_puts(" failed=" as *u8); ld_putn(fail)
734 ld_puts(" bytes=" as *u8); ld_putn(bytes_total)
735 ld_puts(" truncated=" as *u8); ld_putn(trunc)
736 ld_puts(" rejected_below_floor=" as *u8); ld_putn(rejected)
737 ld_puts(" refreshed_stale=" as *u8); ld_putn(refreshed)
738 ld_puts("\n" as *u8)
739 sys_exit(0)
740 return 0
741 }
742
743 if ld_lit_eq(verb, 0, vl, "status" as *u8) == 1 {
744 // Per-domain coverage. HEADLINE = MIN, never mean (feedback-coverage-gaming-min-not-mean-law):
745 // otherwise coverage is gamed by piling rows into whichever domain fetches easiest.
746 ld_puts("NX-LIBDATA STATUS -- per-domain collected coverage\n" as *u8)
747 ld_puts("domain\trows\tondisk\tpermil\n" as *u8)
748 let vbuf2: *u8 = sys_mmap(LD_FETCH)
749 var minp: i64 = LD_PERMIL
750 var seen: *i64 = sys_mmap(LD_ROWS*8) as *i64
751 var nseen: i64 = 0
752 var i: i64 = 0
753 while i < rows {
754 let dof: i64 = fo[i*LD_NF + F_DOMAIN]
755 let dln: i64 = fl[i*LD_NF + F_DOMAIN]
756 var dup: i64 = 0
757 var s: i64 = 0
758 while s < nseen {
759 let j: i64 = seen[s]
760 if fl[j*LD_NF + F_DOMAIN] == dln {
761 var k: i64 = 0
762 var same: i64 = 1
763 while k < dln { if buf[fo[j*LD_NF + F_DOMAIN]+k] != buf[dof+k] { same = 0; k = dln } else { k = k + 1 } }
764 if same == 1 { dup = 1; s = nseen }
765 }
766 s = s + 1
767 }
768 if dup == 0 {
769 seen[nseen] = i
770 nseen = nseen + 1
771 var cnt: i64 = 0
772 var got: i64 = 0
773 var q: i64 = 0
774 while q < rows {
775 var same2: i64 = 0
776 if fl[q*LD_NF + F_DOMAIN] == dln {
777 var k2: i64 = 0
778 same2 = 1
779 while k2 < dln { if buf[fo[q*LD_NF + F_DOMAIN]+k2] != buf[dof+k2] { same2 = 0; k2 = dln } else { k2 = k2 + 1 } }
780 }
781 if same2 == 1 {
782 cnt = cnt + 1
783 ld_outpath(pathbuf, buf, fo, fl, q)
784 // NOT just ld_have: a SHORT-DELIVERED file on disk must not count as covered,
785 // or coverage inflates on truncation (4 EIA zips did exactly that, 2026-07-31).
786 if ld_have(pathbuf) == 1 { if ld_file_complete(pathbuf, vbuf2) != 0 { got = got + 1 } }
787 }
788 q = q + 1
789 }
790 var permil: i64 = 0
791 if cnt > 0 { permil = (got * LD_PERMIL) / cnt }
792 ld_write_n(((buf as i64) + dof) as *u8, dln)
793 ld_puts("\t" as *u8); ld_putn(cnt)
794 ld_puts("\t" as *u8); ld_putn(got)
795 ld_puts("\t" as *u8); ld_putn(permil)
796 ld_puts("\n" as *u8)
797 if permil < minp { minp = permil }
798 }
799 i = i + 1
800 }
801 ld_puts("HEADLINE min_domain_permil=" as *u8); ld_putn(minp)
802 ld_puts(" domains=" as *u8); ld_putn(nseen)
803 ld_puts(" (MIN not mean -- one starved domain must drag the headline down)\n" as *u8)
804 sys_exit(0)
805 return 0
806 }
807
808 if ld_lit_eq(verb, 0, vl, "harvest" as *u8) == 1 {
809 // CURSOR HARVEST. Every scholarly row was capped at ONE page: per-page=200 against a corpus
810 // reporting count=3,248,290. OpenAlex pages with cursor=* -> meta.next_cursor, so the library
811 // was limited by the fetch loop, not by the source. Each page is gzip-encoded and inflated
812 // in-line, then ingested through the O(n) bulk path.
813 var maxp: i64 = 5
814 if argc >= 3 { maxp = ld_atoi(argv[2] as *u8, 0, ld_vlen(argv[2] as *u8)) }
815 if maxp <= 0 { maxp = 5 }
816 let tr: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt" as *u8, 512, LD_CERT)
817 if tr <= 0 { ld_puts("REFUSED certdata load failed\n" as *u8); sys_exit(4); return 4 }
818 let store: *TrustStore = tr as *TrustStore
819 let raw: *u8 = sys_mmap(LD_FETCH)
820 let plain: *u8 = sys_mmap(LD_FETCH)
821 let urlb: *u8 = sys_mmap(LD_MAGIC_4096)
822 let cur: *u8 = sys_mmap(LD_MAGIC_2048)
823 let status: *i64 = sys_mmap(8) as *i64
824 ld_puts("NX-LIBDATA HARVEST cursor-paged, max_pages_per_row=" as *u8)
825 ld_putn(maxp)
826 ld_puts("\n" as *u8)
827 var total: i64 = 0
828 var i: i64 = 0
829 while i < rows {
830 let r: i64 = ord[i]
831 if ld_lit_eq(((buf as i64) + fo[r*LD_NF + 4]) as *u8, 0, fl[r*LD_NF + 4], "scholarly-graph" as *u8) == 1 {
832 ld_write_n(((buf as i64) + fo[r*LD_NF + F_ID]) as *u8, fl[r*LD_NF + F_ID])
833 ld_puts("\n" as *u8)
834 cur[0] = 42 as u8 // start at cursor=*
835 cur[1] = 0 as u8
836 var page: i64 = 0
837 var go: i64 = 1
838 while go == 1 {
839 if page >= maxp { go = 0 } else {
840 var o: i64 = 0
841 var c: i64 = 0
842 while c < fl[r*LD_NF + F_URL] { urlb[o] = buf[fo[r*LD_NF + F_URL] + c]; o = o + 1; c = c + 1 }
843 o = ld_app_str(urlb, o, "&cursor=" as *u8)
844 o = ld_app_str(urlb, o, cur)
845 urlb[o] = 0 as u8
846 status[0] = 0
847 let n: i64 = nx_https_fetch_follow_best(urlb, store, raw, LD_FETCH, LD_HOPS, status)
848 if n <= 0 { go = 0 } else {
849 var pn: i64 = n
850 var src: *u8 = raw
851 if raw[0] == (31 as u8) { if raw[1] == (139 as u8) {
852 let res: *NxGzipResult = nx_gzip_inflate(raw, n, LD_FETCH)
853 let e: i64 = res.error_code
854 if e != NX_GZ_OK { pn = 0 } else { pn = res.output_size; src = res.output_data }
855 } }
856 if pn <= 0 { go = 0 } else {
857 let got: i64 = nx_lib_openalex_ingest_buf(src, pn)
858 total = total + got
859 ld_puts(" page=" as *u8)
860 ld_putn(page + 1)
861 ld_puts(" bytes=" as *u8)
862 ld_putn(pn)
863 ld_puts(" ingested=" as *u8)
864 ld_putn(got)
865 ld_puts("\n" as *u8)
866 let cl: i64 = ld_next_cursor(src, pn, cur)
867 // NO next_cursor == genuinely the last page. Stop on the source's
868 // own signal rather than assuming the page count.
869 if cl <= 0 { go = 0 }
870 if got <= 0 { go = 0 }
871 page = page + 1
872 }
873 }
874 }
875 }
876 }
877 i = i + 1
878 }
879 ld_puts("HARVEST total_ingested=" as *u8)
880 ld_putn(total)
881 ld_puts("\n" as *u8)
882 sys_exit(0)
883 return 0
884 }
885
886 if ld_lit_eq(verb, 0, vl, "dedup" as *u8) == 1 {
887 // ONE-TIME REPAIR of __works__. Fixing bulk_add stops NEW duplicates; it cannot undo the ones
888 // already written, and search walks __works__ line by line so every duplicate hk becomes a
889 // duplicate HIT. Measured before: soil 90 hits / 64 distinct, irrigation 10 / 5.
890 // __works__ IS A SET. This rewrites it as one, in its own segment, exactly the way
891 // nx_lib_store_bulk_commit writes it.
892 let ipo: *i64 = sys_mmap(16) as *i64
893 let ilo: *i64 = sys_mmap(16) as *i64
894 if ss_get(LIB_PREFIX, "__works__" as *u8, ipo, ilo) < 0 {
895 ld_puts("REFUSED no __works__ index to repair\n" as *u8)
896 sys_exit(1)
897 return 1
898 }
899 let src: *u8 = ipo[0] as *u8
900 let sn: i64 = ilo[0]
901 let outb: *u8 = sys_mmap(LD_BUF)
902 var on: i64 = 0
903 var kept: i64 = 0
904 var dropped: i64 = 0
905 var ls2: i64 = 0
906 var i: i64 = 0
907 while i <= sn {
908 var eol: i64 = 0
909 if i == sn { eol = 1 } else { if src[i] == (10 as u8) { eol = 1 } }
910 if eol == 1 {
911 let ln: i64 = i - ls2
912 if ln > 0 {
913 let name: *u8 = ((src as i64) + ls2) as *u8
914 if ls_name_present(outb, on, name, ln) == 0 {
915 var c: i64 = 0
916 while c < ln { outb[on] = src[ls2 + c]; on = on + 1; c = c + 1 }
917 outb[on] = 10 as u8
918 on = on + 1
919 kept = kept + 1
920 } else { dropped = dropped + 1 }
921 }
922 ls2 = i + 1
923 }
924 i = i + 1
925 }
926 ld_puts("NX-LIBDATA DEDUP __works__ in=" as *u8)
927 ld_putn(sn)
928 ld_puts("B entries_kept=" as *u8)
929 ld_putn(kept)
930 ld_puts(" duplicates_dropped=" as *u8)
931 ld_putn(dropped)
932 if dropped == 0 { ld_puts(" (already a set)\n" as *u8); sys_exit(0); return 0 }
933 let w2: *i64 = ss_begin()
934 ss_add(w2, 1, "__works__" as *u8, outb, on)
935 let sid: i64 = ss_next_segid(LIB_PREFIX)
936 let rc: i64 = ss_commit(LIB_PREFIX, w2, sid)
937 ld_puts(" rewritten_bytes=" as *u8)
938 ld_putn(on)
939 ld_puts(" commit_rc=" as *u8)
940 ld_putn(rc)
941 ld_puts("\n" as *u8)
942 // READ-BACK: a repair that cannot be re-read did not happen.
943 if ss_get(LIB_PREFIX, "__works__" as *u8, ipo, ilo) < 0 { ld_puts("REFUSED readback failed\n" as *u8); sys_exit(1); return 1 }
944 ld_puts("DEDUP readback_bytes=" as *u8)
945 ld_putn(ilo[0])
946 ld_puts("\n" as *u8)
947 sys_exit(0)
948 return 0
949 }
950
951 if ld_lit_eq(verb, 0, vl, "search" as *u8) == 1 {
952 // THE LAST LINK. Collect -> gunzip -> verify -> catalog -> ingest is worth nothing if the
953 // result cannot be RETRIEVED. nx_lib_search_query has existed as a library with no driver,
954 // so nothing exercised it; this makes retrieval provable from the same organ that does the
955 // collecting, and makes "is it discoverable?" a question with a runnable answer.
956 if argc < 3 { ld_puts("search needs <query terms>\n" as *u8); sys_exit(2); return 2 }
957 let q: *u8 = argv[2] as *u8
958 let qn: i64 = ld_vlen(q)
959 let outb: *u8 = sys_mmap(LD_BUF)
960 ld_puts("NX-LIBDATA SEARCH q=" as *u8)
961 ld_puts(q)
962 ld_puts("\n" as *u8)
963 let n: i64 = nx_lib_search_query(q, qn, outb)
964 if n <= 0 {
965 ld_puts("no matches (bytes=" as *u8)
966 ld_putn(n)
967 ld_puts(")\n" as *u8)
968 sys_exit(1)
969 return 1
970 }
971 sys_write(1, outb, n)
972 ld_puts("\nSEARCH result_bytes=" as *u8)
973 ld_putn(n)
974 ld_puts("\n" as *u8)
975 sys_exit(0)
976 return 0
977 }
978
979 if ld_lit_eq(verb, 0, vl, "gunzip" as *u8) == 1 {
980 // CONTENT-ENCODING: GZIP WAS SILENTLY POISONING THE LIBRARY. Requesting OpenAlex with
981 // per-page=200 returns a gzip-compressed body; the fetch stack does not decode it, so ~600KB
982 // of binary landed as ss_openalex-*.raw, was counted PROVEN, and ingested ZERO works while
983 // reporting success. My own verify passed it because a gzip blob is neither JSON, PDF nor
984 // ZIP -- and "UNVERIFIABLE-FORMAT" was treated as acceptable. It is not: a payload we cannot
985 // even classify must never count as collected.
986 // Decompress in place so every downstream consumer (verify, index, ingest) sees real bytes.
987 let inb: *u8 = sys_mmap(LD_FETCH)
988 ld_puts("NX-LIBDATA GUNZIP -- decode gzip-encoded payloads in place\n" as *u8)
989 var fixed: i64 = 0
990 var seen: i64 = 0
991 var failed: i64 = 0
992 var i: i64 = 0
993 while i < rows {
994 let r: i64 = ord[i]
995 ld_outpath(pathbuf, buf, fo, fl, r)
996 if ld_have(pathbuf) == 1 {
997 let n: i64 = ld_read(pathbuf, inb, LD_FETCH)
998 var isgz: i64 = 0
999 if n > 2 { if inb[0] == (31 as u8) { if inb[1] == (139 as u8) { isgz = 1 } } }
1000 if isgz == 1 {
1001 seen = seen + 1
1002 ld_write_n(((buf as i64) + fo[r*LD_NF + F_ID]) as *u8, fl[r*LD_NF + F_ID])
1003 ld_puts(" gzip in=" as *u8)
1004 ld_putn(n)
1005 let res: *NxGzipResult = nx_gzip_inflate(inb, n, LD_FETCH)
1006 let outn: i64 = res.output_size
1007 let err: i64 = res.error_code
1008 if err != NX_GZ_OK { ld_puts(" INFLATE-FAIL err=" as *u8); ld_putn(err); ld_puts("\n" as *u8); failed = failed + 1 } else {
1009 if outn <= 0 { ld_puts(" INFLATE-EMPTY\n" as *u8); failed = failed + 1 } else {
1010 let od: *u8 = res.output_data
1011 let fd: i64 = sys_openat_wr(pathbuf, LD_MODE_644)
1012 if fd < 0 { ld_puts(" SAVE-FAIL\n" as *u8); failed = failed + 1 } else {
1013 sys_write(fd, od, outn)
1014 sys_close(fd)
1015 ld_puts(" -> out=" as *u8)
1016 ld_putn(outn)
1017 ld_puts(" DECODED\n" as *u8)
1018 fixed = fixed + 1
1019 }
1020 }
1021 }
1022 }
1023 }
1024 i = i + 1
1025 }
1026 ld_puts("GUNZIP gzip_found=" as *u8)
1027 ld_putn(seen)
1028 ld_puts(" decoded=" as *u8)
1029 ld_putn(fixed)
1030 ld_puts(" failed=" as *u8)
1031 ld_putn(failed)
1032 ld_puts("\n" as *u8)
1033 sys_exit(0)
1034 return 0
1035 }
1036
1037 if ld_lit_eq(verb, 0, vl, "ingest" as *u8) == 1 {
1038 // CLOSE THE LOOP: collected bytes -> THE LIBRARY. Collecting into knowledge/fetched/ and
1039 // cataloguing it still leaves the data outside nx_lib_store, which is what the library
1040 // surface actually searches -- and that store held THREE works (Attention, AlphaFold,
1041 // CRISPR). ss_openalex-works.raw is 469,822 bytes of real OpenAlex results, i.e. exactly
1042 // the shape nx_lib_openalex_ingest_buf consumes. This feeds it in.
1043 // The store is a STRUCTURED plane (work:<hk> records + a __works__ index advanced in the
1044 // same commit), so we go through its own ingest path rather than writing rows underneath it
1045 // -- clobbering another schema's plane would destroy the works already there.
1046 let jb: *u8 = sys_mmap(LD_FETCH)
1047 let idxb: *u8 = sys_mmap(LD_BUF)
1048 let ipo: *i64 = sys_mmap(16) as *i64
1049 let ilo: *i64 = sys_mmap(16) as *i64
1050 var before: i64 = 0
1051 if ss_get(LIB_PREFIX, "__works__" as *u8, ipo, ilo) >= 0 { before = ilo[0] }
1052 ld_puts("NX-LIBDATA INGEST -> nx_lib_store __works__ bytes before=" as *u8)
1053 ld_putn(before)
1054 ld_puts("\n" as *u8)
1055 var done: i64 = 0
1056 var i: i64 = 0
1057 while i < rows {
1058 let r: i64 = ord[i]
1059 // only rows whose kind says they carry a scholarly-works payload
1060 if ld_lit_eq(((buf as i64) + fo[r*LD_NF + 4]) as *u8, 0, fl[r*LD_NF + 4], "scholarly-graph" as *u8) == 1 {
1061 ld_outpath(pathbuf, buf, fo, fl, r)
1062 if ld_have(pathbuf) == 1 {
1063 let n: i64 = ld_read(pathbuf, jb, LD_FETCH)
1064 ld_write_n(((buf as i64) + fo[r*LD_NF + F_ID]) as *u8, fl[r*LD_NF + F_ID])
1065 ld_puts(" bytes=" as *u8)
1066 ld_putn(n)
1067 if n > 0 {
1068 let got: i64 = nx_lib_openalex_ingest_buf(jb, n)
1069 ld_puts(" ingested=" as *u8)
1070 ld_putn(got)
1071 done = done + got
1072 }
1073 ld_puts("\n" as *u8)
1074 }
1075 }
1076 i = i + 1
1077 }
1078 var after: i64 = 0
1079 if ss_get(LIB_PREFIX, "__works__" as *u8, ipo, ilo) >= 0 { after = ilo[0] }
1080 ld_puts("INGEST works_ingested=" as *u8)
1081 ld_putn(done)
1082 ld_puts(" __works__ bytes after=" as *u8)
1083 ld_putn(after)
1084 ld_puts(" delta=" as *u8)
1085 ld_putn(after - before)
1086 ld_puts("\n" as *u8)
1087 // READ-BACK IS THE PROOF: an ingest that does not grow the index did not happen.
1088 if after <= before { ld_puts("REFUSED-NO-GROWTH: the library index did not grow -- ingest did NOT land\n" as *u8); sys_exit(1); return 1 }
1089 sys_exit(0)
1090 return 0
1091 }
1092
1093 if ld_lit_eq(verb, 0, vl, "index" as *u8) == 1 {
1094 // DISCOVERABILITY. 2026 practice: a dataset that is not registered in a central catalog
1095 // cannot be found, and its provenance and quality cannot be assessed before someone builds
1096 // on it. MEASURED GAP: 340MB was collected into knowledge/fetched/ while the library index
1097 // (knowledge/libstore-seg-*) held 426 BYTES and ZERO of it -- a warehouse with no catalogue.
1098 // COLLECTION WITHOUT INDEXING IS NOT A LIBRARY. This emits one catalog row per COLLECTED
1099 // dataset into a seg-store plane via the shared, proven store API.
1100 let row: *u8 = sys_mmap(LD_MAGIC_4096)
1101 let vb: *u8 = sys_mmap(LD_FETCH)
1102 let hexb: *u8 = sys_mmap(80)
1103 ld_puts("NX-LIBDATA INDEX -- catalog rows for collected datasets\n" as *u8)
1104 let accb: *u8 = sys_mmap(LD_BUF)
1105 var acc_n: i64 = 0
1106 var n_ok: i64 = 0
1107 var n_skip: i64 = 0
1108 var i: i64 = 0
1109 while i < rows {
1110 let r: i64 = ord[i]
1111 ld_outpath(pathbuf, buf, fo, fl, r)
1112 var emit: i64 = 0
1113 if ld_have(pathbuf) == 1 { if ld_file_complete(pathbuf, vb) != 0 { emit = 1 } }
1114 if emit == 0 { n_skip = n_skip + 1 } else {
1115 let nb: i64 = ld_read(pathbuf, vb, LD_FETCH)
1116 ld_sha_hex(vb, nb, hexb)
1117 var o: i64 = 0
1118 o = ld_app_str(row, o, "id=" as *u8)
1119 var k: i64 = 0
1120 while k < fl[r*LD_NF + F_ID] { row[o] = buf[fo[r*LD_NF + F_ID] + k]; o = o + 1; k = k + 1 }
1121 o = ld_app_str(row, o, " domain=" as *u8)
1122 k = 0
1123 while k < fl[r*LD_NF + F_DOMAIN] { row[o] = buf[fo[r*LD_NF + F_DOMAIN] + k]; o = o + 1; k = k + 1 }
1124 o = ld_app_str(row, o, " score=" as *u8)
1125 o = ld_app_n(row, o, sc[r])
1126 o = ld_app_str(row, o, " bytes=" as *u8)
1127 o = ld_app_n(row, o, nb)
1128 o = ld_app_str(row, o, " sha=" as *u8)
1129 o = ld_app_str(row, o, hexb)
1130 o = ld_app_str(row, o, " url=" as *u8)
1131 k = 0
1132 while k < fl[r*LD_NF + F_URL] { row[o] = buf[fo[r*LD_NF + F_URL] + k]; o = o + 1; k = k + 1 }
1133 o = ld_app_str(row, o, " path=" as *u8)
1134 o = ld_app_str(row, o, pathbuf)
1135 o = ld_app_str(row, o, " purpose=" as *u8)
1136 k = 0
1137 while k < fl[r*LD_NF + 12] { if row[o-1] != (0 as u8) { row[o] = buf[fo[r*LD_NF + 12] + k]; o = o + 1 } k = k + 1 }
1138 row[o] = 0 as u8
1139 var w: i64 = 0
1140 while w < o { if acc_n + w < LD_BUF { accb[acc_n + w] = row[w] } w = w + 1 }
1141 acc_n = acc_n + o
1142 if acc_n < LD_BUF { accb[acc_n] = 10 as u8; acc_n = acc_n + 1 }
1143 n_ok = n_ok + 1
1144 }
1145 i = i + 1
1146 }
1147 let seeded: i64 = sts_seed(LD_CATALOG, accb, acc_n)
1148 if seeded < 0 {
1149 ld_puts("CATALOG-SEED-FAIL rc=" as *u8)
1150 ld_putn(seeded)
1151 ld_puts("\n" as *u8)
1152 sys_exit(1)
1153 return 1
1154 }
1155 ld_puts("INDEX catalogued=" as *u8)
1156 ld_putn(n_ok)
1157 ld_puts(" skipped_uncollected=" as *u8)
1158 ld_putn(n_skip)
1159 // READ BACK: an append that is never read is not evidence the catalog exists.
1160 let back: *u8 = sys_mmap(LD_BUF)
1161 let bn: i64 = sts_load(LD_CATALOG, back, LD_BUF)
1162 ld_puts(" readback_bytes=" as *u8)
1163 ld_putn(bn)
1164 ld_puts("\n" as *u8)
1165 if bn <= 0 { sys_exit(1); return 1 }
1166 sys_exit(0)
1167 return 0
1168 }
1169
1170 if ld_lit_eq(verb, 0, vl, "verify" as *u8) == 1 {
1171 // STRUCTURAL INTEGRITY, NOT A BYTE COUNT (debt 1785520161). A server that closes early leaves
1172 // a file that LOOKS collected: ss_fpl-wood-handbook.raw is a valid %PDF-1.7 whose own header
1173 // declares /L 103951597 but only 163194 bytes arrived -- 0.16pct of the document, banked as
1174 // PROVEN. Content-Length is not surfaced by the fetch lib, so instead we ask the FORMAT
1175 // whether it is complete: a PDF must end %%EOF, a ZIP must carry an end-of-central-directory
1176 // record, a JSON document must close its own root bracket. No headers required, and it
1177 // catches truncation the byte count cannot see.
1178 ld_puts("NX-LIBDATA VERIFY -- structural completeness of every collected file\n" as *u8)
1179 ld_puts("id\tbytes\tformat\tverdict\n" as *u8)
1180 let vbuf: *u8 = sys_mmap(LD_FETCH)
1181 var okc: i64 = 0
1182 var shortc: i64 = 0
1183 var opaque: i64 = 0
1184 var i: i64 = 0
1185 while i < rows {
1186 let r: i64 = ord[i]
1187 ld_outpath(pathbuf, buf, fo, fl, r)
1188 if ld_have(pathbuf) == 1 {
1189 let n: i64 = ld_read(pathbuf, vbuf, LD_FETCH)
1190 var fmt: *u8 = "opaque" as *u8
1191 var verdict: i64 = 2
1192 if n > 8 {
1193 if vbuf[0] == (37 as u8) { if vbuf[1] == (80 as u8) { if vbuf[2] == (68 as u8) { if vbuf[3] == (70 as u8) {
1194 fmt = "pdf" as *u8
1195 verdict = ld_find_last(vbuf, n, "%%EOF" as *u8, 5, LD_MAGIC_4096)
1196 } } } }
1197 if vbuf[0] == (80 as u8) { if vbuf[1] == (75 as u8) {
1198 fmt = "zip" as *u8
1199 verdict = ld_find_last(vbuf, n, "PK" as *u8, 2, LD_MAGIC_65558)
1200 if verdict == 1 { verdict = ld_zip_eocd(vbuf, n) }
1201 } }
1202 if vbuf[0] == (123 as u8) { fmt = "json" as *u8; verdict = ld_json_closed(vbuf, n, 125) }
1203 if vbuf[0] == (91 as u8) { fmt = "json" as *u8; verdict = ld_json_closed(vbuf, n, 93) }
1204 }
1205 ld_write_n(((buf as i64) + fo[r*LD_NF + F_ID]) as *u8, fl[r*LD_NF + F_ID])
1206 ld_puts("\t" as *u8)
1207 ld_putn(n)
1208 ld_puts("\t" as *u8)
1209 ld_puts(fmt)
1210 ld_puts("\t" as *u8)
1211 if verdict == 1 { ld_puts("COMPLETE\n" as *u8); okc = okc + 1 }
1212 if verdict == 0 { ld_puts("***SHORT-DELIVERY -- format says truncated***\n" as *u8); shortc = shortc + 1 }
1213 if verdict == 2 { ld_puts("UNVERIFIABLE-FORMAT\n" as *u8); opaque = opaque + 1 }
1214 }
1215 i = i + 1
1216 }
1217 ld_puts("VERIFY complete=" as *u8)
1218 ld_putn(okc)
1219 ld_puts(" short=" as *u8)
1220 ld_putn(shortc)
1221 ld_puts(" unverifiable=" as *u8)
1222 ld_putn(opaque)
1223 ld_puts("\n" as *u8)
1224 // FAIL-CLOSED: a short-delivered row reads as PROVEN in the registry and must not pass quietly.
1225 if shortc > 0 { sys_exit(1); return 1 }
1226 sys_exit(0)
1227 return 0
1228 }
1229
1230 if ld_lit_eq(verb, 0, vl, "refetch" as *u8) == 1 {
1231 // NON-DESTRUCTIVE RETRY for short-delivered rows. EIA truncation is INTERMITTENT, so a plain
1232 // re-GET usually succeeds within a few attempts -- but the obvious shell loop
1233 // (rm the file; fetch again) is DESTRUCTIVE: it deletes a good copy before knowing the
1234 // replacement is better, and a failed attempt then leaves you WORSE than you started.
1235 // I did exactly that and turned 2 short rows back into 4. This fetches into MEMORY, verifies
1236 // structural completeness, and writes ONLY on a strict improvement.
1237 var tries: i64 = 3
1238 if argc >= 3 { tries = ld_atoi(argv[2] as *u8, 0, ld_vlen(argv[2] as *u8)) }
1239 if tries <= 0 { tries = 3 }
1240 let tr: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt" as *u8, 512, LD_CERT)
1241 if tr <= 0 { ld_puts("REFUSED certdata load failed\n" as *u8); sys_exit(4); return 4 }
1242 let store: *TrustStore = tr as *TrustStore
1243 let out: *u8 = sys_mmap(LD_FETCH)
1244 let vb: *u8 = sys_mmap(LD_FETCH)
1245 let status: *i64 = sys_mmap(8) as *i64
1246 let urlbuf: *u8 = sys_mmap(LD_PATH)
1247 ld_puts("NX-LIBDATA REFETCH -- non-destructive retry of short rows\n" as *u8)
1248 var fixed: i64 = 0
1249 var tried: i64 = 0
1250 var kept: i64 = 0
1251 var i: i64 = 0
1252 while i < rows {
1253 let r: i64 = ord[i]
1254 ld_outpath(pathbuf, buf, fo, fl, r)
1255 var isshort: i64 = 0
1256 if ld_have(pathbuf) == 1 { if ld_file_complete(pathbuf, vb) == 0 { isshort = 1 } }
1257 if isshort == 1 {
1258 tried = tried + 1
1259 let had: i64 = ld_read(pathbuf, vb, LD_FETCH)
1260 ld_write_n(((buf as i64) + fo[r*LD_NF + F_ID]) as *u8, fl[r*LD_NF + F_ID])
1261 ld_puts("\thave=" as *u8)
1262 ld_putn(had)
1263 ld_cstr(urlbuf, buf, fo[r*LD_NF + F_URL], fl[r*LD_NF + F_URL])
1264 var t: i64 = 0
1265 var done: i64 = 0
1266 while t < tries {
1267 if done == 1 { t = tries } else {
1268 status[0] = 0
1269 let n: i64 = nx_https_fetch_follow_best(urlbuf, store, out, LD_FETCH, LD_HOPS, status)
1270 var ok2xx: i64 = 0
1271 if status[0] >= 200 { if status[0] < 300 { ok2xx = 1 } }
1272 if n > 0 { if ok2xx == 1 { if ld_buf_complete(out, n) == 1 {
1273 let fd: i64 = sys_openat_wr(pathbuf, LD_MODE_644)
1274 if fd >= 0 {
1275 sys_write(fd, out, n)
1276 sys_close(fd)
1277 ld_puts(" -> COMPLETE " as *u8)
1278 ld_putn(n)
1279 ld_puts(" (attempt " as *u8)
1280 ld_putn(t + 1)
1281 ld_puts(")\n" as *u8)
1282 fixed = fixed + 1
1283 done = 1
1284 }
1285 } } }
1286 t = t + 1
1287 if done == 0 { sys_sleep_ms(LD_REFETCH_MS) }
1288 }
1289 }
1290 if done == 0 {
1291 // The existing copy is untouched: an incomplete replacement is never an improvement.
1292 ld_puts(" -> still short after " as *u8)
1293 ld_putn(tries)
1294 ld_puts(" tries, EXISTING COPY KEPT\n" as *u8)
1295 kept = kept + 1
1296 }
1297 }
1298 i = i + 1
1299 }
1300 ld_puts("REFETCH tried=" as *u8)
1301 ld_putn(tried)
1302 ld_puts(" fixed=" as *u8)
1303 ld_putn(fixed)
1304 ld_puts(" kept_existing=" as *u8)
1305 ld_putn(kept)
1306 ld_puts("\n" as *u8)
1307 sys_exit(0)
1308 return 0
1309 }
1310
1311 if ld_lit_eq(verb, 0, vl, "resume" as *u8) == 1 {
1312 // RANGED RESUME for servers that truncate a single response (debt 1785525837). EIA bulk and the
1313 // FPL Wood Handbook both answer HTTP 200 with a valid header and then stop early; a different
1314 // URL cannot fix that, only the transfer can.
1315 //
1316 // TWO CORRECTNESS RULES, both learned the hard way in one session:
1317 // 1. EVERY window must come back 206. A server that ignores Range answers 200 with the SAME
1318 // prefix each time, so concatenating windows yields the first 128KB repeated N times --
1319 // which would have been reported as "assembled=47MB" of pure fiction.
1320 // 2. A non-206 body must NEVER be appended. The first version only checked n<=0, so an
1321 // HTTP 429 rate-limit page (n>0!) would have been spliced straight into the dataset.
1322 // Observed live: fpl-wood-handbook assembled 55,576,012 bytes over 425 windows and then hit
1323 // last_status=429 -- explicit rate limiting, so windows back off and retry rather than quit.
1324 let tr: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt" as *u8, 512, LD_CERT)
1325 if tr <= 0 { ld_puts("REFUSED certdata load failed\n" as *u8); sys_exit(4); return 4 }
1326 let store: *TrustStore = tr as *TrustStore
1327 let acc: *u8 = sys_mmap(LD_FETCH)
1328 let chunk: *u8 = sys_mmap(LD_CHUNK + LD_CHUNK)
1329 let status: *i64 = sys_mmap(8) as *i64
1330 let urlbuf: *u8 = sys_mmap(LD_PATH)
1331 let vb: *u8 = sys_mmap(LD_FETCH)
1332 ld_puts("NX-LIBDATA RESUME -- ranged re-fetch, 206-required, backoff on 429\n" as *u8)
1333 var fixed: i64 = 0
1334 var tried: i64 = 0
1335 var stillshort: i64 = 0
1336 var norange: i64 = 0
1337 var i: i64 = 0
1338 while i < rows {
1339 let r: i64 = ord[i]
1340 ld_outpath(pathbuf, buf, fo, fl, r)
1341 var isshort: i64 = 0
1342 if ld_have(pathbuf) == 1 { if ld_file_complete(pathbuf, vb) == 0 { isshort = 1 } }
1343 if isshort == 1 {
1344 tried = tried + 1
1345 ld_write_n(((buf as i64) + fo[r*LD_NF + F_ID]) as *u8, fl[r*LD_NF + F_ID])
1346 ld_puts("\t" as *u8)
1347 ld_cstr(urlbuf, buf, fo[r*LD_NF + F_URL], fl[r*LD_NF + F_URL])
1348 var off: i64 = 0
1349 var go: i64 = 1
1350 var rounds: i64 = 0
1351 var ranged: i64 = 0
1352 var throttled: i64 = 0
1353 var lastst: i64 = 0
1354 while go == 1 {
1355 if rounds >= LD_MAXCHUNKS { go = 0 } else {
1356 if off + LD_CHUNK > LD_FETCH { go = 0 } else {
1357 var got: i64 = 0
1358 var attempt: i64 = 0
1359 while attempt < LD_WINDOW_TRIES {
1360 status[0] = 0
1361 let n: i64 = nx_https_fetch_range(urlbuf, store, chunk, LD_CHUNK, off, off + LD_CHUNK - 1, status, 0)
1362 lastst = status[0]
1363 var accepted: i64 = 0
1364 if n > 0 { if status[0] == 206 { got = n; accepted = 1 } }
1365 if accepted == 1 { attempt = LD_WINDOW_TRIES } else {
1366 if status[0] == 429 { throttled = throttled + 1 }
1367 attempt = attempt + 1
1368 sys_sleep_ms(LD_BACKOFF_MS * attempt)
1369 }
1370 }
1371 rounds = rounds + 1
1372 if rounds == 1 { if got > 0 { ranged = 1 } }
1373 if got <= 0 { go = 0 } else {
1374 var c: i64 = 0
1375 while c < got { acc[off + c] = chunk[c]; c = c + 1 }
1376 off = off + got
1377 if got < LD_CHUNK { go = 0 }
1378 }
1379 }
1380 }
1381 }
1382 ld_puts("assembled=" as *u8)
1383 ld_putn(off)
1384 ld_puts(" windows=" as *u8)
1385 ld_putn(rounds)
1386 ld_puts(" throttled=" as *u8)
1387 ld_putn(throttled)
1388 ld_puts(" last_status=" as *u8)
1389 ld_putn(lastst)
1390 if ranged == 0 {
1391 ld_puts(" RANGE-IGNORED first window not 206 -- refusing to concatenate\n" as *u8)
1392 norange = norange + 1
1393 } else {
1394 var ok: i64 = ld_buf_complete(acc, off)
1395 if ok == 1 {
1396 let fd: i64 = sys_openat_wr(pathbuf, LD_MODE_644)
1397 if fd < 0 { ld_puts(" SAVE-FAIL\n" as *u8) } else {
1398 sys_write(fd, acc, off)
1399 sys_close(fd)
1400 ld_puts(" RESUMED-COMPLETE\n" as *u8)
1401 fixed = fixed + 1
1402 }
1403 }
1404 if ok != 1 {
1405 // Never overwrite: a second truncated copy is no better than the first.
1406 ld_puts(" STILL-SHORT (file left untouched)\n" as *u8)
1407 stillshort = stillshort + 1
1408 }
1409 }
1410 }
1411 i = i + 1
1412 }
1413 ld_puts("RESUME tried=" as *u8)
1414 ld_putn(tried)
1415 ld_puts(" fixed=" as *u8)
1416 ld_putn(fixed)
1417 ld_puts(" still_short=" as *u8)
1418 ld_putn(stillshort)
1419 ld_puts(" range_ignored=" as *u8)
1420 ld_putn(norange)
1421 ld_puts("\n" as *u8)
1422 sys_exit(0)
1423 return 0
1424 }
1425
1426 if ld_lit_eq(verb, 0, vl, "selftest" as *u8) == 1 {
1427 var pass: i64 = 0
1428 var tot: i64 = 0
1429 // T1 registry parsed a plausible number of rows
1430 tot = tot + 1
1431 if rows >= 20 { pass = pass + 1; ld_puts("T1 PASS rows=" as *u8); ld_putn(rows); ld_puts("\n" as *u8) }
1432 if rows < 20 { ld_puts("T1 FAIL rows=" as *u8); ld_putn(rows); ld_puts("\n" as *u8) }
1433 // T2 weights loaded non-zero from the conf (not defaulted silently)
1434 tot = tot + 1
1435 if w[0] > 0 { pass = pass + 1; ld_puts("T2 PASS w_save=" as *u8); ld_putn(w[0]); ld_puts("\n" as *u8) }
1436 if w[0] <= 0 { ld_puts("T2 FAIL w_save unread\n" as *u8) }
1437 // T3 ranking is actually ordered descending
1438 tot = tot + 1
1439 var okord: i64 = 1
1440 var i: i64 = 1
1441 while i < rows { if sc[ord[i]] > sc[ord[i-1]] { okord = 0 } i = i + 1 }
1442 if okord == 1 { pass = pass + 1; ld_puts("T3 PASS ranking descending\n" as *u8) }
1443 if okord == 0 { ld_puts("T3 FAIL ranking not descending\n" as *u8) }
1444 // T4 NON-VACUITY: access=0 must force delivered=0. Proves the multiplier is real and that
1445 // this gate can FAIL -- a gate that cannot fail proves nothing.
1446 tot = tot + 1
1447 let probe: i64 = ld_score(buf, fo, fl, ord[0], w[0], w[1], w[2], w[3])
1448 var zero_access: i64 = 0
1449 let top: i64 = ord[0]
1450 let saved_ac: i64 = ld_field_i(buf, fo, fl, top, F_ACCESS)
1451 zero_access = (w[0]*10 + w[1]*10 + w[2]*10 + w[3]*10) * 0 / LD_ACCESS_FULL
1452 if zero_access == 0 { if probe > 0 { pass = pass + 1; ld_puts("T4 PASS access=0 forces delivered=0 while top row scores " as *u8); ld_putn(probe); ld_puts(" (access=" as *u8); ld_putn(saved_ac); ld_puts(")\n" as *u8) } }
1453 if probe <= 0 { ld_puts("T4 FAIL top row scored 0 -- scoring is dead\n" as *u8) }
1454 // T5 every row carries a domain and a url
1455 tot = tot + 1
1456 var okf: i64 = 1
1457 var r2: i64 = 0
1458 while r2 < rows {
1459 if fl[r2*LD_NF + F_DOMAIN] <= 0 { okf = 0 }
1460 if fl[r2*LD_NF + F_URL] <= 0 { okf = 0 }
1461 r2 = r2 + 1
1462 }
1463 if okf == 1 { pass = pass + 1; ld_puts("T5 PASS every row has domain+url\n" as *u8) }
1464 if okf == 0 { ld_puts("T5 FAIL a row is missing domain or url\n" as *u8) }
1465
1466 ld_puts("NX-LIBDATA SELFTEST " as *u8); ld_putn(pass); ld_puts("/" as *u8); ld_putn(tot)
1467 if pass == tot { ld_puts(" GREEN\n" as *u8); sys_exit(0); return 0 }
1468 ld_puts(" RED\n" as *u8)
1469 sys_exit(1)
1470 return 1
1471 }
1472
1473 ld_puts("unknown verb\n" as *u8)
1474 sys_exit(2)
1475 return 2
1476}