nx_organ_ship_loss_lib_candidate_t370.nx
buildroot/runtime/nx_organ_ship_loss_lib_candidate_t370.nx
about
nx_organ_ship_lib.nx -- WHICH GATE PROVES THIS TARGET? The resolver the ship loop was missing.
WHY (measured 2026-08-20). nx_organ_ship's PROVE stage looked for exactly ONE name, "<target>_gate",
and when that artifact did not exist it announced GATE=NONE and carried on. Shipping
nx_gate_roster_run therefore SKIPPED THE PROOF STAGE ENTIRELY -- its gate is nx_gate_roster_gate --
and the loop reported SHIPPED having proven nothing about the binary it installed.
A SHIP LOOP THAT SILENTLY SKIPS ITS PROOF STAGE WHEN A NAME DOES NOT MATCH IS THE VACUOUS-TEST
DEFECT IN THE ONE ORGAN EVERY OTHER SHIP DEPENDS ON.
THE REMEDY IS NOT A RENAME. Renaming a gate to satisfy a classifier is dodging by luck; the estate
settled that question once already for a sibling classifier (organ_kind.conf: "renaming a third time
would be dodging classifiers by luck"). So: RESOLVE the gate, and PUBLISH THE SEARCH. Every candidate
path probed is appended to `tried` in the order probed, so a miss can NAME what it looked for instead
of being a silent skip, and a hit can NAME the rule that found it.
RESOLUTION ORDER -- declaration first, derivation second (rule 17):
1 explicit the caller passed gate=<name>. A caller ASSERTION: if it is absent the loop REFUSES,
because a declared gate that is not there is a caller error, not a missing gate.
2 conf row knowledge/organ_gate.conf, "<target> TAB <gatename>". The declaration path: a target
whose gate cannot be derived from its name gets a ROW, never a rename.
3 convention <target>_gate -- what the estate mostly does.
4 self the target ITSELF when it ends in _gate. Shipping a gate used to skip PROVE for the
same reason (nx_foo_gate_gate does not exist); a gate proves itself by running.
5 strip1 <target minus its LAST underscore segment>_gate. This is the measured shape:
nx_gate_roster_run -> nx_gate_roster_gate.
EXACTLY ONE segment, deliberately. Each further strip walks toward a DIFFERENT
organ's gate, and A GATE WHOSE SUBJECT IS NOT THE TARGET PROVES NOTHING ABOUT THE
TARGET -- a resolver that reached far enough would manufacture a FALSE proof, which
is strictly worse than the silent skip it replaces.
ROOT ORDER -- WHICH COPY OF THE RESOLVED GATE RUNS (added 2026-08-25). Each candidate is probed at
two roots: the promoted serving root and the build scratch. Promoted-first is right for a gate that
is a DIFFERENT organ from the target, because this invocation did not build it. It is WRONG for the
one candidate that IS the target just built, and for an in-process gate -- whose subject is compiled
INTO the gate -- that means reporting a tooth count from code the loop did not build. `fresh` names
the target so osl_try_fresh can flip the order for that candidate alone; osl_root_of reports which
root any resolved path came from, so the number always travels with its provenance.
WHY A LIB AND NOT A FUNCTION INSIDE THE LOOP: nx_organ_ship's main() BUILDS before it proves, so a
gate that drove main() would fork real compiles. The roots are PARAMETERS here (dir + suffix pairs)
dependencies 3 imports · 2 importers
imports: nx_syscalls.nxnx_tool_run.nxnx_sha256.nx
imported by: nx_organ_ship_loss_candidate_t370.nxnx_organ_ship_loss_gate_t370.nx
structs
| 920 | struct OslLossSet { count:i64,record:NxBufOwned,digest:*u8 } |
consts
| 46 | const OSL_NAMECAP: i64 = 256 |
| 47 | const OSL_PATHCAP: i64 = 512 |
| 48 | const OSL_TAB: i64 = 9 |
| 49 | const OSL_SP: i64 = 32 |
| 50 | const OSL_NL: i64 = 10 |
| 51 | const OSL_CR: i64 = 13 |
| 52 | const OSL_SEMI: i64 = 59 |
| 53 | const OSL_HASH: i64 = 35 |
| 54 | const OSL_US: i64 = 95 |
| 56 | const OSL_WHY_NONE: i64 = 0 |
| 57 | const OSL_WHY_EXPLICIT: i64 = 1 |
| 58 | const OSL_WHY_CONF: i64 = 2 |
| 59 | const OSL_WHY_CONVENTION: i64 = 3 |
| 60 | const OSL_WHY_SELF: i64 = 4 |
| 61 | const OSL_WHY_STRIP1: i64 = 5 |
| 62 | const OSL_GATE_SUFFIX: *u8 = "_gate" |
| 63 | const OSL_CONF_DEFAULT: *u8 = "knowledge/organ_gate.conf" |
| 66 | const OSL_ROOT_NONE: i64 = 0 |
| 67 | const OSL_ROOT_A: i64 = 1 |
| 68 | const OSL_ROOT_B: i64 = 2 |
| 386 | const OSL_SRC_SUF: *u8 = ".nx" |
| 387 | const OSL_LIB_SUFFIX: *u8 = "_lib" |
| 388 | const OSL_KW_IMPORT: *u8 = "import" |
| 389 | const OSL_CMT: *u8 = "//" |
| 390 | const OSL_QUOTE: i64 = 34 |
| 392 | const OSL_SRC_DIR_HDL: *u8 = "./buildroot/runtime/_hdl_build/" |
| 393 | const OSL_SRC_DIR_RT: *u8 = "./buildroot/runtime/" |
| 398 | const OSL_CLO_UNPROVEN: i64 = 0 |
| 399 | const OSL_CLO_INDEPENDENT: i64 = 1 |
| 400 | const OSL_CLO_CONTAINS: i64 = 2 |
| 405 | const OSL_VINT_UNKNOWN: i64 = 0 |
| 406 | const OSL_VINT_STAGE1: i64 = 1 |
| 407 | const OSL_VINT_REBUILT: i64 = 2 |
| 408 | const OSL_VINT_INDEPENDENT: i64 = 3 |
| 409 | const OSL_VINT_STALE_REFUSED: i64 = 4 |
| 410 | const OSL_VINT_STALE_NOARTIFACT: i64 = 5 |
| 411 | const OSL_VINT_UNKNOWN_NOSRC: i64 = 6 |
| 412 | const OSL_VINT_UNKNOWN_NONAME: i64 = 7 |
| 413 | const OSL_VINT_STALE_WRONGSRC: i64 = 8 |
| 459 | const OSL_PROV_UNPROVEN: i64 = 0 |
| 460 | const OSL_PROV_CURRENT: i64 = 1 |
| 461 | const OSL_PROV_DRIFTED: i64 = 2 |
| 466 | const OSL_PC_EXIT_CURRENT: i64 = 0 |
| 467 | const OSL_PC_EXIT_DRIFTED: i64 = 1 |
| 472 | const OSL_VINT_PROV_CURRENT: i64 = 9 |
| 473 | const OSL_VINT_REBUILT_PROV: i64 = 10 |
| 474 | const OSL_VINT_STALE_PROV: i64 = 11 |
| 765 | const OSL_PICK_KEEP: i64 = 0 // run what the resolver picked: root B already, or root A byte-identical to the banked artifact |
| 766 | const OSL_PICK_SWITCH_B: i64 = 1 // root A differs from the banked root B: run root B, and say root A is BEHIND its own source |
| 767 | const OSL_PICK_UNPROVEN: i64 = 2 // the bank cannot be matched to anything executable (root B absent -- a refused build eats the fossil and leaves the sidecar -- or a digest unreadable): UNPROVEN, never CURRENT |
| 804 | const OSL_HM_BUF: i64 = 16384 |
| 805 | const OSL_HM_MODE: i64 = 420 |
| 809 | const OSL_FNV_OFFSET: i64 = 0 - 3750763034362895579 |
| 810 | const OSL_FNV_PRIME: i64 = 1099511628211 |
| 811 | const OSL_HM_HEX: i64 = 16 |
| 812 | const OSL_HM_HEX_A: i64 = 87 |
| 813 | const OSL_HM_ZERO: i64 = 48 |
functions
| 70 | func osl_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 71 | func osl_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var oo: i64 = o; while s[i] != (0 as u8) { d[oo] = s[i]; oo = oo + 1; i = i + 1 } d[oo] = 0 as u8; return oo } |
| 72 | func osl_streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] == b[i] { if a[i] == (0 as u8) { return 1 } i = i + 1 } return 0 } called by 1: osl_try_fresh |
| 76 | func osl_catb(d: *u8, o: i64, cap: i64, s: *u8) -> i64 called by 1: osl_probe1 |
| 85 | func osl_tried_cap() -> i64 { return 10 * (OSL_PATHCAP + 1) } |
| 87 | func osl_starts(s: *u8, p: *u8) -> i64 { var i: i64 = 0; while p[i] != (0 as u8) { if s[i] != p[i] { return 0 } i = i + 1 } return 1 } called by 1: osl_root_of |
| 94 | func osl_root_of(path: *u8, dirA: *u8, dirB: *u8) -> i64 |
| 106 | func osl_root_name(r: i64) -> *u8 |
| 112 | func osl_ends_gate(s: *u8) -> i64 |
| 122 | func osl_strip1(target: *u8, dst: *u8) -> i64 |
| 147 | func osl_conf_scan(conf: *u8, target: *u8, idx: i64, dst: *u8, countp: *i64) -> i64 called by 3: osl_conf_gateosl_conf_gate_nthosl_conf_gate_count calls 4: sys_mmapsys_read_fileosl_slensys_free_file |
| 216 | func osl_conf_gate(conf: *u8, target: *u8, dst: *u8) -> i64 |
| 222 | func osl_conf_gate_nth(conf: *u8, target: *u8, idx: i64, dst: *u8) -> i64 |
| 228 | func osl_conf_gate_count(conf: *u8, target: *u8) -> i64 |
| 239 | func osl_probe1(cand: *u8, dir: *u8, suf: *u8, tried: *u8, tcap: i64, tp: *i64, dst: *u8) -> i64 |
| 252 | func osl_try(cand: *u8, dirA: *u8, sufA: *u8, dirB: *u8, sufB: *u8, tried: *u8, tcap: i64, tp: *i64, dst: *u8) -> i64 |
| 275 | func osl_try_fresh(cand: *u8, fresh: *u8, dirA: *u8, sufA: *u8, dirB: *u8, sufB: *u8, tried: *u8, tcap: i64, tp: *i64, dst: *u8) -> i64 |
| 291 | func osl_gate_resolve_fresh(target: *u8, explicit: *u8, fresh: *u8, conf: *u8, dirA: *u8, sufA: *u8, dirB: *u8, sufB: *u8, tried: *u8, tcap: i64, dst: *u8, why: *i64) -> i64 called by 2: mainosl_gate_resolve calls 6: sys_mmaposl_catosl_try_freshosl_conf_gateosl_ends_gateosl_strip1 |
| 328 | func osl_gate_resolve(target: *u8, explicit: *u8, conf: *u8, dirA: *u8, sufA: *u8, dirB: *u8, sufB: *u8, tried: *u8, tcap: i64, dst: *u8, why: *i64) -> i64 calls 1: osl_gate_resolve_fresh |
| 332 | func osl_why_name(w: i64) -> *u8 called by 1: main |
| 478 | func osl_closure_tried_cap() -> i64 { return 2 * (OSL_PATHCAP + 1) } |
| 485 | func osl_name_of(path: *u8, dirA: *u8, sufA: *u8, dirB: *u8, sufB: *u8, dst: *u8) -> i64 |
| 510 | func osl_eol(buf: *u8, n: i64, from: i64) -> i64 |
| 518 | func osl_qend(buf: *u8, end: i64, from: i64) -> i64 |
| 526 | func osl_skipws(buf: *u8, n: i64, from: i64) -> i64 |
| 542 | func osl_at(buf: *u8, end: i64, at: i64, s: *u8) -> i64 |
| 551 | func osl_line_imports(buf: *u8, ls: i64, le: i64, name: *u8, nl: i64) -> i64 |
| 581 | func osl_imports(buf: *u8, n: i64, name: *u8) -> i64 |
| 596 | func osl_closure_of_buf(buf: *u8, n: i64, target: *u8) -> i64 |
| 611 | func osl_gate_closure(gate: *u8, target: *u8, dirA: *u8, dirB: *u8, suf: *u8, tried: *u8, tcap: i64, srcdst: *u8, seenp: *i64) -> i64 |
| 647 | func osl_should_rebuild(gate: *u8, target: *u8, clo: i64) -> i64 |
| 657 | func osl_vint_current(v: i64) -> i64 |
| 669 | func osl_vint_name(v: i64) -> *u8 |
| 683 | func osl_closure_name(c: i64) -> *u8 |
| 699 | func osl_prov_of_exit(rc: i64) -> i64 |
| 704 | func osl_prov_name(p: i64) -> *u8 |
| 719 | func osl_should_rebuild_prov(gate: *u8, target: *u8, clo: i64, prov: i64) -> i64 |
| 733 | func osl_vint_norebuild(prov: i64, clo: i64) -> i64 |
| 743 | func osl_vint_rebuilt(prov: i64) -> i64 |
| 754 | func osl_vint_max() -> i64 { return OSL_VINT_STALE_PROV } |
| 768 | func osl_pick_banked(resolved_root: i64, sha_a: *u8, sha_b: *u8, b_exists: i64) -> i64 |
| 776 | func osl_pick_name(p: i64) -> *u8 |
| 789 | func osl_should_rebuild_pick(gate: *u8, target: *u8, clo: i64, prov: i64, pick: i64) -> i64 |
| 815 | func osl_fnv64(h0: i64, buf: *u8, n: i64) -> i64 |
| 821 | func osl_fnv64_file(h0: i64, path: *u8) -> i64 |
| 827 | func osl_hm_hex(h: i64, out: *u8) -> i64 |
| 838 | func osl_hm_nl(d: *u8, o0: i64) -> i64 |
| 847 | func osl_hm_row(d: *u8, o0: i64, comp: *u8, path: *u8) -> i64 |
| 863 | func osl_hm_val(d: *u8, o0: i64, comp: *u8, v: i64) -> i64 |
| 887 | func osl_harness_manifest(outpath: *u8, target_src_sha: *u8, gatepath: *u8, timeout_ms: i64, allow_loss: i64, extra: *u8, tok: *u8) -> i64 |
| 921 | func osls_len(s:*u8)->i64{var n:i64=0;while s[n]!=(0 as u8){n=n+1};return n} |
| 922 | func osls_eq(a:*u8,b:*u8,n:i64)->i64{var i:i64=0;while i<n{if a[i]!=b[i]{return 0};i=i+1};return 1} |
| 923 | func osls_prefix(a:*u8,n:i64,s:*u8)->i64{let m:i64=osls_len(s);if n<m{return 0};return osls_eq(a,s,m)} |
| 924 | func osls_hex(s:*u8)->i64{if (s as i64)<=0{return 0};if osls_len(s)!=64{return 0};var i:i64=0;while i<64{let c:i64=s[i] as i64;if c<48{return 0};if c>57{if c<97||c>102{return 0}};i=i+1};return 1} |
| 926 | func osls_uint(s:*u8,n:i64)->i64{if n<=0{return -1};var v:i64=0;var i:i64=0;while i<n{let c:i64=s[i] as i64;if c<48||c>57{return -1};if v>(NX_BO_I64_MAX-(c-48))/10{return -1};v=v*10+c-48;i=i+1};return v} |
| 927 | func osls_find(s:*u8,n:i64,key:*u8)->i64{let m:i64=osls_len(key);var i:i64=0;while i+m<=n{if osls_eq(s+i,key,m)==1{return i};i=i+1};return -1} |
| 928 | func osls_token(s:*u8,n:i64,key:*u8,length:*i64)->i64 |
| 936 | func osls_field(s:*u8,n:i64,key:*u8)->i64 |
| 940 | func osls_report(buf:*u8,n:i64)->i64 |
| 958 | func osls_add(b:*NxBufOwned,s:*u8,n:i64)->i64{return nx_bo_append(b,s,n,0)} |
| 959 | func osls_text(b:*NxBufOwned,s:*u8)->i64{return osls_add(b,s,osls_len(s))} |
| 960 | func osls_build(live:*u8,candidate:*u8,report:*u8,n:i64,set:*OslLossSet)->i64 |
| 974 | func osls_close(set:*OslLossSet)->i64{var rc:i64=nx_bo_release(&set.record);if (set.digest as i64)>0{let r:i64=sys_munmap_direct(set.digest,65);if r<0{rc=r};set.digest=0 as *u8};return rc} |
| 975 | func osls_approve(set:*OslLossSet,approval:*u8,live:*u8,candidate:*u8)->i64 |
| 985 | func osls_sync_existing(fd:i64,set:*OslLossSet)->i64 |
| 996 | func osls_retain(path:*u8,dir:*u8,set:*OslLossSet)->i64 |