code wiki / (root) / nx_artifactdrift_gate.nx

nx_artifactdrift_gate.nx source

↩ module page · 259 lines · 13869 B

1// nx_artifactdrift_gate.nx -- THE BITE PROOF FOR THE FORK-ROOT AXIS (2026-08-31). 2// 3// WHY THIS GATE EXISTS. On 2026-08-31 a compare regen returned `published=201 fails=0 verdict=GREEN` 4// and published NOTHING: every one of the 201 lines reported prev= EQUAL to its new byte count. The 5// cause was a THIRD TWIN nobody was censusing -- nx_compare_regen chdirs into buildroot and forks the 6// BARE path `_offc/nx_swcompare_*.elf`, so buildroot/_offc is the copy the publisher actually executes, 7// and /api/promote never writes it. FOUR INDEPENDENT AGENTS each verified their promote against the 8// serving root and/or nishihost/_offc and all four missed it, because nx_catalog enumerates 9// SOURCE/BUILT/STAGED/PROMOTED/_offc and NOT buildroot/_offc -- so every row read BUILT==PROMOTED. 10// 11// nx_artifactdrift grew a FORK-ROOT axis for exactly this. That axis had never been proven to go 12// SILENT. A detector that has only ever fired on real data is HALF verified: firing proves it can 13// speak, never that its silence means anything. A GREEN THAT NEVER HAD A CORRESPONDING RED IS 14// UNVERIFIED -- AND SO IS A RED THAT NEVER HAD A CORRESPONDING GREEN. 15// 16// THIS GATE NEVER TOUCHES buildroot/_offc. The subject fork root is argv[7], overridable precisely 17// so a gate can point the axis at a FIXTURE tree. A gate that must perturb the directory the compare 18// publisher forks in order to report on it is a gate that can take the estate down to test itself. 19// Every fixture lives under /tmp/nx_artifactdrift_gate/ and the subject trend log is redirected 20// there too, so this can never append to knowledge/status/artifactdrift.log -- a gate must not share 21// its fixture with a production beat. 22// 23// THREE LEGS, because the axis has three honest answers and all three must be proven: 24// RED a planted twin that differs -> FIRES and NAMES it, carrying BOTH byte counts 25// GREEN a byte-identical twin -> SILENT (FORK-STALE=0 and no offender line at all) 26// ABSTAIN a fork root it cannot open -> UNPROVEN, and must NOT report agreement 27// The GREEN leg additionally asserts the twin was EXAMINED (FORK-IDENTICAL=1): a zero from an EMPTY 28// directory is the gate-passes-on-the-empty-set defect, and would look exactly like a real green. 29// 30// Exit carries the verdict via gv_verdict (0 GREEN / 1 RED / 3 SKIP). 31// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 32import "nx_gate_verdict.nx" 33import "nx_gatekit_lib.nx" 34import "nx_tool_run.nx" 35 36// The subject is the SERVING-ROOT binary, which is what nx_job_run and the roster fork. Measured 37// 2026-08-31: serving root and nishihost/_offc are byte-identical (sha 8b5a4f9f..., 71925 B), and 38// buildroot/_offc holds no twin of this organ at all -- so there is one artifact to prove, not three. 39// The leading ./ is REQUIRED: execve does no PATH lookup, so a bare basename fails ENOENT and the 40// gate would report on a subject it never launched. 41const AG_SUBJECT: *u8 = "./nx_artifactdrift.elf" 42const AG_DIR: *u8 = "/tmp/nx_artifactdrift_gate" 43const AG_A: *u8 = "/tmp/nx_artifactdrift_gate/forkA/" 44const AG_B: *u8 = "/tmp/nx_artifactdrift_gate/forkB/" 45const AG_BLIND: *u8 = "/tmp/nx_artifactdrift_gate/no_such_forkroot/" 46const AG_LOG: *u8 = "/tmp/nx_artifactdrift_gate/drift_fixture.log" 47const AG_ADIR: *u8 = "/tmp/nx_artifactdrift_gate/forkA" 48const AG_BDIR: *u8 = "/tmp/nx_artifactdrift_gate/forkB" 49 50// The subject own defaults, passed through so the MAIN census is unchanged and only the fork root 51// and the trend log move. Holding these fixed is what makes the separateness tooth meaningful. 52const AG_REG: *u8 = "tool_allowlist.conf" 53const AG_BROOT: *u8 = "buildroot/_build/" 54const AG_SRCA: *u8 = "buildroot/runtime/_hdl_build/" 55const AG_SRCB: *u8 = "buildroot/runtime/" 56const AG_DECL: *u8 = "knowledge/status/drift_owner_declare.conf" 57 58// DONOR is copied byte-for-byte to make an IDENTICAL twin. VICTIM is written as short text to make a 59// twin that DIFFERS. ORPHAN has no serving-root counterpart. All three are ordinary serving-root names 60// chosen because they exist; nothing about the proof depends on WHICH files these are, and the expected 61// output strings are DERIVED from the sizes measured at runtime, never written as literals -- a 62// hand-counted size beside a fixture is a second copy of that fixture shape and the two drift. 63const AG_DONOR: *u8 = "nx_magic.elf" 64const AG_VICTIM: *u8 = "nx_debtmine.elf" 65const AG_ORPHAN: *u8 = "nx_zzz_gatefixture.elf" 66const AG_PLANT: *u8 = "NOT-THE-SERVED-BYTES-planted-by-nx_artifactdrift_gate\n" 67 68const AG_CAP: i64 = 1048576 // > 12x the ~82 KB the live census emits; truncation is ASSERTED, not assumed 69const AG_MODE644: i64 = 420 70const AG_PATHBUF: i64 = 256 71const AG_LINEBUF: i64 = 1024 72const AG_NL: i64 = 10 73 74func ag_path(dir: *u8, name: *u8) -> *u8 { 75 let p: *u8 = sys_mmap(AG_PATHBUF) 76 var o: i64 = gv_cat(p, 0, dir) 77 o = gv_cat(p, o, name) 78 p[o] = 0 as u8 79 return p 80} 81 82// Binary-safe copy. gk_write takes a NUL-terminated STRING and would stop at the first zero byte of an 83// ELF, so the copy is done with an explicit length. A full buffer is reported as its own failure: 84// a silently truncated donor would produce a twin that DIFFERS, which is the opposite of what the 85// IDENTICAL fixture is for, and the gate would then pass its RED leg for the wrong reason. 86func ag_copy(src: *u8, dst: *u8, buf: *u8, cap: i64) -> i64 { 87 let n: i64 = gk_read(src, buf, cap) 88 if n < 0 { return 0 - 1 } 89 if n >= cap { return 0 - 2 } 90 let fd: i64 = sys_openat_wr(dst, AG_MODE644) 91 if fd < 0 { return 0 - 1 } 92 let w: i64 = gk_write_all(fd, buf, n) 93 sys_close(fd) 94 if w != n { return 0 - 1 } 95 return n 96} 97 98func ag_same(a: *u8, b: *u8, ba: *u8, bb: *u8, cap: i64) -> i64 { 99 let na: i64 = gk_read(a, ba, cap) 100 let nb: i64 = gk_read(b, bb, cap) 101 if na < 0 { return 0 } 102 if nb < 0 { return 0 } 103 if na != nb { return 0 } 104 var i: i64 = 0 105 var ok: i64 = 1 106 while i < na { if ba[i] != bb[i] { ok = 0; i = na } else { i = i + 1 } } 107 return ok 108} 109 110// Copy the line that STARTS at `key` up to the newline. Used to compare the subject main partition 111// summary across two runs that differ ONLY in their fork root. 112func ag_line_at(buf: *u8, n: i64, key: *u8, dst: *u8, cap: i64) -> i64 { 113 let p: i64 = gk_out_pos(buf, n, key) 114 if p < 0 { return 0 - 1 } 115 var i: i64 = p 116 var k: i64 = 0 117 while i < n { 118 if buf[i] == (AG_NL as u8) { i = n } else { 119 if k < cap - 1 { dst[k] = buf[i]; k = k + 1 } 120 i = i + 1 121 } 122 } 123 dst[k] = 0 as u8 124 return k 125} 126 127// Drive the subject with a full argv. gk_run_capture stops at four arguments and the fork root is the 128// SEVENTH, so the arbitrary-arity runner is the one composed here. 129func ag_run(forkp: *u8, out: *u8, cap: i64, ol: *i64) -> i64 { 130 let av: *i64 = sys_mmap(128) as *i64 131 av[0] = AG_SUBJECT as i64 132 av[1] = AG_REG as i64 133 av[2] = AG_BROOT as i64 134 av[3] = AG_SRCA as i64 135 av[4] = AG_SRCB as i64 136 av[5] = AG_DECL as i64 137 av[6] = AG_LOG as i64 138 av[7] = forkp as i64 139 av[8] = 0 140 return tr_run_capture(AG_SUBJECT, av, out, cap, ol) 141} 142 143func main(argc: i64, argv: *i64) -> i64 { 144 let ctr: *i64 = gv_ctr() 145 gv_head("nx_artifactdrift_gate -- FORK-ROOT AXIS: fires, stays silent, and abstains" as *u8) 146 147 // PRECONDITIONS. An absent subject or registry must ABSTAIN, never fail the axis. A gate that 148 // reports RED because it could not find what it guards indicts the wrong subject. 149 let donor_sz: i64 = gk_size(AG_DONOR) 150 let victim_sz: i64 = gk_size(AG_VICTIM) 151 gv_need("subject-present" as *u8, gk_exists(AG_SUBJECT), ctr) 152 gv_need("registry-present" as *u8, gk_exists(AG_REG), ctr) 153 gv_need("donor-present" as *u8, gk_exists(AG_DONOR), ctr) 154 gv_need("victim-present" as *u8, gk_exists(AG_VICTIM), ctr) 155 156 // SETUP. Fixtures are ASSEMBLED AT RUNTIME, never checked in: a detector that scans a tree would 157 // find its own committed fixture. Directories are created unconditionally and the fixture files are 158 // removed before being rewritten, so a second run cannot inherit the first run tree -- a gate that 159 // is not idempotent reports on its first run and lies on every run after. 160 gk_mkdir(AG_DIR) 161 gk_mkdir(AG_ADIR) 162 gk_mkdir(AG_BDIR) 163 let fa_donor: *u8 = ag_path(AG_A, AG_DONOR) 164 let fa_victim: *u8 = ag_path(AG_A, AG_VICTIM) 165 let fa_orphan: *u8 = ag_path(AG_A, AG_ORPHAN) 166 let fb_donor: *u8 = ag_path(AG_B, AG_DONOR) 167 let fb_victim: *u8 = ag_path(AG_B, AG_VICTIM) 168 let fb_orphan: *u8 = ag_path(AG_B, AG_ORPHAN) 169 gk_rm(fa_donor) 170 gk_rm(fa_victim) 171 gk_rm(fa_orphan) 172 gk_rm(fb_donor) 173 gk_rm(fb_victim) 174 gk_rm(fb_orphan) 175 176 let cpbuf: *u8 = sys_mmap(AG_CAP) 177 let cmpa: *u8 = sys_mmap(AG_CAP) 178 let cmpb: *u8 = sys_mmap(AG_CAP) 179 let ca: i64 = ag_copy(AG_DONOR, fa_donor, cpbuf, AG_CAP) 180 let cb: i64 = ag_copy(AG_DONOR, fb_donor, cpbuf, AG_CAP) 181 gk_write(fa_victim, AG_PLANT) 182 gk_write(fa_orphan, AG_PLANT) 183 184 // FIXTURE-REACHED-THE-CONDITION. Asserted BEFORE any outcome, because a fixture the defect cannot 185 // fail is not a test, and every outcome tooth below is meaningless if these do not hold. 186 var cpok: i64 = 0 187 if ca == donor_sz { if cb == donor_sz { cpok = 1 } } 188 gv_check("fixture-donor-copied-without-truncation" as *u8, cpok, ctr) 189 gv_check("fixture-identical-twin-is-byte-identical" as *u8, ag_same(fa_donor, AG_DONOR, cmpa, cmpb, AG_CAP), ctr) 190 var vdiff: i64 = 0 191 if gk_size(fa_victim) != victim_sz { vdiff = 1 } 192 gv_check("fixture-stale-twin-really-differs-from-served" as *u8, vdiff, ctr) 193 var orph: i64 = 0 194 if gk_exists(AG_ORPHAN) == 0 { orph = 1 } 195 gv_check("fixture-orphan-has-no-serving-root-counterpart" as *u8, orph, ctr) 196 197 let outa: *u8 = sys_mmap(AG_CAP) 198 let outb: *u8 = sys_mmap(AG_CAP) 199 let outc: *u8 = sys_mmap(AG_CAP) 200 let ola: *i64 = sys_mmap(16) as *i64 201 let olb: *i64 = sys_mmap(16) as *i64 202 let olc: *i64 = sys_mmap(16) as *i64 203 ag_run(AG_A, outa, AG_CAP, ola) 204 ag_run(AG_B, outb, AG_CAP, olb) 205 ag_run(AG_BLIND, outc, AG_CAP, olc) 206 207 // A capture that hit its ceiling is a PARTIAL read, and every absence tooth below would then be 208 // measuring the buffer instead of the subject. 209 var nota: i64 = 0 210 if ola[0] < AG_CAP { if olb[0] < AG_CAP { if olc[0] < AG_CAP { nota = 1 } } } 211 gv_check("captures-not-truncated" as *u8, nota, ctr) 212 213 // RED. The expected row is DERIVED from the two sizes this gate just measured, so the tooth proves 214 // the row carries the CORRECT byte counts, not merely that some digits are present. 215 let exp: *u8 = sys_mmap(AG_PATHBUF) 216 var eo: i64 = gv_cat(exp, 0, "FORK-STALE " as *u8) 217 eo = gv_cat(exp, eo, AG_VICTIM) 218 eo = gv_cat(exp, eo, " forkroot=" as *u8) 219 eo = gk_catn(exp, eo, gk_size(fa_victim)) 220 eo = gv_cat(exp, eo, " served=" as *u8) 221 eo = gk_catn(exp, eo, victim_sz) 222 exp[eo] = 0 as u8 223 gv_check("red-fires-and-names-the-offender-with-both-byte-counts" as *u8, gk_out_has(outa, ola[0], exp), ctr) 224 gv_check("red-counts-the-identical-twin-as-FORK-IDENTICAL" as *u8, gk_out_has(outa, ola[0], "FORK-IDENTICAL=1" as *u8), ctr) 225 gv_check("red-names-the-orphan-as-FORK-ONLY-not-an-offender" as *u8, gk_out_has(outa, ola[0], "FORK-ONLY nx_zzz_gatefixture.elf" as *u8), ctr) 226 gv_check("red-fork-partition-reconciles" as *u8, gk_out_has(outa, ola[0], "sum=3 fork_partition=RECONCILES" as *u8), ctr) 227 gv_check("red-count-travels-with-its-remedy" as *u8, gk_out_has(outa, ola[0], "REMEDY: nx_restage" as *u8), ctr) 228 229 // GREEN neg-controls. FORK-STALE=0 alone is not silence: the offender line must be ABSENT, and the 230 // twin must have been EXAMINED or the zero came from an empty directory. 231 gv_check("neg-control-green-reports-zero-stale" as *u8, gk_out_has(outb, olb[0], "FORK-STALE=0" as *u8), ctr) 232 var quiet: i64 = 0 233 if gk_out_has(outb, olb[0], "FORK-STALE nx_" as *u8) == 0 { quiet = 1 } 234 gv_check("neg-control-green-names-no-offender-at-all" as *u8, quiet, ctr) 235 gv_check("neg-control-green-actually-examined-the-twin" as *u8, gk_out_has(outb, olb[0], "FORK-IDENTICAL=1" as *u8), ctr) 236 237 // ABSTENTION neg-controls. An axis that cannot see must never report agreement. 238 gv_check("neg-control-blind-axis-abstains-UNPROVEN" as *u8, gk_out_has(outc, olc[0], "FORK-ROOT UNPROVEN" as *u8), ctr) 239 var noacq: i64 = 0 240 if gk_out_has(outc, olc[0], "FORK-STALE=0" as *u8) == 0 { noacq = 1 } 241 gv_check("neg-control-blind-axis-does-not-acquit" as *u8, noacq, ctr) 242 243 // SEPARATENESS. The fork axis is declared a SEPARATE axis rather than a partition member, because a 244 // binary can be IDENTICAL on the build axis and FORK-STALE on this one at the same time. This proves 245 // it empirically: two runs whose fork roots hold DIFFERENT numbers of rows must produce a 246 // byte-identical main partition line. If fork rows ever leaked into that sum, this fails. 247 let la: *u8 = sys_mmap(AG_LINEBUF) 248 let lb: *u8 = sys_mmap(AG_LINEBUF) 249 let na: i64 = ag_line_at(outa, ola[0], "distinct_binaries=" as *u8, la, AG_LINEBUF) 250 let nb: i64 = ag_line_at(outb, olb[0], "distinct_binaries=" as *u8, lb, AG_LINEBUF) 251 var sep: i64 = 0 252 if na > 0 { if nb > 0 { sep = gk_streq(la, lb) } } 253 gv_check("fork-axis-is-separate-main-partition-unchanged" as *u8, sep, ctr) 254 255 // The gate must not be able to pollute the production trend log it is testing around. 256 gv_check("subject-trend-log-redirected-to-the-fixture" as *u8, gk_out_has(outa, ola[0], "appended -> /tmp/nx_artifactdrift_gate/" as *u8), ctr) 257 258 return gv_verdict("nx_artifactdrift_gate" as *u8, ctr, "fork-root axis of the deployed nx_artifactdrift; every fixture under /tmp/nx_artifactdrift_gate/" as *u8) 259}