code wiki / _hdl_build / nx_pub_gallery_handoff.nx
nx_pub_gallery_handoff.nx source
↩ module page · 57 lines · 4196 B
1// nx_pub_gallery_handoff.nx -- push the gallery search upgrade (the additive /api/suggest autocomplete daemon
2// binary + its vocab artifact) to the Nishi Publisher. Operator law: NO workstream pushes to nishifamily.com /
3// the live gallery directly; the search workstream REQUESTS, the publisher SHIPS (stage -> VERIFY-sha ->
4// ATOMIC-promote -> ledger) to a LOCAL liveroot. The OUTWARD promote to the live gallery (NAS / supervisor) is
5// OPERATOR-GATED + coordinated -- this proves the law-compliant binary deploy pipeline without touching the live
6// high-value daemon (never-brick). Mirrors nx_pub_search_handoff / nx_pub_reader_handoff. license_tier: ORIGINAL
7import "nx_publisher.nx"
8import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
9import "nx_syscalls.nx"
10
11func gh_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != 0 as u8 { n = n + 1 } sys_write(1, s, n); return 0 }
12// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
13// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
14// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
15// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
16func gh_putn(v: i64) -> i64 { nxi_out(v); return 0 }
17func gh_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 }
18
19func main() -> i64 {
20 gh_puts("=== NISHI PUBLISHER <- gallery search upgrade (/api/suggest binary + vocab): REQUEST then SHIP ===\n")
21 let bin: *u8 = "knowledge/staging/bin/nx_gallery_serve.elf\x00" as *u8
22 let vocab: *u8 = "knowledge/index/gallery.vocab\x00" as *u8
23 let q: *u8 = "knowledge/publish/gallery-queue.tsv\x00" as *u8
24 let led: *u8 = "knowledge/publish/gallery-ledger.tsv\x00" as *u8
25 let stageroot: *u8 = "knowledge/publish/gallery-stage\x00" as *u8
26 let liveroot: *u8 = "knowledge/publish/gallery-live\x00" as *u8
27 let live_bin: *u8 = "knowledge/publish/gallery-live/nx_gallery_serve.elf\x00" as *u8
28 let live_vocab: *u8 = "knowledge/publish/gallery-live/gallery.vocab\x00" as *u8
29
30 if gh_exists(bin) == 0 { gh_puts(" FATAL: staged daemon binary missing (build + cp to knowledge/staging/bin/ first)\n"); sys_exit(1); return 1 }
31 if gh_exists(vocab) == 0 { gh_puts(" FATAL: gallery.vocab missing (run nx_vocab_extract on galx_search.tsv first)\n"); sys_exit(1); return 1 }
32 pub_init()
33 sys_mkdir(stageroot, 0x1ed)
34 sys_mkdir(liveroot, 0x1ed)
35
36 // 1. REQUEST -- submit the binary + its vocab (sha256 content-identified), decoupled + durable, isolated queue.
37 let s1: i64 = pub_submit_to(q, bin, "nx_gallery_serve.elf\x00" as *u8, "nishifamily\x00" as *u8, "nishi-search\x00" as *u8, "binary-galx-serve\x00" as *u8)
38 gh_puts(" [search] pub_submit nx_gallery_serve.elf -> "); gh_putn(s1); gh_puts("\n")
39 let s2: i64 = pub_submit_to(q, vocab, "gallery.vocab\x00" as *u8, "nishifamily\x00" as *u8, "nishi-search\x00" as *u8, "data-galx-vocab\x00" as *u8)
40 gh_puts(" [search] pub_submit gallery.vocab -> "); gh_putn(s2); gh_puts("\n")
41
42 // 2. SHIP -- the publisher owns this: serialize -> idempotent -> stage -> VERIFY-sha -> ATOMIC-promote -> ledger.
43 let pubd: i64 = pub_run_full(q, led, stageroot, liveroot, "publish:gallery\x00" as *u8)
44 gh_puts(" [publisher] pub_run_full -> published_this_pass="); gh_putn(pubd); gh_puts("\n")
45
46 var ok: i64 = 0
47 if gh_exists(live_bin) == 1 { ok = ok + 1 }
48 if gh_exists(live_vocab) == 1 { ok = ok + 1 }
49 gh_puts(" landed_in_liveroot="); gh_putn(ok); gh_puts(" / 2 (daemon binary, vocab)\n")
50 if ok == 2 {
51 gh_puts(" SHIPPED by the Nishi Publisher -> knowledge/publish/gallery-live/ (sha-verified, ledgered, isolated gallery queue)\n")
52 gh_puts(" COORDINATED: search REQUESTED, publisher SHIPPED (NO direct push). OUTWARD live-root -> live gallery daemon (NAS/supervisor) = OPERATOR-GATED + post-deploy SMOKE (pub smoke gate) before promote.\n")
53 sys_exit(0); return 0
54 }
55 gh_puts(" publisher did not promote both (idempotent if already live, or a verify hold)\n")
56 sys_exit(1); return 1
57}