code wiki / _hdl_build / nx_aritycheck_gate.nx
nx_aritycheck_gate.nx
buildroot/runtime/_hdl_build/nx_aritycheck_gate.nx
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
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
structs
| none |
consts
| 39 | const AC_MAXDEF: i64 = 4096 // distinct function names per directory |
| 40 | const AC_NAMELEN: i64 = 64 // bytes per name slot |
| 41 | const AC_FILECAP: i64 = 1048576 // 1MiB per source; over-cap is UNKNOWN, never "clean" |
| 42 | const AC_DIRBUF: i64 = 131072 |
| 43 | const AC_PATHCAP: i64 = 4096 |
| 44 | const AC_STDOUT: i64 = 1 |
functions
| 47 | func ac_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 48 | func ac_w(s: *u8) -> i64 { sys_write(AC_STDOUT, s, ac_slen(s)); return 0 } |
| 49 | func ac_wn(v: i64) -> i64 |
| 62 | func ac_wb(p: *u8, n: i64) -> i64 { sys_write(AC_STDOUT, p, n); return 0 } |
| 65 | func ac_isidst(c: i64) -> i64 |
| 71 | func ac_isidc(c: i64) -> i64 |
| 78 | func ac_slurp(path: *u8, buf: *u8, cap: i64) -> i64 |
| 93 | func ac_slot(names: *u8, i: i64) -> *u8 { return ((names as i64) + i * AC_NAMELEN) as *u8 } |
| 95 | func ac_find(names: *u8, n: i64, p: *u8, plen: i64) -> i64 |
| 111 | func ac_params(buf: *u8, n: i64, at: i64) -> i64 called by 1: ac_collect |
| 145 | func ac_args(buf: *u8, n: i64, op: i64) -> i64 called by 1: ac_check |
| 179 | func ac_is_def_at(buf: *u8, n: i64, i: i64) -> i64 |
| 208 | func ac_collect(buf: *u8, n: i64, names: *u8, arity: *i64, dcount: *i64, fseen: *i64, fileid: i64, cnt: i64, dup: *i64, fname: *u8) -> i64 |
| 268 | func ac_check(buf: *u8, n: i64, names: *u8, arity: *i64, dcount: *i64, cnt: i64, fname: *u8, amb: *i64) -> i64 |
| 345 | func ac_ends_nx(nm: *u8) -> i64 |
| 354 | func ac_join(out: *u8, dir: *u8, name: *u8) -> i64 called by 1: ac_scan_dir |
| 369 | func ac_scan_dir(dir: *u8, stats: *i64) -> i64 called by 2: ac_selftestac_retired_corpus_scan calls 12: sys_mmapsys_openat_rdsys_getdents64dirent_namedirent_typeac_ends_nx+6 |
| 432 | func ac_wfile(path: *u8, s: *u8) -> i64 |
| 439 | func ac_selftest() -> i64 |
| 478 | func main(argc: i64, argv: *i64) -> i64 |
| 515 | func ac_retired_corpus_scan(argc: i64, argv: *i64) -> i64 |