code wiki / _hdl_build / nx_pub_search_handoff.nx
nx_pub_search_handoff.nx source
↩ module page · 55 lines · 3818 B
1// nx_pub_search_handoff.nx -- push onsite-search front-end surfaces to the Nishi Publisher (operator law: NO
2// workstream pushes to nishifamily.com directly -- the sites.elf-outage law). The SEARCH workstream REQUESTS;
3// the publisher SHIPS. Mirrors nx_pub_reader_handoff / nx_pub_library_handoff exactly: pub_submit each artifact
4// to an ISOLATED search queue, then run the publisher's full pipeline (serialize -> idempotent sha-skip -> stage
5// -> VERIFY-sha -> ATOMIC-promote -> ledger) to a LOCAL liveroot. This establishes the law-compliant publish path
6// the search workstream was missing (reader + library had handoffs; search did not).
7//
8// Artifact = the sovereign ZERO-JS search UI page. The ENGINE improvements (hybrid/stem/fuzzy) ship later as a
9// BINARY deploy of nx_gallery_serve (the live BM25 search at gallery_serve:1040) -- a coordinated change to a
10// gallery-OWNED daemon, submitted the same way (pub_submit dest=.../nx_gallery_serve.elf policy=binary), NOT a
11// direct push. The OUTWARD transport liveroot -> nishifamily.com is OPERATOR-GATED (publisher R6 outward + R8).
12// license_tier: ORIGINAL
13import "nx_publisher.nx"
14import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
15import "nx_syscalls.nx"
16
17func sh_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != 0 as u8 { n = n + 1 } sys_write(1, s, n); return 0 }
18// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
19// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
20// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
21// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
22func sh_putn(v: i64) -> i64 { nxi_out(v); return 0 }
23func sh_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 }
24
25func main() -> i64 {
26 sh_puts("=== NISHI PUBLISHER <- search handoff: REQUEST (pub_submit) then the publisher SHIPS ===\n")
27 let page: *u8 = "knowledge/staging/media/search.html\x00" as *u8
28 let q: *u8 = "knowledge/publish/search-queue.tsv\x00" as *u8
29 let led: *u8 = "knowledge/publish/search-ledger.tsv\x00" as *u8
30 let stageroot: *u8 = "knowledge/publish/search-stage\x00" as *u8
31 let liveroot: *u8 = "knowledge/publish/search-live\x00" as *u8
32 let live_page: *u8 = "knowledge/publish/search-live/search.html\x00" as *u8
33
34 if sh_exists(page) == 0 { sh_puts(" FATAL: search.html not staged\n"); sys_exit(1); return 1 }
35 pub_init()
36 sys_mkdir(stageroot, 0x1ed)
37 sys_mkdir(liveroot, 0x1ed)
38
39 // 1. REQUEST -- the search workstream submits the publish request (sha256 of content); decoupled, durable.
40 let s1: i64 = pub_submit_to(q, page, "search.html\x00" as *u8, "nishifamily\x00" as *u8, "nishi-search\x00" as *u8, "internal\x00" as *u8)
41 sh_puts(" [search] pub_submit search.html -> "); sh_putn(s1); sh_puts("\n")
42
43 // 2. SHIP -- the publisher owns this: serialize -> idempotent -> stage -> VERIFY-sha -> ATOMIC-promote -> ledger.
44 let pubd: i64 = pub_run_full(q, led, stageroot, liveroot, "publish:search\x00" as *u8)
45 sh_puts(" [publisher] pub_run_full -> published_this_pass="); sh_putn(pubd); sh_puts("\n")
46
47 if sh_exists(live_page) == 1 {
48 sh_puts(" landed_in_liveroot=1 / 1 (search.html)\n")
49 sh_puts(" SHIPPED by the Nishi Publisher -> knowledge/publish/search-live/ (sha-verified, ledgered, isolated search queue)\n")
50 sh_puts(" COORDINATED: search REQUESTED, publisher SHIPPED (NO direct push). OUTWARD live-root -> nishifamily.com = OPERATOR-GATED (R6 outward + R8 transport).\n")
51 sys_exit(0); return 0
52 }
53 sh_puts(" publisher did not promote (idempotent if already live, or a verify hold)\n")
54 sys_exit(1); return 1
55}