code wiki / _hdl_build / nx_prim_registry.nx

nx_prim_registry.nx source

↩ module page · 210 lines · 15530 B

1// nx_prim_registry.nx -- prim lane F781 (BOTTOM-UP pillar of the meet-in-the-middle synthesis engine). 2// Tier-1: read knowledge/tool_schemas.conf (name|title|readOnly|destructive|idempotent|openWorld| 3// output-desc|argv-grammar[col8]) and EMIT a primitives manifest knowledge/store/prim_registry.json 4// -- one primitive per MCP tool: primitive_id, title, domain (name-prefix-derived), capabilities 5// (structural facets from data, NOT hallucinated verbs -- rule 4), signature (the col8 typed argv grammar 6// VERBATIM, or a flagged generic when absent = back-compat), output, safety{ro/destr/idem/open}, typed. 7// The 'what do I have' half of meet-in-the-middle; F782 query_primitives reads this. ATOMIC (tmp+rename, 8// no torn read). READ-ONLY over the source (Rule 26). Declares its envelope (scanned/typed/generic/window). 9// 10// ENVELOPES ARE DERIVED, NOT PICKED (2026-09-14, search rung E7; operator: the estate-wide magic numbers go). 11// Until today this organ admitted the first K_MAGIC_1024 rows and DROPPED the rest -- 936 of 1966 registered 12// tools on 2026-09-14 -- so every organ registered after the 1024th (the whole search ship loop among them) 13// was undiscoverable to nx_prim_query, which answered matched=0 scanned=1024 for search_ship. A row cap with 14// no buffer behind it is a defect generator: it was announced (dropped=) and still nobody read it. Now the 15// input is read WHOLE by sys_read_file (sized from the file, cannot short-read), the output window is 16// DERIVED from that size (every schema byte can at most double under JSON escaping) plus a per-row overhead 17// for the keys and facets this emitter adds (PR_ROW_OVERHEAD, counted per newline), and the only bound left 18// is that window, which refuses LOUDLY on saturation instead of truncating. No row is ever dropped. 19// 20// THE OUTPUT IS NOT SOVEREIGN AND NOT A PLANE (corrected 2026-08-15 -- the line above used to read 21// "a sovereign primitives manifest"). It is JSON, and it sits in knowledge/store/, which is the 22// SEG-STORE PLANE DIRECTORY (comparewatch- elarastate- im- ...). A third-party format inside the plane 23// directory is exactly what the standing order forbids, and the word "sovereign" made the exception 24// invisible to anyone grepping for one. 25// A NAME THAT CLAIMS THE PROPERTY ITS ARTIFACT LACKS HIDES THE ONE PLACE SOMEBODY WOULD HAVE LOOKED. 26// MIGRATION CONTRACT, measured 2026-08-15 (corpus_complete=1) so the next seat need not re-derive it: 27// WRITER this organ (out path in main, tmp beside it) 28// READERS nx_prim_synth.nx:93 . nx_model_card.nx:325 . nx_prim_gap.nx:109 . nx_prim_query.nx:71 29// nx_prim_gap:153 and nx_prim_query:117 ALSO EMIT this path as a "source" field in their own 30// reports, so the migration has SIX edit sites, not four -- a repoint that fixes only the reads 31// leaves two published reports citing a file that no longer exists. 32// Same shape as the TSV lane: one emitter, N readers, and the FORMAT is the whole defect. 33// nx_prim_registry run [schema.conf] [out.json] [tmp.json] 34// exit: 0 GREEN | 4 ABSENT-INPUT (schema unreadable) | 5 WRITE-FAIL | 2 usage. 35// license_tier: ORIGINAL expect_exit: 0 36import "nx_syscalls.nx" 37// every literal below is named for its ONE purpose; none is a tunable 38const PR_FIELDS: i64 = 8 // tool_schemas.conf columns: name title ro destr idem open output grammar 39const 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) 40const PR_DIGITS: i64 = 28 // decimal digits an i64 can need, with its sign 41const PR_DOMAIN_MAX: i64 = 60 // a name-prefix facet longer than this is cut at the facet, never at the id 42const PR_TAB: i64 = 9 43const PR_NL: i64 = 10 44const PR_HASH: i64 = 35 45const PR_QUOTE: i64 = 34 46const PR_BACKSLASH: i64 = 92 47const PR_SPACE: i64 = 32 48const PR_ONE: i64 = 49 49const PR_ZERO: i64 = 48 50const PR_MINUS: i64 = 45 51const PR_UNDERSCORE: i64 = 95 52const PR_LOWER_N: i64 = 110 53const PR_LOWER_X: i64 = 120 54const PR_MODE_RW: i64 = 420 55const PR_EXIT_ABSENT: i64 = 4 56const PR_EXIT_WRITEFAIL: i64 = 5 57// the derived output window (set once in main from the input size and row count; every emitter bounds on it) 58static pr_cap_g: i64 59 60func 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 } 61func 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 } 62func 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 } 63func 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 } 64func 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 } 65func pr_je(rep: *u8, pos: i64, src: *u8, s: i64, e: i64) -> i64 { 66 var p: i64 = pos 67 var i: i64 = s 68 while i < e { 69 let c: i64 = src[i] 70 if c == PR_QUOTE { if p < pr_cap_g { rep[p] = PR_BACKSLASH as u8; p = p + 1 } if p < pr_cap_g { rep[p] = PR_QUOTE as u8; p = p + 1 } } 71 else { if c == PR_BACKSLASH { if p < pr_cap_g { rep[p] = PR_BACKSLASH as u8; p = p + 1 } if p < pr_cap_g { rep[p] = PR_BACKSLASH as u8; p = p + 1 } } 72 else { if c < PR_SPACE { if p < pr_cap_g { rep[p] = PR_SPACE as u8; p = p + 1 } } 73 else { if p < pr_cap_g { rep[p] = c as u8; p = p + 1 } } } } 74 i = i + 1 75 } 76 return p 77} 78// the domain facet: the name's first underscore-delimited segment after an nx_ prefix, else the whole name 79func pr_domain(src: *u8, s: i64, e: i64, dom: *u8) -> i64 { 80 var start: i64 = s 81 if e - s > 3 { if src[s] == PR_LOWER_N { if src[s+1] == PR_LOWER_X { if src[s+2] == PR_UNDERSCORE { start = s + 3 } } } } 82 var d: i64 = 0 83 var i: i64 = start 84 var go: i64 = 1 85 while go == 1 { 86 if i >= e { go = 0 } else { let c: i64 = src[i]; if c == PR_UNDERSCORE { go = 0 } else { if d < PR_DOMAIN_MAX { dom[d] = c as u8; d = d + 1 } i = i + 1 } } 87 } 88 if d == 0 { var j: i64 = s; d = 0; while j < e { if d < PR_DOMAIN_MAX { dom[d] = src[j]; d = d + 1 } j = j + 1 } } 89 return d 90} 91func main(argc: i64, argv: *i64) -> i64 { 92 var schemapath: *u8 = "knowledge/tool_schemas.conf" as *u8 93 var outpath: *u8 = "knowledge/store/prim_registry.json" as *u8 94 var tmppath: *u8 = "knowledge/store/prim_registry.json.tmp" as *u8 95 if argc >= 3 { schemapath = argv[2] as *u8 } 96 if argc >= 4 { outpath = argv[3] as *u8 } 97 if argc >= 5 { tmppath = argv[4] as *u8 } 98 // the input, whole: sized from the file by sys_read_file, so there is no window to saturate on the way in 99 let nb: *i64 = sys_mmap(16) as *i64 100 let buf: *u8 = sys_read_file(schemapath, nb) 101 if (buf as i64) == 0 { pr_w(1, "PRIM-REGISTRY verdict=ABSENT-INPUT schema unreadable\n" as *u8); sys_exit(PR_EXIT_ABSENT); return PR_EXIT_ABSENT } 102 let n: i64 = nb[0] 103 // the output window, DERIVED: every input byte at most doubles under escaping, plus the fixed overhead per row 104 var rows: i64 = 1 105 var ri: i64 = 0 106 while ri < n { if buf[ri] == (PR_NL as u8) { rows = rows + 1 } ri = ri + 1 } 107 pr_cap_g = 2 * n + rows * PR_ROW_OVERHEAD + PR_ROW_OVERHEAD 108 let rep: *u8 = sys_mmap(pr_cap_g + 16) 109 let fs: *i64 = sys_mmap(8 * (PR_FIELDS + 4)) as *i64 110 let fe: *i64 = sys_mmap(8 * (PR_FIELDS + 4)) as *i64 111 let dom: *u8 = sys_mmap(PR_DOMAIN_MAX + 4) 112 var p: i64 = 0 113 p = pr_b(rep, p, "{" as *u8) 114 p = pr_key(rep, p, "v" as *u8); p = pr_bn(rep, p, 1); p = pr_b(rep, p, "," as *u8) 115 p = pr_key(rep, p, "kind" as *u8); p = pr_q(rep, p); p = pr_b(rep, p, "primitive_registry" as *u8); p = pr_q(rep, p); p = pr_b(rep, p, "," as *u8) 116 p = pr_key(rep, p, "tier" as *u8); p = pr_q(rep, p); p = pr_b(rep, p, "mcp-tools" as *u8); p = pr_q(rep, p); p = pr_b(rep, p, "," as *u8) 117 p = pr_key(rep, p, "source" as *u8); p = pr_q(rep, p); p = pr_b(rep, p, "knowledge/tool_schemas.conf" as *u8); p = pr_q(rep, p); p = pr_b(rep, p, "," as *u8) 118 p = pr_key(rep, p, "primitives" as *u8); p = pr_b(rep, p, "[" as *u8) 119 var scanned: i64 = 0 120 var typedc: i64 = 0 121 var genericc: i64 = 0 122 var first: i64 = 1 123 var i: i64 = 0 124 while i < n { 125 var e2: i64 = i 126 var eol: i64 = 0 127 while eol == 0 { if e2 >= n { eol = 1 } else { if buf[e2] == (PR_NL as u8) { eol = 1 } else { e2 = e2 + 1 } } } 128 if e2 > i { 129 let c0: i64 = buf[i] 130 if c0 != PR_HASH { 131 // split [i, e2) into up to PR_FIELDS tab fields; the last field absorbs trailing tabs 132 var nf: i64 = 1 133 fs[0] = i 134 var q: i64 = i 135 while q < e2 { if buf[q] == (PR_TAB as u8) { if nf < PR_FIELDS { fe[nf-1] = q; fs[nf] = q + 1; nf = nf + 1 } } q = q + 1 } 136 fe[nf-1] = e2 137 let nlen: i64 = fe[0] - fs[0] 138 if nlen > 0 { 139 var ro: i64 = 0 140 var destr: i64 = 0 141 var idem: i64 = 0 142 var opn: i64 = 0 143 if nf >= 3 { if buf[fs[2]] == (PR_ONE as u8) { ro = 1 } } 144 if nf >= 4 { if buf[fs[3]] == (PR_ONE as u8) { destr = 1 } } 145 if nf >= 5 { if buf[fs[4]] == (PR_ONE as u8) { idem = 1 } } 146 if nf >= 6 { if buf[fs[5]] == (PR_ONE as u8) { opn = 1 } } 147 var typed: i64 = 0 148 if nf >= PR_FIELDS { if fe[PR_FIELDS - 1] > fs[PR_FIELDS - 1] { typed = 1 } } 149 let dlen: i64 = pr_domain(buf, fs[0], fe[0], dom) 150 if first == 1 { first = 0 } else { p = pr_b(rep, p, "," as *u8) } 151 p = pr_b(rep, p, "{" as *u8) 152 p = pr_key(rep, p, "primitive_id" as *u8); p = pr_q(rep, p); p = pr_je(rep, p, buf, fs[0], fe[0]); p = pr_q(rep, p); p = pr_b(rep, p, "," as *u8) 153 p = pr_key(rep, p, "title" as *u8); p = pr_q(rep, p); if nf >= 2 { p = pr_je(rep, p, buf, fs[1], fe[1]) } p = pr_q(rep, p); p = pr_b(rep, p, "," as *u8) 154 p = pr_key(rep, p, "domain" as *u8); p = pr_q(rep, p); p = pr_je(rep, p, dom, 0, dlen); p = pr_q(rep, p); p = pr_b(rep, p, "," as *u8) 155 p = pr_key(rep, p, "capabilities" as *u8); p = pr_b(rep, p, "[" as *u8) 156 p = pr_q(rep, p); p = pr_je(rep, p, dom, 0, dlen); p = pr_q(rep, p); p = pr_b(rep, p, "," as *u8) 157 p = pr_q(rep, p); if ro == 1 { p = pr_b(rep, p, "read-only" as *u8) } else { p = pr_b(rep, p, "mutating" as *u8) } p = pr_q(rep, p); p = pr_b(rep, p, "," as *u8) 158 p = pr_q(rep, p); if opn == 1 { p = pr_b(rep, p, "reaches-external" as *u8) } else { p = pr_b(rep, p, "sovereign-local" as *u8) } p = pr_q(rep, p) 159 p = pr_b(rep, p, "]," as *u8) 160 p = pr_key(rep, p, "signature" as *u8); p = pr_q(rep, p); if typed == 1 { p = pr_je(rep, p, buf, fs[PR_FIELDS - 1], fe[PR_FIELDS - 1]) } else { p = pr_b(rep, p, "(generic: no typed argv grammar; back-compat)" as *u8) } p = pr_q(rep, p); p = pr_b(rep, p, "," as *u8) 161 p = pr_key(rep, p, "output" as *u8); p = pr_q(rep, p); if nf >= 7 { p = pr_je(rep, p, buf, fs[6], fe[6]) } p = pr_q(rep, p); p = pr_b(rep, p, "," as *u8) 162 p = pr_key(rep, p, "safety" as *u8); p = pr_b(rep, p, "{" as *u8) 163 p = pr_key(rep, p, "read_only" as *u8); p = pr_bn(rep, p, ro); p = pr_b(rep, p, "," as *u8) 164 p = pr_key(rep, p, "destructive" as *u8); p = pr_bn(rep, p, destr); p = pr_b(rep, p, "," as *u8) 165 p = pr_key(rep, p, "idempotent" as *u8); p = pr_bn(rep, p, idem); p = pr_b(rep, p, "," as *u8) 166 p = pr_key(rep, p, "open_world" as *u8); p = pr_bn(rep, p, opn) 167 p = pr_b(rep, p, "}," as *u8) 168 p = pr_key(rep, p, "typed" as *u8); p = pr_bn(rep, p, typed) 169 p = pr_b(rep, p, "}" as *u8) 170 scanned = scanned + 1 171 if typed == 1 { typedc = typedc + 1 } else { genericc = genericc + 1 } 172 } 173 } 174 } 175 i = e2 + 1 176 } 177 p = pr_b(rep, p, "]," as *u8) 178 p = pr_key(rep, p, "envelope" as *u8); p = pr_b(rep, p, "{" as *u8) 179 p = pr_key(rep, p, "scanned" as *u8); p = pr_bn(rep, p, scanned); p = pr_b(rep, p, "," as *u8) 180 p = pr_key(rep, p, "typed_signature" as *u8); p = pr_bn(rep, p, typedc); p = pr_b(rep, p, "," as *u8) 181 p = pr_key(rep, p, "generic" as *u8); p = pr_bn(rep, p, genericc); p = pr_b(rep, p, "," as *u8) 182 // cap 0 and dropped 0 BY CONSTRUCTION (kept as keys so older readers still parse); the window is the derived bound 183 p = pr_key(rep, p, "cap" as *u8); p = pr_bn(rep, p, 0); p = pr_b(rep, p, "," as *u8) 184 p = pr_key(rep, p, "dropped_over_cap" as *u8); p = pr_bn(rep, p, 0); p = pr_b(rep, p, "," as *u8) 185 p = pr_key(rep, p, "input_bytes" as *u8); p = pr_bn(rep, p, n); p = pr_b(rep, p, "," as *u8) 186 p = pr_key(rep, p, "output_window_bytes" as *u8); p = pr_bn(rep, p, pr_cap_g); p = pr_b(rep, p, "," as *u8) 187 p = pr_key(rep, p, "note" as *u8); p = pr_q(rep, p); p = pr_b(rep, p, "tier-1 MCP tools, the WHOLE allowlist (no row cap since 2026-09-14); capabilities are structural facets from data; verb-semantic tags + tier-2 ecograph organ deps are F781b/F231" as *u8); p = pr_q(rep, p) 188 p = pr_b(rep, p, "}}" as *u8) 189 if p >= pr_cap_g { pr_w(1, "PRIM-REGISTRY verdict=REFUSED output-window-saturated: the derived window (2 x input + rows x PR_ROW_OVERHEAD) was exceeded, so the per-row overhead measurement is stale -- a truncated manifest is invalid JSON and is NOT written\n" as *u8); sys_exit(PR_EXIT_WRITEFAIL); return PR_EXIT_WRITEFAIL } 190 let tmpfd: i64 = sys_openat_wr(tmppath, PR_MODE_RW) 191 if tmpfd < 0 { pr_w(1, "PRIM-REGISTRY verdict=WRITE-FAIL tmp-open\n" as *u8); sys_exit(PR_EXIT_WRITEFAIL); return PR_EXIT_WRITEFAIL } 192 sys_write(tmpfd, rep, p) 193 sys_close(tmpfd) 194 let rr: i64 = sys_renameat(tmppath, outpath) 195 if rr < 0 { pr_w(1, "PRIM-REGISTRY verdict=WRITE-FAIL rename\n" as *u8); sys_exit(PR_EXIT_WRITEFAIL); return PR_EXIT_WRITEFAIL } 196 // the summary line reuses the (already written) output buffer, so it needs no window of its own 197 let written: i64 = p 198 var sp: i64 = 0 199 sp = pr_b(rep, sp, "PRIM-REGISTRY scanned=" as *u8); sp = pr_bn(rep, sp, scanned) 200 sp = pr_b(rep, sp, " typed=" as *u8); sp = pr_bn(rep, sp, typedc) 201 sp = pr_b(rep, sp, " generic=" as *u8); sp = pr_bn(rep, sp, genericc) 202 sp = pr_b(rep, sp, " dropped=0 cap=none input_bytes=" as *u8); sp = pr_bn(rep, sp, n) 203 sp = pr_b(rep, sp, " window_bytes=" as *u8); sp = pr_bn(rep, sp, pr_cap_g) 204 sp = pr_b(rep, sp, " bytes=" as *u8); sp = pr_bn(rep, sp, written) 205 sp = pr_b(rep, sp, " out=" as *u8); sp = pr_b(rep, sp, outpath) 206 sp = pr_b(rep, sp, " verdict=GREEN\n" as *u8) 207 sys_write(1, rep, sp) 208 sys_exit(0) 209 return 0 210}