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}