code wiki / _hdl_build / nx_search_ship.nx
nx_search_ship.nx
buildroot/runtime/_hdl_build/nx_search_ship.nx
about
nx_search_ship.nx -- THE SEARCH SHIP LOOP AS ONE ORGAN (operator 2026-09-14: "make sure our primitives get
shifted into workflows get shifted to agents so we are 1 2 3 step"). On 2026-09-14 the seat shipped the docportal
search daemon four times and every ship was ten hand-pecked calls: build the daemon, build the judged-set referee,
run the promote ruler, run the promoted AND the staged referee and diff their per-query lines, run the sticky gate,
bank the live binary by hash, deploy through the health-checked /api/deploy with expect_sha256, wait out the
warm-before-listen window, probe cold two-common-term queries through the edge and read phase_us, then journal.
This organ is that loop as ONE call. It refuses at the first RED, and it composes the estate's rulers by FORK
(nx_mgmt_call, nx_contentdiff, nx_qrels_bench, nx_filehash, nx_filecopy, nx_https_get_cli2) -- it re-implements
none of them, so there is still exactly one of each. The pure parsers live in nx_search_ship_lib (gate-driven).
TWO MODES (the Codex method: a worker ends at a PRIVATE CANDIDATE + RECEIPT, only the root adopts):
nx_search_ship dry -- build + ruler + referee A/B + receipt; NOTHING is deployed (the candidate)
nx_search_ship deploy -- the same, then bank + deploy + warm-wait + cold probes + journal (the adoption)
OPTIONS: allow_loss=<n> (named lost runs the ruler may report; each is journalled) | bar=<ms> (cold-probe bar,
default the search-query row of knowledge/uat_journeys.conf, else 3000) | probes=<path> (one query per line,
default knowledge/search_probes.conf, else the journey's own query family photos).
REFEREE RULE: identical per-query lines = GREEN; lines moved with mean ndcg AND mrr not lower = PROCEEDS ANNOUNCED
with the first differing line printed and journalled (a ranking change the caller adjudicates); a lower mean
REFUSES. EXIT: 0 GREEN | 2 usage | 12 build refused | 11 wrong src_path | 31 ruler RED | 41 referee worse |
53 bank failed | 51 deploy did not land | 52 deploy_status not GREEN | 61 daemon never answered | 71 a probe over
the bar. The LAST line is SEARCH-SHIP verdict=... for positional readers.
license_tier: ORIGINAL expect_exit: 0
dependencies 4 imports · 0 importers
imports: nx_syscalls.nxnx_estate_path.nxnx_tool_run.nxnx_search_ship_lib.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
| 27 | const SS_CAP: i64 = 262144 |
| 28 | const SS_SMALL: i64 = 8192 |
| 29 | const SS_TMO_MS: i64 = 900000 |
| 30 | const SS_MGMT: *u8 = "./nx_mgmt_call.elf" as *u8 |
| 31 | const SS_CONTENTDIFF: *u8 = "./nx_contentdiff.elf" as *u8 |
| 32 | const SS_FILEHASH: *u8 = "./nx_filehash.elf" as *u8 |
| 33 | const SS_FILECOPY: *u8 = "./nx_filecopy.elf" as *u8 |
| 34 | const SS_HTTPS: *u8 = "./nx_https_get_cli2.elf" as *u8 |
| 35 | const SS_BENCH_LIVE: *u8 = "./nx_qrels_bench.elf" as *u8 |
| 36 | const SS_BENCH_STAGED: *u8 = "./nx_qrels_bench.sov.elf.new" as *u8 |
| 37 | const SS_DAEMON: *u8 = "nx_docportal_admin_daemon" as *u8 |
| 38 | const SS_DAEMON_ELF: *u8 = "nx_docportal_admin_daemon.elf" as *u8 |
| 39 | const SS_DAEMON_NEW: *u8 = "nx_docportal_admin_daemon.sov.elf.new" as *u8 |
| 40 | const SS_DAEMON_SRC: *u8 = "/nx_docportal_admin_daemon.nx" as *u8 |
| 41 | const SS_BENCH: *u8 = "nx_qrels_bench" as *u8 |
| 42 | const SS_BENCH_SRC: *u8 = "/nx_qrels_bench.nx" as *u8 |
| 43 | const SS_DEPLOY_BODY: *u8 = "target=docportal&confirm=yes&expect_sha256=" as *u8 |
| 44 | const SS_EDGE: *u8 = "127.0.0.1:8443" as *u8 |
| 45 | const SS_URL_HEAD: *u8 = "https://nishifamily.com/api/search?q=" as *u8 |
| 46 | const SS_URL_TAIL: *u8 = "&scope=web" as *u8 |
| 47 | const SS_JOURNEYS: *u8 = "knowledge/uat_journeys.conf" as *u8 |
| 48 | const SS_JOURNEY_ID: *u8 = "search-query" as *u8 |
| 49 | const SS_PROBES: *u8 = "knowledge/search_probes.conf" as *u8 |
| 50 | const SS_PROBE_DEFAULT: *u8 = "family photos" as *u8 |
| 51 | const SS_PLAN: *u8 = "buildroot/knowledge/compare/search.plan" as *u8 |
| 52 | const SS_JRNL: *u8 = "knowledge/status/search_ship.jrnl" as *u8 |
| 53 | const SS_BANK_DIR: *u8 = "knowledge/status/bank/" as *u8 |
| 54 | const SS_DEFAULT_BAR_MS: i64 = 3000 |
| 55 | const SS_WARM_TRIES: i64 = 30 |
| 56 | const SS_WARM_STEP_MS: i64 = 2000 |
| 57 | const SS_SETTLE_MS: i64 = 1500 |
| 58 | const SS_MAX_PROBES: i64 = 16 |
| 59 | const SS_PROBE_W: i64 = 96 |
| 60 | const SS_LINE: i64 = 4096 |
| 61 | const SS_MODE_0644: i64 = 420 |
| 62 | const SS_QPFX: *u8 = " q=" as *u8 |
| 63 | const SS_RUNG_DEFAULT: *u8 = "L3" as *u8 // the rung a ship journals under when the caller names none; rung=<id> overrides it |
| 197 | const SS_PROBE_CONF: *u8 = "deploy_probe.conf" as *u8 |
| 198 | const SS_PROBE_UP_TRIES_DFLT: i64 = 10 |
| 199 | const SS_PROBE_UP_TICK_MS_DFLT: i64 = 3000 |
functions
| 66 | func sx_puts(s: *u8) -> i64 { sys_write(1, s, sx_slen(s)); return 0 } |
| 67 | func sx_pn(v: i64) -> i64 { let b: *u8 = sys_mmap(32); sx_catn(b, 0, v); sx_puts(b); sys_munmap(b, 32); return 0 } |
| 69 | func sx_tail(buf: *u8, n: i64, lines: i64) -> i64 |
| 83 | func sx_fork(path: *u8, a1: *u8, a2: *u8, a3: *u8, out: *u8, cap: i64, olen: *i64) -> i64 |
| 96 | func sx_mgmt(method: *u8, path: *u8, body: *u8, out: *u8, olen: *i64) -> i64 { return sx_fork(SS_MGMT, method, path, body, out, SS_CAP, olen) } |
| 98 | func sx_sha_of(path: *u8, dst: *u8) -> i64 |
| 107 | func sx_append(path: *u8, line: *u8, n: i64) -> i64 |
| 115 | func sx_jrnl(stage: *u8, verdict: *u8, detail: *u8) -> i64 |
| 130 | func sx_plan_log(kind: *u8, text: *u8) -> i64 |
| 148 | func sx_bank(tag: *u8, sha: *u8, pathout: *u8) -> i64 |
| 174 | func sx_build(target: *u8, srcsuffix: *u8, stage: *u8, sha: *u8, out: *u8, olen: *i64) -> i64 |
| 200 | func sx_conf_key_int(buf: *u8, n: i64, key: *u8, dflt: i64) -> i64 |
| 218 | func sx_probe_budget_ms() -> i64 |
| 230 | func main(argc: i64, argv: *i64) -> i64 |