code wiki / _hdl_build / nx_aritycheck_gate.nx

nx_aritycheck_gate.nx

buildroot/runtime/_hdl_build/nx_aritycheck_gate.nx

28906 B542 linesdepth 2pulls 2 transitivereach 0 importersview sourcekind gate/proof
docsdependenciesstructsconstsfunctions

about

nx_aritycheck_gate.nx -- THE ARITY CENSUS: report every CALL SITE whose argument count disagrees with the definition its own directory resolves. The axis nothing currently measures. WHY THIS EXISTS (measured 2026-07-31, lib-reconcile). nx_cc is fails-open on arity: seq1012 shows undefined identifiers compile clean and 1785447657 shows duplicate definitions compile clean with zero diagnostics. nx_undefscan closes the "called but never DEFINED" axis and is the right tool for it -- but it reports VERDICT=CLEAN on nx_input_abstract_gate, which passes ONE argument to a TWO-parameter ia_init at eight sites, because ia_init IS defined in the closure. The target also compiles. So nx_cc says fine, undefscan says CLEAN, the artifact exists, and the call is still wrong. ★★★★★CLEAN + BUILDS != CORRECT WHEN NO INSTRUMENT MEASURES THE AXIS THE DEFECT LIVES ON. SCOPE, stated so a caller never has to guess: ONE DIRECTORY. An import binds the importer's OWN directory first (proven from compiler output at buildroot/_build/nx_f32_llm_serve.s:2511), so the definitions visible to a file are, to first order, the ones beside it. That makes a per-directory census sound for the common case and DELIBERATELY BLIND to cross-layer resolution -- which is reported as UNKNOWN-NAME rather than silently ignored, because a name this organ cannot see is not a name it may bless. KNOWN FALSE POSITIVES, bounded and declared (the nx_undefscan doctrine, inherited on purpose): - a call through a FUNCTION-POINTER VARIABLE looks like a call to a name it cannot resolve - a name that is BOTH a local variable and a function elsewhere in the dir Both are bounded by the POSITIVE CONTROL: nx_m2d_engine calls ia_init(ia, 5) correctly in the SAME directory against the SAME definition and MUST report zero. A checker that flagged everything fails it. ⚠STATUS 2026-07-31: DESK-CHECKED, NEVER COMPILED. Authored while /mcp was wedged, so it has not been through nx_cc or its own selftest even once. Do NOT treat "reviewed" as "works" -- that is the exact confusion this organ exists to remove. WHAT THE SELFTEST MUST PRINT on a first good build: defs collected >= 3 (two_p=2, bad_caller=0, inner=2, good_caller=0) EXACTLY 1 arity mismatch: bad.nx two_p called with 1 arg(s), defined with 2 0 conflicting duplicates in /tmp/nxarity, and EXACTLY 1 in /tmp/nxarity2 If it reports 2 mismatches, ac_args lost its depth-awareness and counted the comma inside inner(1, 9); if it reports 0, ac_find or ac_is_def_at is failing to see the definition at all. Both failure modes are distinguishable from the message alone, on purpose. FIRST REAL TARGET once built: buildroot/runtime/_hdl_build -- it must reproduce the 8 ia_init mismatches in nx_input_abstract_gate (pre-move) and report ZERO for nx_m2d_engine. license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 when clean

dependencies 1 imports · 0 importers

nx_syscalls.nx nx_aritycheck_gate.nx

imports: nx_syscalls.nx

imported by: nobody (leaf or entry point)

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

main ac_w sys_write ac_slen ac_selftest sys_mkdir ac_wfile sys_openat_wr sys_write ↻ ac_slen ↻ sys_close sys_mmap ac_scan_dir sys_mmap ↻ sys_openat_rd sys_getdents64 dirent_name dirent_type ac_ends_nx ac_slen ↻ ac_join ac_slurp sys_openat_rd ↻ sys_read sys_close ↻ ac_collect ac_is_def_at ac_isidc ac_isidst ac_params ac_find ac_slot ac_slot ↻ ac_w ↻ ac_wb sys_write ↻ ac_wn sys_mmap ↻ sys_write ↻ dirent_reclen

structs

none

consts

39const AC_MAXDEF: i64 = 4096 // distinct function names per directory
40const AC_NAMELEN: i64 = 64 // bytes per name slot
41const AC_FILECAP: i64 = 1048576 // 1MiB per source; over-cap is UNKNOWN, never "clean"
42const AC_DIRBUF: i64 = 131072
43const AC_PATHCAP: i64 = 4096
44const AC_STDOUT: i64 = 1

functions

47func ac_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
48func ac_w(s: *u8) -> i64 { sys_write(AC_STDOUT, s, ac_slen(s)); return 0 }
49func ac_wn(v: i64) -> i64
62func ac_wb(p: *u8, n: i64) -> i64 { sys_write(AC_STDOUT, p, n); return 0 }
called by 2: ac_collectac_check calls 1: sys_write
65func ac_isidst(c: i64) -> i64
called by 2: ac_isidcac_check
71func ac_isidc(c: i64) -> i64
called by 2: ac_collectac_check calls 1: ac_isidst
78func ac_slurp(path: *u8, buf: *u8, cap: i64) -> i64
93func ac_slot(names: *u8, i: i64) -> *u8 { return ((names as i64) + i * AC_NAMELEN) as *u8 }
called by 2: ac_findac_collect
95func ac_find(names: *u8, n: i64, p: *u8, plen: i64) -> i64
called by 2: ac_collectac_check calls 1: ac_slot
111func ac_params(buf: *u8, n: i64, at: i64) -> i64
called by 1: ac_collect
145func ac_args(buf: *u8, n: i64, op: i64) -> i64
called by 1: ac_check
179func ac_is_def_at(buf: *u8, n: i64, i: i64) -> i64
called by 2: ac_collectac_check
208func ac_collect(buf: *u8, n: i64, names: *u8, arity: *i64, dcount: *i64, fseen: *i64, fileid: i64, cnt: i64, dup: *i64, fname: *u8) -> i64
268func ac_check(buf: *u8, n: i64, names: *u8, arity: *i64, dcount: *i64, cnt: i64, fname: *u8, amb: *i64) -> i64
345func ac_ends_nx(nm: *u8) -> i64
called by 1: ac_scan_dir calls 1: ac_slen
354func ac_join(out: *u8, dir: *u8, name: *u8) -> i64
called by 1: ac_scan_dir
369func ac_scan_dir(dir: *u8, stats: *i64) -> i64
432func ac_wfile(path: *u8, s: *u8) -> i64
439func ac_selftest() -> i64
478func main(argc: i64, argv: *i64) -> i64
515func ac_retired_corpus_scan(argc: i64, argv: *i64) -> i64