code wiki / (root) / nx_forkfresh_gate.nx

nx_forkfresh_gate.nx source

↩ module page · 222 lines · 13983 B

1// nx_forkfresh_gate.nx -- THE REFEREE FOR FORK FRESHNESS (nx_forkfresh_lib), 2026-08-31. 2// 3// IN-PROCESS over nx_forkfresh_lib.nx, deliberately. Nothing can import a main(), and a gate that 4// fork/execs the deployed nx_compare_regen.elf reports NOT-REACHED for every mutant -- its GREEN would 5// prove nothing about the code under test. organ_gate.conf carries that reasoning five times over. 6// 7// SCOPE, STATED SO IT CANNOT BE OVER-READ: this proves the DECISION CORE -- path derivation, the digest 8// ruler, the four-state classification and the abstention contract. It does NOT prove the nx_compare_regen 9// emit loop, its watchlist pass or its census; those stay unreferee'd and are the next rung, not a claim 10// being made here. 11// 12// FIXTURES LIVE IN /tmp/nx_forkfresh_gate/ AND NEVER IN knowledge/store/: a gate that shares its fixture 13// with a production beat reports on the fixture, not on the code (measured estate-wide, ratcheted). 14// Setup truncate-writes every fixture it needs on every run, and the two ABSENT fixtures are absent BY 15// CONSTRUCTION -- they are paths this gate never creates -- so the run is idempotent without a teardown. 16// A gate that is not idempotent reports on its first run and lies about every run after. 17// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 18import "nx_gate_verdict.nx" 19import "nx_forkfresh_lib.nx" 20 21const FG_DIR: *u8 = "/tmp/nx_forkfresh_gate" 22const FG_MODE_DIR: i64 = 493 // 0755 23const FG_MODE_FILE: i64 = 420 // 0644 24const FG_BODY_BYTES: i64 = 4096 25const FG_SUBJECTS: i64 = 5 // the five fixture pairs this gate classifies 26const FG_ABC_LEN: i64 = 3 27const FG_FILLER: i64 = 65 // ASCII A -- fixture body filler 28const FG_MUTANT: i64 = 66 // ASCII B -- the ONE byte that differs at equal size 29const FG_MUT_AT: i64 = 2048 // mid-body, so neither a header nor a tail special case 30const FG_SETUP_FILES: i64 = 7 31// Two DISTINCT sizes for the direction teeth. Their only property that matters is SMALL < LARGE, so they 32// are named for the role they play rather than left as bare numbers a reader would have to compare. 33const FG_DIR_SMALL: i64 = 1024 34const FG_DIR_LARGE: i64 = 4096 35 36func fg_write(path: *u8, buf: *u8, n: i64) -> i64 { 37 let fd: i64 = sys_openat_wr(path, FG_MODE_FILE) 38 if fd < 0 { return 0 } 39 var w: i64 = 0 40 while w < n { 41 let k: i64 = sys_write(fd, ((buf as i64) + w) as *u8, n - w) 42 if k <= 0 { w = n } else { w = w + k } 43 } 44 sys_close(fd) 45 return 1 46} 47 48func fg_streq(a: *u8, b: *u8) -> i64 { 49 var i: i64 = 0 50 while a[i] != (0 as u8) { 51 if a[i] != b[i] { return 0 } 52 i = i + 1 53 } 54 if b[i] != (0 as u8) { return 0 } 55 return 1 56} 57 58func main(argc: i64, argv: *i64) -> i64 { 59 gv_head("nx_forkfresh_gate -- the fork-freshness decision core, in-process" as *u8) 60 let ctr: *i64 = gv_ctr() 61 gv_subjects("fixture pairs classified" as *u8, FG_SUBJECTS, ctr) 62 63 sys_mkdir(FG_DIR, FG_MODE_DIR) 64 sys_mkdir("/tmp/nx_forkfresh_gate/_offc" as *u8, FG_MODE_DIR) 65 66 let body: *u8 = sys_mmap(FG_BODY_BYTES) 67 var i: i64 = 0 68 while i < FG_BODY_BYTES { body[i] = FG_FILLER as u8; i = i + 1 } 69 let mutant: *u8 = sys_mmap(FG_BODY_BYTES) 70 i = 0 71 while i < FG_BODY_BYTES { mutant[i] = FG_FILLER as u8; i = i + 1 } 72 mutant[FG_MUT_AT] = FG_MUTANT as u8 73 74 let f_same: *u8 = "/tmp/nx_forkfresh_gate/_offc/gen_same.elf" 75 let r_same: *u8 = "/tmp/nx_forkfresh_gate/gen_same.elf" 76 let f_diff: *u8 = "/tmp/nx_forkfresh_gate/_offc/gen_diff.elf" 77 let r_diff: *u8 = "/tmp/nx_forkfresh_gate/gen_diff.elf" 78 let f_noref: *u8 = "/tmp/nx_forkfresh_gate/_offc/gen_noref.elf" 79 let r_noref: *u8 = "/tmp/nx_forkfresh_gate/gen_noref_NEVER_CREATED.elf" 80 let f_gone: *u8 = "/tmp/nx_forkfresh_gate/_offc/gen_NEVER_CREATED.elf" 81 let f_empty: *u8 = "/tmp/nx_forkfresh_gate/_offc/gen_empty.elf" 82 let r_empty: *u8 = "/tmp/nx_forkfresh_gate/gen_empty.elf" 83 84 var wrote: i64 = 0 85 wrote = wrote + fg_write(f_same, body, FG_BODY_BYTES) 86 wrote = wrote + fg_write(r_same, body, FG_BODY_BYTES) 87 wrote = wrote + fg_write(f_diff, mutant, FG_BODY_BYTES) 88 wrote = wrote + fg_write(r_diff, body, FG_BODY_BYTES) 89 wrote = wrote + fg_write(f_noref, body, FG_BODY_BYTES) 90 wrote = wrote + fg_write(f_empty, body, 0) 91 wrote = wrote + fg_write(r_empty, body, 0) 92 93 // ASSERT THE FIXTURE REACHED THE CONDITION BEFORE ASSERTING THE OUTCOME. Every tooth below is a 94 // claim about files this run wrote; if setup silently failed, each one would pass or fail for a 95 // reason that has nothing to do with the code under test. 96 gv_check("fixture-setup-wrote-every-declared-file" as *u8, wrote == FG_SETUP_FILES, ctr) 97 98 let fd0: *u8 = sys_mmap(FF_DIGEST_BYTES) 99 let rd0: *u8 = sys_mmap(FF_DIGEST_BYTES) 100 let sz: *i64 = sys_mmap(FF_SIZES_SLOTS * 8) as *i64 101 var classified: i64 = 0 102 103 let s_same: i64 = ff_classify(f_same, r_same, fd0, rd0, sz) 104 classified = classified + 1 105 gv_check("identical-bytes-read-FORK-FRESH" as *u8, s_same == FF_FRESH, ctr) 106 gv_check("fresh-reports-both-sizes-measured" as *u8, sz[0] == FG_BODY_BYTES, ctr) 107 108 // THE LOAD-BEARING TOOTH: same size, one byte apart -> STALE. 109 // A SIZE COMPARISON CANNOT SEE THIS, AND A SIZE COMPARISON IS WHAT THE ESTATE KEPT REACHING FOR. 110 // The equal-size assertion runs FIRST and on the SAME classification, so this can never pass by 111 // accidentally comparing two differently-sized files. 112 let s_diff: i64 = ff_classify(f_diff, r_diff, fd0, rd0, sz) 113 classified = classified + 1 114 gv_check("fixture-reached-condition-equal-sizes" as *u8, sz[0] == sz[1], ctr) 115 gv_check("fixture-reached-condition-sizes-nonzero" as *u8, sz[0] == FG_BODY_BYTES, ctr) 116 gv_check("same-size-differing-content-reads-FORK-STALE" as *u8, s_diff == FF_STALE, ctr) 117 118 let s_nr: i64 = ff_classify(f_noref, r_noref, fd0, rd0, sz) 119 classified = classified + 1 120 gv_check("absent-reference-reads-FORK-UNPROVEN" as *u8, s_nr == FF_UNPROVEN, ctr) 121 gv_check("neg-control-absent-reference-is-not-STALE" as *u8, s_nr != FF_STALE, ctr) 122 gv_check("neg-control-absent-reference-is-not-FRESH" as *u8, s_nr != FF_FRESH, ctr) 123 // NEVER PRINT A FABRICATED SIZE BESIDE AN ABSTENTION. 124 gv_check("unmeasured-reference-size-stays-minus-one" as *u8, sz[1] == (0 - 1), ctr) 125 126 let s_gone: i64 = ff_classify(f_gone, r_same, fd0, rd0, sz) 127 classified = classified + 1 128 gv_check("absent-fork-target-reads-FORK-ABSENT" as *u8, s_gone == FF_NOFORK, ctr) 129 gv_check("neg-control-two-absences-are-distinguishable" as *u8, s_gone != s_nr, ctr) 130 131 // Two zero-byte files digest IDENTICALLY. A classifier that trusted the digest alone would call a 132 // pair of empty stubs FRESH and clear a build tree that contains nothing at all. 133 let s_empty: i64 = ff_classify(f_empty, r_empty, fd0, rd0, sz) 134 classified = classified + 1 135 gv_check("neg-control-empty-pair-does-not-read-FRESH" as *u8, s_empty != FF_FRESH, ctr) 136 gv_check("empty-pair-reads-FORK-ABSENT" as *u8, s_empty == FF_NOFORK, ctr) 137 138 // BIND THE AGGREGATE TO ITS DENOMINATOR: a tooth that passes because it examined zero subjects is 139 // not a tooth. This asserts the classifier was actually driven FG_SUBJECTS times. 140 gv_check("denominator-every-declared-subject-was-classified" as *u8, classified == FG_SUBJECTS, ctr) 141 142 gv_check("only-STALE-is-actionable" as *u8, ff_is_actionable(FF_STALE) == 1, ctr) 143 gv_check("neg-control-UNPROVEN-is-not-actionable" as *u8, ff_is_actionable(FF_UNPROVEN) == 0, ctr) 144 gv_check("neg-control-ABSENT-is-not-actionable" as *u8, ff_is_actionable(FF_NOFORK) == 0, ctr) 145 gv_check("neg-control-FRESH-is-not-actionable" as *u8, ff_is_actionable(FF_FRESH) == 0, ctr) 146 147 let pbuf: *u8 = sys_mmap(FF_PATH_BYTES) 148 ff_promoted_path("_offc/nx_swcompare_matrix.elf" as *u8, pbuf, "../" as *u8) 149 gv_check("promoted-path-derives-parent-plus-basename" as *u8, fg_streq(pbuf, "../nx_swcompare_matrix.elf" as *u8), ctr) 150 ff_promoted_path("nx_gen.elf" as *u8, pbuf, "../" as *u8) 151 gv_check("promoted-path-handles-a-bare-basename" as *u8, fg_streq(pbuf, "../nx_gen.elf" as *u8), ctr) 152 ff_promoted_path("a/b/c/deep.elf" as *u8, pbuf, "" as *u8) 153 gv_check("promoted-path-flattens-every-segment" as *u8, fg_streq(pbuf, "deep.elf" as *u8), ctr) 154 // neg-control: a derivation that simply echoed its input would pass a laxer test than the ones above. 155 ff_promoted_path("_offc/nx_swcompare_matrix.elf" as *u8, pbuf, "../" as *u8) 156 gv_check("neg-control-derivation-is-not-an-echo" as *u8, fg_streq(pbuf, "_offc/nx_swcompare_matrix.elf" as *u8) == 0, ctr) 157 158 // THE RULER ITSELF, against a PUBLISHED external vector (FIPS 180-4 NIST SHA-256 of abc). 159 // This is the tooth that makes the digest field cross-checkable: the same value nx_filehash prints. 160 let kd: *u8 = sys_mmap(FF_DIGEST_BYTES) 161 let kh: *u8 = sys_mmap(FF_HEX_BYTES) 162 sha256_digest("abc" as *u8, FG_ABC_LEN, kd) 163 ff_hex(kd, kh, FF_DIGEST_BYTES) 164 gv_check("sha256-hex-matches-the-published-NIST-abc-vector" as *u8, fg_streq(kh, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" as *u8), ctr) 165 // neg-control: a renderer that returned a constant would pass the vector tooth above forever. 166 let kd2: *u8 = sys_mmap(FF_DIGEST_BYTES) 167 let kh2: *u8 = sys_mmap(FF_HEX_BYTES) 168 sha256_digest("abd" as *u8, FG_ABC_LEN, kd2) 169 ff_hex(kd2, kh2, FF_DIGEST_BYTES) 170 gv_check("neg-control-hex-of-a-different-input-differs" as *u8, fg_streq(kh, kh2) == 0, ctr) 171 gv_check("hex-renders-full-digest-width" as *u8, ff_hex(kd, kh, FF_DIGEST_BYTES) == (FF_DIGEST_BYTES * 2), ctr) 172 173 gv_check("state-words-are-distinct-per-state" as *u8, fg_streq(ff_state_word(FF_FRESH), ff_state_word(FF_STALE)) == 0, ctr) 174 175 // ===== THE STALE DIRECTION, AND WHICH REMEDY IT MAKES SAFE ===================================== 176 // A fork can differ from the promoted artifact in two directions that want OPPOSITE actions, and the 177 // consumer printed ONE remedy for both. These teeth pin the direction AND the safety predicate, 178 // because the failure that motivated them was not a wrong classification -- it was a CORRECT 179 // classification followed by the destructive remedy. 180 let dsz: *i64 = sys_mmap(FF_SIZES_SLOTS * 8) as *i64 181 dsz[0] = FG_DIR_SMALL; dsz[1] = FG_DIR_LARGE 182 gv_check("smaller-fork-reads-FORK-BEHIND" as *u8, ff_direction(FF_STALE, dsz) == FF_DIR_BEHIND, ctr) 183 dsz[0] = FG_DIR_LARGE; dsz[1] = FG_DIR_SMALL 184 gv_check("larger-fork-reads-FORK-AHEAD" as *u8, ff_direction(FF_STALE, dsz) == FF_DIR_AHEAD, ctr) 185 dsz[0] = FG_DIR_LARGE; dsz[1] = FG_DIR_LARGE 186 gv_check("equal-sizes-read-FORK-DIVERGED-SAME-SIZE" as *u8, ff_direction(FF_STALE, dsz) == FF_DIR_UNDECIDED, ctr) 187 188 // A DIRECTION ONLY EXISTS FOR A PAIR ALREADY PROVEN TO DIFFER. Deriving one for a FRESH pair would 189 // invent a remedy for an artifact that needs none, and for an ABSTENTION it would fabricate a finding. 190 dsz[0] = FG_DIR_SMALL; dsz[1] = FG_DIR_LARGE 191 gv_check("neg-control-a-FRESH-pair-has-no-direction" as *u8, ff_direction(FF_FRESH, dsz) == FF_DIR_NA, ctr) 192 gv_check("neg-control-an-UNPROVEN-pair-has-no-direction" as *u8, ff_direction(FF_UNPROVEN, dsz) == FF_DIR_NA, ctr) 193 gv_check("neg-control-an-ABSENT-pair-has-no-direction" as *u8, ff_direction(FF_NOFORK, dsz) == FF_DIR_NA, ctr) 194 195 // NEVER FABRICATE A DIRECTION FROM AN UNMEASURED SIZE -- the same law the -1 size slots already carry. 196 dsz[0] = 0 - 1; dsz[1] = FG_DIR_LARGE 197 gv_check("neg-control-unmeasured-fork-size-yields-no-direction" as *u8, ff_direction(FF_STALE, dsz) == FF_DIR_NA, ctr) 198 dsz[0] = FG_DIR_LARGE; dsz[1] = 0 - 1 199 gv_check("neg-control-unmeasured-promoted-size-yields-no-direction" as *u8, ff_direction(FF_STALE, dsz) == FF_DIR_NA, ctr) 200 201 // THE LOAD-BEARING TEETH: restage is safe for exactly ONE direction. The shipped defect answered YES 202 // for all of them, so a predicate that returned 1 everywhere would still pass the BEHIND tooth alone -- 203 // the three refusals below are what make this a test rather than a restatement. 204 gv_check("restage-is-safe-for-a-fork-that-is-BEHIND" as *u8, ff_restage_is_safe(FF_DIR_BEHIND) == 1, ctr) 205 gv_check("neg-control-restage-is-NOT-safe-for-a-fork-that-is-AHEAD" as *u8, ff_restage_is_safe(FF_DIR_AHEAD) == 0, ctr) 206 gv_check("neg-control-restage-is-NOT-safe-when-UNDECIDED" as *u8, ff_restage_is_safe(FF_DIR_UNDECIDED) == 0, ctr) 207 gv_check("neg-control-restage-is-NOT-safe-with-no-direction" as *u8, ff_restage_is_safe(FF_DIR_NA) == 0, ctr) 208 209 // BIND THE DIRECTION TO THE REAL CLASSIFIER, NOT ONLY TO HAND-BUILT ARRAYS. The equal-size differing 210 // pair is the estate's own blind spot; re-classifying it here proves the two functions compose on a 211 // REAL measurement rather than on numbers this gate typed for itself. 212 let s_dir: i64 = ff_classify(f_diff, r_diff, fd0, rd0, sz) 213 gv_check("fixture-reached-condition-real-pair-is-STALE" as *u8, s_dir == FF_STALE, ctr) 214 gv_check("fixture-reached-condition-real-pair-sizes-equal" as *u8, sz[0] == sz[1], ctr) 215 gv_check("real-same-size-stale-pair-is-UNDECIDED-not-a-guess" as *u8, ff_direction(s_dir, sz) == FF_DIR_UNDECIDED, ctr) 216 gv_check("real-same-size-stale-pair-does-NOT-authorise-restage" as *u8, ff_restage_is_safe(ff_direction(s_dir, sz)) == 0, ctr) 217 218 gv_check("direction-words-are-distinct-per-direction" as *u8, fg_streq(ff_direction_word(FF_DIR_BEHIND), ff_direction_word(FF_DIR_AHEAD)) == 0, ctr) 219 gv_check("neg-control-a-direction-word-is-not-a-state-word" as *u8, fg_streq(ff_direction_word(FF_DIR_AHEAD), ff_state_word(FF_STALE)) == 0, ctr) 220 221 return gv_verdict("nx_forkfresh_gate" as *u8, ctr, "in-process over nx_forkfresh_lib: derivation, the digest ruler against a published vector, the four-state classification and the abstention contract" as *u8) 222}