code wiki / _hdl_build / nx_builddeploy_gate_t146.nx

nx_builddeploy_gate_t146.nx source

↩ module page · 267 lines · 17608 B

1// nx_builddeploy_gate.nx -- holds nx_builddeploy_lib, THE ruler for "may this build write a 2// consumer-visible binary?". IN-PROCESS by construction: the lib is pure integer logic in this gate's own 3// build closure, so nx_gate_bite can actually reach it. A gate that fork/execs a deployed elf cannot be 4// mutation-proven (every mutant reads NOT-REACHED), which is precisely why the queued-build class went 5// unmeasured -- the decision lived inline in a 105KB builder that no fixture could drive. 6// 7// THE DEFECT THIS EXISTS TO STOP, measured 2026-08-26 from the queue's own artifact: 8// [nx_sov_build_run] nx_gate_roster_run: DEPLOYED to serving root (twin refresh, live for the next 9// fork) -> ../nx_gate_roster_run.elf 10// seeded by /api/build's load-refusal path, which had told the caller only that the build was deferred 11// and to "promote deliberately afterwards". 12// 13// THE TWO TEETH THAT MATTER ARE A PAIR, AND EITHER ALONE IS A TRAP: 14// - build-only must install NOTHING (stops the defect) 15// - the DEFAULT path must still refresh a present twin (stops the over-correction) 16// A fix that silenced the first by disabling all installs would reintroduce LM-026 staleness estate-wide 17// and every consumer would silently fork a stale binary. Both directions are held here. 18// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 19import "nx_gate_verdict.nx" 20import "nx_tool_run.nx" 21import "nx_builddeploy_lib.nx" 22 23// Input-state counts, named so the exhaustive tooth's denominator is DERIVED rather than typed. 24const BDG_BOOL_STATES: i64 = 2 // any twin probe answers exactly: present or absent 25const BDG_DKIND_STATES: i64 = 3 // organ_kind.conf answers daemon(1), not-daemon(0), UNPROVEN(-1) 26const BDG_DKIND_LO: i64 = 0 - 1 27const BDG_DKIND_HI: i64 = 1 28const BDG_NOT_DAEMON: i64 = 0 29const BDG_IS_DAEMON: i64 = 1 30const BDG_UNPROVEN: i64 = 0 - 1 31 32func bdg_eq(a: i64, b: i64) -> i64 { if a == b { return 1 } return 0 } 33 34 35func bdg_retain(mark:*u8,out:*u8,n:i64)->i64 { 36 let path:*u8=sys_mmap(256);let prefix:*u8="/volume1/homes/elderwesto/nishihost/buildroot/knowledge/gates/qualify-20260912-t146-" as *u8 37 var k:i64=0;while prefix[k]!=0 as u8 { path[k]=prefix[k];k=k+1 };var j:i64=0 38 while mark[j]!=0 as u8 { if k>=250 { return 0 };path[k]=mark[j];k=k+1;j=j+1 };path[k]=0 as u8 39 let fd:i64=sys_openat_wr(path,0x1a4);if fd<0 { return 0 };var at:i64=0 40 while at<n { let w:i64=sys_write(fd,((out as i64)+at) as *u8,n-at);if w<=0 { sys_close(fd);return 0 };at=at+w };sys_close(fd);return 1 41} 42 43func bdg_runtime(runner:*u8,target:*u8,f1:*u8,f2:*u8,tail:*u8,expected:i64,mark:*u8,ctr:*i64)->i64 { 44 let av:*i64=sys_mmap(64) as *i64 45 av[0]=runner as i64;av[1]=target as i64;av[2]=f1 as i64;av[3]=f2 as i64 46 var n:i64=4 47 if (tail as i64)!=0 { av[n]=tail as i64;n=n+1 };av[n]=0 48 let out:*u8=sys_mmap(65536);let len:*i64=sys_mmap(16) as *i64;let cut:*i64=sys_mmap(16) as *i64 49 let rc:i64=tr_run_capture_tr(runner,av,out,65536,len,120000,cut) 50 let retained:i64=bdg_retain(mark,out,len[0]) 51 gv_check(mark,rc==expected && cut[0]==0 && retained==1,ctr) 52 return rc 53} 54func bdg_same_file(path:*u8,before:*u8,n:i64)->i64 { 55 let len:*i64=sys_mmap(16) as *i64;let after:*u8=sys_read_file(path,len) 56 if (before as i64)==0 || (after as i64)==0 || len[0]!=n || n<=0 { return 0 } 57 var i:i64=0;while i<n { if before[i]!=after[i] { return 0 };i=i+1 };return 1 58} 59func bdg_runtime_checks(runner:*u8,target:*u8,ctr:*i64)->i64 { 60 if sys_chdir("/volume1/homes/elderwesto/nishihost" as *u8)!=0 { gv_check("serving-root-CWD-required" as *u8,0,ctr);return 1 } 61 let root:*u8=sys_mmap(256);let offc:*u8=sys_mmap(256) 62 var n:i64=0;while target[n]!=0 as u8 { if n>=245 { gv_check("fixture-target-name-too-long" as *u8,0,ctr);return 1 };root[n]=target[n];n=n+1 } 63 let suffix:*u8=".elf" as *u8;var i:i64=0;while i<5 { root[n+i]=suffix[i];i=i+1 } 64 let prefix:*u8="_offc/" as *u8;i=0;while i<6 { offc[i]=prefix[i];i=i+1 };i=0;while i<n+5 { offc[i+6]=root[i];i=i+1 } 65 let rn:*i64=sys_mmap(16) as *i64;let on:*i64=sys_mmap(16) as *i64 66 let rb:*u8=sys_read_file(root,rn);let ob:*u8=sys_read_file(offc,on) 67 if (rb as i64)==0 || (ob as i64)==0 { gv_check("actual-existing-consumer-twins-required" as *u8,0,ctr);return 1 } 68 gv_check("actual-existing-consumer-twins-required" as *u8,rn[0]>0 && on[0]>0,ctr) 69 bdg_runtime(runner,target,"--qualify" as *u8,"--debug" as *u8,0 as *u8,0,"qualification-runs-reviewed-gate" as *u8,ctr) 70 gv_check("qualification-root-twin-byte-identical" as *u8,bdg_same_file(root,rb,rn[0]),ctr) 71 gv_check("qualification-offc-twin-byte-identical" as *u8,bdg_same_file(offc,ob,on[0]),ctr) 72 bdg_runtime(runner,target,"--qualfy" as *u8,"--debug" as *u8,0 as *u8,2,"misspelled-qualification-refuses" as *u8,ctr) 73 bdg_runtime(runner,target,"--unrecognized" as *u8,"--debug" as *u8,0 as *u8,2,"unknown-flag-refuses" as *u8,ctr) 74 bdg_runtime(runner,target,"--qualify" as *u8,"--install" as *u8,0 as *u8,2,"qualify-install-refuses" as *u8,ctr) 75 bdg_runtime(runner,target,"--install" as *u8,"--qualify" as *u8,0 as *u8,2,"install-qualify-refuses" as *u8,ctr) 76 bdg_runtime(runner,target,"--qualify" as *u8,"--build-only" as *u8,0 as *u8,2,"qualify-build-only-refuses" as *u8,ctr) 77 bdg_runtime(runner,target,"--build-only" as *u8,"--qualify" as *u8,0 as *u8,2,"build-only-qualify-refuses" as *u8,ctr) 78 bdg_runtime(runner,target,"--qualify" as *u8,"--run-timeout-ms" as *u8,"9223372036854775808" as *u8,2,"overflow-deadline-refuses" as *u8,ctr) 79 bdg_runtime(runner,target,"--qualify" as *u8,"--run-timeout-ms" as *u8,"50x" as *u8,2,"malformed-deadline-refuses" as *u8,ctr) 80 gv_check("all-conflicts-root-twin-byte-identical" as *u8,bdg_same_file(root,rb,rn[0]),ctr) 81 gv_check("all-conflicts-offc-twin-byte-identical" as *u8,bdg_same_file(offc,ob,on[0]),ctr) 82 return 0 83} 84 85 86func bdg_text_eq(a:*u8,b:*u8)->i64 { 87 var i:i64=0;while b[i]!=0 as u8 { if a[i]!=b[i] { return 0 };i=i+1 } 88 if a[i]!=0 as u8 { return 0 };return 1 89} 90func bdg_process_fixture(runner:*u8,mode:*u8,budget:*u8,expected:i64,ctr:*i64)->i64 { 91 let av:*i64=sys_mmap(64) as *i64 92 av[0]=runner as i64;av[1]="nx_builddeploy_gate" as *u8 as i64;av[2]="--qualify" as *u8 as i64;av[3]="--run-timeout-ms" as *u8 as i64;av[4]=budget as i64;av[5]=mode as i64;av[6]=0 93 let out:*u8=sys_mmap(65536);let len:*i64=sys_mmap(16) as *i64;let cut:*i64=sys_mmap(16) as *i64 94 let rc:i64=tr_run_capture_tr(runner,av,out,65536,len,120000,cut) 95 let retained:i64=bdg_retain(mode,out,len[0]);gv_check(mode,rc==expected && cut[0]==0 && retained==1,ctr);return rc 96} 97 98func main(argc: i64, argv: *i64) -> i64 { 99 if argc==2 { 100 let mode:*u8=argv[1] as *u8 101 if bdg_text_eq(mode,"fixture-fail" as *u8)==1 { return 23 } 102 if bdg_text_eq(mode,"fixture-sleep" as *u8)==1 { sys_sleep_ms(1000);return 0 } 103 } 104 let ctr: *i64 = gv_ctr() 105 gv_head("NX-BUILDDEPLOY-GATE -- may this build write a consumer-visible binary" as *u8) 106 107 // ---- ANTI-VACUITY FIRST. Every "installs nothing" tooth below is worthless unless this ruler CAN 108 // say yes. Assert the fixture reaches the condition before asserting any outcome. ---- 109 let dflt_root: i64 = bd_locations(0, 1, 0, 0, 0, BDG_NOT_DAEMON) 110 gv_check("anti-vacuity-default-path-CAN-write-the-serving-root" as *u8, 111 bdg_eq(bd_writes_root(dflt_root), 1), ctr) 112 let dflt_offc: i64 = bd_locations(1, 0, 0, 0, 0, BDG_NOT_DAEMON) 113 gv_check("anti-vacuity-default-path-CAN-write-offc" as *u8, 114 bdg_eq(bd_writes_offc(dflt_offc), 1), ctr) 115 116 // ---- THE DEFECT ---- 117 let bo_root: i64 = bd_locations(0, 1, 0, 1, 0, BDG_NOT_DAEMON) 118 gv_check("build-only-with-a-serving-root-twin-writes-NOTHING" as *u8, 119 bdg_eq(bo_root, BD_LOC_NONE), ctr) 120 let bo_offc: i64 = bd_locations(1, 0, 0, 1, 0, BDG_NOT_DAEMON) 121 gv_check("build-only-with-an-offc-twin-writes-NOTHING" as *u8, 122 bdg_eq(bo_offc, BD_LOC_NONE), ctr) 123 let bo_both: i64 = bd_locations(1, 1, 0, 1, 0, BDG_NOT_DAEMON) 124 gv_check("build-only-with-BOTH-twins-writes-NOTHING" as *u8, 125 bdg_eq(bo_both, BD_LOC_NONE), ctr) 126 127 // ---- EXHAUSTIVE over every input combination a build-only caller can present. NO SAMPLING: the 128 // denominator is the product of the declared state counts and is asserted, so a loop that silently 129 // stopped early cannot read as a clean sweep. ---- 130 var cases: i64 = 0 131 var installed: i64 = 0 132 var oi: i64 = 0 133 while oi < BDG_BOOL_STATES { 134 var ri: i64 = 0 135 while ri < BDG_BOOL_STATES { 136 var ti: i64 = 0 137 while ti < BDG_BOOL_STATES { 138 var di: i64 = BDG_DKIND_LO 139 while di <= BDG_DKIND_HI { 140 let loc: i64 = bd_locations(oi, ri, 0, 1, ti, di) 141 cases = cases + 1 142 if loc != BD_LOC_NONE { installed = installed + 1 } 143 di = di + 1 144 } 145 ti = ti + 1 146 } 147 ri = ri + 1 148 } 149 oi = oi + 1 150 } 151 let expect_cases: i64 = BDG_BOOL_STATES * BDG_BOOL_STATES * BDG_BOOL_STATES * BDG_DKIND_STATES 152 gv_puts(" [enumerated build-only input combinations: " as *u8); gv_num(cases) 153 gv_puts(" of an expected " as *u8); gv_num(expect_cases) 154 gv_puts("; combinations that would still install: " as *u8); gv_num(installed); gv_puts("]\n" as *u8) 155 var exh: i64 = 0 156 if cases == expect_cases { if installed == 0 { exh = 1 } } 157 gv_check("build-only-installs-nothing-across-EVERY-enumerated-input-combination" as *u8, exh, ctr) 158 159 // ---- THE OVER-CORRECTION GUARD. These must stay green or the fix has broken the estate's 160 // staleness retirement (LM-026) instead of the defect. ---- 161 gv_check("neg-control-default-path-STILL-refreshes-a-present-serving-root-twin" as *u8, 162 bdg_eq(bd_writes_root(dflt_root), 1), ctr) 163 gv_check("neg-control-default-path-STILL-refreshes-a-present-offc-twin" as *u8, 164 bdg_eq(bd_writes_offc(dflt_offc), 1), ctr) 165 let dflt_both: i64 = bd_locations(1, 1, 0, 0, 0, BDG_NOT_DAEMON) 166 var both_ok: i64 = 0 167 if bd_writes_offc(dflt_both) == 1 { if bd_writes_root(dflt_both) == 1 { both_ok = 1 } } 168 gv_check("neg-control-default-path-STILL-refreshes-BOTH-twins-when-both-exist" as *u8, both_ok, ctr) 169 170 // ---- EXPLICIT INTENT still installs. --install is a deliberate act and outranks --build-only. ---- 171 let force_new: i64 = bd_locations(0, 0, 1, 0, 0, BDG_NOT_DAEMON) 172 gv_check("force-install-with-no-existing-twin-still-installs-to-offc" as *u8, 173 bdg_eq(bd_writes_offc(force_new), 1), ctr) 174 let force_bo: i64 = bd_locations(0, 0, 1, 1, 0, BDG_NOT_DAEMON) 175 gv_check("build-only-AND-install-together-honour-the-explicit-install" as *u8, 176 bdg_eq(bd_writes_offc(force_bo), 1), ctr) 177 178 // ---- RULE 26 outranks everything, including an explicit --install. ---- 179 let tc_dflt: i64 = bd_locations(1, 1, 0, 0, 1, BDG_NOT_DAEMON) 180 gv_check("toolchain-is-never-auto-installed-on-the-default-path" as *u8, 181 bdg_eq(tc_dflt, BD_LOC_NONE), ctr) 182 let tc_force: i64 = bd_locations(1, 1, 1, 0, 1, BDG_NOT_DAEMON) 183 gv_check("toolchain-is-never-installed-even-under-an-explicit-force-install" as *u8, 184 bdg_eq(tc_force, BD_LOC_NONE), ctr) 185 186 // ---- DAEMON: the serving-root write IS a deploy (the supervisor respawns from disk). ---- 187 let dm_root: i64 = bd_locations(0, 1, 0, 0, 0, BDG_IS_DAEMON) 188 gv_check("declared-daemon-serving-root-twin-is-NOT-written-on-the-default-path" as *u8, 189 bdg_eq(bd_writes_root(dm_root), 0), ctr) 190 let dm_both: i64 = bd_locations(1, 1, 0, 0, 0, BDG_IS_DAEMON) 191 var dm_ok: i64 = 0 192 if bd_writes_root(dm_both) == 0 { if bd_writes_offc(dm_both) == 1 { dm_ok = 1 } } 193 gv_check("declared-daemon-keeps-its-offc-refresh-while-its-serving-root-is-held" as *u8, dm_ok, ctr) 194 195 // ---- PINNED RESIDUAL, NOT AN ENDORSEMENT. organ_kind.conf unreadable means daemon-ness UNPROVEN, 196 // and the incumbent still writes the serving root. This tooth exists so that behaviour is a DECLARED 197 // choice a later lane can adjudicate, not an assumption inherited in silence. An abstention that 198 // acquits is a real defect; changing it belongs to the default-path lane, not this one. ---- 199 let unp: i64 = bd_locations(0, 1, 0, 0, 0, BDG_UNPROVEN) 200 gv_check("PINNED-incumbent-UNPROVEN-daemon-kind-still-permits-a-serving-root-write" as *u8, 201 bdg_eq(bd_writes_root(unp), 1), ctr) 202 gv_check("PINNED-but-build-only-overrides-it-so-an-UNPROVEN-kind-can-never-deploy-from-the-queue" as *u8, 203 bdg_eq(bd_locations(0, 1, 0, 1, 0, BDG_UNPROVEN), BD_LOC_NONE), ctr) 204 205 // ---- NO TWIN: nothing consumes this name, so nothing is written and the reason says so. ---- 206 gv_check("no-twin-anywhere-writes-nothing" as *u8, 207 bdg_eq(bd_locations(0, 0, 0, 0, 0, BDG_NOT_DAEMON), BD_LOC_NONE), ctr) 208 209 // ---- bd_root_held: the caller owes its reader a NAMED "I left your live binary alone". ---- 210 gv_check("root-held-is-reported-when-build-only-declines-a-present-serving-root-twin" as *u8, 211 bdg_eq(bd_root_held(1, 0, 1, 0, BDG_NOT_DAEMON), 1), ctr) 212 gv_check("root-held-is-NOT-reported-when-the-default-path-actually-writes-the-twin" as *u8, 213 bdg_eq(bd_root_held(1, 0, 0, 0, BDG_NOT_DAEMON), 0), ctr) 214 gv_check("root-held-is-reported-for-a-declared-daemon" as *u8, 215 bdg_eq(bd_root_held(1, 0, 0, 0, BDG_IS_DAEMON), 1), ctr) 216 gv_check("root-held-is-NOT-reported-when-no-serving-root-twin-exists-to-hold" as *u8, 217 bdg_eq(bd_root_held(0, 0, 1, 0, BDG_NOT_DAEMON), 0), ctr) 218 219 // ---- the reason code travels with the decision ---- 220 gv_check("why-names-BUILD-ONLY-when-the-flag-is-what-declined" as *u8, 221 bdg_eq(bd_why(1, 1, 0, 1, 0, BDG_NOT_DAEMON), BD_WHY_BUILD_ONLY), ctr) 222 gv_check("why-names-TOOLCHAIN-ahead-of-every-other-rule" as *u8, 223 bdg_eq(bd_why(1, 1, 1, 1, 1, BDG_NOT_DAEMON), BD_WHY_TOOLCHAIN), ctr) 224 gv_check("why-names-FORCE-for-an-explicit-install" as *u8, 225 bdg_eq(bd_why(0, 0, 1, 0, 0, BDG_NOT_DAEMON), BD_WHY_FORCE), ctr) 226 gv_check("why-names-REFRESH-for-the-default-path-over-a-present-twin" as *u8, 227 bdg_eq(bd_why(0, 1, 0, 0, 0, BDG_NOT_DAEMON), BD_WHY_REFRESH), ctr) 228 gv_check("why-names-NO-TWIN-when-there-is-nothing-to-refresh" as *u8, 229 bdg_eq(bd_why(0, 0, 0, 0, 0, BDG_NOT_DAEMON), BD_WHY_NO_TWIN), ctr) 230 231 // ---- THE LOAD-BEARING BITE. This is the one tooth that CANNOT pass if the fix is removed. 232 // BAD = the incumbent behaviour, reproduced exactly: the flag is ignored, so a build-only caller 233 // with a serving-root twin gets a live deploy. 234 // GOOD = the same inputs WITH the flag honoured. 235 // If anyone deletes the build_only rule from bd_locations, bad and good become equal and this 236 // reports VACUOUS rather than passing. A green here means the flag is genuinely load-bearing. ---- 237 let bite_bad: i64 = bd_writes_root(bd_locations(0, 1, 0, 0, 0, BDG_NOT_DAEMON)) 238 let bite_good: i64 = bd_writes_root(bd_locations(0, 1, 0, 1, 0, BDG_NOT_DAEMON)) 239 gv_bite("neg-control-bite-the-build-only-flag-is-load-bearing-for-the-serving-root" as *u8, 240 bite_bad, bite_good, ctr) 241 let bite_bad2: i64 = bd_writes_offc(bd_locations(1, 0, 0, 0, 0, BDG_NOT_DAEMON)) 242 let bite_good2: i64 = bd_writes_offc(bd_locations(1, 0, 0, 1, 0, BDG_NOT_DAEMON)) 243 gv_bite("neg-control-bite-the-build-only-flag-is-load-bearing-for-offc" as *u8, 244 bite_bad2, bite_good2, ctr) 245 246 247 gv_check("deadline-minimum",bd_positive_ms("1" as *u8)==1,ctr) 248 gv_check("deadline-max-i64",bd_positive_ms("9223372036854775807" as *u8)==9223372036854775807,ctr) 249 gv_check("deadline-overflow-refuses",bd_positive_ms("9223372036854775808" as *u8)==-1,ctr) 250 gv_check("deadline-zero-refuses",bd_positive_ms("0" as *u8)==-1,ctr) 251 gv_check("deadline-negative-refuses",bd_positive_ms("-1" as *u8)==-1,ctr) 252 gv_check("deadline-empty-refuses",bd_positive_ms("" as *u8)==-1,ctr) 253 gv_check("deadline-suffix-refuses",bd_positive_ms("50x" as *u8)==-1,ctr) 254 gv_check("deadline-huge-refuses",bd_positive_ms("9999999999999999999999999" as *u8)==-1,ctr) 255 gv_check("unknown-lane-flag-refuses" as *u8,bd_lane_flag_known("--qualfy" as *u8)==0 && bd_lane_flag_known("--unrecognized" as *u8)==0,ctr) 256 gv_check("qualification-exact-flag" as *u8,bd_qualification_flag("--qualify" as *u8)==1,ctr) 257 gv_check("qualification-prefix-not-a-flag" as *u8,bd_qualification_flag("--qualify-more" as *u8)==0 && bd_qualification_flag("--qual" as *u8)==0,ctr) 258 gv_check("qualification-runs-with-no-install-intent" as *u8,bd_qualification_mode(1,0,0)==1,ctr) 259 gv_check("qualification-build-only-conflict-refuses" as *u8,bd_qualification_mode(1,1,0)==-1,ctr) 260 gv_check("qualification-install-conflict-refuses" as *u8,bd_qualification_mode(1,0,1)==-1,ctr) 261 gv_check("qualification-both-conflicts-refuse" as *u8,bd_qualification_mode(1,1,1)==-1,ctr) 262 gv_check("legacy-install-build-only-intent-preserved" as *u8,bd_qualification_mode(0,1,1)==0,ctr) 263 gv_check("qualification-effective-policy-blocks-both-twins" as *u8,bd_locations(1,1,0,1,0,0)==BD_LOC_NONE,ctr) 264 if argc==3 { bdg_runtime_checks(argv[1] as *u8,argv[2] as *u8,ctr);bdg_process_fixture(argv[1] as *u8,"fixture-fail" as *u8,"1000" as *u8,23,ctr);bdg_process_fixture(argv[1] as *u8,"fixture-sleep" as *u8,"50" as *u8,8,ctr) } 265 return gv_verdict("BUILDDEPLOY-GATE" as *u8, ctr, 266 "the queued build lane cannot install a consumer-visible binary" as *u8) 267}