nx_research_engine_admission_t68.nx source
↩ module page · 389 lines · 19988 B
1// nx_research_engine.nx -- the SHARED sovereign research fetch->extract->bank ENGINE. Rule-15 DRY: ONE copy of the
2// fetch loop that was copy-pasted into every nx_*_research_fetch organ. Topic organs (nx_arith_research, ...) stay
3// THIN: they COMPOSE this engine and declare their STRUCTURED sources (sections + purpose) -- no copy-pasted loop,
4// no flat TSV. Functionality is a strict SUPERSET of the old fetchers:
5// PRESERVED: idempotent have-skip, sovereign TLS-1.3 fetch, status print, GZIP-guard, raw archive, readable count,
6// descriptive SECTIONS (rf_section).
7// ADDED: HTML -> clean plain text -> knowledge/library/<name>.txt (so nx_library_harvest_v2 banks it).
8// 100% sovereign (own TLS, nx_cc->nxasm, no curl/wget/gcc). license_tier: ORIGINAL
9import "nx_syscalls.nx"
10import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
11import "nx_x509_trust_store.nx"
12import "nx_trust_store_load_from_certdata.nx"
13import "nx_https_fetch_follow.nx"
14import "nx_research_ka.nx"
15import "nx_fetch_any.nx" // EAT-THE-DEBT 2026-07-14: intelligent cascade + classify + always-inform
16import "nx_gzip_wrap.nx" // we advertise gzip, so we must be able to decode it
17const RF_GZ_MAX_OUT: i64 = 16777216 // 16 MiB inflated cap per document
18const RF_MAGIC_2026: i64 = 2026
19const RF_MAGIC_4194304: i64 = 4194304
20const RF_MAGIC_2048: i64 = 2048
21const RF_MAGIC_16384: i64 = 16384
22const RF_MAGIC_16383: i64 = 16383
23const RF_MAGIC_1024: i64 = 1024
24const RF_MAGIC_4096: i64 = 4096
25const RF_MAGIC_8192: i64 = 8192
26
27func rf_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
28// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
29// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
30// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
31// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
32func rf_putn(v: i64) -> i64 { nxi_out(v); return 0 }
33func rf_have(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 }
34func rf_scat(dst: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[o + i] = s[i]; i = i + 1 } return o + i }
35func rf_bpath(dst: *u8, dir: *u8, name: *u8, suf: *u8) -> i64 {
36 var o: i64 = rf_scat(dst, 0, dir); o = rf_scat(dst, o, name); o = rf_scat(dst, o, suf); dst[o] = 0 as u8; return o
37}
38func rf_save(path: *u8, buf: *u8, n: i64) -> i64 {
39 let fd: i64 = sys_openat_wr(path, 0x1a4)
40 if fd < 0 { return 0 }
41 var off: i64 = 0
42 while off < n { let w: i64 = sys_write(fd, ((buf as i64) + off) as *u8, n - off); if w <= 0 { sys_close(fd); return 0 } off = off + w }
43 sys_close(fd); return 1
44}
45
46// case-insensitive compare src[off..off+litlen) == lit (lit lowercase)
47func rf_tag_eq(src: *u8, off: i64, n: i64, lit: *u8, litlen: i64) -> i64 {
48 if off + litlen > n { return 0 }
49 var i: i64 = 0
50 while i < litlen {
51 var c: i64 = src[off + i] as i64
52 if c >= 0x41 { if c <= 0x5a { c = c + 0x20 } }
53 if c != (lit[i] as i64) { return 0 }
54 i = i + 1
55 }
56 return 1
57}
58
59// minimal HTML -> plain text for the corpus: drop <...> tags, suppress <script>/<style> content, collapse ws.
60func rf_strip(src: *u8, n: i64, out: *u8, cap: i64) -> i64 {
61 var op: i64 = 0
62 var i: i64 = 0
63 var last_ws: i64 = 1
64 var suppress: i64 = 0
65 while i < n {
66 let c: i64 = src[i] as i64
67 if c == 0x3c {
68 var nameoff: i64 = i + 1
69 var isclose: i64 = 0
70 if nameoff < n { if (src[nameoff] as i64) == 0x2f { isclose = 1; nameoff = nameoff + 1 } }
71 var iss: i64 = 0
72 if rf_tag_eq(src, nameoff, n, "script" as *u8, 6) == 1 { iss = 1 }
73 if rf_tag_eq(src, nameoff, n, "style" as *u8, 5) == 1 { iss = 1 }
74 if iss == 1 { if isclose == 1 { suppress = 0 } else { suppress = 1 } }
75 i = i + 1
76 var g: i64 = 0
77 while g == 0 { if i >= n { g = 1 } else { if (src[i] as i64) == 0x3e { g = 1 } else { i = i + 1 } } }
78 if i < n { i = i + 1 }
79 if last_ws == 0 { if op < cap { out[op] = 0x20 as u8; op = op + 1; last_ws = 1 } }
80 } else {
81 if suppress == 1 { i = i + 1 }
82 else {
83 var isws: i64 = 0
84 if c == 0x20 { isws = 1 }
85 if c == 0x09 { isws = 1 }
86 if c == 0x0a { isws = 1 }
87 if c == 0x0d { isws = 1 }
88 if isws == 1 {
89 if last_ws == 0 { if op < cap { out[op] = 0x20 as u8; op = op + 1; last_ws = 1 } }
90 } else {
91 if op < cap { out[op] = c as u8; op = op + 1; last_ws = 0 }
92 }
93 i = i + 1
94 }
95 }
96 }
97 return op
98}
99
100// ---- the engine API the thin topic organs compose ----
101
102// load the sovereign trust store + ensure dirs. Returns the store, or 0 on failure.
103func rf_init() -> *TrustStore {
104 let r: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt" as *u8, 512, RF_MAGIC_4194304)
105 if r <= 0 { return 0 as *TrustStore }
106 sys_mkdir("knowledge/fetched" as *u8, 0x1ed)
107 sys_mkdir("knowledge/library" as *u8, 0x1ed)
108 return r as *TrustStore
109}
110
111// print a research SECTION header (the structure/intelligence the old fetchers carried -- preserved).
112func rf_section(s: *u8) -> i64 { rf_puts(" == " as *u8); rf_puts(s); rf_puts(" ==\n" as *u8); return 0 }
113
114// GZIP magic detection (0x1f 0x8b) -- the guard the old fetchers carried; a gzip body must be skipped, never
115// banked as garbage. A tested function (nx_research_engine_gate) rather than an inline check.
116func rf_is_gzip(buf: *u8, n: i64) -> i64 { if n >= 2 { if (buf[0] as i64) == 0x1f { if (buf[1] as i64) == 0x8b { return 1 } } } return 0 }
117
118// ---- R2/R3: POLITE + BOUNDED-PARALLEL fetch coordination (folded into the engine so ALL researchers inherit it).
119// Resource-sized slots use descriptor-owned kernel locks. Close/process exit releases ownership;
120// persistent slot inodes are never age-reaped. Legacy files fail closed for explicit reconciliation.
121const RF_OEXCL: i64 = 193
122const RF_MODE: i64 = 420
123const RF_MAX_SLOTS: i64 = 4
124const RF_PER_FETCH_MB: i64 = 256
125const RF_STALE_SEC: i64 = 30
126const RF_WAIT_MS: i64 = 200
127const RF_WAIT_MAX: i64 = 300
128const RF_HOST_DELAY: i64 = 1 // seconds between fetches to the SAME host (polite per-host crawl-delay) -> svc-config
129func rf_sleep_ms(ms: i64) -> i64 { sys_poll(0 as *u8, 0, ms); return 0 }
130func rf_free_mb() -> i64 {
131 let fd: i64 = sys_openat_rd("/proc/meminfo" as *u8)
132 if fd < 0 { return RF_MAGIC_2048 }
133 let b: *u8 = sys_mmap(RF_MAGIC_16384); let n: i64 = sys_read(fd, b, RF_MAGIC_16383); sys_close(fd)
134 let pat: *u8 = "MemAvailable:" as *u8
135 var i: i64 = 0; var found: i64 = 0 - 1
136 while i < n - 13 {
137 var j: i64 = 0; var m: i64 = 1
138 while j < 13 { if b[i+j] != pat[j] { m = 0; j = 13 } else { j = j + 1 } }
139 if m == 1 { found = i + 13; i = n } else { i = i + 1 }
140 }
141 if found < 0 { return RF_MAGIC_2048 }
142 var kb: i64 = 0; var started: i64 = 0; var done: i64 = 0; var p: i64 = found
143 while done == 0 {
144 if p >= n { done = 1 } else {
145 let c: i64 = b[p] as i64
146 var isdig: i64 = 0
147 if c >= 48 { if c <= 57 { isdig = 1 } }
148 if isdig == 1 { kb = kb * 10 + (c - 48); started = 1; p = p + 1 }
149 else { if started == 1 { done = 1 } else { p = p + 1 } }
150 }
151 }
152 return kb / RF_MAGIC_1024
153}
154func rf_nslots() -> i64 {
155 let mb: i64 = rf_free_mb()
156 var n: i64 = mb / RF_PER_FETCH_MB
157 if n < 1 { n = 1 }
158 if n > RF_MAX_SLOTS { n = RF_MAX_SLOTS }
159 return n
160}
161func rf_slotpath(dir: *u8, idx: i64, out: *u8) -> *u8 {
162 var o: i64 = 0; var i: i64 = 0
163 while dir[i] != (0 as u8) { out[o] = dir[i]; o = o + 1; i = i + 1 }
164 out[o] = 47 as u8; o = o + 1
165 out[o] = 115 as u8; o = o + 1
166 out[o] = (48 + idx) as u8; o = o + 1
167 out[o] = 46 as u8; o = o + 1
168 out[o] = 108 as u8; o = o + 1
169 out[o] = 107 as u8; o = o + 1
170 out[o] = 0 as u8
171 return out
172}
173// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
174// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
175// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
176// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
177func rf_wint(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 }
178func rf_rint(path: *u8) -> i64 { let fd: i64=sys_openat_rd(path); if fd<0{return 0} let b: *u8=sys_mmap(64); let n: i64=sys_read(fd,b,63); sys_close(fd); var v: i64=0; var i: i64=0; while i<n { if b[i]>=(48 as u8){if b[i]<=(57 as u8){v=v*10+((b[i] as i64)-48)}} i=i+1 } return v }
179func rf_unlink(path: *u8) -> i64 { return __syscall(263, AT_FDCWD, path as i64, 0, 0, 0, 0) }
180// Persistent, digit-free marker keeps legacy timestamp readers from age-stealing.
181// Legacy/partial files require explicit owner reconciliation; never delete a live inode.
182const RF_SLOT_MARKER_LEN: i64 = 9
183const RF_SLOT_LEGACY: i64 = 0 - 116
184const RF_SLOT_BUSY: i64 = 0 - 11
185const RF_SLOT_RDWR: i64 = 2
186func rf_slot_lock(path: *u8) -> i64 {
187 var fd: i64 = __syscall(SYS_OPENAT, AT_FDCWD, path as i64, RF_OEXCL | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK, RF_MODE, 0, 0)
188 var created: i64 = 0
189 if fd >= 0 { created = 1 }
190 else {
191 if fd != (0 - 17) { return fd }
192 fd = __syscall(SYS_OPENAT, AT_FDCWD, path as i64, RF_SLOT_RDWR | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK, 0, 0, 0)
193 if fd < 0 { return fd }
194 }
195 let locked: i64 = sys_flock(fd, SYS_LOCK_EX | SYS_LOCK_NB)
196 if locked < 0 { sys_close(fd); return locked }
197 if created == 1 {
198 let wrote: i64 = sys_write(fd, "NXRFLOCK\n" as *u8, RF_SLOT_MARKER_LEN)
199 if wrote != RF_SLOT_MARKER_LEN { sys_close(fd); return RF_SLOT_LEGACY }
200 return fd
201 }
202 let b: *u8 = sys_mmap(16)
203 if (b as i64) < 0 { sys_close(fd); return 0 - 12 }
204 let got: i64 = sys_read(fd, b, RF_SLOT_MARKER_LEN + 1)
205 let marker: *u8 = "NXRFLOCK\n" as *u8
206 var valid: i64 = 1
207 if got != RF_SLOT_MARKER_LEN { valid = 0 }
208 var i: i64 = 0
209 while i < RF_SLOT_MARKER_LEN { if b[i] != marker[i] { valid = 0 } i = i + 1 }
210 sys_munmap(b, 16)
211 if valid == 0 { sys_close(fd); return RF_SLOT_LEGACY }
212 return fd
213}
214func rf_slot_acquire(dir: *u8, n: i64, idx_out: *i64) -> i64 {
215 idx_out[0] = 0 - 1
216 if n < 1 { return 0 - 22 }
217 if n > RF_MAX_SLOTS { return 0 - 22 }
218 let pbuf: *u8 = sys_mmap(512)
219 if (pbuf as i64) < 0 { return 0 - 12 }
220 var wait: i64 = 0
221 while wait < RF_WAIT_MAX {
222 var i: i64 = 0
223 var busy: i64 = 0
224 var problem: i64 = RF_SLOT_LEGACY
225 while i < n {
226 rf_slotpath(dir, i, pbuf)
227 let fd: i64 = rf_slot_lock(pbuf)
228 if fd >= 0 { idx_out[0] = i; sys_munmap(pbuf, 512); return fd }
229 if fd == RF_SLOT_BUSY { busy = 1 } else { problem = fd }
230 i = i + 1
231 }
232 if busy == 0 { sys_munmap(pbuf, 512); return problem }
233 rf_sleep_ms(RF_WAIT_MS); wait = wait + 1
234 }
235 sys_munmap(pbuf, 512)
236 return RF_SLOT_BUSY
237}
238func rf_slot_release(dir: *u8, idx: i64, fd: i64) -> i64 {
239 if fd < 0 { return 0 - 9 }
240 return sys_close(fd)
241}
242// ---- R2b/R6b per-host politeness + resilience: host-keyed state files under research_hosts/<host>.<suf> ----
243const RF_CB_THRESHOLD: i64 = 3 // consecutive fails to TRIP the circuit breaker
244const RF_CB_COOLDOWN: i64 = 60 // seconds a tripped host is fast-failed (don't hammer a down site)
245func rf_wfile(path: *u8, v: i64) -> i64 {
246 let fd: i64 = __syscall(SYS_OPENAT, AT_FDCWD, path as i64, 577, RF_MODE, 0, 0) // O_WRONLY|O_CREAT|O_TRUNC
247 if fd >= 0 { rf_wint(fd, v); sys_close(fd) }
248 return 0
249}
250// build "knowledge/status/research_hosts/<sanitized-host>.<suf>" into out (host parsed after "://", until '/')
251func rf_host_key(url: *u8, suf: *u8, out: *u8) -> i64 {
252 var i: i64 = 0; var schemeend: i64 = 0; var d1: i64 = 0
253 while d1 == 0 {
254 if url[i] == (0 as u8) { d1 = 1 }
255 else { if url[i]==(58 as u8) { if url[i+1]==(47 as u8) { if url[i+2]==(47 as u8) { schemeend = i+3; d1 = 1 } } } if d1==0 { i=i+1 } }
256 }
257 let pre: *u8 = "knowledge/status/research_hosts/" as *u8
258 var o: i64 = 0; var j: i64 = 0
259 while pre[j] != (0 as u8) { out[o]=pre[j]; o=o+1; j=j+1 }
260 var h: i64 = schemeend; var d2: i64 = 0
261 while d2 == 0 {
262 let c: i64 = url[h] as i64
263 if c == 0 { d2 = 1 } else { if c == 47 { d2 = 1 } else {
264 var ok: i64 = 0
265 if c>=48 { if c<=57 { ok=1 } }
266 if c>=97 { if c<=122 { ok=1 } }
267 if c>=65 { if c<=90 { ok=1 } }
268 if ok==1 { out[o]=url[h] } else { out[o]=95 as u8 }
269 o=o+1; h=h+1
270 } }
271 }
272 out[o]=46 as u8; o=o+1
273 var s: i64 = 0
274 while suf[s] != (0 as u8) { out[o]=suf[s]; o=o+1; s=s+1 }
275 out[o]=0 as u8
276 return o
277}
278// R2b PER-HOST CRAWL-DELAY (polite): ensure >= RF_HOST_DELAY sec between fetches to the SAME host (cross-process).
279func rf_host_gate(url: *u8) -> i64 {
280 let fn: *u8 = sys_mmap(512); rf_host_key(url, "t" as *u8, fn)
281 sys_mkdir("knowledge/status/research_hosts" as *u8, 0x1ed)
282 let last: i64 = rf_rint(fn)
283 let now: i64 = sys_now_realtime_sec()
284 if last > 0 { let gap: i64 = now - last; if gap < RF_HOST_DELAY { rf_sleep_ms((RF_HOST_DELAY - gap) * 1000) } }
285 rf_wfile(fn, sys_now_realtime_sec())
286 return 0
287}
288// R6b CIRCUIT BREAKER: is host tripped (fast-fail window active)? <host>.cbt = trip-until epoch (0 = closed).
289func rf_circuit_open(url: *u8) -> i64 {
290 let fn: *u8 = sys_mmap(512); rf_host_key(url, "cbt" as *u8, fn)
291 let trip: i64 = rf_rint(fn)
292 if trip > 0 { if sys_now_realtime_sec() < trip { return 1 } }
293 return 0
294}
295// record the outcome: success -> reset; failure -> count, and TRIP for RF_CB_COOLDOWN after RF_CB_THRESHOLD in a row.
296func rf_circuit_record(url: *u8, ok: i64) -> i64 {
297 let fnf: *u8 = sys_mmap(512); rf_host_key(url, "cbf" as *u8, fnf)
298 let fnt: *u8 = sys_mmap(512); rf_host_key(url, "cbt" as *u8, fnt)
299 if ok == 1 { rf_wfile(fnf, 0); rf_wfile(fnt, 0); return 0 }
300 var f: i64 = rf_rint(fnf); f = f + 1
301 if f >= RF_CB_THRESHOLD { rf_wfile(fnt, sys_now_realtime_sec() + RF_CB_COOLDOWN); rf_wfile(fnf, 0) }
302 else { rf_wfile(fnf, f) }
303 return 0
304}
305
306// fetch ONE source -> raw archive + clean library .txt. idempotent (skip if already banked; reuse raw archive),
307// GZIP-guarded (skip gzip bodies -- PRESERVED from the old fetchers). Returns 1 iff a clean .txt is banked.
308func rf_fetch_bank(url: *u8, name: *u8, store: *TrustStore, out: *u8, cap: i64) -> i64 {
309 let rawpath: *u8 = sys_mmap(RF_MAGIC_4096); rf_bpath(rawpath, "knowledge/fetched/" as *u8, name, ".raw" as *u8)
310 let txtpath: *u8 = sys_mmap(RF_MAGIC_4096); rf_bpath(txtpath, "knowledge/library/" as *u8, name, ".txt" as *u8)
311 let lenbox: *i64 = sys_mmap(16) as *i64
312 if rf_have(txtpath) == 1 { rf_puts(" "); rf_puts(name); rf_puts(" [banked-skip]\n" as *u8); return 1 }
313 var raw: *u8 = 0 as *u8
314 var n: i64 = 0
315 if rf_have(rawpath) == 1 {
316 raw = sys_read_file(rawpath, lenbox); n = lenbox[0]
317 rf_puts(" "); rf_puts(name); rf_puts(" [raw cached]")
318 } else {
319 // R6b CIRCUIT BREAKER: skip a recently-failing host (fast-fail, no slot -- don't hammer a down site).
320 if rf_circuit_open(url) == 1 { rf_puts(" "); rf_puts(name); rf_puts(" [circuit-open skip]\n" as *u8); return 0 }
321 // R2+R3: acquire a resource-sized concurrency SLOT (wait politely if all busy).
322 let sdir: *u8 = "knowledge/status/research_slots" as *u8
323 sys_mkdir(sdir, 0x1ed)
324 rf_host_gate(url) // R2b: polite per-host crawl-delay (no slot held while waiting)
325 let nsl: i64 = rf_nslots()
326 let sidx: *i64 = sys_mmap(16) as *i64
327 let sfd: i64 = rf_slot_acquire(sdir, nsl, sidx)
328 if sfd < 0 {
329 rf_puts(" "); rf_puts(name); rf_puts(" [admission-refused code=" as *u8); rf_putn(sfd)
330 rf_puts("; no fetch; reconcile legacy/invalid slots or retry contention]\n" as *u8)
331 sys_munmap(sidx as *u8, 16)
332 return 0
333 }
334 let status: *i64 = sys_mmap(8) as *i64
335 // EAT-THE-DEBT (operator 2026-07-14): route through nx_fetch_any -- the INTELLIGENT dispatcher that
336 // CASCADES fetchers (sovereign TLS-1.3/1.2 -> browser spoof) and CLASSIFIES the result, so a Cloudflare
337 // challenge or an empty is NEVER banked as if it were real research (the old rf_fetch_ka banked 200-OK
338 // challenge HTML). nx_fetch_any cascades strategies internally; one polite retry on a hard failure.
339 let attbuf: *u8 = sys_mmap(RF_MAGIC_8192)
340 n = nx_fetch_any(url, store, out, cap, 6, status, 0 as *u8, 0, attbuf, RF_MAGIC_8192)
341 if n <= 0 { rf_sleep_ms(500); n = nx_fetch_any(url, store, out, cap, 6, status, 0 as *u8, 0, attbuf, RF_MAGIC_8192) }
342 rf_slot_release(sdir, sidx[0], sfd)
343 sys_munmap(sidx as *u8, 16)
344 var cbok: i64 = 0
345 if n > 0 { cbok = 1 }
346 rf_circuit_record(url, cbok) // R6b: feed the breaker (reset on success, count on fail)
347 rf_sleep_ms(150) // polite inter-fetch delay
348 rf_puts(" "); rf_puts(name); rf_puts(" status="); rf_putn(status[0])
349 if n <= 0 {
350 // ALWAYS-INFORM (operator: "dont return nothing without informing the user"): bank a <name>.fail
351 // sidecar carrying the per-strategy attempts log, so absence becomes DATA the census/adversary/critic
352 // can SEE -- never a silent empty file.
353 let failpath: *u8 = sys_mmap(RF_MAGIC_4096); rf_bpath(failpath, "knowledge/library/" as *u8, name, ".fail" as *u8)
354 var fl: i64 = 0
355 while attbuf[fl] != (0 as u8) { fl = fl + 1 }
356 rf_save(failpath, attbuf, fl)
357 rf_puts(" FETCH-FAILED -> banked " as *u8); rf_puts(name); rf_puts(".fail\n" as *u8)
358 rf_puts(" " as *u8); rf_puts(attbuf)
359 return 0
360 }
361 // INFLATE -- do not discard. nx_codec_caps DERIVES Accept-Encoding from the decoders that exist
362 // and now advertises gzip, so servers legitimately compress. Throwing the body away made the
363 // request a lie in the OTHER direction: we asked for gzip, got 200, and banked ZERO documents.
364 // Measured 2026-08-01: arch 0/14, archive 0/18, adversarial 0/20 -- which is why
365 // knowledge/library did not exist at all and the librarian domain read RED for "no corpus".
366 // The decoder (nx_gzip_wrap) has been in-tree the whole time. THE HEADER MUST EQUAL THE
367 // CAPABILITY, IN BOTH DIRECTIONS.
368 if rf_is_gzip(out, n) == 1 {
369 let gr: *NxGzipResult = nx_gzip_inflate(out, n, RF_GZ_MAX_OUT)
370 let gerr: i64 = gr.error_code
371 if gerr != 0 { rf_puts(" [GZIP-FAIL code=" as *u8); rf_putn(gerr); rf_puts("]\n" as *u8); return 0 }
372 let gsz: i64 = gr.output_size
373 if gsz <= 0 { rf_puts(" [GZIP-EMPTY]\n" as *u8); return 0 }
374 raw = gr.output_data
375 n = gsz
376 rf_save(rawpath, raw, n)
377 rf_puts(" [gunzip]" as *u8)
378 } else {
379 rf_save(rawpath, out, n); raw = out
380 }
381 }
382 let txt: *u8 = sys_mmap(cap)
383 let tn: i64 = rf_strip(raw, n, txt, cap)
384 if rf_save(txtpath, txt, tn) == 0 { rf_puts(" TXT-FAIL\n" as *u8); return 0 }
385 rf_puts(" raw="); rf_putn(n); rf_puts(" -> lib.txt="); rf_putn(tn); rf_puts(" BANKED\n" as *u8)
386 return 1
387}
388
389func main() -> i64 { return 0 }