code wiki / _hdl_build / nx_bld_cache_cas_gate.nx

nx_bld_cache_cas_gate.nx source

↩ module page · 682 lines · 39257 B

1// nx_bld_cache_cas_gate.nx -- VERDICT gate for rung B2 of /compare/toolchain: the content-addressed 2// build cache in nx_sov_build_run (watch symbol bld_cache_cas). Runs the REAL builder binary end to end 3// inside an ISOLATED fixture tree under <buildroot>/_build/nx_bld_cache_cas_gate/ (its own runtime/, its own _offc/ 4// copy of the live toolchain, its own _build/cache) so nothing here touches the estate's cache, its 5// toolchain, or its knowledge/ confs -- and so the gate is idempotent: the fixture is wiped at SETUP, 6// never at teardown (a teardown does not run when a run crashes). 7// 8// DONE-RULE UNDER TEST (toolchain.plan B2, verbatim): an unchanged rebuild returns byte-identical bytes 9// with ZERO compiler invocation, and a one-byte source edit MISSES; a hit is byte-verified before use; a 10// key miss on any input change is the tooth; determinism re-proven by byte-identical cold rebuilds. 11// 12// THE ZERO-INVOCATION WITNESS IS STATE, NOT A MESSAGE: the builder writes _build/<t>.s ONLY inside its 13// compile loop (sys_openat_wr(spath) immediately before it forks nx_cc). The gate deletes that file 14// before a rebuild; if the artifact comes back and the .s is still ABSENT, the compiler was not forked. 15// A tooth asserts the .s IS present after a real build, so the absence witness cannot pass vacuously. 16// 17// Subject: argv[1] = builder elf (absolute or cwd-relative), else the first of 18// <nishihost>/nx_sov_build_run.sov.elf.new (STAGED -- what the next promote installs) 19// <buildroot>/_build/nx_sov_build_run.sov.elf (the last build) 20// <buildroot>/_offc/nx_sov_build_run.elf (LIVE) 21// and the chosen path + its sha256 are PRINTED, so the reader knows which binary was judged. 22// Bounded by the subject's OWN declared per-step deadline (it time-boxes compile and assemble); the 23// gate passes ms=0 so that bound is inherited rather than copied. license_tier: ORIGINAL 24import "nx_syscalls.nx" 25import "nx_sha256.nx" 26import "nx_gate_verdict.nx" 27import "nx_gatekit_lib.nx" 28 29// FIXTURE ROOT IS DERIVED, NOT /tmp (measured 2026-08-23 on the NAS: a byte-identical copy of the live 30// compiler placed under /tmp/ returned execve 127 -- the mount refuses execution -- so every builder run 31// failed with an empty .s and an empty stderr, which READS as a compiler defect). The fixture therefore 32// lives under <buildroot>/_build/nx_bld_cache_cas_gate/, build-artifact territory that is executable by 33// construction and never the serving root. Created and wiped at SETUP. The law "gate scratch lives in 34// /tmp/<gate>/" is followed for everything that is not executed; an executable fixture cannot live there. 35const CG_SHA_HEX: i64 = 64 36const CG_PATH: i64 = 4096 37const CG_OUT: i64 = 1048576 // one builder run prints well under this; = GK_BUF 38const CG_DIRBUF: i64 = 65536 39const CG_DENT_RECLEN_OFF: i64 = 16 // linux_dirent64: d_reclen u16 at +16, d_name at +19 (gk_dirscan uses the same) 40const CG_DENT_NAME_OFF: i64 = 19 41const CG_MODE_X: i64 = 493 // 0755 42const CG_FX_EXIT_A: i64 = 42 // fixture v1 exit code 43const CG_FX_EXIT_B: i64 = 43 // fixture v2 exit code (ONE byte differs: '2' -> '3') 44const CG_MAXOUT_SHOW: i64 = 4096 // how much of a captured run to echo into the report on a failure 45 46const CG_FX: *u8 = "casfx" 47const CG_FXREL: *u8 = "_build/nx_bld_cache_cas_gate" 48static cgp_root_p: i64 49static cgp_tree_p: i64 50static cgp_know_p: i64 51static cgp_conf_p: i64 52static cgp_fxsrc_p: i64 53static cgp_fxs_p: i64 54static cgp_fxelf_p: i64 55static cgp_cache_p: i64 56static cgp_cc_p: i64 57static cgp_asm_p: i64 58static cgp_lock_p: i64 59static cgp_rt_p: i64 60static cgp_hdl_p: i64 61static cgp_offc_p: i64 62static cgp_build_p: i64 63func cgp_mk(base: *u8, tail: *u8) -> i64 { 64 let b: *u8 = sys_mmap(CG_PATH) 65 var o: i64 = gk_cat(b, 0, base) 66 o = gk_cat(b, o, tail) 67 b[o] = 0 as u8 68 return b as i64 69} 70func cgp_init(buildroot: *u8) -> i64 { 71 cgp_root_p = cgp_mk(buildroot, CG_FXREL) 72 cgp_tree_p = cgp_mk(cgp_root_p as *u8, "/tree" as *u8) 73 cgp_know_p = cgp_mk(cgp_root_p as *u8, "/knowledge" as *u8) 74 cgp_conf_p = cgp_mk(cgp_know_p as *u8, "/buildcache.conf" as *u8) 75 cgp_rt_p = cgp_mk(cgp_tree_p as *u8, "/runtime" as *u8) 76 cgp_hdl_p = cgp_mk(cgp_rt_p as *u8, "/_hdl_build" as *u8) 77 cgp_offc_p = cgp_mk(cgp_tree_p as *u8, "/_offc" as *u8) 78 cgp_build_p = cgp_mk(cgp_tree_p as *u8, "/_build" as *u8) 79 cgp_fxsrc_p = cgp_mk(cgp_hdl_p as *u8, "/casfx.nx" as *u8) 80 cgp_fxs_p = cgp_mk(cgp_build_p as *u8, "/casfx.s" as *u8) 81 cgp_fxelf_p = cgp_mk(cgp_build_p as *u8, "/casfx.sov.elf" as *u8) 82 cgp_lock_p = cgp_mk(cgp_build_p as *u8, "/casfx.lock" as *u8) 83 cgp_cache_p = cgp_mk(cgp_build_p as *u8, "/cache" as *u8) 84 cgp_cc_p = cgp_mk(cgp_offc_p as *u8, "/nx_cc_sovereign.elf" as *u8) 85 cgp_asm_p = cgp_mk(cgp_offc_p as *u8, "/nxasm_x86_main.elf" as *u8) 86 return 0 87} 88func cgp_root() -> *u8 { return cgp_root_p as *u8 } 89func cgp_tree() -> *u8 { return cgp_tree_p as *u8 } 90func cgp_know() -> *u8 { return cgp_know_p as *u8 } 91func cgp_conf() -> *u8 { return cgp_conf_p as *u8 } 92func cgp_fxsrc() -> *u8 { return cgp_fxsrc_p as *u8 } 93func cgp_fxs() -> *u8 { return cgp_fxs_p as *u8 } 94func cgp_fxelf() -> *u8 { return cgp_fxelf_p as *u8 } 95func cgp_cache() -> *u8 { return cgp_cache_p as *u8 } 96func cgp_cc() -> *u8 { return cgp_cc_p as *u8 } 97func cgp_asm() -> *u8 { return cgp_asm_p as *u8 } 98func cgp_lock() -> *u8 { return cgp_lock_p as *u8 } 99func cgp_rt() -> *u8 { return cgp_rt_p as *u8 } 100func cgp_hdl() -> *u8 { return cgp_hdl_p as *u8 } 101func cgp_offc() -> *u8 { return cgp_offc_p as *u8 } 102func cgp_build() -> *u8 { return cgp_build_p as *u8 } 103 104 105func cg_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 106func cg_p(s: *u8) -> i64 { sys_write(1, s, cg_len(s)); return 0 } 107func cg_nl() -> i64 { let b: *u8 = sys_mmap(2); b[0] = 10 as u8; sys_write(1, b, 1); sys_munmap(b, 2); return 0 } 108func cg_pn(v: i64) -> i64 { gv_num(v); return 0 } 109 110// sha256 hex of a file; 1 ok (out[0..64] + NUL), 0 unreadable 111func cg_sha(path: *u8, out: *u8) -> i64 { 112 let ln: *i64 = sys_mmap(16) as *i64 113 ln[0] = 0 114 let buf: *u8 = sys_read_file(path, ln) 115 if (buf as i64) == 0 { return 0 } 116 let n: i64 = ln[0] 117 let d: *u8 = sys_mmap(48) 118 sha256_digest(buf, n, d) 119 var i: i64 = 0 120 while i < 32 { 121 let v: i64 = d[i] as i64 122 let hi: i64 = (v >> 4) & 15 123 let lo: i64 = v & 15 124 if hi < 10 { out[i*2] = (48+hi) as u8 } else { out[i*2] = (87+hi) as u8 } 125 if lo < 10 { out[i*2+1] = (48+lo) as u8 } else { out[i*2+1] = (87+lo) as u8 } 126 i = i + 1 127 } 128 out[CG_SHA_HEX] = 0 as u8 129 return 1 130} 131func cg_hexeq(a: *u8, b: *u8) -> i64 { 132 var i: i64 = 0 133 while i < CG_SHA_HEX { if a[i] != b[i] { return 0 } i = i + 1 } 134 return 1 135} 136 137// copy whole file src -> dst, mode applied; 1 ok, 0 fail 138func cg_copy(src: *u8, dst: *u8, mode: i64) -> i64 { 139 let ln: *i64 = sys_mmap(16) as *i64 140 ln[0] = 0 141 let buf: *u8 = sys_read_file(src, ln) 142 if (buf as i64) == 0 { return 0 } 143 let n: i64 = ln[0] 144 sys_unlinkat(dst) 145 let fd: i64 = sys_openat_wr(dst, mode) 146 if fd < 0 { return 0 } 147 let w: i64 = gk_write_all(fd, buf, n) 148 sys_close(fd) 149 if w != n { return 0 } 150 nx_chmod(dst, mode) 151 return 1 152} 153 154// unlink every regular file directly inside dir (no recursion; the fixture cache is flat). Returns the 155// number removed, -1 if the dir could not be opened. 156func cg_clear_dir(dir: *u8) -> i64 { 157 let fd: i64 = sys_openat_rd(dir) 158 if fd < 0 { return 0 - 1 } 159 let gbuf: *u8 = sys_mmap(CG_DIRBUF) 160 let path: *u8 = sys_mmap(CG_PATH) 161 var removed: i64 = 0 162 var nread: i64 = sys_getdents64(fd, gbuf, CG_DIRBUF) 163 while nread > 0 { 164 var off: i64 = 0 165 while off < nread { 166 let reclen: i64 = (gbuf[off + CG_DENT_RECLEN_OFF] as i64) | ((gbuf[off + CG_DENT_RECLEN_OFF + 1] as i64) << 8) 167 if reclen <= 0 { off = nread } 168 if reclen > 0 { 169 let nm: *u8 = ((gbuf as i64) + off + CG_DENT_NAME_OFF) as *u8 170 var isdot: i64 = 0 171 if nm[0] == (46 as u8) { if nm[1] == (0 as u8) { isdot = 1 } } 172 if nm[0] == (46 as u8) { if nm[1] == (46 as u8) { if nm[2] == (0 as u8) { isdot = 1 } } } 173 if isdot == 0 { 174 var o: i64 = gk_cat(path, 0, dir) 175 path[o] = 47 as u8; o = o + 1 176 o = gk_cat(path, o, nm); path[o] = 0 as u8 177 if sys_unlinkat(path) == 0 { removed = removed + 1 } 178 } 179 off = off + reclen 180 } 181 } 182 nread = sys_getdents64(fd, gbuf, CG_DIRBUF) 183 } 184 sys_close(fd) 185 return removed 186} 187// count entries in dir whose name ends with `suffix`; -1 if unopenable 188func cg_count_suffix(dir: *u8, suffix: *u8) -> i64 { 189 let fd: i64 = sys_openat_rd(dir) 190 if fd < 0 { return 0 - 1 } 191 let gbuf: *u8 = sys_mmap(CG_DIRBUF) 192 let sl: i64 = cg_len(suffix) 193 var cnt: i64 = 0 194 var nread: i64 = sys_getdents64(fd, gbuf, CG_DIRBUF) 195 while nread > 0 { 196 var off: i64 = 0 197 while off < nread { 198 let reclen: i64 = (gbuf[off + CG_DENT_RECLEN_OFF] as i64) | ((gbuf[off + CG_DENT_RECLEN_OFF + 1] as i64) << 8) 199 if reclen <= 0 { off = nread } 200 if reclen > 0 { 201 let nm: *u8 = ((gbuf as i64) + off + CG_DENT_NAME_OFF) as *u8 202 let nl: i64 = cg_len(nm) 203 if nl >= sl { 204 var j: i64 = 0 205 var ok: i64 = 1 206 while j < sl { if nm[nl - sl + j] != suffix[j] { ok = 0; j = sl } else { j = j + 1 } } 207 if ok == 1 { cnt = cnt + 1 } 208 } 209 off = off + reclen 210 } 211 } 212 nread = sys_getdents64(fd, gbuf, CG_DIRBUF) 213 } 214 sys_close(fd) 215 return cnt 216} 217 218// write the fixture program with the given exit code (the ONE byte that differs between v1 and v2) 219func cg_write_fixture(exit_code: i64) -> i64 { 220 let txt: *u8 = sys_mmap(CG_PATH) 221 var o: i64 = gk_cat(txt, 0, "import \"nx_syscalls.nx\"" as *u8) 222 txt[o] = 10 as u8; o = o + 1 223 o = gk_cat(txt, o, "func main(argc: i64, argv: *i64) -> i64 {" as *u8) 224 txt[o] = 10 as u8; o = o + 1 225 o = gk_cat(txt, o, " sys_write(1, \"casfx\" as *u8, 5)" as *u8) 226 txt[o] = 10 as u8; o = o + 1 227 o = gk_cat(txt, o, " return " as *u8) 228 o = gk_catn(txt, o, exit_code) 229 txt[o] = 10 as u8; o = o + 1 230 o = gk_cat(txt, o, "}" as *u8) 231 txt[o] = 10 as u8; o = o + 1 232 txt[o] = 0 as u8 233 if gk_write(cgp_fxsrc(), txt) < 0 { return 0 } 234 // Fixture source changes and their identity evidence are one authoring operation. 235 let status_dir: *u8 = cgp_mk(cgp_know(), "/status" as *u8) as *u8 236 gk_mkdir(status_dir) 237 let rule_path: *u8 = cgp_mk(cgp_know(), "/tree_canon.conf" as *u8) as *u8 238 if gk_write(rule_path, "_hdl_build/casfx.nx\n" as *u8) < 0 { return 0 } 239 let digest: *u8 = sys_mmap(CG_SHA_HEX + 2) 240 if cg_sha(cgp_fxsrc(), digest) != 1 { return 0 } 241 let row: *u8 = sys_mmap(CG_PATH) 242 var ro: i64 = gk_cat(row, 0, digest) 243 ro = gk_cat(row, ro, " " as *u8) 244 ro = gk_catn(row, ro, gk_size(cgp_fxsrc())) 245 ro = gk_cat(row, ro, " _hdl_build/casfx.nx\n" as *u8) 246 row[ro] = 0 as u8 247 let manifest: *u8 = cgp_mk(status_dir, "/treecanon_laptop_hash.mf" as *u8) as *u8 248 if gk_write(manifest, row) < 0 { return 0 } 249 return 1 250} 251 252// run the subject builder on the fixture INSIDE the fixture tree; output captured into out; returns rc. 253// extra = an optional lane flag (e.g. "--no-cache") or 0. 254func cg_build(subject: *u8, extra: *u8, out: *u8, outlen: *i64, ctr: *i64) -> i64 { 255 let here: *u8 = sys_mmap(CG_PATH) 256 sys_getcwd(here, CG_PATH) 257 sys_chdir(cgp_tree()) 258 var rc: i64 = 0 259 if extra == (0 as *u8) { rc = gk_run_capture_ms(subject, CG_FX, "--build-only" as *u8, 0 as *u8, 0 as *u8, 0, out, CG_OUT, outlen) } 260 if extra != (0 as *u8) { rc = gk_run_capture_ms(subject, CG_FX, extra, "--build-only" as *u8, 0 as *u8, 0, out, CG_OUT, outlen) } 261 sys_chdir(here) 262 if rc != 0 { 263 cg_show_on_fail(0, out, outlen[0]) 264 var blocked: i64 = gk_out_has(out, outlen[0], "REFUSED-BUILD-ADMIT" as *u8) 265 if gk_out_has(out, outlen[0], "REFUSED-TREE-CANON" as *u8) == 1 { blocked = 1 } 266 if blocked == 1 { gv_need("build prerequisites admitted; dependent cache checks stopped" as *u8, 0, ctr) } 267 else { gv_check("fixture build completed; dependent cache checks stopped" as *u8, 0, ctr) } 268 let verdict: i64 = gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "see failed build receipt above" as *u8) 269 sys_exit(verdict) 270 } 271 return rc 272} 273// run the BUILT fixture; returns its exit code 274func cg_run_fx() -> i64 { return gk_run(cgp_fxelf(), 0 as *u8, 0 as *u8, 0 as *u8, 0 as *u8) } 275 276// copy the 64-hex key after the first "key=" in out into keyout (NUL-terminated); 1 ok / 0 absent 277func cg_key_of(out: *u8, n: i64, keyout: *u8) -> i64 { 278 let p: i64 = gk_out_pos(out, n, " key=" as *u8) 279 if p < 0 { return 0 } 280 var i: i64 = 0 281 while i < CG_SHA_HEX { 282 if p + 5 + i >= n { return 0 } 283 keyout[i] = out[p + 5 + i] 284 i = i + 1 285 } 286 keyout[CG_SHA_HEX] = 0 as u8 287 return 1 288} 289// Does a FILE contain <needle>? 1 yes / 0 no / -1 unreadable. Used only to ask whether the subject binary 290// carries the vocabulary for a refusal -- i.e. whether the failure has a NAME at all. 291func cg_file_has(path: *u8, needle: *u8) -> i64 { 292 let ln: *i64 = sys_mmap(16) as *i64 293 ln[0] = 0 294 let buf: *u8 = sys_read_file(path, ln) 295 if (buf as i64) == 0 { return 0 - 1 } 296 return gk_out_has(buf, ln[0], needle) 297} 298// THE NEEDLE IS ASSEMBLED, NEVER WRITTEN CONTIGUOUSLY. A detector that spells its own pattern in one 299// literal appears in every grep for that pattern beside the organs that actually emit it, and matches 300// itself the moment anyone points it at its own binary -- the estate has paid for that twice. Two halves, 301// joined at run time, so this gate's elf does not contain the string it hunts. 302func cg_needle_anm(out: *u8) -> *u8 { 303 var o: i64 = gk_cat(out, 0, "artifact-not-mat" as *u8) 304 o = gk_cat(out, o, "erialised" as *u8) 305 out[o] = 0 as u8 306 return out 307} 308func cg_show_on_fail(cond: i64, out: *u8, n: i64) -> i64 { 309 if cond == 1 { return 0 } 310 var m: i64 = n 311 if m > CG_MAXOUT_SHOW { m = CG_MAXOUT_SHOW } 312 cg_p(" ---- subject output (head) ----" as *u8); cg_nl() 313 sys_write(1, out, m) 314 cg_nl() 315 return 0 316} 317// append ONE byte to a file (the toolchain-change fixture); returns new size or -1 318func cg_append_byte(path: *u8) -> i64 { 319 let fd: i64 = sys_openat_rdwr(path, CG_MODE_X) 320 if fd < 0 { return 0 - 1 } 321 let end: i64 = sys_lseek(fd, 0, 2) 322 let b: *u8 = sys_mmap(2) 323 b[0] = 0 as u8 324 let w: i64 = sys_write(fd, b, 1) 325 sys_close(fd) 326 if w != 1 { return 0 - 1 } 327 return end + 1 328} 329// flip the LAST byte of a file in place (size preserved); 1 ok 330func cg_flip_last(path: *u8) -> i64 { 331 let fd: i64 = sys_openat_rdwr(path, CG_MODE_X) 332 if fd < 0 { return 0 } 333 let end: i64 = sys_lseek(fd, 0, 2) 334 if end <= 0 { sys_close(fd); return 0 } 335 sys_lseek(fd, end - 1, 0) 336 let b: *u8 = sys_mmap(2) 337 if sys_read(fd, b, 1) != 1 { sys_close(fd); return 0 } 338 b[0] = (b[0] as i64 ^ 255) as u8 339 sys_lseek(fd, end - 1, 0) 340 let w: i64 = sys_write(fd, b, 1) 341 sys_close(fd) 342 if w != 1 { return 0 } 343 return 1 344} 345 346func main(argc: i64, argv: *i64) -> i64 { 347 gv_head("nx_bld_cache_cas_gate -- B2 content-addressed build cache: hit=verified+zero-compile, miss on any input change, corruption refused" as *u8) 348 let ctr: *i64 = gv_ctr() 349 350 // ---- resolve the tree and the subject, and SAY which ---- 351 let rt: *u8 = sys_mmap(CG_PATH) 352 if gv_need("source tree resolvable (gk_corpus_root)" as *u8, gk_corpus_root(rt), ctr) == 0 { 353 return gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "no tree" as *u8) 354 } 355 // buildroot = rt minus trailing "runtime/"; nishihost = buildroot minus trailing "buildroot/" 356 let rtl: i64 = cg_len(rt) 357 let buildroot: *u8 = sys_mmap(CG_PATH) 358 var bo: i64 = 0 359 while bo < rtl - 8 { buildroot[bo] = rt[bo]; bo = bo + 1 } 360 buildroot[bo] = 0 as u8 361 let nishihost: *u8 = sys_mmap(CG_PATH) 362 var ho: i64 = 0 363 if bo > 10 { while ho < bo - 10 { nishihost[ho] = buildroot[ho]; ho = ho + 1 } } 364 nishihost[ho] = 0 as u8 365 let subject: *u8 = sys_mmap(CG_PATH) 366 var chosen: *u8 = "argv" as *u8 367 if argc >= 2 { 368 let a1: *u8 = argv[1] as *u8 369 var so: i64 = 0 370 if a1[0] != (47 as u8) { 371 let here: *u8 = sys_mmap(CG_PATH) 372 sys_getcwd(here, CG_PATH) 373 so = gk_cat(subject, 0, here); subject[so] = 47 as u8; so = so + 1 374 } 375 so = gk_cat(subject, so, a1); subject[so] = 0 as u8 376 } 377 if argc < 2 { 378 var so: i64 = gk_cat(subject, 0, nishihost); so = gk_cat(subject, so, "nx_sov_build_run.sov.elf.new" as *u8); subject[so] = 0 as u8 379 chosen = "staged(.sov.elf.new)" as *u8 380 if gk_exists(subject) == 0 { 381 so = gk_cat(subject, 0, buildroot); so = gk_cat(subject, so, "_build/nx_sov_build_run.sov.elf" as *u8); subject[so] = 0 as u8 382 chosen = "built(_build)" as *u8 383 } 384 if gk_exists(subject) == 0 { 385 so = gk_cat(subject, 0, buildroot); so = gk_cat(subject, so, "_offc/nx_sov_build_run.elf" as *u8); subject[so] = 0 as u8 386 chosen = "live(_offc)" as *u8 387 } 388 } 389 let subj_sha: *u8 = sys_mmap(CG_SHA_HEX + 2) 390 let have_subj: i64 = cg_sha(subject, subj_sha) 391 cg_p(" subject=" as *u8); cg_p(subject); cg_p(" [" as *u8); cg_p(chosen); cg_p("] sha256=" as *u8) 392 if have_subj == 1 { cg_p(subj_sha) } else { cg_p("UNREADABLE" as *u8) } 393 cg_nl() 394 if gv_need("subject builder readable" as *u8, have_subj, ctr) == 0 { 395 return gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "no subject" as *u8) 396 } 397 398 // ---- fixture tree: created/wiped at SETUP (idempotent across runs) ---- 399 cgp_init(buildroot) 400 cg_p(" fixture=" as *u8); cg_p(cgp_root()); cg_nl() 401 gk_mkdir(cgp_root()); gk_mkdir(cgp_tree()); gk_mkdir(cgp_know()) 402 gk_mkdir(cgp_rt()); gk_mkdir(cgp_hdl()); gk_mkdir(cgp_offc()); gk_mkdir(cgp_build()) 403 gk_mkdir(cgp_cache()) 404 cg_clear_dir(cgp_cache()) 405 sys_unlinkat(cgp_fxs()); sys_unlinkat(cgp_fxelf()); sys_unlinkat(cgp_conf()) 406 sys_unlinkat(cgp_lock()) 407 let p1: *u8 = sys_mmap(CG_PATH) 408 let p2: *u8 = sys_mmap(CG_PATH) 409 var ok_src: i64 = 1 410 var o1: i64 = gk_cat(p1, 0, rt); o1 = gk_cat(p1, o1, "nx_syscalls.nx" as *u8); p1[o1] = 0 as u8 411 if cg_copy(p1, cgp_mk(cgp_rt(), "/nx_syscalls.nx" as *u8) as *u8, 420) == 0 { ok_src = 0 } 412 o1 = gk_cat(p1, 0, rt); o1 = gk_cat(p1, o1, "nx_tier.nx" as *u8); p1[o1] = 0 as u8 413 if cg_copy(p1, cgp_mk(cgp_rt(), "/nx_tier.nx" as *u8) as *u8, 420) == 0 { ok_src = 0 } 414 o1 = gk_cat(p1, 0, rt); o1 = gk_cat(p1, o1, "nx_crash.nx" as *u8); p1[o1] = 0 as u8 415 if cg_copy(p1, cgp_mk(cgp_rt(), "/nx_crash.nx" as *u8) as *u8, 420) == 0 { ok_src = 0 } 416 var o2: i64 = gk_cat(p2, 0, buildroot); o2 = gk_cat(p2, o2, "_offc/nx_cc_sovereign.elf" as *u8); p2[o2] = 0 as u8 417 var ok_tc: i64 = 1 418 if cg_copy(p2, cgp_cc(), CG_MODE_X) == 0 { ok_tc = 0 } 419 let cc_real_sha: *u8 = sys_mmap(CG_SHA_HEX + 2) 420 let cc_copy_sha: *u8 = sys_mmap(CG_SHA_HEX + 2) 421 if cg_sha(p2, cc_real_sha) == 0 { ok_tc = 0 } 422 o2 = gk_cat(p2, 0, buildroot); o2 = gk_cat(p2, o2, "_offc/nxasm_x86_main.elf" as *u8); p2[o2] = 0 as u8 423 if cg_copy(p2, cgp_asm(), CG_MODE_X) == 0 { ok_tc = 0 } 424 if gv_need("fixture closure sources copied (nx_syscalls, nx_tier, nx_crash)" as *u8, ok_src, ctr) == 0 { 425 return gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "fixture" as *u8) 426 } 427 if gv_need("live toolchain copied into the fixture _offc (nx_cc_sovereign + nxasm_x86_main)" as *u8, ok_tc, ctr) == 0 { 428 return gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "fixture" as *u8) 429 } 430 // The real runner requires explicit admission; fixtures must provision that dependency too. 431 o2 = gk_cat(p2, 0, buildroot); o2 = gk_cat(p2, o2, "_build/nx_build_admit.sov.elf" as *u8); p2[o2] = 0 as u8 432 if gk_exists(p2) == 0 { 433 o2 = gk_cat(p2, 0, nishihost); o2 = gk_cat(p2, o2, "nx_build_admit.elf" as *u8); p2[o2] = 0 as u8 434 } 435 let admit_dest: *u8 = cgp_mk(cgp_build(), "/nx_build_admit.sov.elf" as *u8) as *u8 436 if gv_need("fixture admission executable copied from real tree", cg_copy(p2, admit_dest, CG_MODE_X), ctr) == 0 { 437 return gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "fixture admission unavailable; cache not exercised" as *u8) 438 } 439 let admit_source_sha: *u8 = sys_mmap(CG_SHA_HEX + 2) 440 let admit_copy_sha: *u8 = sys_mmap(CG_SHA_HEX + 2) 441 var admit_same: i64 = 0 442 if cg_sha(p2, admit_source_sha) == 1 { if cg_sha(admit_dest, admit_copy_sha) == 1 { admit_same = cg_hexeq(admit_source_sha, admit_copy_sha) } } 443 if gv_need("fixture admission copy matches real executable bytes", admit_same, ctr) == 0 { 444 return gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "fixture admission identity mismatch; cache not exercised" as *u8) 445 } 446 // Keep the host policy, including confirmation timestamps; never relax thresholds for a test. 447 var host_policy: *u8 = cgp_mk(buildroot, "knowledge/build_admit.conf" as *u8) as *u8 448 if gk_exists(host_policy) == 0 { host_policy = cgp_mk(nishihost, "knowledge/build_admit.conf" as *u8) as *u8 } 449 let fixture_policy: *u8 = cgp_mk(cgp_know(), "/build_admit.conf" as *u8) as *u8 450 if gk_exists(host_policy) == 1 { 451 if gv_need("host admission policy copied unchanged", cg_copy(host_policy, fixture_policy, 420), ctr) == 0 { return gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "policy copy failed" as *u8) } 452 cg_p(" admission_policy=" as *u8); cg_p(host_policy); cg_nl() 453 } else { 454 sys_unlinkat(fixture_policy) 455 cg_p(" admission_policy=host-derived (no host policy file)\n" as *u8) 456 } 457 var host_confirm: *u8 = cgp_mk(buildroot, "knowledge/status/ioconfirm.status" as *u8) as *u8 458 if gk_exists(host_confirm) == 0 { host_confirm = cgp_mk(nishihost, "knowledge/status/ioconfirm.status" as *u8) as *u8 } 459 let fixture_status: *u8 = cgp_mk(cgp_know(), "/status" as *u8) as *u8 460 gk_mkdir(fixture_status) 461 let fixture_confirm: *u8 = cgp_mk(fixture_status, "/ioconfirm.status" as *u8) as *u8 462 if gk_exists(host_confirm) == 1 { 463 if gv_need("confirmation snapshot copied with original timestamp", cg_copy(host_confirm, fixture_confirm, 420), ctr) == 0 { return gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "confirmation copy failed" as *u8) } 464 } else { sys_unlinkat(fixture_confirm) } 465 var cc_same: i64 = 0 466 if cg_sha(cgp_cc(), cc_copy_sha) == 1 { cc_same = cg_hexeq(cc_real_sha, cc_copy_sha) } 467 gv_check("fixture-reached: fixture compiler copy re-hashes to the live compiler" as *u8, cc_same, ctr) 468 gv_check("fixture-reached: fixture cache dir empty at setup" as *u8, (cg_count_suffix(cgp_cache(), ".sov.elf" as *u8) == 0) as i64, ctr) 469 cg_write_fixture(CG_FX_EXIT_A) 470 // The fixture toolchain must EXECUTE from where it was copied (a noexec mount or a lost mode bit 471 // would make every builder run below fail with an empty .s and an empty stderr -- which reads as a 472 // compiler defect). Run the copied compiler directly on the fixture source, inside the tree. 473 let cco: *u8 = sys_mmap(CG_OUT) 474 let ccl: *i64 = sys_mmap(16) as *i64 475 let here0: *u8 = sys_mmap(CG_PATH) 476 sys_getcwd(here0, CG_PATH) 477 sys_chdir(cgp_tree()) 478 let ccrc: i64 = gk_run_capture_ms(cgp_cc(), "runtime/_hdl_build/casfx.nx" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, 0, cco, CG_OUT, ccl) 479 sys_chdir(here0) 480 cg_p(" fixture compiler direct run: rc=" as *u8); cg_pn(ccrc); cg_p(" out_bytes=" as *u8); cg_pn(ccl[0]); cg_nl() 481 let ccok: i64 = ((ccrc == 0) as i64) * ((ccl[0] > 0) as i64) 482 if gv_need("fixture-reached: the copied compiler EXECUTES in the fixture tree and emits asm (rc 0, bytes > 0)" as *u8, ccok, ctr) == 0 { 483 cg_show_on_fail(0, cco, ccl[0]) 484 return gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "fixture toolchain cannot run here (noexec /tmp? mode?) -- no evidence about the builder" as *u8) 485 } 486 487 let out: *u8 = sys_mmap(CG_OUT) 488 let ol: *i64 = sys_mmap(16) as *i64 489 let sha1: *u8 = sys_mmap(CG_SHA_HEX + 2) 490 let shax: *u8 = sys_mmap(CG_SHA_HEX + 2) 491 let key1: *u8 = sys_mmap(CG_SHA_HEX + 2) 492 let keyx: *u8 = sys_mmap(CG_SHA_HEX + 2) 493 494 // ---- T1: first build MISSES (no entry), compiles, stores entry + sidecar ---- 495 var rc: i64 = cg_build(subject, 0 as *u8, out, ol, ctr) 496 var c: i64 = (rc == 0) as i64 497 if gv_need("T1 first build: builder exit 0" as *u8, c, ctr) == 0 { 498 cg_show_on_fail(c, out, ol[0]) 499 return gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "first build failed; dependent cache assertions not run" as *u8) 500 } 501 gv_check("T1 first build: announces BUILD-CACHE MISS reason=no-entry" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE MISS reason=no-entry" as *u8), ctr) 502 gv_check("T1 first build: announces BUILD-CACHE STORE" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE STORE" as *u8), ctr) 503 gv_check("T1 first build: compiler RAN (_build/casfx.s present -- the witness the hit tooth relies on)" as *u8, gk_exists(cgp_fxs()), ctr) 504 gv_check("T1 first build: artifact present" as *u8, gk_exists(cgp_fxelf()), ctr) 505 gv_check("T1 first build: cache holds exactly one entry" as *u8, (cg_count_suffix(cgp_cache(), ".sov.elf" as *u8) == 1) as i64, ctr) 506 gv_check("T1 first build: cache holds exactly one sidecar" as *u8, (cg_count_suffix(cgp_cache(), ".sha" as *u8) == 1) as i64, ctr) 507 let have1: i64 = cg_sha(cgp_fxelf(), sha1) 508 let t1size: i64 = gk_size(cgp_fxelf()) 509 gv_check("T1 first build: artifact hashable" as *u8, have1, ctr) 510 gv_check("T1 first build: key printed" as *u8, cg_key_of(out, ol[0], key1), ctr) 511 gv_check("T1 first build: built fixture runs with its declared exit code" as *u8, (cg_run_fx() == CG_FX_EXIT_A) as i64, ctr) 512 513 // ---- T2: unchanged rebuild HITS, compiler NOT forked, bytes identical, artifact executable ---- 514 sys_unlinkat(cgp_fxs()) 515 rc = cg_build(subject, 0 as *u8, out, ol, ctr) 516 c = (rc == 0) as i64 517 gv_check("T2 unchanged rebuild: builder exit 0" as *u8, c, ctr); cg_show_on_fail(c, out, ol[0]) 518 gv_check("T2 unchanged rebuild: announces BUILD-CACHE HIT" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE HIT" as *u8), ctr) 519 gv_check("T2 unchanged rebuild: ZERO compiler invocations (_build/casfx.s stays ABSENT)" as *u8, (gk_exists(cgp_fxs()) == 0) as i64, ctr) 520 var eq: i64 = 0 521 if cg_sha(cgp_fxelf(), shax) == 1 { eq = cg_hexeq(sha1, shax) } 522 gv_check("T2 unchanged rebuild: artifact byte-identical to the compiled one" as *u8, eq, ctr) 523 gv_check("T2 unchanged rebuild: served artifact is EXECUTABLE (mode preserved) and exits as declared" as *u8, (cg_run_fx() == CG_FX_EXIT_A) as i64, ctr) 524 gv_check("T2 unchanged rebuild: same key as T1" as *u8, (cg_key_of(out, ol[0], keyx) == 1) as i64 * cg_hexeq(key1, keyx), ctr) 525 526 // ---- T10: THE REFUSAL'S FOOTPRINT -- A HIT MUST MATERIALISE THE ARTIFACT (2026-09-04) ---------- 527 // A build refused by admission UNLINKS _build/<t>.sov.elf (nx_sov_build_run does that before it 528 // consults the admitter) and leaves the cache entry and its sidecar untouched. That is the exact 529 // state the 2026-09-04 incident was reported in -- and NO tooth above exercises it: T2's rebuild runs 530 // with T1's artifact already on disk, so every T2 assertion about the served file is about a file the 531 // hit path never had to produce. MEASURED that day on a copy of the builder with the copy-back chain 532 // removed: it printed BUILD-CACHE HIT ... byte-identical artifact reused, exited 0, and left NO FILE. 533 // The two T2 teeth that happened to notice named the WRONG SUBJECT (wrong bytes, wrong mode) rather 534 // than "the builder claimed reuse and produced nothing", which is the sentence a reader needs. 535 sys_unlinkat(cgp_fxelf()) 536 sys_unlinkat(cgp_fxs()) 537 gv_check("fixture-reached-T10: artifact AND .s both ABSENT before the rebuild (the refusal's footprint)" as *u8, ((gk_exists(cgp_fxelf()) == 0) as i64) * ((gk_exists(cgp_fxs()) == 0) as i64), ctr) 538 rc = cg_build(subject, 0 as *u8, out, ol, ctr) 539 c = (rc == 0) as i64 540 gv_check("T10 artifact deleted, entry+sidecar intact: builder exit 0" as *u8, c, ctr); cg_show_on_fail(c, out, ol[0]) 541 gv_check("T10 artifact deleted, entry+sidecar intact: still announces BUILD-CACHE HIT" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE HIT" as *u8), ctr) 542 let t10_present: i64 = gk_exists(cgp_fxelf()) 543 gv_check("T10 A HIT MUST MATERIALISE THE ARTIFACT -- a verified HIT that leaves no file on disk is the 2026-09-04 incident" as *u8, t10_present, ctr) 544 cg_show_on_fail(t10_present, out, ol[0]) 545 gv_check_eq("T10 materialised artifact size equals the compiled one" as *u8, gk_size(cgp_fxelf()), t1size, ctr) 546 var eq10: i64 = 0 547 if cg_sha(cgp_fxelf(), shax) == 1 { eq10 = cg_hexeq(sha1, shax) } 548 gv_check("T10 materialised artifact is byte-identical to the compiled one" as *u8, eq10, ctr) 549 gv_check("T10 materialised artifact is EXECUTABLE and exits as declared" as *u8, (cg_run_fx() == CG_FX_EXIT_A) as i64, ctr) 550 gv_check("T10 ZERO compiler invocations (.s stays ABSENT -- a hit, not a silent recompile)" as *u8, (gk_exists(cgp_fxs()) == 0) as i64, ctr) 551 // ANTI-VACUITY, AND ITS LIMIT STATED IN ITS OWN NAME. The refusal this rung adds cannot be made to 552 // FIRE from outside the builder: with the copy-back chain intact the invariant it guards is not 553 // breakable by any arrangement of the cache, the sidecar or the artifact (all six such states were 554 // swept on 2026-09-04 and every one behaved correctly). Only a MUTANT builder makes it fire, and that 555 // is where its bite proof lives. What a gate CAN check from here is that the failure has a NAME at 556 // all -- a builder that cannot say "artifact-not-materialised" can only say HIT. 557 let anm: *u8 = sys_mmap(CG_PATH) 558 cg_needle_anm(anm) 559 gv_check("neg-control-T10-vocabulary: subject can NAME the artifact-not-materialised refusal (tests that the failure HAS a name, NOT that it fires -- only a mutant builder can make it fire)" as *u8, (cg_file_has(subject, anm) == 1) as i64, ctr) 560 561 // ---- T3: ONE-BYTE source edit MISSES (new key), compiles, new bytes, new behaviour ---- 562 cg_write_fixture(CG_FX_EXIT_B) 563 sys_unlinkat(cgp_fxs()) 564 rc = cg_build(subject, 0 as *u8, out, ol, ctr) 565 c = (rc == 0) as i64 566 gv_check("T3 one-byte source edit: builder exit 0" as *u8, c, ctr); cg_show_on_fail(c, out, ol[0]) 567 gv_check("T3 one-byte source edit: MISS reason=no-entry" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE MISS reason=no-entry" as *u8), ctr) 568 gv_check("neg-control-T3: the HIT detector stays silent on a real miss" as *u8, (gk_out_has(out, ol[0], "BUILD-CACHE HIT" as *u8) == 0) as i64, ctr) 569 gv_check("T3 one-byte source edit: compiler ran (.s present)" as *u8, gk_exists(cgp_fxs()), ctr) 570 var keydiff: i64 = 0 571 if cg_key_of(out, ol[0], keyx) == 1 { keydiff = (cg_hexeq(key1, keyx) == 0) as i64 } 572 gv_check("T3 one-byte source edit: key DIFFERS from T1" as *u8, keydiff, ctr) 573 var diff3: i64 = 0 574 if cg_sha(cgp_fxelf(), shax) == 1 { diff3 = (cg_hexeq(sha1, shax) == 0) as i64 } 575 gv_check("T3 one-byte source edit: artifact bytes differ" as *u8, diff3, ctr) 576 gv_check("T3 one-byte source edit: new artifact runs with the NEW exit code" as *u8, (cg_run_fx() == CG_FX_EXIT_B) as i64, ctr) 577 gv_check("T3: cache now holds two entries (both closures)" as *u8, (cg_count_suffix(cgp_cache(), ".sov.elf" as *u8) == 2) as i64, ctr) 578 579 // ---- T4: toolchain artifact change (one byte appended to the fixture compiler) MISSES on identical source ---- 580 cg_write_fixture(CG_FX_EXIT_A) 581 let cc_size_before: i64 = gk_size(cgp_cc()) 582 let cc_size_after: i64 = cg_append_byte(cgp_cc()) 583 gv_check("fixture-reached-T4: fixture compiler is one byte longer" as *u8, (cc_size_after == cc_size_before + 1) as i64, ctr) 584 sys_unlinkat(cgp_fxs()) 585 rc = cg_build(subject, 0 as *u8, out, ol, ctr) 586 c = (rc == 0) as i64 587 gv_check("T4 toolchain sha change: builder exit 0 (appended compiler still compiles)" as *u8, c, ctr); cg_show_on_fail(c, out, ol[0]) 588 gv_check("T4 toolchain sha change: MISS reason=no-entry on UNCHANGED source" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE MISS reason=no-entry" as *u8), ctr) 589 gv_check("T4 toolchain sha change: compiler ran (.s present)" as *u8, gk_exists(cgp_fxs()), ctr) 590 let key4: *u8 = sys_mmap(CG_SHA_HEX + 2) 591 var key4diff: i64 = 0 592 if cg_key_of(out, ol[0], key4) == 1 { key4diff = (cg_hexeq(key1, key4) == 0) as i64 } 593 gv_check("T4 toolchain sha change: key DIFFERS from T1 (toolchain bytes are in the key)" as *u8, key4diff, ctr) 594 var same4: i64 = 0 595 if cg_sha(cgp_fxelf(), shax) == 1 { same4 = cg_hexeq(sha1, shax) } 596 gv_check("T4 toolchain sha change: artifact bytes equal T1 (appended byte changes identity, not codegen)" as *u8, same4, ctr) 597 598 // ---- T5: corrupted cache entry is REFUSED (sha-mismatch), evicted, rebuilt, re-stored ---- 599 let ent: *u8 = sys_mmap(CG_PATH) 600 var eo: i64 = gk_cat(ent, 0, cgp_cache()); ent[eo] = 47 as u8; eo = eo + 1 601 eo = gk_cat(ent, eo, key4); eo = gk_cat(ent, eo, ".sov.elf" as *u8); ent[eo] = 0 as u8 602 let side: *u8 = sys_mmap(CG_PATH) 603 var sdo: i64 = gk_cat(side, 0, ent); sdo = gk_cat(side, sdo, ".sha" as *u8); side[sdo] = 0 as u8 604 gv_check("fixture-reached-T5: T4's entry and sidecar exist at the printed key" as *u8, gk_exists(ent) * gk_exists(side), ctr) 605 let esha_before: *u8 = sys_mmap(CG_SHA_HEX + 2) 606 let esha_after: *u8 = sys_mmap(CG_SHA_HEX + 2) 607 cg_sha(ent, esha_before) 608 let flipped: i64 = cg_flip_last(ent) 609 var changed5: i64 = 0 610 if flipped == 1 { if cg_sha(ent, esha_after) == 1 { changed5 = (cg_hexeq(esha_before, esha_after) == 0) as i64 } } 611 gv_check("fixture-reached-T5: cached entry bytes were corrupted in place (size preserved, sha changed)" as *u8, changed5, ctr) 612 sys_unlinkat(cgp_fxs()) 613 rc = cg_build(subject, 0 as *u8, out, ol, ctr) 614 c = (rc == 0) as i64 615 gv_check("T5 corrupt entry: builder exit 0" as *u8, c, ctr); cg_show_on_fail(c, out, ol[0]) 616 gv_check("neg-control-T5: corrupt entry REFUSED -- MISS reason=sha-mismatch" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE MISS reason=sha-mismatch" as *u8), ctr) 617 gv_check("neg-control-T5: corrupt entry not served as a HIT" as *u8, (gk_out_has(out, ol[0], "BUILD-CACHE HIT" as *u8) == 0) as i64, ctr) 618 gv_check("T5 corrupt entry: compiler ran (.s present)" as *u8, gk_exists(cgp_fxs()), ctr) 619 gv_check("T5 corrupt entry: re-stored (BUILD-CACHE STORE)" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE STORE" as *u8), ctr) 620 var good5: i64 = 0 621 if cg_sha(cgp_fxelf(), shax) == 1 { good5 = cg_hexeq(sha1, shax) } 622 gv_check("T5 corrupt entry: delivered artifact is the CORRECT bytes (equal T1)" as *u8, good5, ctr) 623 var repaired5: i64 = 0 624 if cg_sha(ent, shax) == 1 { repaired5 = cg_hexeq(sha1, shax) } 625 gv_check("T5 corrupt entry: cache entry repaired to the correct bytes" as *u8, repaired5, ctr) 626 627 // ---- T6: sidecar absent -> MISS (not served), rebuilt, repopulated; then a HIT follows ---- 628 sys_unlinkat(side) 629 sys_unlinkat(cgp_fxs()) 630 rc = cg_build(subject, 0 as *u8, out, ol, ctr) 631 c = (rc == 0) as i64 632 gv_check("T6 sidecar absent: builder exit 0" as *u8, c, ctr); cg_show_on_fail(c, out, ol[0]) 633 gv_check("neg-control-T6: entry without sidecar is NOT served -- MISS reason=sidecar-absent" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE MISS reason=sidecar-absent" as *u8), ctr) 634 gv_check("T6 sidecar absent: compiler ran (.s present)" as *u8, gk_exists(cgp_fxs()), ctr) 635 gv_check("T6 sidecar absent: sidecar re-written" as *u8, gk_exists(side), ctr) 636 sys_unlinkat(cgp_fxs()) 637 rc = cg_build(subject, 0 as *u8, out, ol, ctr) 638 gv_check("T6 after repopulate: next rebuild HITS with zero compiler invocations" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE HIT" as *u8) * ((gk_exists(cgp_fxs()) == 0) as i64), ctr) 639 640 // ---- T7: kill switches -- conf row and lane flag both bypass the store, loudly ---- 641 gk_write(cgp_conf(), "cache_enabled=0\n" as *u8) 642 sys_unlinkat(cgp_fxs()) 643 rc = cg_build(subject, 0 as *u8, out, ol, ctr) 644 gv_check("T7 conf cache_enabled=0: MISS reason=disabled-by-conf and the compiler ran" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE MISS reason=disabled-by-conf" as *u8) * gk_exists(cgp_fxs()), ctr) 645 gk_write(cgp_conf(), "cache_enabled=1\n" as *u8) 646 sys_unlinkat(cgp_fxs()) 647 rc = cg_build(subject, "--no-cache" as *u8, out, ol, ctr) 648 gv_check("T7 --no-cache: MISS reason=disabled-by-flag and the compiler ran" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE MISS reason=disabled-by-flag" as *u8) * gk_exists(cgp_fxs()), ctr) 649 sys_unlinkat(cgp_fxs()) 650 rc = cg_build(subject, 0 as *u8, out, ol, ctr) 651 gv_check("T7 switches off again: plain rebuild HITS" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE HIT" as *u8) * ((gk_exists(cgp_fxs()) == 0) as i64), ctr) 652 653 // ---- T8: determinism -- two COLD builds (cache wiped) are byte-identical ---- 654 cg_clear_dir(cgp_cache()) 655 sys_unlinkat(cgp_fxs()) 656 rc = cg_build(subject, 0 as *u8, out, ol, ctr) 657 let sha_a: *u8 = sys_mmap(CG_SHA_HEX + 2) 658 let ha: i64 = cg_sha(cgp_fxelf(), sha_a) 659 gv_check("T8 cold build A: MISS (cache was wiped) and compiled" as *u8, gk_out_has(out, ol[0], "BUILD-CACHE MISS reason=no-entry" as *u8) * gk_exists(cgp_fxs()), ctr) 660 cg_clear_dir(cgp_cache()) 661 sys_unlinkat(cgp_fxs()) 662 rc = cg_build(subject, 0 as *u8, out, ol, ctr) 663 let sha_b: *u8 = sys_mmap(CG_SHA_HEX + 2) 664 let hb: i64 = cg_sha(cgp_fxelf(), sha_b) 665 var det: i64 = 0 666 if ha == 1 { if hb == 1 { det = cg_hexeq(sha_a, sha_b) } } 667 gv_check("T8 determinism: two cold builds are byte-identical" as *u8, det, ctr) 668 var det1: i64 = 0 669 if ha == 1 { det1 = cg_hexeq(sha_a, sha1) } 670 gv_check("T8 determinism: cold builds equal the T1 artifact (same source, same codegen)" as *u8, det1, ctr) 671 672 // ---- T9: store hygiene -- no tmp residue left behind ---- 673 gv_check("T9 store hygiene: no .tmp- residue in the cache dir" as *u8, (cg_count_suffix(cgp_cache(), ".tmp-casfx" as *u8) == 0) as i64, ctr) 674 675 gv_values_head() 676 gv_kv("t1_compiled_artifact_bytes" as *u8, t1size) 677 gv_kv("t10_delivered_after_hit_bytes" as *u8, gk_size(cgp_fxelf())) 678 gv_kv("cache_entries_at_end" as *u8, cg_count_suffix(cgp_cache(), ".sov.elf" as *u8)) 679 gv_kv("cache_sidecars_at_end" as *u8, cg_count_suffix(cgp_cache(), ".sha" as *u8)) 680 gv_kv("cache_tmp_residue_at_end" as *u8, cg_count_suffix(cgp_cache(), ".tmp-casfx" as *u8)) 681 return gv_verdict("nx_bld_cache_cas_gate" as *u8, ctr, "subject builder judged end to end in an isolated fixture tree" as *u8) 682}