code wiki / _hdl_build / nx_sitededup_gate.nx

nx_sitededup_gate.nx

buildroot/runtime/_hdl_build/nx_sitededup_gate.nx

35857 B544 linesdepth 6pulls 13 transitivereach 0 importersview sourcekind gate/proof
docsdependenciesstructsconstsfunctions

about

nx_sitededup_gate.nx -- proves the near-duplicate collapse decision COLLAPSES WHAT IT SHOULD AND NOTHING ELSE, and that DIGIT NORMALISATION is what makes the first one possible. A dedup pass that collapses everything scores a perfect duplicate-removal rate and destroys the corpus. So the load-bearing tooth here is not "did the duplicate collapse" -- it is the NEG-CONTROL: genuinely different documents that must SURVIVE. Without it this gate would go green on an implementation that suppressed every document but one. And because normalisation can only ever make two texts MORE similar, the neg-control matters MORE after normalisation than before it, not less. ---- WHAT THIS GATE MEASURED THAT CHANGED THE DESIGN ------------------------------------------- The first version of this gate ran its fixtures through the RAW fingerprint and reported dup(A,A2) = 6 against a bar of k = 3 i.e. the collapse pass DID NOT COLLAPSE the exact production duplicate class it was written for. That is why nx_textnorm_lib exists. The teeth below pin BOTH sides of that finding: the raw ruler must MISS the pair (or the normalisation tooth proves nothing) and the normalised ruler must CATCH it. A single tooth asserting only the second would pass just as happily on a ruler that collapses the entire corpus. ---- AND WHAT THE SECOND RUN MEASURED, WHICH CHANGED THE FIXTURES ------------------------------- Two of the first fixtures were VACUOUS and this gate said so rather than being quietly believed: * the capture-header pair was a single string literal with NO NEWLINES, so the header block had no line structure to parse, the strip correctly refused, and the pair measured raw=6 vs normalised=7 -- normalisation made it WORSE. A capture header in the real store has line breaks; a fixture without them tests a document shape that cannot occur. * the digit-only pair was 607 bytes of prose carrying nine numbers, and its RAW distance was already 2 -- INSIDE the k=3 bar. It could never have shown that normalisation was necessary, because the un-normalised ruler already caught it. Both are fixed below by BUILDING the fixtures at runtime, and the prose pair is kept -- with an honest tooth of its own asserting the opposite property (normalisation must not LOSE a duplicate the raw ruler already had). A fixture that cannot fail is not a test; a fixture that fails for a reason other than the one under test is worse, because its red looks like evidence. The fixtures are REAL TEXT run through the REAL hashers and the REAL shared clusterer (nx_sitededup_lib) -- not hand-picked fingerprints. The one place fingerprints ARE constructed by bit-flipping is the CHAIN fixture, where the property under test is about exact distances and must be exercised at exact distances. THE DIGIT FIXTURES ARE VERIFIED MECHANICALLY, NOT ASSERTED IN A COMMENT. sg_differs_only_in_digits walks both texts byte by byte and requires every differing position to be a digit in BOTH and at least one difference to exist. A fixture that merely CLAIMS to differ only in digits, and in fact

dependencies 3 imports · 0 importers

nx_gate_verdict.nx nx_sitededup_lib.nx nx_textnorm_lib.nx nx_sitededup_gate.nx

imports: nx_gate_verdict.nxnx_sitededup_lib.nxnx_textnorm_lib.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main gv_ctr sys_mmap nxa_die sys_write sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ gv_head gv_puts sys_write ↻ sdd_conf_k sdd_conf_int lcf_int_of sys_mmap ↻ sys_read_file sys_openat_rd sys_lseek sys_mmap ↻ sys_read sys_munmap sys_close lcf_int lcf_find sdd_confpath sdd_confpath_up sdd_conf_which lcf_int_of ↻ sdd_confpath ↻ sdd_confpath_up ↻ gv_puts ↻

structs

none

consts

50const SG_N: i64 = 4
51const SG_WORD: i64 = 8
52const SG_CHAIN_N: i64 = 3
54const SG_CHAIN2_N: i64 = 4
55const SG_BOX: i64 = 8
56const SG_NL: i64 = 10
60const SG_HDRCAP: i64 = 512
64const SG_CID_A2: i64 = 9100
65const SG_CID_A: i64 = 4200
66const SG_CID_B: i64 = 7300
67const SG_CID_C: i64 = 5500

functions

69func g_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
72func sg_cat(dst: *u8, o0: i64, s: *u8) -> i64
82func sg_nl(dst: *u8, o: i64) -> i64 { dst[o] = SG_NL as u8; return o + 1 }
87func sg_differs_only_in_digits(a: *u8, b: *u8) -> i64
called by 1: main calls 2: g_slentn_is_digit
106func sg_body() -> *u8
114func sg_build_capture(dst: *u8, hdr: i64, revline: *u8) -> i64
called by 1: main calls 3: sg_catsg_nlsg_body
128func sg_rev_a() -> *u8 { return "Revision 3907 captured 2026 07 14 at 09 12 44." as *u8 }
called by 1: main
129func sg_rev_a2() -> *u8 { return "Revision 4821 captured 2026 08 02 at 17 07 07." as *u8 }
called by 1: main
132func sg_doc_b() -> *u8
called by 1: main
135func sg_doc_c() -> *u8
called by 1: main
145func sg_doc_num1() -> *u8
called by 1: main
148func sg_doc_num2() -> *u8
called by 1: main
158func sg_doc_pro1() -> *u8
called by 1: main
161func sg_doc_pro2() -> *u8
called by 1: main
165func main(argc: i64, argv: *i64) -> i64