code wiki / (root) / nx_paper_beat.nx

nx_paper_beat.nx source

↩ module page · 201 lines · 9083 B

1// nx_paper_beat.nx -- THE NATIVE-LIBRARY CONVERSION BEAT (operator 2026-08-13: no third-party 2// formats; papers native to Nishi from the first bit). Walks a fetched CVF listing, and for each 3// paper: fetch its ABSTRACT PAGE over our own TLS (rf_fetch_bank, ~6KB each) -> convert to NXPAP2 4// via the promoted nx_paper_native -> emit its reader view. BOUNDED and RESUMABLE by construction: 5// <limit> papers per run and a cursor file holding the next index, so a run is a paced slice, never 6// a hammer on the host (the resource-excellence law) and never a restart from zero. 7// 8// Composes, never re-implements: the fetch is the researcher's proven lane, the conversion is the 9// promoted organ, this owns only the WALK + the CURSOR. 10// 11// 2026-08-14 -- FILE READS NO LONGER CARRY A CAP. This organ used to read the listing through its 12// own hand-rolled pb_read with a fixed 4 MiB ceiling, which silently short-read any bigger listing: 13// a caller could not tell a 4 MiB page from a 4 MiB-capped 9 MiB page, and CVPR 2026 day 3 came 14// back at EXACTLY 4,194,304 B for that reason. The estate's own sys_read_file has sized its buffer 15// from the file (lseek END) since 2026-07-15; this organ was hand-rolling a capped reader beside it. 16// Worse, the ONE constant was doing DOUBLE DUTY as a file-read ceiling and a network-buffer 17// reserve -- two unrelated quantities that can never be tuned together. File reads now compose 18// sys_read_file and cannot truncate; the only remaining bound is the network reserve below, which 19// is named for exactly what it is. 20// 21// nx_paper_beat <listing.raw> <limit> <cursor-file> [name-prefix] 22// Announces converted/skipped/failed + the new cursor. exit 0 ok | 1 io | 2 usage | 3 refuse. 23// license_tier: ORIGINAL. No hw writes (Rule 26). 24import "nx_syscalls.nx" 25import "nx_research_fetch_ext.nx" 26const PB_MAGIC_1024: i64 = 1024 27 28// The ONLY bound in this organ, and it is a NETWORK bound, not a file bound: an HTTP body's size is 29// not knowable before the fetch, so a buffer must be reserved up front. CVF abstract pages measure 30// ~6 KB; this reserves three orders of magnitude of headroom, and mmap faults pages in on demand, 31// so the reservation costs address space rather than resident memory. 32const PB_FETCH_RESERVE: i64 = 8388608 33const PB_NATIVE: *u8 = "/volume1/homes/elderwesto/nishihost/nx_paper_native.elf" 34 35func pb_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 36func pb_puts(s: *u8) -> i64 { sys_write(1, s, pb_len(s)); return 0 } 37func pb_num(v: i64) -> i64 { 38 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 39 var m: i64 = v 40 let t: *u8 = sys_mmap(32) 41 var k: i64 = 0 42 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 43 let o: *u8 = sys_mmap(32) 44 var i: i64 = 0 45 while i < k { o[i] = t[k - 1 - i]; i = i + 1 } 46 sys_write(1, o, k) 47 return 0 48} 49func pb_app(d: *u8, off: i64, s: *u8) -> i64 { 50 var i: i64 = 0 51 var o: i64 = off 52 while s[i] != (0 as u8) { d[o] = s[i]; o = o + 1; i = i + 1 } 53 return o 54} 55func pb_appn(d: *u8, off: i64, src: *u8, a: i64, b: i64) -> i64 { 56 var o: i64 = off 57 var i: i64 = a 58 while i < b { d[o] = src[i]; o = o + 1; i = i + 1 } 59 return o 60} 61func pb_appnum(d: *u8, off: i64, v: i64) -> i64 { 62 var o: i64 = off 63 if v == 0 { d[o] = 48 as u8; return o + 1 } 64 var m: i64 = v 65 let t: *u8 = sys_mmap(32) 66 var k: i64 = 0 67 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 68 while k > 0 { k = k - 1; d[o] = t[k]; o = o + 1 } 69 return o 70} 71func pb_find(src: *u8, a: i64, b: i64, pat: *u8) -> i64 { 72 let pl: i64 = pb_len(pat) 73 if pl == 0 { return 0 - 1 } 74 var i: i64 = a 75 while i + pl <= b { 76 var j: i64 = 0 77 var hit: i64 = 1 78 while j < pl { if src[i + j] != pat[j] { hit = 0; j = pl } else { j = j + 1 } } 79 if hit == 1 { return i } 80 i = i + 1 81 } 82 return 0 - 1 83} 84func pb_int(s: *u8, n: i64) -> i64 { 85 var v: i64 = 0 86 var i: i64 = 0 87 while i < n { 88 let c: i64 = s[i] as i64 89 if c >= 48 { if c <= 57 { v = v*10 + (c - 48) } } 90 i = i + 1 91 } 92 return v 93} 94func pb_run3(a1: *u8, a2: *u8, a3: *u8) -> i64 { 95 let pid: i64 = sys_fork() 96 if pid == 0 { 97 let av: *i64 = sys_mmap(64) as *i64 98 let p0: *u8 = PB_NATIVE 99 av[0] = p0 as i64 100 av[1] = a1 as i64 101 av[2] = a2 as i64 102 av[3] = a3 as i64 103 av[4] = 0 104 let ep: *i64 = sys_mmap(16) as *i64 105 let e0: *u8 = "PATH=/usr/bin:/bin" as *u8 106 ep[0] = e0 as i64 107 ep[1] = 0 108 sys_execve(PB_NATIVE, av, ep) 109 sys_exit(127) 110 } 111 let st: *i64 = sys_mmap(16) as *i64 112 sys_wait4(pid, st, 0) 113 return wait_exit_code(st[0]) 114} 115 116func main(argc: i64, argv: *i64) -> i64 { 117 if argc < 4 { pb_puts("usage: nx_paper_beat <listing.raw> <limit> <cursor-file> [name-prefix]\n" as *u8); sys_exit(2); return 2 } 118 let ln: *i64 = sys_mmap(16) as *i64 119 let fb: *u8 = sys_read_file(argv[1] as *u8, ln) 120 if (fb as i64) == 0 { pb_puts("PAPER-BEAT REFUSE: cannot read listing\n" as *u8); sys_exit(3); return 3 } 121 let n: i64 = ln[0] 122 if n <= 0 { pb_puts("PAPER-BEAT REFUSE: cannot read listing\n" as *u8); sys_exit(3); return 3 } 123 let al: *i64 = sys_mmap(16) as *i64 124 al[0] = pb_len(argv[2] as *u8) 125 let lim: i64 = pb_int(argv[2] as *u8, al[0]) 126 if lim <= 0 { pb_puts("PAPER-BEAT REFUSE: limit must be positive\n" as *u8); sys_exit(3); return 3 } 127 let cl: *i64 = sys_mmap(16) as *i64 128 let cb: *u8 = sys_read_file(argv[3] as *u8, cl) 129 var cur: i64 = 0 130 if (cb as i64) != 0 { if cl[0] > 0 { cur = pb_int(cb, cl[0]) } } 131 // NAME PREFIX (4th arg, default cvfp): indices are PER-LISTING, so two listings sharing one 132 // prefix overwrite each other's papers at the same index -- measured live, ~120 conversions 133 // lost before this existed. Each listing MUST pass its own prefix. 134 var pfx: *u8 = "cvfp" as *u8 135 if argc > 4 { pfx = argv[4] as *u8 } 136 let store: *TrustStore = rf_init() 137 if (store as i64) == 0 { pb_puts("PAPER-BEAT REFUSE: trust store load failed\n" as *u8); sys_exit(3); return 3 } 138 let bodyb: *u8 = sys_mmap(PB_FETCH_RESERVE) 139 let url: *u8 = sys_mmap(PB_MAGIC_1024) 140 let nm: *u8 = sys_mmap(256) 141 let raw: *u8 = sys_mmap(512) 142 let nxp: *u8 = sys_mmap(512) 143 let vw: *u8 = sys_mmap(512) 144 var idx: i64 = 0 145 var done: i64 = 0 146 var failed: i64 = 0 147 var p: i64 = 0 148 var run: i64 = 1 149 while run == 1 { 150 let h: i64 = pb_find(fb, p, n, "/content/" as *u8) 151 if h < 0 { run = 0 } else { 152 let e: i64 = pb_find(fb, h, n, "\"" as *u8) 153 if e < 0 { run = 0 } else { 154 let isabs: i64 = pb_find(fb, h, e, "/html/" as *u8) 155 if isabs >= 0 { 156 if idx >= cur { 157 if done + failed < lim { 158 var u: i64 = pb_app(url, 0, "https://openaccess.thecvf.com" as *u8) 159 u = pb_appn(url, u, fb, h, e) 160 url[u] = 0 as u8 161 var q: i64 = pb_app(nm, 0, pfx) 162 q = pb_appnum(nm, q, idx) 163 nm[q] = 0 as u8 164 rf_fetch_bank(url, nm, store, bodyb, PB_FETCH_RESERVE) 165 var r2: i64 = pb_app(raw, 0, "knowledge/fetched/" as *u8) 166 r2 = pb_app(raw, r2, nm) 167 r2 = pb_app(raw, r2, ".raw" as *u8) 168 raw[r2] = 0 as u8 169 var x2: i64 = pb_app(nxp, 0, "knowledge/papers/" as *u8) 170 x2 = pb_app(nxp, x2, nm) 171 x2 = pb_app(nxp, x2, ".nxpap" as *u8) 172 nxp[x2] = 0 as u8 173 var v2: i64 = pb_app(vw, 0, "sites/nishifamily/papers/" as *u8) 174 v2 = pb_app(vw, v2, nm) 175 v2 = pb_app(vw, v2, ".html" as *u8) 176 vw[v2] = 0 as u8 177 let c1: i64 = pb_run3("abs" as *u8, raw, nxp) 178 var okp: i64 = 0 179 if c1 == 0 { if pb_run3("view" as *u8, nxp, vw) == 0 { okp = 1 } } 180 if okp == 1 { done = done + 1 } else { failed = failed + 1 } 181 } else { run = 0 } 182 } 183 idx = idx + 1 184 } 185 p = e 186 } 187 } 188 } 189 let newcur: i64 = cur + done + failed 190 let ob: *u8 = sys_mmap(64) 191 let oo: i64 = pb_appnum(ob, 0, newcur) 192 ob[oo] = 10 as u8 193 let cf: i64 = sys_openat_wr(argv[3] as *u8, 0x1a4) 194 if cf >= 0 { sys_write(cf, ob, oo + 1); sys_close(cf) } 195 pb_puts("PAPER-BEAT-OK converted=" as *u8); pb_num(done) 196 pb_puts(" failed=" as *u8); pb_num(failed) 197 pb_puts(" cursor=" as *u8); pb_num(cur) 198 pb_puts("->" as *u8); pb_num(newcur) 199 pb_puts(" seen=" as *u8); pb_num(idx); pb_puts("\n" as *u8) 200 return 0 201}