code wiki / _hdl_build / nx_toolhealth.nx
nx_toolhealth.nx
buildroot/runtime/_hdl_build/nx_toolhealth.nx
about
nx_toolhealth.nx -- FOUNDATION CENSUS over the REGISTERED-TOOL POPULATION (lane D, 2026-08-20).
The operator named three symptoms in one sentence -- "broken tools and duplicate tools and things like
the research only are half capable" -- and the estate counted them in separate censuses that never
adjudicated as ONE foundation. This organ measures the two that had no instrument at all, over EVERY
row of tool_allowlist.conf (the GREEN execution allowlist == the registered-tool registry), dedupes
REFERENCES to SUBJECTS, and prints a partition that must SUM.
BROKEN, per SUBJECT, one class each and the four sum to the subject count:
PHANTOM no elf anywhere AND no .nx -- the CALLER must be fixed or deleted; it can never
be built, and hiding it in a build queue guarantees the queue never finishes.
MISSING-BUILDABLE no elf, source exists -- a build.
BINARY-NO-SOURCE elf present, no .nx -- often code that SHIPS INSIDE ANOTHER ARTIFACT. Its own
bucket on purpose: a stat-based catalogue reads this as "build it", which is a
harmful work order, so it is NEVER folded into MISSING-BUILDABLE.
OK elf and source both present.
UNREACHABLE is a SEPARATE AXIS, never a partition member -- a subject can be OK and non-GREEN at
once, so folding it in would silently break the reconciliation. COUNT ONLY (lane A owns the repair).
HALF-CAPABLE: a verb DECLARED in the SERVED call grammar with no dispatch branch in the source. The
served grammar is resolved exactly as nx_tools_api resolves it -- authored tool_schemas.conf col8
first, derived tool_grammar.conf second -- so this measures the contract an AGENT actually reads.
HOW A VERB IS JUDGED IMPLEMENTED: its name appears in the source as a QUOTED STRING LITERAL (the
byte sequence quote-verb-quote). That is what every dispatch in this estate compiles to, and a usage
line -- which is a COMMENT, or a single long "usage: a | b" literal -- can never satisfy it.
THE DETECTOR IS DELIBERATELY WRONG IN THE DIRECTION OF NOT ACCUSING. Four abstentions, each its own
bucket, because a false positive teaches everyone to ignore the detector:
PINNED the allowlist row carries a 4th column, so the registry supplies argv and the caller's is
DISCARDED. Its grammar names no callable verb; it can have no dead verb by construction.
NO-GRAMMAR neither grammar file has a row -- an agent has NO contract to read. A real gap, listed.
POSITIONAL-ONLY a contract exists and declares no VERB. NOT a defect -- and NOT the same bucket
as NO-GRAMMAR, whose remedy is the opposite. Merging them read 618 of 959.
(this bullet is indented FOUR spaces on purpose: at 2-3 spaces the grammar harvester
reads a comment carrying < or [ as a USAGE LINE, so this very explanation became this
organ's declared call grammar and the census then accused ITSELF of a dead verb named
POSITIONAL-ONLY. A TOOL WHOSE INPUT IS ITS OWN DOCUMENTATION MUST OBEY THE DOCUMENT
CONVENTION IT MEASURES -- caught by the ratchet, not by review.)
UNDECIDABLE the grammar declares 2+ verbs and NOT ONE of them appears as a literal => this organ
cannot see this subject's dispatch mechanism at all. Reporting N dead verbs there would
be a confident wrong answer; abstaining names it for a human instead.
RATCHET: the baseline is a SET OF NAMES, never a count -- a count-only ratchet on a shared tree
reports a regression without saying whose. Removals ratchet down automatically; ADDITIONS keep firing
until fixed or explicitly adopted with `accept`.
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_estr.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
| 50 | const TH_ROWCAP: i64 = 8192 |
| 52 | const TH_SUBJCAP: i64 = 8192 |
| 54 | const TH_NAMECAP: i64 = 128 |
| 56 | const TH_PATHCAP: i64 = 1024 |
| 58 | const TH_GRAMCAP: i64 = 2048 |
| 60 | const TH_VERBCAP: i64 = 48 |
| 62 | const TH_MAXVERBS: i64 = 48 |
| 64 | const TH_STATBUF: i64 = 256 |
| 66 | const TH_LINEBUF: i64 = 4096 |
| 68 | const TH_UNDECIDABLE_MIN: i64 = 2 |
| 69 | const TH_MODE_FILE: i64 = 0x1a4 |
| 70 | const TH_MODE_DIR: i64 = 0x1ed |
| 71 | const TH_EXIT_OK: i64 = 0 |
| 72 | const TH_EXIT_REGRESSED: i64 = 1 |
| 73 | const TH_EXIT_USAGE: i64 = 2 |
| 74 | const TH_EXIT_REFUSED: i64 = 4 |
| 76 | const TH_TAB: i64 = 9 |
| 77 | const TH_NL: i64 = 10 |
| 78 | const TH_SPACE: i64 = 32 |
| 79 | const TH_QUOTE: i64 = 34 |
| 80 | const TH_HASH: i64 = 35 |
| 81 | const TH_PIPE: i64 = 124 |
| 82 | const TH_SLASH: i64 = 47 |
| 83 | const TH_LT: i64 = 60 |
| 84 | const TH_GT: i64 = 62 |
| 85 | const TH_LBRACK: i64 = 91 |
| 86 | const TH_LPAREN: i64 = 40 |
| 87 | const TH_RPAREN: i64 = 41 |
| 88 | const TH_RBRACK: i64 = 93 |
| 89 | const TH_EQ: i64 = 61 |
| 90 | const TH_DASH: i64 = 45 |
| 91 | const TH_UNDER: i64 = 95 |
| 92 | const TH_DIGIT0: i64 = 48 |
| 93 | const TH_DIGIT9: i64 = 57 |
| 94 | const TH_UPA: i64 = 65 |
| 95 | const TH_UPZ: i64 = 90 |
| 96 | const TH_LOA: i64 = 97 |
| 97 | const TH_LOZ: i64 = 122 |
| 99 | const TH_DEF_ALLOW: *u8 = "tool_allowlist.conf" |
| 100 | const TH_DEF_SCHEMAS: *u8 = "knowledge/tool_schemas.conf" |
| 101 | const TH_DEF_GRAMMAR: *u8 = "knowledge/tool_grammar.conf" |
| 102 | const TH_DEF_LOG: *u8 = "knowledge/status/toolhealth.log" |
| 103 | const TH_DEF_BASE: *u8 = "knowledge/status/toolhealth_ratchet.conf" |
| 104 | const TH_SRC_A: *u8 = "buildroot/runtime/_hdl_build/" |
| 105 | const TH_SRC_B: *u8 = "buildroot/runtime/" |
| 106 | const TH_STATUS_DIR: *u8 = "knowledge/status" |
| 109 | const TH_CLS_OK: i64 = 0 |
| 110 | const TH_CLS_MISSING_BUILDABLE: i64 = 1 |
| 111 | const TH_CLS_PHANTOM: i64 = 2 |
| 112 | const TH_CLS_BINARY_NO_SOURCE: i64 = 3 |
| 114 | const TH_HC_CLEAN: i64 = 0 |
| 115 | const TH_HC_DEAD: i64 = 1 |
| 116 | const TH_HC_PINNED: i64 = 2 |
| 117 | const TH_HC_NOGRAMMAR: i64 = 3 |
| 118 | const TH_HC_UNDECIDABLE: i64 = 4 |
| 119 | const TH_HC_NOSOURCE: i64 = 5 |
| 120 | const TH_HC_POSITIONAL: i64 = 6 |
functions
| 124 | func thw(s: *u8) -> i64 { es_puts(s); return 0 } |
| 125 | func thn(v: i64) -> i64 { es_putn(v); return 0 } |
| 127 | func th_streq(a: *u8, al: i64, b: *u8, bl: i64) -> i64 |
| 134 | func th_exists(path: *u8) -> i64 |
| 141 | func th_field(buf: *u8, ls: i64, le: i64, idx: i64, out: *u8, cap: i64) -> i64 |
| 169 | func th_count_fields(buf: *u8, ls: i64, le: i64) -> i64 called by 1: main |
| 176 | func th_ends(s: *u8, sl: i64, suf: *u8, fl: i64) -> i64 called by 1: th_stem |
| 184 | func th_stem(elf: *u8, el: i64, out: *u8, cap: i64) -> i64 |
| 207 | func th_lookup(buf: *u8, n: i64, key: *u8, kl: i64, gidx: i64, out: *u8, cap: i64) -> i64 |
| 233 | func th_is_wordbyte(c: i64) -> i64 called by 1: th_verbs |
| 242 | func th_is_alpha(c: i64) -> i64 called by 1: th_verbs |
| 257 | func th_is_toolname(names: *u8, nn: i64, tok: *u8, tl: i64) -> i64 called by 1: th_verbs |
| 292 | func th_verbs(gram: *u8, gl: i64, selfname: *u8, snl: i64, names: *u8, nn: i64, verbs: *u8, vlen: *i64, nv0: i64) -> i64 |
| 446 | func th_has_literal(src: *u8, sn: i64, verb: *u8, vl: i64) -> i64 |
| 464 | func th_srcpath(root: *u8, stem: *u8, out: *u8) -> i64 |
| 472 | func th_verbscan(gramfile: *u8, srcfile: *u8, selfname: *u8) -> i64 |
| 524 | func th_key(buf: *u8, ls: i64, le: i64, out: *u8, cap: i64) -> i64 |
| 550 | func th_base_has(bb: *u8, bn: i64, want: *u8, wl: i64) -> i64 |
| 564 | func th_clsname(c: i64) -> *u8 called by 1: main |
| 571 | func main(argc: i64, argv: *i64) -> i64 |