code wiki / _hdl_build / nx_toolgrammar.nx
nx_toolgrammar.nx
buildroot/runtime/_hdl_build/nx_toolgrammar.nx
about
nx_toolgrammar.nx -- CALL-GRAMMAR HARVESTER (2026-08-06). Derives each tool's argv CONTRACT from its
own source header and emits knowledge/tool_grammar.conf, which nx_tools_api reads as the col8 FALLBACK
so tools/list serves a real call grammar instead of the generic "positional CLI args" placeholder.
WHY A SEPARATE FILE, NOT A REWRITE: tool_schemas.conf is a SHARED registry and col8 there is
HAND-AUTHORED. An authored col8 must always win over a derived one, and a derived value must never
overwrite a human's. Emitting a sibling file keeps this ADDITIVE and reversible (delete the file) and
keeps the precedence obvious: authored col8 > derived grammar > generic placeholder.
MEASURED 2026-08-06 over the live tools/list: 749 of 869 tools (86.2%) had no col8 at all -- the gap
tool_schemas.conf itself named on 2026-07-17 as "the tool-schema SOTA gap" and nothing ever derived.
THE CONVENTION, read off real organs (nx_pm_board, nx_ws_miner, nx_atlas_discover, nx_feeder), NOT
invented: a usage line is a `//` comment indented by EXACTLY 2-3 spaces whose text carries a grammar
marker (`<`, `[`, or `->`). 1 space is prose ("// nx_x.nx -- ...", "// license_tier: ..."); 4+ spaces
is a continuation ("// defaults: ...", "// out row: ..."). The first token may be the tool's
OWN NAME (nx_pm_board [frontierpfx] ...) or a bare VERB (mine <journal> ...) -- both are real and an
earlier name-anchored scan found only 131 of 749 precisely because it assumed the former.
HONEST: no source / no usage line / too short => SKIPPED + COUNTED, never guessed (blank beats bad).
Runs of whitespace collapse to one space and TAB/controls are scrubbed, so a header can never inject
a column or split a row.
nx_toolgrammar -> writes knowledge/tool_grammar.conf, prints a JSON census on stdout
license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
dependencies 2 imports · 0 importers
imports: nx_mgmt_api.nxnx_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
| 25 | const TG_ALCAP: i64 = 1 << 18 |
| 27 | const TG_HDRCAP: i64 = 8192 |
| 29 | const TG_GRAMCAP: i64 = 400 |
| 31 | const TG_MINGRAM: i64 = 8 |
| 33 | const TG_NAMECAP: i64 = 128 |
| 35 | const TG_PATHCAP: i64 = 512 |
| 37 | const TG_MAXLINES: i64 = 4 |
| 39 | const TG_OUT: *u8 = "knowledge/tool_grammar.conf" as *u8 |
| 171 | const TG_SRCCAP: i64 = 262144 |
functions
| 45 | func tgw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 46 | func tgn(v: i64) -> i64 |
| 56 | func tg_ends(s: *u8, sl: i64, suf: *u8, fl: i64) -> i64 |
| 64 | func tg_grammar_from_header(path: *u8, out: *u8) -> i64 |
| 183 | func tg_usage_literal(path: *u8, out: *u8, stem: *u8, stl: i64) -> i64 |
| 267 | func tg_max_argv(path: *u8) -> i64 |
| 312 | func tg_pinned_args(al: *u8, ls: i64, le: i64, out: *u8) -> i64 |
| 363 | func tg_is_argless(path: *u8) -> i64 |
| 385 | func main() -> i64 |