code wiki / _hdl_build / nx_galx_join.nx
nx_galx_join.nx
buildroot/runtime/_hdl_build/nx_galx_join.nx
about
nx_galx_join.nx -- join a gen sidecar into the gallery's READER index, idempotently.
MEASURED DEFECT THIS CLOSES (2026-08-07). The gen pipeline appends every image it produces to
/volume1/ai/gen/cids.tsv. The gallery server resolves /img/<cid> from a DIFFERENT file --
/volume1/ai/galx/knowledge/status/galx_cid_paths.tsv, compiled into a sovereign O(1) idx+blob at
startup. Nothing ever joined the two. Measured:
gen sidecar rows ................ 109
gen blobs present on disk ....... 109 (nothing lost)
gen CIDs in the reader index ..... 0 of 109
So EVERY image the gen pipeline has ever produced 404s in the gallery, and has since at least the
reader TSV's mtime (2026-06-18). The images were fine; the index simply never learned about them.
★★★★★★ TWO INDEXES, ONE WRITTEN AND ONE READ, WITH NOTHING JOINING THEM, IS INDISTINGUISHABLE
FROM AN EMPTY GALLERY -- and BOTH FILES LOOK HEALTHY IN ISOLATION, which is why it survived.
★ THE WRITER'S SUCCESS AND THE READER'S INPUT ARE DIFFERENT CLAIMS; ONLY THE READER'S DECIDES.
Idempotent by construction (rule 10): a CID already in the reader index is never appended again,
so this is safe to run on every gen, on a clock, or twice by accident.
⚠THE APPEND ALONE DOES NOT PUBLISH. The server compiles the TSV into knowledge/index/galx_cid.*
ONCE AT STARTUP, so a joined row is invisible until the gallery restarts. This organ says so
explicitly rather than reporting a success that the reader cannot yet see.
Usage: nx_galx_join <reader_tsv> <sidecar_tsv> [--apply]
Default is a DRY RUN -- it reports what it would join and changes nothing.
license_tier: ORIGINAL
dependencies 3 imports · 0 importers
imports: nx_syscalls.nxnx_strconv.nxnx_galx_cid_index.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 31 | const GJ_BUCKETS: i64 = 1048576 // 2^20 >> 2*235k entries; open addressing wants headroom |
functions
| 33 | func gj_puts(s: *u8) -> i64 |
| 38 | func gj_i(v: i64) -> i64 |
| 42 | func gj_eq(s: *u8) -> i64 |
| 56 | func gj_eol(buf: *u8, n: i64, from: i64) -> i64 called by 1: main |
| 69 | func gj_cidlen(buf: *u8, from: i64, eol: i64) -> i64 called by 1: main |
| 80 | func gj_ins(tab: *i64, h0: i64) -> i64 called by 1: main |
| 92 | func gj_has(tab: *i64, h0: i64) -> i64 called by 1: main |
| 105 | func main(argc: i64, argv: *i64) -> i64 |