code wiki / _hdl_build / nx_bless_compiler.nx

nx_bless_compiler.nx source

↩ module page · 463 lines · 25135 B

1// nx_bless_compiler.nx -- TEAM-OWNED self-deploy for the sovereign compiler 2// (GAME arc G2, operator: "keep building the team to handle this 3// autonomously"). The whole win-win-win update gate from 4// [[project-pm-plan-maintainer-winwinwin-2026-06-05]] mechanized: 5// 6// 1. BUILD the candidate SOVEREIGNLY: current _offc compiler compiles 7// runtime/nx_compile_x86.nx (retry-guarded), nxasm_x86_main assembles. 8// nxasm crash/refusal -> REFUSE "BLOCKED-BY-G1" (today's state: the 9// 2.4MB-.s capacity segfault). NO gcc anywhere on this path. 10// 2. MEASURE: nx_game_gate runs twice -- candidate vs live _offc. 11// Verdict is DATA (fails counts), not opinion. 12// 3. BLESS only if candidate is STRICTLY better (fewer fails). The live 13// compiler is backed up to _offc/nx_cc_sovereign.elf.bak first. 14// 4. POST-VERIFY: gate the freshly blessed _offc; if it does not match the 15// candidate's measurement, ROLL BACK from the .bak and re-verify. 16// 5. The gate-loop daemon is STOPPED before measuring and RESTARTED after 17// (two concurrent gates corrupt each other's /tmp artifacts -- learned 18// live 2026-06-09). 19// 20// Exit: 0 blessed+verified, 1 refused (candidate not better), 2 blocked at 21// build (G1), 3 rolled back (post-verify mismatch), 4 internal error. 22// license_tier: ORIGINAL 23import "nx_pm_review_log.nx" 24import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 25import "nx_syscalls.nx" 26const BC_MAGIC_65536: i64 = 65536 27const BC_MAGIC_4095: i64 = 4095 28const BC_MAGIC_4096: i64 = 4096 29 30const BC_MIN_ASM_BYTES: i64 = 128 31const BC_MAX_RETRIES: i64 = 12 32 33func bc_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 34// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 35// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 36// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 37// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 38func bc_putn(v: i64) -> i64 { nxi_out(v); return 0 } 39func bc_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[off+i] = s[i]; i = i + 1 } return off + i } 40func bc_cat_n(dst: *u8, off: i64, v: i64) -> i64 { 41 var o: i64 = off 42 var m: i64 = v 43 if m < 0 { dst[o] = 45; o = o + 1; m = 0 - m } 44 let t: *u8 = sys_mmap(28) 45 var k: i64 = 0 46 if m == 0 { t[0] = 48; k = 1 } 47 while m > 0 { t[k] = 48 + (m % 10); m = m / 10; k = k + 1 } 48 var i: i64 = 0 49 while i < k { dst[o+i] = t[k-1-i]; i = i + 1 } 50 return o + k 51} 52 53func bc_run(path: *u8, argv: *i64, envp: *i64, redir_out: i64, redir_err: i64) -> i64 { 54 let pid: i64 = sys_fork() 55 if pid == 0 { 56 if redir_out >= 0 { sys_dup3(redir_out, 1, 0) } 57 if redir_err >= 0 { sys_dup3(redir_err, 2, 0) } 58 sys_execve(path, argv, envp) 59 sys_exit(127) 60 } 61 let st: *i64 = sys_mmap(16) as *i64 62 sys_wait4(pid, st, 0) 63 let sig: i64 = st[0] & 0x7f 64 if sig != 0 { return 128 + sig } 65 return (st[0] >> 8) & 0xff 66} 67 68func bc_run1(path: *u8, arg1: *u8, envp: *i64, devnull: i64) -> i64 { 69 let argv: *i64 = sys_mmap(32) as *i64 70 argv[0] = path as i64; argv[1] = arg1 as i64; argv[2] = 0 71 return bc_run(path, argv, envp, devnull, devnull) 72} 73 74func bc_filesize(path: *u8) -> i64 { 75 let fd: i64 = sys_openat_rd(path) 76 if fd < 0 { return 0 - 1 } 77 let buf: *u8 = sys_mmap(BC_MAGIC_65536) 78 var total: i64 = 0 79 var n: i64 = sys_read(fd, buf, BC_MAGIC_65536) 80 while n > 0 { total = total + n; n = sys_read(fd, buf, BC_MAGIC_65536) } 81 sys_close(fd) 82 return total 83} 84 85// copy src -> dst with mode 0755 (the dst is an executable tool) 86func bc_copy(src: *u8, dst: *u8) -> i64 { 87 let in_fd: i64 = sys_openat_rd(src) 88 if in_fd < 0 { return 0 - 1 } 89 let out_fd: i64 = sys_openat_wr(dst, 0x1ed) 90 if out_fd < 0 { sys_close(in_fd); return 0 - 1 } 91 let buf: *u8 = sys_mmap(BC_MAGIC_65536) 92 var n: i64 = sys_read(in_fd, buf, BC_MAGIC_65536) 93 while n > 0 { 94 sys_write(out_fd, buf, n) 95 n = sys_read(in_fd, buf, BC_MAGIC_65536) 96 } 97 sys_close(in_fd) 98 sys_close(out_fd) 99 return 0 100} 101 102func bc_read_pidfile(path: *u8) -> i64 { 103 let len_p: *i64 = sys_mmap(8) as *i64 104 let buf: *u8 = sys_read_file(path, len_p) 105 if (buf as i64) == 0 { return 0 - 1 } 106 let n: i64 = len_p[0] 107 var v: i64 = 0 108 var any: i64 = 0 109 var i: i64 = 0 110 while i < n { 111 let c: i64 = buf[i] as i64 112 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); any = 1 } } 113 i = i + 1 114 } 115 if any == 0 { return 0 - 1 } 116 return v 117} 118 119// substring search in buf[0,n) 120func bc_substr(buf: *u8, n: i64, needle: *u8) -> i64 { 121 var nl: i64 = 0 122 while needle[nl] != (0 as u8) { nl = nl + 1 } 123 if nl == 0 { return 1 } 124 var i: i64 = 0 125 while i + nl <= n { 126 var k: i64 = 0 127 var ok: i64 = 1 128 while k < nl { if buf[i+k] != needle[k] { ok = 0; k = nl } else { k = k + 1 } } 129 if ok == 1 { return 1 } 130 i = i + 1 131 } 132 return 0 133} 134 135// Index of the LAST occurrence of needle in buf[0,n); -1 if absent. 136func bc_find_last(buf: *u8, n: i64, needle: *u8) -> i64 { 137 var nl: i64 = 0 138 while needle[nl] != (0 as u8) { nl = nl + 1 } 139 var last: i64 = 0 - 1 140 var i: i64 = 0 141 while i + nl <= n { 142 var k: i64 = 0 143 var ok: i64 = 1 144 while k < nl { if buf[i+k] != needle[k] { ok = 0; k = nl } else { k = k + 1 } } 145 if ok == 1 { last = i } 146 i = i + 1 147 } 148 return last 149} 150 151// 1 iff the LAST line of the equiv log at `path` carries selfhost=1 + verdict=GREEN AND the run that 152// wrote it began at or after t0 (the epoch this bless recorded before invoking the gate). 153// FRESHNESS IS PART OF THE VERDICT (2026-09-15). Measured on the laptop: the gate anchors into 154// buildroot/ and writes buildroot/knowledge/status/cc_equiv_gate.log, while this reader opened 155// knowledge/status/cc_equiv_gate.log at the nxc2 root -- a Sep-4 fossil whose last line read 156// GREEN 10/10. The gate invocation itself had REFUSED to run (no challenger given), so this guard 157// would have blessed ANY candidate on a log nobody had written in eleven days. A verdict line older 158// than the bless that consults it is not evidence about this candidate; say so and refuse. 159func bc_equiv_green(path: *u8, t0: i64) -> i64 { 160 let fd: i64 = sys_openat_rd(path) 161 if fd < 0 { bc_puts("[bless] equiv log ABSENT at " as *u8); bc_puts(path); bc_puts(" -- no verdict to read\n" as *u8); return 0 } 162 let sz: i64 = sys_lseek(fd, 0, 2) 163 var off: i64 = 0 164 if sz > BC_MAGIC_4095 { off = sz - BC_MAGIC_4095 } 165 sys_lseek(fd, off, 0) 166 let buf: *u8 = sys_mmap(BC_MAGIC_4096) 167 var n: i64 = 0 168 var r: i64 = sys_read(fd, buf, BC_MAGIC_4095) 169 while r > 0 { n = n + r; if n >= BC_MAGIC_4095 { r = 0 } else { r = sys_read(fd, buf + n, BC_MAGIC_4095 - n) } } 170 sys_close(fd) 171 // the epoch of the run that wrote the tail: the LAST "CC-EQUIV epoch=<n>" line in the window 172 let ndl: *u8 = "CC-EQUIV epoch=" as *u8 173 var nlen: i64 = 0 174 while ndl[nlen] != (0 as u8) { nlen = nlen + 1 } 175 let ep: i64 = bc_find_last(buf, n, ndl) 176 var epoch: i64 = 0 - 1 177 if ep >= 0 { 178 epoch = 0 179 var q: i64 = ep + nlen 180 var go: i64 = 1 181 while go == 1 { 182 if q >= n { go = 0 } else { 183 let c: i64 = buf[q] as i64 184 if c >= 48 { if c <= 57 { epoch = epoch * 10 + (c - 48); q = q + 1 } else { go = 0 } } else { go = 0 } 185 } 186 } 187 } 188 bc_puts("[bless] equiv log=" as *u8); bc_puts(path); bc_puts(" last_epoch=" as *u8); bc_putn(epoch); bc_puts(" bless_t0=" as *u8); bc_putn(t0); bc_puts("\n" as *u8) 189 if epoch < t0 - 2 { bc_puts("[bless] equiv verdict is STALE (older than this bless) -- not evidence about this candidate\n" as *u8); return 0 } 190 var s: i64 = n 191 if s > 0 { if buf[s-1] == (10 as u8) { s = s - 1 } } 192 var ls: i64 = s 193 while ls > 0 { if buf[ls-1] == (10 as u8) { ls = 0 - ls } else { ls = ls - 1 } } 194 if ls < 0 { ls = 0 - ls } 195 let len: i64 = s - ls 196 if len <= 0 { return 0 } 197 if bc_substr(buf + ls, len, "selfhost=1" as *u8) == 1 { if bc_substr(buf + ls, len, "verdict=GREEN" as *u8) == 1 { return 1 } } 198 return 0 199} 200 201func main(argc: i64, argv: *i64) -> i64 { 202 // NEUTRAL mode (opt-in, argv[1]=="NEUTRAL"): bless a behavior-NEUTRAL capability fix (e.g. the 203 // flock syscall-map fix, X-SYSXLATE-FLOCK) on NO-REGRESSION (b_fails <= a_fails) instead of the 204 // default STRICTLY-better (b_fails < a_fails). Default (no arg) is UNCHANGED so the daemon's 205 // automatic bless still requires a genuine improvement. 206 var allow_equal: i64 = 0 207 if argc >= 2 { 208 let av: *u8 = argv[1] as *u8 209 if av[0] == (78 as u8) { if av[1] == (69 as u8) { if av[2] == (85 as u8) { allow_equal = 1 } } } 210 } 211 let envp: *i64 = sys_mmap(8*4) as *i64 212 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 213 let devnull: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 214 let live: *u8 = "_offc/nx_cc_sovereign.elf" as *u8 215 let bak: *u8 = "_offc/nx_cc_sovereign.elf.bak" as *u8 216 let cand_s: *u8 = "/tmp/nx_cc_candidate.s" as *u8 217 let cand: *u8 = "/tmp/nx_cc_candidate.elf" as *u8 218 var gate: *u8 = "/tmp/nx_game_gate.sov.elf" as *u8 219 220 // ---- 0. ROOT-LOCATE (2026-08-06) ---- 221 // Every path in this organ is relative to the BUILDROOT. It is now reachable through the tools 222 // daemon, which runs organs with CWD=nishihost -- one level ABOVE buildroot. From there 223 // _offc/nx_cc_sovereign.elf does not exist, the candidate compile execve-fails all 12 retries, and 224 // the organ reports "candidate compile produced no usable .s". That message names the CANDIDATE, 225 // so a wrong working directory reads as a compiler-source regression -- a diagnosis pointing at 226 // the wrong subsystem entirely. Locate the root explicitly and PRINT which one was chosen, so the 227 // root is never inferred from a downstream symptom. Fail-safe: if neither root has the compiler, 228 // abort before building or touching anything. 229 var root_is_cwd: i64 = 0 230 let probe0: i64 = sys_openat_rd(live) 231 if probe0 >= 0 { sys_close(probe0); root_is_cwd = 1; bc_puts("[bless] root=CWD (already buildroot)\n" as *u8) } 232 if probe0 < 0 { 233 let probe1: i64 = sys_openat_rd("buildroot/_offc/nx_cc_sovereign.elf" as *u8) 234 if probe1 < 0 { 235 bc_puts("[bless] ABORT: no _offc/nx_cc_sovereign.elf at CWD or ./buildroot -- wrong root; nothing built, nothing touched\n" as *u8) 236 return 4 237 } 238 sys_close(probe1) 239 sys_chdir("buildroot" as *u8) 240 bc_puts("[bless] root=./buildroot (chdir'd; organ was launched from the nishihost root)\n" as *u8) 241 } 242 // THE EQUIV GATE ANCHORS INTO buildroot/ ON ITS OWN (eq_anchor_root), so every path IT reads or writes 243 // is buildroot-relative whichever root THIS organ chose. From root=CWD (a tree that itself contains a 244 // buildroot/ twin -- the laptop nxc2 layout) the log we must read and the challenger we must stage both 245 // carry a `buildroot/` prefix; from the chdir'd root the prefix is empty. Derive both paths ONCE here 246 // so the reader and the stager cannot disagree (2026-09-15: they did, and the disagreement read as a 247 // GREEN verdict). 248 let eqlog: *u8 = sys_mmap(256) 249 var eo: i64 = 0 250 if root_is_cwd == 1 { eo = bc_cat(eqlog, eo, "buildroot/" as *u8) } 251 eo = bc_cat(eqlog, eo, "knowledge/status/cc_equiv_gate.log" as *u8) 252 eqlog[eo] = 0 as u8 253 let chal_stage: *u8 = sys_mmap(256) 254 var co: i64 = 0 255 if root_is_cwd == 1 { co = bc_cat(chal_stage, co, "buildroot/" as *u8) } 256 co = bc_cat(chal_stage, co, "_build/cc_challenger.elf" as *u8) 257 chal_stage[co] = 0 as u8 258 259 // ---- 0b. GATE-VACUITY GUARD (2026-08-06) ---- 260 // bc_run returns 127 when execve FAILS -- that is not a fail COUNT. With no gate binary on disk 261 // BOTH measurements come back 127, NEUTRAL mode reads 127==127 as "no regression", and the 262 // post-verify then compares 127 to 127 and confirms it. Two of the three teeth go vacuous together 263 // and silently, leaving cc_equiv as the only real one while the log still reads BLESSED+VERIFIED. 264 // OBSERVED LIVE 2026-08-06: /tmp/nx_game_gate.sov.elf did not exist and the organ reported 265 // "candidate fails=127 live fails=127" as though it had measured something. 266 // A gate that could not RUN is not a gate that AGREED. Resolve it explicitly, print which binary 267 // was chosen, and REFUSE when there is none: absence of evidence must never be recorded as 268 // evidence of equivalence. 269 var gate_ok: i64 = 0 270 let g0: i64 = sys_openat_rd(gate) 271 if g0 >= 0 { sys_close(g0); gate_ok = 1 } 272 if gate_ok == 0 { 273 let g1: i64 = sys_openat_rd("../nx_game_gate.elf" as *u8) 274 if g1 >= 0 { sys_close(g1); gate = "../nx_game_gate.elf" as *u8; gate_ok = 1 } 275 } 276 if gate_ok == 0 { 277 let g2: i64 = sys_openat_rd("./nx_game_gate.elf" as *u8) 278 if g2 >= 0 { sys_close(g2); gate = "./nx_game_gate.elf" as *u8; gate_ok = 1 } 279 } 280 if gate_ok == 0 { 281 // the sovereign builder's own output slot (`nx_sov_build_run nx_game_gate --build-only`) -- the 282 // path a node that has no promoted twin can produce without copying anything (2026-09-15) 283 let g3: i64 = sys_openat_rd("_build/nx_game_gate.sov.elf" as *u8) 284 if g3 >= 0 { sys_close(g3); gate = "_build/nx_game_gate.sov.elf" as *u8; gate_ok = 1 } 285 } 286 if gate_ok == 0 { 287 bc_puts("[bless] ABORT: no runnable nx_game_gate at /tmp/nx_game_gate.sov.elf, ../nx_game_gate.elf, ./nx_game_gate.elf or _build/nx_game_gate.sov.elf -- the measurement would be vacuous (both sides 127); nothing built, nothing touched\n" as *u8) 288 return 5 289 } 290 bc_puts("[bless] gate=" as *u8); bc_puts(gate); bc_puts("\n" as *u8) 291 292 // ---- 1. sovereign build of the candidate ---- 293 bc_puts("[bless] building candidate: " as *u8); bc_puts(live); bc_puts(" -> nx_compile_x86.nx -> nxasm\n" as *u8) 294 var asmbytes: i64 = 0 295 var tries: i64 = 0 296 while tries < BC_MAX_RETRIES { 297 let sfd: i64 = sys_openat_wr(cand_s, 0x1a4) 298 let cc: *i64 = sys_mmap(8*4) as *i64 299 cc[0] = live as i64; cc[1] = "runtime/nx_compile_x86.nx" as *u8 as i64; cc[2] = 0 300 let rc_c: i64 = bc_run(live, cc, envp, sfd, devnull) 301 sys_close(sfd) 302 asmbytes = bc_filesize(cand_s) 303 if rc_c == 0 { if asmbytes > BC_MIN_ASM_BYTES { tries = BC_MAX_RETRIES } } 304 if tries != BC_MAX_RETRIES { tries = tries + 1 } 305 } 306 if asmbytes <= BC_MIN_ASM_BYTES { 307 bc_puts("[bless] REFUSED: candidate compile produced no usable .s\n" as *u8) 308 return 2 309 } 310 let asm_tool: *u8 = "_offc/nxasm_x86_main.elf" as *u8 311 let aa: *i64 = sys_mmap(8*4) as *i64 312 aa[0] = asm_tool as i64; aa[1] = cand_s as i64; aa[2] = cand as i64; aa[3] = 0 313 let rc_a: i64 = bc_run(asm_tool, aa, envp, devnull, devnull) 314 if rc_a != 0 { 315 bc_puts("[bless] REFUSED: BLOCKED-BY-G1 -- nxasm rc=" as *u8); bc_putn(rc_a) 316 bc_puts(" on the " as *u8); bc_putn(asmbytes) 317 bc_puts("B candidate .s (capacity bug; see GAME arc G1). _offc UNTOUCHED.\n" as *u8) 318 let pm: i64 = pm_open("/tmp/nishi_pm_review.log" as *u8) 319 pm_gap(pm, "toolchain/x86" as *u8, "BLOCKED" as *u8, "compiler self-deploy blocked by G1" as *u8, "nx_bless_compiler: candidate .s built fine but nxasm failed (capacity/encoding); the parser-fixed compiler still cannot be sovereignly blessed; fix GAME-G1 then re-run nx_bless_compiler" as *u8) 320 sys_close(pm) 321 return 2 322 } 323 324 // ---- 1b. pause the gate-loop daemon (concurrent gates corrupt artifacts) ---- 325 let loop_pid: i64 = bc_read_pidfile("/tmp/nishi_game_gate_loop.pid" as *u8) 326 if loop_pid > 0 { 327 nx_kill(loop_pid, 15) 328 bc_puts("[bless] paused gate-loop daemon pid=" as *u8); bc_putn(loop_pid); bc_puts("\n" as *u8) 329 } 330 331 // ---- 2. measure: candidate vs live ---- 332 let b_fails: i64 = bc_run1(gate, cand, envp, devnull) 333 let a_fails: i64 = bc_run1(gate, 0 as *u8, envp, devnull) 334 bc_puts("[bless] gate: candidate fails=" as *u8); bc_putn(b_fails) 335 bc_puts(" live fails=" as *u8); bc_putn(a_fails); bc_puts("\n" as *u8) 336 337 // 127 is bc_run's execve-FAILURE code, not a fail count. If either side reports it, the comparison 338 // is between two non-runs and equality there means nothing. Refuse rather than bless on it -- this 339 // is the second half of the 0b guard, covering a gate binary that EXISTS but cannot execute 340 // (wrong arch, truncated stage, lost +x) which a file-presence probe alone would pass. 341 if b_fails == 127 { 342 bc_puts("[bless] ABORT: gate did not RUN for the candidate (127) -- measurement vacuous; _offc UNTOUCHED\n" as *u8) 343 return 5 344 } 345 if a_fails == 127 { 346 bc_puts("[bless] ABORT: gate did not RUN for live (127) -- measurement vacuous; _offc UNTOUCHED\n" as *u8) 347 return 5 348 } 349 350 var verdict: i64 = 4 351 var should_bless: i64 = 0 352 if b_fails < a_fails { should_bless = 1 } 353 if allow_equal == 1 { if b_fails == a_fails { should_bless = 1 } } 354 if allow_equal == 1 { bc_puts("[bless] NEUTRAL mode: blessing on NO-REGRESSION (b_fails <= a_fails)\n" as *u8) } 355 if should_bless == 1 { 356 // ---- 2b. PRE-DEPLOY EQUIV GUARD (runs ONLY when a bless is imminent, so it never slows a 357 // refused attempt): the candidate must be byte-behavior-equivalent to the baseline on the 358 // corpus AND self-host -- this catches the deref-cast / gen3 regression CLASS that 359 // nx_game_gate cannot. Point the equiv-gate's default challenger (/tmp/cc_challenger.elf) at 360 // our candidate, run it, require GREEN; a RED REFUSES the bless so a regressing compiler can 361 // never go live. (Folds in nx_cc_promote's equiv validation -> nx_cc_promote can retire.) ---- 362 // THE CHALLENGER MUST LAND WHERE IT CAN BE EXECUTED (2026-08-06). 363 // This used to stage the candidate at /tmp/cc_challenger.elf and let the gate pick it up by 364 // DEFAULT. NAS /tmp is mounted noexec, so the gate could never exec the challenger: every row 365 // came back build_b=1 eb=-1, the summary read verdict=RED, and this guard then reported 366 // "cc_equiv NOT GREEN -- deref-cast/gen3 guard" -- accusing the COMPILER SOURCE of a 367 // miscompile when the actual fault was a mount option. That is the same wrong-subsystem 368 // diagnosis this organ already made once at the working directory. 369 // PROVEN BY CONTROLLED EXPERIMENT, not inferred: the SAME BYTES (sha 71424493..., 635099B) 370 // scored RED as /tmp/cc_challenger.elf and GREEN as ../nx_compile_x86.sov.elf.new. Identical 371 // bytes, different path, opposite verdict -- so the location was the whole cause. 372 // Stage beside the other sovereign ELFs and pass the path to the gate EXPLICITLY rather than 373 // relying on a default that is unreachable on this host. 374 // 2026-09-15: stage the candidate where the GATE resolves it after ITS OWN anchor (chal_stage, derived 375 // beside eqlog at root-locate) and hand the gate the buildroot-relative path. The gate prints 376 // challenger_bytes, so the identity of the binary it judged is checkable against the size printed here. 377 bc_copy(cand, chal_stage) 378 let chal: *u8 = "_build/cc_challenger.elf" as *u8 379 bc_puts("[bless] cc_equiv: challenger staged at " as *u8); bc_puts(chal_stage); bc_puts(" bytes=" as *u8); bc_putn(bc_filesize(chal_stage)); bc_puts("\n" as *u8) 380 // the epoch BEFORE the gate runs: the verdict reader refuses any log line older than this 381 let t0: i64 = sys_now_realtime_sec() 382 var eq_ran: i64 = 0 383 let eg: *i64 = sys_mmap(8*4) as *i64 384 // Gate binary, in order: the promoted twin one level up (chdir'd root: the nishihost serving root), 385 // the promoted twin at this root, then a SOURCE BUILD through the sovereign builder (--build-only, 386 // so it deploys nothing) at _build/. The old legacy leg ran the builder WITHOUT a challenger and the 387 // gate has refused a missing challenger since 2026-08-14, so that leg could never pass -- and its 388 // refusal was then read from a stale log as GREEN. 389 var gbin: *u8 = "../nx_cc_equiv_gate.elf" as *u8 390 var gok: i64 = 0 391 if root_is_cwd == 0 { let e0: i64 = sys_openat_rd(gbin); if e0 >= 0 { sys_close(e0); gok = 1 } } 392 if gok == 0 { gbin = "./nx_cc_equiv_gate.elf" as *u8; let e1: i64 = sys_openat_rd(gbin); if e1 >= 0 { sys_close(e1); gok = 1 } } 393 if gok == 0 { 394 let bb: *i64 = sys_mmap(8*4) as *i64 395 bb[0] = "./_offc/nx_sov_build_run.elf" as *u8 as i64; bb[1] = "nx_cc_equiv_gate" as *u8 as i64; bb[2] = "--build-only" as *u8 as i64; bb[3] = 0 396 bc_run("./_offc/nx_sov_build_run.elf" as *u8, bb, envp, devnull, devnull) 397 gbin = "_build/nx_cc_equiv_gate.sov.elf" as *u8 398 let e2: i64 = sys_openat_rd(gbin); if e2 >= 0 { sys_close(e2); gok = 1 } 399 bc_puts("[bless] cc_equiv: no promoted gate twin -- source-built via the sovereign builder (--build-only)\n" as *u8) 400 } 401 if gok == 1 { 402 eg[0] = gbin as i64; eg[1] = chal as i64; eg[2] = 0 403 bc_run(gbin, eg, envp, devnull, devnull) 404 eq_ran = 1 405 bc_puts("[bless] cc_equiv: gate=" as *u8); bc_puts(gbin); bc_puts(" challenger=" as *u8); bc_puts(chal); bc_puts("\n" as *u8) 406 } 407 if eq_ran == 0 { bc_puts("[bless] cc_equiv: NO GATE BINARY could be resolved or built -- the guard cannot run; this is a REFUSAL, not a pass\n" as *u8) } 408 let eq_green: i64 = bc_equiv_green(eqlog, t0) 409 bc_puts("[bless] cc_equiv guard (corpus+self-host) green=" as *u8); bc_putn(eq_green); bc_puts("\n" as *u8) 410 if eq_green == 0 { 411 bc_puts("[bless] REFUSED: cc_equiv NOT GREEN -- deref-cast/gen3 guard; _offc UNTOUCHED\n" as *u8) 412 let pmq: i64 = pm_open("/tmp/nishi_pm_review.log" as *u8) 413 pm_gap(pmq, "toolchain/x86" as *u8, "BLOCKED" as *u8, "bless equiv-guard RED" as *u8, "nx_bless_compiler: candidate failed nx_cc_equiv_gate (corpus/self-host differential) -> refused to bless; investigate the compiler-source regression before re-bless" as *u8) 414 sys_close(pmq) 415 verdict = 2 416 } 417 if eq_green == 1 { 418 // ---- 3. bless with backup ---- 419 let rc_bak: i64 = bc_copy(live, bak) 420 if rc_bak < 0 { bc_puts("[bless] ERROR: backup copy failed; ABORT (no bless)\n" as *u8); verdict = 4 } 421 if rc_bak >= 0 { 422 let rc_bls: i64 = bc_copy(cand, live) 423 if rc_bls < 0 { bc_puts("[bless] ERROR: bless copy failed\n" as *u8); verdict = 4 } 424 if rc_bls >= 0 { 425 // ---- 4. post-verify the blessed live tool ---- 426 let c_fails: i64 = bc_run1(gate, 0 as *u8, envp, devnull) 427 bc_puts("[bless] post-verify: blessed-live fails=" as *u8); bc_putn(c_fails) 428 bc_puts(" (need ==" as *u8); bc_putn(b_fails); bc_puts(")\n" as *u8) 429 if c_fails == b_fails { 430 bc_puts("[bless] BLESSED + VERIFIED\n" as *u8) 431 let pm2: i64 = pm_open("/tmp/nishi_pm_review.log" as *u8) 432 pm_deliverable(pm2, "toolchain/x86" as *u8, "compiler-blessed" as *u8, "nx_bless_compiler: candidate gated strictly better than live, blessed to _offc/nx_cc_sovereign.elf (backup at .bak), post-verify matched; GAME-G2 satisfied by the team" as *u8) 433 sys_close(pm2) 434 verdict = 0 435 } 436 if c_fails != b_fails { 437 bc_copy(bak, live) 438 let r_fails: i64 = bc_run1(gate, 0 as *u8, envp, devnull) 439 bc_puts("[bless] POST-VERIFY MISMATCH -> ROLLED BACK; live fails now=" as *u8); bc_putn(r_fails); bc_puts("\n" as *u8) 440 let pm3: i64 = pm_open("/tmp/nishi_pm_review.log" as *u8) 441 pm_gap(pm3, "toolchain/x86" as *u8, "NEEDS-FIX" as *u8, "bless post-verify mismatch" as *u8, "nx_bless_compiler: blessed tool gated differently than the candidate binary (nondeterminism or copy fault); ROLLED BACK from .bak; investigate before re-bless" as *u8) 442 sys_close(pm3) 443 verdict = 3 444 } 445 } 446 } 447 } 448 } 449 if should_bless == 0 { 450 bc_puts("[bless] REFUSED: candidate not better (neutral mode allows ==); _offc UNTOUCHED\n" as *u8) 451 verdict = 1 452 } 453 454 // ---- 5. restart the gate-loop daemon ---- 455 let loop_elf: *u8 = "/tmp/nx_gate_loop.sov.elf" as *u8 456 let chk: i64 = sys_openat_rd(loop_elf) 457 if chk >= 0 { 458 sys_close(chk) 459 bc_run1(loop_elf, 0 as *u8, envp, devnull) 460 bc_puts("[bless] gate-loop daemon restarted\n" as *u8) 461 } 462 return verdict 463}