code wiki / (root) / nx_libdata.nx

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}