code wiki / _hdl_build / nx_pub_reader_handoff.nx

nx_pub_reader_handoff.nx source

↩ module page · 128 lines · 9483 B

1// nx_pub_reader_handoff.nx -- push the ZERO-JS reader + library shelf updates to the Nishi Publisher (operator 2// 2026-06-21: "push the updates to the publisher, don't directly do"). The reader workstream REQUESTS; the 3// publisher SHIPS (no direct push -- the sites.elf-outage law). Mirrors nx_pub_library_handoff exactly: import the 4// real publisher, pub_submit each artifact to an ISOLATED reader queue, then run the publisher's full pipeline 5// (serialize -> idempotent sha-skip -> stage -> VERIFY-sha -> ATOMIC-promote -> ledger) to a LOCAL liveroot. 6// Artifacts = the new sovereign zero-JS surfaces: the library shelf + a representative reader page. 7// The OUTWARD transport liveroot -> nishifamily.com is OPERATOR-GATED (publisher R6 policy=outward + R8 transport) 8// and needs the REAL book content (NAS) -- NOT run in-sandbox. license_tier: ORIGINAL 9import "nx_publisher.nx" 10import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 11import "nx_syscalls.nx" 12const K_MAGIC_1024: i64 = 1024 13const K_MAGIC_65536: i64 = 65536 14 15func rh_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != 0 as u8 { n = n + 1 } sys_write(1, s, n); return 0 } 16// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 17// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 18// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 19// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 20func rh_putn(v: i64) -> i64 { nxi_out(v); return 0 } 21func rh_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 } 22func rh_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){d[o+i]=s[i];i=i+1} return o+i } 23// submit reader/<slug>/cover.<ext> if it exists (dest mirrors the served path). returns 1 if submitted. 24func rh_cover(q: *u8, slug: *u8, ext: *u8) -> i64 { 25 let src: *u8 = sys_mmap(K_MAGIC_1024); var k: i64 = rh_cat(src,0,"knowledge/staging/media/reader/" as *u8); k=rh_cat(src,k,slug); k=rh_cat(src,k,"/cover." as *u8); k=rh_cat(src,k,ext); src[k]=0 as u8 26 if rh_exists(src) == 0 { return 0 } 27 let dst: *u8 = sys_mmap(K_MAGIC_1024); var d: i64 = rh_cat(dst,0,"reader/" as *u8); d=rh_cat(dst,d,slug); d=rh_cat(dst,d,"/cover." as *u8); d=rh_cat(dst,d,ext); dst[d]=0 as u8 28 pub_submit_to(q, src, dst, "nishifamily\x00" as *u8, "nishi-reader\x00" as *u8, "internal\x00" as *u8) 29 return 1 30} 31// publish one rendered book: its reader_static page + whatever cover it carries. returns count submitted. 32func rh_pub_slug(q: *u8, slug: *u8) -> i64 { 33 var n: i64 = 0 34 let rp: *u8 = sys_mmap(K_MAGIC_1024); var k: i64 = rh_cat(rp,0,"knowledge/staging/media/reader_static_" as *u8); k=rh_cat(rp,k,slug); k=rh_cat(rp,k,".html" as *u8); rp[k]=0 as u8 35 if rh_exists(rp) == 1 { 36 let dn: *u8 = sys_mmap(K_MAGIC_1024); var d: i64 = rh_cat(dn,0,"reader_static_" as *u8); d=rh_cat(dn,d,slug); d=rh_cat(dn,d,".html" as *u8); dn[d]=0 as u8 37 pub_submit_to(q, rp, dn, "nishifamily\x00" as *u8, "nishi-reader\x00" as *u8, "internal\x00" as *u8); n = n + 1 38 } 39 n = n + rh_cover(q, slug, "jpg" as *u8) 40 n = n + rh_cover(q, slug, "gif" as *u8) 41 n = n + rh_cover(q, slug, "png" as *u8) 42 return n 43} 44 45func main() -> i64 { 46 rh_puts("=== NISHI PUBLISHER <- reader/shelf handoff: REQUEST (pub_submit) then the publisher SHIPS ===\n") 47 let shelf: *u8 = "knowledge/staging/media/library_shelf.html\x00" as *u8 48 let reader: *u8 = "knowledge/staging/media/reader_static_nishi_fixture.html\x00" as *u8 49 let q: *u8 = "knowledge/publish/reader-queue.tsv\x00" as *u8 50 let led: *u8 = "knowledge/publish/reader-ledger.tsv\x00" as *u8 51 let stageroot: *u8 = "knowledge/publish/reader-stage\x00" as *u8 52 let liveroot: *u8 = "knowledge/publish/reader-live\x00" as *u8 53 let live_shelf: *u8 = "knowledge/publish/reader-live/library_shelf.html\x00" as *u8 54 let live_reader: *u8 = "knowledge/publish/reader-live/reader_static_nishi_fixture.html\x00" as *u8 55 56 if rh_exists(shelf) == 0 { rh_puts(" FATAL: shelf not emitted -- run nx_library_shelf first\n"); sys_exit(1); return 1 } 57 if rh_exists(reader) == 0 { rh_puts(" FATAL: reader not emitted -- run nx_reader_render first\n"); sys_exit(1); return 1 } 58 pub_init() 59 sys_mkdir(stageroot, 0x1ed) 60 sys_mkdir(liveroot, 0x1ed) 61 62 // 1. REQUEST -- the reader workstream submits two publish requests (sha256 of content); decoupled, durable. 63 let s1: i64 = pub_submit_to(q, shelf, "library_shelf.html\x00" as *u8, "nishifamily\x00" as *u8, "nishi-reader\x00" as *u8, "internal\x00" as *u8) 64 rh_puts(" [reader] pub_submit shelf -> "); rh_putn(s1); rh_puts("\n") 65 let s2: i64 = pub_submit_to(q, reader, "reader_static_nishi_fixture.html\x00" as *u8, "nishifamily\x00" as *u8, "nishi-reader\x00" as *u8, "internal\x00" as *u8) 66 rh_puts(" [reader] pub_submit reader -> "); rh_putn(s2); rh_puts("\n") 67 // image assets carry SUBDIR dests (reader/<slug>/<file>) -- a complete reader bundle needs them at the served root. 68 let cover_src: *u8 = "knowledge/staging/media/reader/nishi_fixture/cover.png\x00" as *u8 69 let fig_src: *u8 = "knowledge/staging/media/reader/nishi_fixture/fig1.png\x00" as *u8 70 let s3: i64 = pub_submit_to(q, cover_src, "reader/nishi_fixture/cover.png\x00" as *u8, "nishifamily\x00" as *u8, "nishi-reader\x00" as *u8, "internal\x00" as *u8) 71 rh_puts(" [reader] pub_submit cover -> "); rh_putn(s3); rh_puts("\n") 72 let s4: i64 = pub_submit_to(q, fig_src, "reader/nishi_fixture/fig1.png\x00" as *u8, "nishifamily\x00" as *u8, "nishi-reader\x00" as *u8, "internal\x00" as *u8) 73 rh_puts(" [reader] pub_submit fig -> "); rh_putn(s4); rh_puts("\n") 74 75 // 1b. AUTO-ENUMERATE -- publish EVERY rendered book (reader_static_<slug>.html) + the cover it carries, so each 76 // new capability goes live as it lands (operator: "make sure this stuff is pushed live as we gain capabilities"). 77 // getdents64 over reader/<slug>/ -- the same enumeration the shelf uses; idempotent (sha-skip) so re-runs are free. 78 let rdir: *u8 = "knowledge/staging/media/reader\x00" as *u8 79 let edfd: i64 = __syscall(257, 0-100, rdir, 0x10000, 0, 0, 0) // openat AT_FDCWD O_RDONLY|O_DIRECTORY 80 var auto: i64 = 0 81 if edfd >= 0 { 82 let buf: *u8 = sys_mmap(K_MAGIC_65536); let nm: *u8 = sys_mmap(512) 83 var go: i64 = 1 84 while go == 1 { 85 let nread: i64 = __syscall(217, edfd, buf, K_MAGIC_65536, 0, 0, 0) // getdents64 86 if nread <= 0 { go = 0 } else { 87 var pos: i64 = 0 88 while pos < nread { 89 let reclen: i64 = (buf[pos+16] as i64) | ((buf[pos+17] as i64) << 8) 90 let dtype: i64 = buf[pos+18] as i64 91 var nl: i64 = 0 92 while buf[pos+19+nl] != (0 as u8) { nm[nl]=buf[pos+19+nl]; nl=nl+1 } nm[nl]=0 as u8 93 var skip: i64 = 0 94 if nl==0 { skip=1 } 95 if nl==1 { if nm[0]==(0x2e as u8) { skip=1 } } 96 if nl==2 { if nm[0]==(0x2e as u8) { if nm[1]==(0x2e as u8) { skip=1 } } } 97 if dtype != 4 { skip=1 } // DT_DIR only 98 if skip == 0 { auto = auto + rh_pub_slug(q, nm) } 99 if reclen <= 0 { pos=nread } else { pos=pos+reclen } 100 } 101 } 102 } 103 sys_close(edfd) 104 } 105 rh_puts(" [reader] auto-enumerated (reader pages + covers) submitted = "); rh_putn(auto); rh_puts("\n") 106 107 // 2. SHIP -- the publisher owns this: serialize -> idempotent -> stage -> VERIFY-sha -> ATOMIC-promote -> ledger. 108 let pubd: i64 = pub_run_full(q, led, stageroot, liveroot, "publish:reader\x00" as *u8) 109 rh_puts(" [publisher] pub_run_full -> published_this_pass="); rh_putn(pubd); rh_puts("\n") 110 111 let live_cover: *u8 = "knowledge/publish/reader-live/reader/nishi_fixture/cover.png\x00" as *u8 112 var ok: i64 = 0 113 if rh_exists(live_shelf) == 1 { ok = ok + 1 } 114 if rh_exists(live_reader) == 1 { ok = ok + 1 } 115 if rh_exists(live_cover) == 1 { ok = ok + 1 } 116 rh_puts(" landed_in_liveroot="); rh_putn(ok); rh_puts(" / 3 (shelf, reader, cover-asset)\n") 117 // the real liberated Kindle covers, live (proof the auto-enumeration shipped the new capability) 118 if rh_exists("knowledge/publish/reader-live/reader/real_huffdic/cover.jpg\x00" as *u8) == 1 { rh_puts(" LIVE: reader/real_huffdic/cover.jpg (real MOBI cover, extracted offline)\n") } 119 if rh_exists("knowledge/publish/reader-live/reader/real_kf8/cover.jpg\x00" as *u8) == 1 { rh_puts(" LIVE: reader/real_kf8/cover.jpg (real KF8 cover, extracted offline)\n") } 120 if rh_exists(live_cover) == 0 { rh_puts(" ^ ASSET-IN-SUBDIR did NOT land -- publisher pub_deploy doesn't mkdir dest subdirs (the rung to build)\n") } 121 if ok == 3 { 122 rh_puts(" SHIPPED by the Nishi Publisher -> knowledge/publish/reader-live/ (sha-verified, ledgered, isolated reader queue)\n") 123 rh_puts(" COORDINATED: reader REQUESTED, publisher SHIPPED (NO direct push). OUTWARD live-root -> nishifamily.com = OPERATOR-GATED (R6 policy=outward + R8 transport) + needs real NAS book content.\n") 124 sys_exit(0); return 0 125 } 126 rh_puts(" publisher did not promote both (idempotent if already live, or a verify hold)\n") 127 sys_exit(1); return 1 128}