code wiki / _hdl_build / nx_prim_registry.nx
nx_prim_registry.nx
buildroot/runtime/_hdl_build/nx_prim_registry.nx
about
nx_prim_registry.nx -- prim lane F781 (BOTTOM-UP pillar of the meet-in-the-middle synthesis engine).
Tier-1: read knowledge/tool_schemas.conf (name|title|readOnly|destructive|idempotent|openWorld|
output-desc|argv-grammar[col8]) and EMIT a primitives manifest knowledge/store/prim_registry.json
-- one primitive per MCP tool: primitive_id, title, domain (name-prefix-derived), capabilities
(structural facets from data, NOT hallucinated verbs -- rule 4), signature (the col8 typed argv grammar
VERBATIM, or a flagged generic when absent = back-compat), output, safety{ro/destr/idem/open}, typed.
The 'what do I have' half of meet-in-the-middle; F782 query_primitives reads this. ATOMIC (tmp+rename,
no torn read). READ-ONLY over the source (Rule 26). Declares its envelope (scanned/typed/generic/window).
ENVELOPES ARE DERIVED, NOT PICKED (2026-09-14, search rung E7; operator: the estate-wide magic numbers go).
Until today this organ admitted the first K_MAGIC_1024 rows and DROPPED the rest -- 936 of 1966 registered
tools on 2026-09-14 -- so every organ registered after the 1024th (the whole search ship loop among them)
was undiscoverable to nx_prim_query, which answered matched=0 scanned=1024 for search_ship. A row cap with
no buffer behind it is a defect generator: it was announced (dropped=) and still nobody read it. Now the
input is read WHOLE by sys_read_file (sized from the file, cannot short-read), the output window is
DERIVED from that size (every schema byte can at most double under JSON escaping) plus a per-row overhead
for the keys and facets this emitter adds (PR_ROW_OVERHEAD, counted per newline), and the only bound left
is that window, which refuses LOUDLY on saturation instead of truncating. No row is ever dropped.
THE OUTPUT IS NOT SOVEREIGN AND NOT A PLANE (corrected 2026-08-15 -- the line above used to read
"a sovereign primitives manifest"). It is JSON, and it sits in knowledge/store/, which is the
SEG-STORE PLANE DIRECTORY (comparewatch- elarastate- im- ...). A third-party format inside the plane
directory is exactly what the standing order forbids, and the word "sovereign" made the exception
invisible to anyone grepping for one.
A NAME THAT CLAIMS THE PROPERTY ITS ARTIFACT LACKS HIDES THE ONE PLACE SOMEBODY WOULD HAVE LOOKED.
MIGRATION CONTRACT, measured 2026-08-15 (corpus_complete=1) so the next seat need not re-derive it:
WRITER this organ (out path in main, tmp beside it)
READERS nx_prim_synth.nx:93 . nx_model_card.nx:325 . nx_prim_gap.nx:109 . nx_prim_query.nx:71
nx_prim_gap:153 and nx_prim_query:117 ALSO EMIT this path as a "source" field in their own
reports, so the migration has SIX edit sites, not four -- a repoint that fixes only the reads
leaves two published reports citing a file that no longer exists.
Same shape as the TSV lane: one emitter, N readers, and the FORMAT is the whole defect.
nx_prim_registry run [schema.conf] [out.json] [tmp.json]
exit: 0 GREEN | 4 ABSENT-INPUT (schema unreadable) | 5 WRITE-FAIL | 2 usage.
license_tier: ORIGINAL expect_exit: 0
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
| 38 | const PR_FIELDS: i64 = 8 // tool_schemas.conf columns: name title ro destr idem open output grammar |
| 39 | const PR_ROW_OVERHEAD: i64 = 640 // JSON keys, facet words and the safety block emitted per row beyond the row's own bytes (measured 2026-09-14: 497257 B for 1024 rows of a 481639 B input, under 490 B per row; 640 is that plus margin) |
| 40 | const PR_DIGITS: i64 = 28 // decimal digits an i64 can need, with its sign |
| 41 | const PR_DOMAIN_MAX: i64 = 60 // a name-prefix facet longer than this is cut at the facet, never at the id |
| 42 | const PR_TAB: i64 = 9 |
| 43 | const PR_NL: i64 = 10 |
| 44 | const PR_HASH: i64 = 35 |
| 45 | const PR_QUOTE: i64 = 34 |
| 46 | const PR_BACKSLASH: i64 = 92 |
| 47 | const PR_SPACE: i64 = 32 |
| 48 | const PR_ONE: i64 = 49 |
| 49 | const PR_ZERO: i64 = 48 |
| 50 | const PR_MINUS: i64 = 45 |
| 51 | const PR_UNDERSCORE: i64 = 95 |
| 52 | const PR_LOWER_N: i64 = 110 |
| 53 | const PR_LOWER_X: i64 = 120 |
| 54 | const PR_MODE_RW: i64 = 420 |
| 55 | const PR_EXIT_ABSENT: i64 = 4 |
| 56 | const PR_EXIT_WRITEFAIL: i64 = 5 |
functions
| 60 | func pr_w(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 } |
| 61 | func pr_b(rep: *u8, pos: i64, s: *u8) -> i64 { var p: i64 = pos; var i: i64 = 0; while s[i] != (0 as u8) { if p < pr_cap_g { rep[p] = s[i]; p = p + 1 } i = i + 1 } return p } |
| 62 | func pr_bn(rep: *u8, pos: i64, v: i64) -> i64 { var p: i64 = pos; var m: i64 = v; if m < 0 { if p < pr_cap_g { rep[p] = PR_MINUS as u8; p = p + 1 } m = 0 - m } let t: *u8 = sys_mmap(PR_DIGITS); var k: i64 = 0; if m == 0 { t[0] = PR_ZERO as u8; k = 1 } while m > 0 { t[k] = (PR_ZERO + (m % 10)) as u8; m = m / 10; k = k + 1 } var i: i64 = 0; while i < k { if p < pr_cap_g { rep[p] = t[k - 1 - i]; p = p + 1 } i = i + 1 } sys_munmap(t, PR_DIGITS); return p } |
| 63 | func pr_q(rep: *u8, pos: i64) -> i64 { var p: i64 = pos; if p < pr_cap_g { rep[p] = PR_QUOTE as u8; p = p + 1 } return p } |
| 64 | func pr_key(rep: *u8, pos: i64, k: *u8) -> i64 { var p: i64 = pos; p = pr_q(rep, p); p = pr_b(rep, p, k); p = pr_q(rep, p); p = pr_b(rep, p, ":" as *u8); return p } |
| 65 | func pr_je(rep: *u8, pos: i64, src: *u8, s: i64, e: i64) -> i64 called by 1: main |
| 79 | func pr_domain(src: *u8, s: i64, e: i64, dom: *u8) -> i64 called by 1: main |
| 91 | func main(argc: i64, argv: *i64) -> i64 |