nx_hashdiverge.nx
buildroot/runtime/nx_hashdiverge.nx
about
nx_hashdiverge.nx -- CONTENT-EXACT CROSS-TREE DIVERGENCE. The comparer half of nx_treehash.
WHY IT EXISTS (measured 2026-08-06, tree-canon-single-writer lane):
nx_treediverge compares nx_treediff manifests, which carry SIZE. Its own usage line says the
verdicts are "(by BYTES, a FLOOR)" and it is right. The hourly treediverge beat therefore
reported a size floor as if it were the fork, for days, and one of the files it could not see
was an ESCAPED nx_gate_bite MUTANT in buildroot: _hdl_build/nx_media_extract.nx held
`if hit != 0` where the SSOT held `if hit == 0` -- one byte, 4389 bytes on BOTH sides, so every
plain-http: URL was silently dropped from media harvest and no size gauge could ever notice.
=> A MUTATION-CLASS DEFECT IS SIZE-PRESERVING BY CONSTRUCTION. A size screen is not merely
approximate against it, it is STRUCTURALLY BLIND to the whole class. Of 18060 files present in
both trees, only 5 differed at equal size -- and 1 of those 5 was the mutant.
TWO IMPROVEMENTS OVER THE ORGAN IT SUCCEEDS, both learned by being bitten in the same session:
1. DETAIL GOES TO A FILE, ENVELOPE GOES TO STDOUT. Running nx_treediverge over these trees
returned 163,936 characters and was cut off at capture_cap mid-row, so the envelope -- the
only line carrying the counts -- was the part that got dropped. A comparer whose SUMMARY is
the first casualty of its own verbosity cannot be wired to a beat. Rows go to [outfile].
2. THE SAME-SIZE CLASS IS COUNTED SEPARATELY. It is the only class a size screen cannot reach,
so it is the number that says whether the cheap gauge upstream is still trustworthy.
CLASSES: IDENT (sha equal) / DIFFSZ (sha differs, size differs -- a size screen sees these) /
SAMESZ (sha differs, size EQUAL -- the blind spot) / A-ONLY / B-ONLY.
An UNREADABLE row from nx_treehash is 64 '-', which is not hex and never equals itself, so an
unreadable file always classifies as divergent rather than silently matching another unreadable.
DIALECT: plain-if, <=6 params, consts above use. Tables are mmap'd through static POINTERS --
a BSS static ARRAY silently crashes the module at startup (banked gotcha).
license_tier: ORIGINAL expect_exit: 0 No hw writes (Rule 26).
dependencies 1 imports · 0 importers
imports: nx_syscalls.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
| 32 | const HD_SLOTS: i64 = 65536 // power of two; ~18k rows = 28% load |
| 33 | const HD_MASK: i64 = 65535 |
| 34 | const HD_SHA_CHARS: i64 = 64 |
| 35 | const HD_OUTBUF: i64 = 8388608 |
| 36 | const HD_NUMBUF: i64 = 64 |
| 37 | const HD_FNV_OFF: i64 = 1469598103934665603 |
| 38 | const HD_FNV_PRIME: i64 = 1099511628211 |
| 39 | const HD_SAMPLE_CAP: i64 = 40 // stdout sample rows; the FULL list always goes to [outfile] |
functions
| 52 | func hd_puts(s: *u8) -> i64 |
| 58 | func hd_putn(v: i64) -> i64 |
| 69 | func hd_slen(s: *u8) -> i64 called by 1: hd_emit |
| 74 | func hd_streq(a: *u8, b: *u8) -> i64 |
| 86 | func hd_hash(s: *u8) -> i64 |
| 98 | func hd_shaeq(a: *u8, b: *u8) -> i64 called by 1: hd_scan |
| 104 | func hd_put(rel: *u8, sha: *u8, sz: *u8) -> i64 |
| 121 | func hd_find(rel: *u8) -> i64 |
| 132 | func hd_emit(cls: *u8, rel: *u8, x: *u8, y: *u8) -> i64 |
| 156 | func hd_sample(cls: *u8, rel: *u8) -> i64 |
| 166 | func hd_scan(buf: *u8, n: i64, side: i64) -> i64 |
| 224 | func main(argc: i64, argv: *i64) -> i64 |