code wiki / _hdl_build / nx_builddeploy_lib_qualify_20260910.nx
nx_builddeploy_lib_qualify_20260910.nx
buildroot/runtime/_hdl_build/nx_builddeploy_lib_qualify_20260910.nx
about
nx_builddeploy_lib.nx -- THE ONE RULER FOR "MAY THIS BUILD WRITE A CONSUMER-VISIBLE BINARY?"
WHY THIS EXISTS. nx_sov_build_run decides, inline and in three scattered places, whether a successful
build ALSO replaces the binary consumers fork. Those guards were written on three different days for
three different incidents -- toolchain (rule 26), the daemon supervisor-respawn class, and now the
queued-build class -- and each only ever covered the case that motivated it. A LAW APPLIED IN ONE VERB
AND NOT ITS SIBLING IS HALF A LAW: the flag literally named --build-only was never part of the decision
at all, so it built AND deployed, and nothing in the estate could test that it did.
MEASURED 2026-08-26 from the queue's OWN artifact (knowledge/store/planrun-build-nx_gate_roster_run-):
[nx_sov_build_run] nx_gate_roster_run: DEPLOYED to serving root (twin refresh, live for the next
fork) -> ../nx_gate_roster_run.elf
That row was seeded by /api/build's own load-refusal path: nx_mgmt_api ma_build_refusal_body forks
nx_job_run nx_buildq add, and nx_buildq seeds the plan step "nx_sov_build_run <target> --build-only".
The refusal receipt tells the caller the result "lands in knowledge/store/planrun-build-<target>-;
promote deliberately afterwards". By the time the caller reads that row the binary is ALREADY LIVE:
no nx_contentdiff, no nx_behaveprobe, no capability-loss check, no .prev bank.
A CALLER TOLD ITS WORK WAS MERELY DEFERRED HAD ITS SERVING BINARY REPLACED, WITH NO SEAT IN THE LOOP.
THE HIDDEN VARIABLE IS THE CALLER'S WORKING DIRECTORY, AND IT IS WHY THIS SURVIVED SO LONG.
The same binary, the same flag and the same target deploy or do not deploy depending only on where the
caller stood. /api/build (nx_hostctl cmd_buildrun) chdir's INTO buildroot before exec, so the builder's
CWD anchor never fires, root_pfx stays empty, the twin probe asks for buildroot/<name>.elf -- which does
not exist -- and nothing is installed, which is why the build/promote split has held there and why
hundreds of BEHIND rows exist on the drift board. The queue's runner starts in the SERVING ROOT, the
anchor fires, root_pfx becomes "../", and the identical command deploys. The "../" in the receipt above
is the PROOF the anchor fired: no other branch can emit that prefix.
A FLAG WHOSE MEANING DEPENDS ON THE CALLER'S CWD CANNOT BE REASONED ABOUT FROM ITS NAME.
WHAT THIS LIB IS. A pure integer decision -- no I/O, no paths, no forks -- so a gate holds every
combination of its inputs with a fixture instead of reproducing a host state. The CALLER keeps its
probes (does a twin exist, is this a toolchain, is this a declared daemon); this owns the JUDGEMENT.
Because there is only ONE of it, the queued lane and the seat lane cannot disagree.
SCOPE STATED HONESTLY -- WHAT THIS DELIBERATELY DOES NOT CHANGE:
(1) dkind < 0 (organ_kind.conf unreadable, so daemon-ness UNPROVEN) still permits a serving-root
write on the DEFAULT path, exactly as the incumbent does, and the caller still warns. That is an
abstention-that-acquits and it is a real residual, but it is a DIFFERENT lane from this one and
narrowing it would change the default build path for every caller. It is encoded faithfully here
and pinned by its own tooth so the next reader adjudicates it instead of inheriting it silently.
dependencies 0 imports · 2 importers
imports: none
imported by: nx_builddeploy_gate_qualify_20260910.nxnx_sov_build_run_qualify_20260910.nx
structs
| none |
consts
| 46 | const BD_LOC_NONE: i64 = 0 |
| 47 | const BD_LOC_OFFC: i64 = 1 |
| 48 | const BD_LOC_ROOT: i64 = 2 |
| 51 | const BD_WHY_TOOLCHAIN: i64 = 1 // rule 26: only /api/promote_toolchain may move the toolchain |
| 52 | const BD_WHY_BUILD_ONLY: i64 = 2 // the caller said build only, so this build installs nothing |
| 53 | const BD_WHY_FORCE: i64 = 3 // --install: explicit, deliberate intent to make it permanent |
| 54 | const BD_WHY_REFRESH: i64 = 4 // refresh-IF-PRESENT (LM-026): a twin exists and is being kept fresh |
| 55 | const BD_WHY_NO_TWIN: i64 = 5 // nothing consumes this name yet; nothing to refresh |
functions
| 61 | func bd_intent_permits_install(build_only: i64, force_install: i64) -> i64 |
| 68 | func bd_locations(has_offc: i64, has_root: i64, force_install: i64, build_only: i64, toolchain: i64, dkind: i64) -> i64 |
| 86 | func bd_writes_offc(loc: i64) -> i64 { if (loc & BD_LOC_OFFC) != 0 { return 1 } return 0 } |
| 87 | func bd_writes_root(loc: i64) -> i64 { if (loc & BD_LOC_ROOT) != 0 { return 1 } return 0 } |
| 90 | func bd_why(has_offc: i64, has_root: i64, force_install: i64, build_only: i64, toolchain: i64, dkind: i64) -> i64 |
| 102 | func bd_root_held(has_root: i64, force_install: i64, build_only: i64, toolchain: i64, dkind: i64) -> i64 |
| 112 | func bd_qualification_mode(qualify:i64, build_only:i64, force_install:i64)->i64 |
| 118 | func bd_qualification_flag(flag:*u8)->i64 |
| 127 | func bd_lane_flag_known(flag:*u8)->i64 |
| 134 | func bd_run_timeout_flag(flag:*u8)->i64 called by 1: main |
| 141 | func bd_positive_ms(s:*u8)->i64 |