code wiki / (root) / nx_cc_equiv_gate.nx

nx_cc_equiv_gate.nx

buildroot/runtime/nx_cc_equiv_gate.nx

35165 B675 linesdepth 3pulls 3 transitivereach 0 importersview sourcekind gate/prooftopic cc
docsdependenciesstructsconstsfunctions

about

nx_cc_equiv_gate.nx -- COMPILER DIFFERENTIAL-BEHAVIOR ORACLE: miscompile-detection for the sovereign toolchain (EMI-style baseline-vs-challenger build + stdout byte-equal + self-host stage). Team organ (Engineer-owned) born from the dom/licm dormant-paths discovery (ledger T#opt-dom-licm-dormant-paths, 2026-06-10): the deref-cast precedence bug had silently disabled 4 optimizer reads since they were written, and AWAKENING them broke the self-host at generation 3 -- a class of defect no single-binary test catches. This gate judges ANY compiler mutation by BEHAVIOR, not by asm: For each corpus row (deterministic, network-free modules): build with BASELINE cc -> run -> raw wait4 status + stdout bytes build with CHALLENGER cc -> run -> same row PASS iff both build, statuses EQUAL, stdout BYTE-EQUAL. (Different codegen/hoisting is fine; different BEHAVIOR is not.) SELF-HOST stage (the gen3-class catch): challenger compiles runtime/nx_compile_x86.nx -> gen2 binary; gen2 must then compile a probe module whose binary runs exit 0. This is exactly where the awakened-LICM breakage surfaced (gen3: "unknown type name 'nx_size'"). Usage: nx_cc_equiv_gate <challenger_elf> [feature_source.nx] challenger: REQUIRED (a stale default once produced ten confident FAIL rows about a leftover). baseline: _offc/nx_cc_sovereign.elf (the LIVE toolchain) unless knowledge/cc_equiv_baseline.conf names another compiler on its first line. A node names the HUB's promoted compiler there (pulled through nx_content_get, digest-verified) so a candidate that ADDS a language feature can still be judged DIFFERENTIALLY against a baseline that builds the whole corpus (2026-09-15: __size_of on struct types left 5 of 10 rows unbuildable by the live laptop compiler, and "both sides must build" could never pass any capability-adding release -- loosening the rule was the only other exit, and it is the wrong one). ⚠PATHS ARE RESOLVED AFTER THE BUILDROOT ANCHOR: from nxc2/ a relative `_build/x.elf` means buildroot/_build/x.elf. Measured 2026-09-15: a relative challenger path silently named a Sep-4 fossil in buildroot/_build instead of the candidate in nxc2/_build, and the gate printed the caller's path as if it were that binary. Pass an ABSOLUTE path; the gate prints the byte size of every compiler it will exec so the identity is checkable, and refuses a challenger byte-identical to the baseline (a self-comparison measures nothing). Run with CWD=nxc2/ or nishihost/ (it anchors into buildroot/). Exit 0 iff all rows + self-host PASS. Verdicts stream to stdout AND append to the durable log knowledge/status/cc_equiv_gate.log (Archivist rule).

dependencies 2 imports · 0 importers

nx_syscalls.nx nx_gate_verdict.nx nx_cc_equiv_gate.nx

imports: nx_syscalls.nxnx_gate_verdict.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sys_ignore_sigpipe sys_mmap nxa_die sys_write sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ eq_anchor_root sys_openat_rd sys_close sys_chdir sys_mmap ↻ sys_mmap ↻ sys_openat_wr sys_mkdir sys_openat_append eq_puts2 sys_write ↻ sys_exit ↻ eq_putn2 sys_mmap ↻ sys_write ↻ sys_now_realtime_sec sys_mmap ↻ sys_clock_gettime_real eq_probe sys_openat_rd ↻ eq_puts2 ↻ sys_close ↻ sys_openat_rd ↻

structs

none

consts

49const EQ_ROWS: i64 = 10
51const EQ_CONF_CAP: i64 = 4096

functions

54func eq_first_line(buf: *u8, n: i64) -> i64
called by 1: main
65func eq_puts2(logfd: i64, s: *u8) -> i64
called by 2: eq_probemain calls 1: sys_write
73func eq_putn2(logfd: i64, v: i64) -> i64
called by 1: main calls 2: sys_mmapsys_write
91func eq_cat(dst: *u8, off: i64, s: *u8) -> i64
called by 2: eq_uniqmain
98func eq_catn(dst: *u8, off: i64, v: i64) -> i64
called by 1: eq_uniq calls 1: sys_mmap
117func eq_uniq(pre: *u8, nonce: i64, suf: *u8) -> *u8
called by 1: main calls 3: sys_mmapeq_cateq_catn
128func eq_nonce() -> i64
144func eq_run(path: *u8, argv: *i64, envp: *i64, redir_out: i64, redir_err: i64) -> i64
160func eq_fsize(path: *u8) -> i64
177func eq_build(cc_path: *u8, src_path: *u8, s_tmp: *u8, o_tmp: *u8,
214func eq_run_capture(elf: *u8, out_path: *u8, envp: *i64, devnull: i64) -> i64
224func eq_files_equal(pa: *u8, pb: *u8) -> i64
257func eq_probe(logfd: i64, tag: *u8, path: *u8) -> i64
called by 1: main calls 3: sys_openat_rdeq_puts2sys_close
266func eq_anchor_root() -> i64
273func main(argc: i64, argv: *i64) -> i64