nx_forkfresh_lib.nx
buildroot/runtime/nx_forkfresh_lib.nx
about
nx_forkfresh_lib.nx -- FORK FRESHNESS: is the binary an organ is ABOUT TO FORK the same bytes as the
artifact that was PROMOTED? The decision core, split into a lib so a gate can drive it IN-PROCESS
(nothing can import a main(), and a gate that fork/execs a deployed elf reports NOT-REACHED for every
mutant -- organ_gate.conf records that lesson five times over).
WHY THIS EXISTS, MEASURED 2026-08-31 AND REGENERATED THE SAME DAY.
nx_compare_regen chdirs into buildroot and forks the BARE paths _offc/nx_swcompare_{matrix,sota,hub}.elf,
so the PUBLISHER of every /compare page executes buildroot/_offc/. But /api/promote writes the SERVING
ROOT (and nishihost/_offc); buildroot/_offc updates ONLY via a manual nx_restage. A regen therefore
returned published=201 fails=0 verdict=GREEN and CHANGED NOTHING -- every publish line read prev= EQUAL
to the new byte count -- because all three generators were a generation behind.
FOUR AGENTS EACH VERIFIED THEIR PROMOTE AGAINST THE SERVING ROOT AND/OR nishihost/_offc AND ALL FOUR
MISSED THE COPY THE PUBLISHER ACTUALLY RUNS. nx_catalog CANNOT see buildroot/_offc, so every row read
BUILT==PROMOTED, with_gaps=0, VERDICT LIVE -- the clean-looking reading that hid it.
(STAR)A CATALOGUE THAT CANNOT SEE THE COPY THAT EXECUTES WILL REPORT A STALE FLEET AS LIVE.
The remedy so far was "remember to nx_restage", which is O(seats) forever. The estate standing law is
that a law which must be RECALLED at the moment of temptation is not a control -- only a mechanism in
the path is, and writing another rule is the weakest available fix. This lib is that mechanism.
WHY THE PROMOTED SERVING-ROOT ARTIFACT IS THE REFERENCE, AND NOT THE OTHER TWO CANDIDATES:
* NOT _build/<t>.sov.elf -- that is a BUILD FOSSIL. It is whatever the last build anybody ran left
behind, it can predate the source, and a REFUSED build DELETES it. A BEHIND row whose reference is
a fossil points at exactly the wrong action, and re-baselining against an absence reports a live
subject as never-built.
* NOT a fresh rebuild from source -- that is what nx_stale_check does, and it answers a DIFFERENT
question (is this behind SOURCE). Three compiles inside the publisher hot path, on a box whose
build admission already refuses under load, would make the publish surface hostage to the compiler.
* THE PROMOTED ARTIFACT IS THE AUTHORITY because /api/promote is what installs it, nx_catalog calls
that path PROMOTED, and -- decisively -- nx_compare_regen ALREADY forks its gapmap generator from
../nx_swcompare_gapmap.elf with the comment "promoted-elf path (nishihost root, CWD is buildroot):
/api/build + /api/promote place it". The convention is the organ own, established, not invented
here. That is also why the gapmap fork needs no check: it already reads the authority directly.
COMPARE BY HASH, NEVER BY SIZE. Measured on the day this shipped: buildroot/_offc/nx_maturity_board.elf
and its promoted twin differ by TWENTY-SIX BYTES with different digests, and the buildroot copy is the
LARGER of the two -- so both a size-equality test and an is-the-fork-smaller heuristic acquit it. The
full-width digest is the only ruler that convicts.
FAIL DIRECTION, ESTABLISHED BEFORE SHIPPING: every unreadable input degrades to a NAMED third state
(FF_UNPROVEN / FF_NOFORK), never to FRESH and never to STALE. An axis that cannot see must abstain, not
dependencies 2 imports · 4 importers
imports: nx_syscalls.nxnx_sha256.nx
imported by: nx_compare_regen.nxnx_compare_regen_scoped.nxnx_compare_regen_t138.nxnx_forkfresh_gate.nx
structs
| none |
consts
| 50 | const FF_FRESH: i64 = 0 // fork target and promoted artifact are byte-identical |
| 51 | const FF_STALE: i64 = 1 // both readable, digests DIFFER -- the publisher would run the wrong code |
| 52 | const FF_UNPROVEN: i64 = 2 // the PROMOTED reference could not be read: could not look, no conclusion |
| 53 | const FF_NOFORK: i64 = 3 // the fork target itself could not be read: the fork will fail anyway |
| 55 | const FF_DIGEST_BYTES: i64 = 32 // SHA-256, FIPS 180-4 -- the whole digest is compared, always |
| 56 | const FF_HEX_BYTES: i64 = 65 // FF_DIGEST_BYTES * 2 plus one for the NUL |
| 57 | const FF_PATH_BYTES: i64 = 512 |
| 58 | const FF_SIZES_SLOTS: i64 = 2 // [0] fork bytes, [1] reference bytes; -1 = not measured |
| 59 | const FF_HEX_DIGIT_0: i64 = 48 // ASCII zero |
| 60 | const FF_HEX_ALPHA_A: i64 = 87 // lowercase a minus 10, so 10..15 render a..f |
| 61 | const FF_NIBBLE: i64 = 16 |
| 62 | const FF_TEN: i64 = 10 |
| 63 | const FF_SLASH: i64 = 47 // ASCII forward slash |
| 64 | const FF_SCRATCH_PTR: i64 = 16 |
| 182 | const FF_DIR_NA: i64 = 0 // not a STALE pair, or a side was never measured: no direction exists |
| 183 | const FF_DIR_BEHIND: i64 = 1 // fork SMALLER than promoted -- restage brings the executing copy up |
| 184 | const FF_DIR_AHEAD: i64 = 2 // fork LARGER than promoted -- restage would DESTROY what it carries |
| 185 | const FF_DIR_UNDECIDED: i64 = 3 // sizes equal, digests differ -- size cannot discriminate; say so |
functions
| 69 | func ff_basename(p: *u8) -> i64 |
| 83 | func ff_promoted_path(forkpath: *u8, out: *u8, prefix: *u8) -> i64 |
| 96 | func ff_hex(dig: *u8, out: *u8, nbytes: i64) -> i64 |
| 121 | func ff_digest_file(path: *u8, dig: *u8, szout: *i64) -> i64 |
| 136 | func ff_classify(forkpath: *u8, refpath: *u8, fdig: *u8, rdig: *u8, sizes: *i64) -> i64 |
| 155 | func ff_state_word(st: i64) -> *u8 |
| 165 | func ff_is_actionable(st: i64) -> i64 called by 1: main |
| 187 | func ff_direction(st: i64, sizes: *i64) -> i64 |
| 200 | func ff_direction_word(d: i64) -> *u8 |
| 209 | func ff_restage_is_safe(d: i64) -> i64 |