code wiki / _hdl_build / nx_magic_lib.nx
nx_magic_lib.nx
buildroot/runtime/_hdl_build/nx_magic_lib.nx
about
nx_magic_lib.nx -- THE RULE-11 LITERAL SCANNER. Extracted out of nx_magic.nx on 2026-08-25 for two
reasons, and the second is the one that mattered.
(1) IT COULD NEVER BE MUTATION-PROVEN WHERE IT WAS. mg_scan lived inside a program with main(), so the
only way to exercise it was to fork the deployed elf -- and every mutant of a fork/exec'd subject comes
back NOT-REACHED. The estate's most widely-consumed text scanner (it decides what /api/build calls a
rule-11 breach) had therefore never had a single tooth on it. In a lib it sits inside the gate's own
build closure and nx_gate_bite can kill mutants in it.
(2) IT WAS BLIND TO HEXADECIMAL, AND THE BLINDNESS WAS DECLARED RATHER THAN FIXED. nx_magic's header
said "Decimal only -- hex is DECLARED out of envelope (nearly all hex here is < 1024)" and the map
envelope printed decimal_only:1, hex_out_of_envelope:1 on every call. A declaration does not make a
count mean what its name says. MEASURED 2026-08-25 on buildroot/runtime/_hdl_build/nx_activities_gate.nx
at floor 2: 41 sites / 26 distinct, one of which is the decimal literal 420 -- while the FOUR `0x1ed`
literals on lines 123/124/127/128 of the same file, which are THE SAME NUMBER, were not sites at all.
The mechanism was mechanical and total: at `0x1ed` the scanner read the digit run `0`, saw that the next
byte `x` is an identifier character, and discarded the whole token as identifier-digits. So the value it
would have carried was not merely mis-scaled, it was 0.
A file written entirely in 0x notation read as magic:0.
The estate had ALREADY banked the law -- "THE SAME CONSTANT IN TWO BASES IS TWO CONSTANTS TO EVERY
SCANNER", earned when a 39-site MODE_0644 sweep matched decimal 420 and missed a raw 0x1a4 -- and then
never taught the ruler the second base. A LAW BANKED IN PROSE AND ABSENT FROM THE INSTRUMENT IS A LAW
THE NEXT SWEEP WILL BREAK AGAIN.
SCOPE OF THE FIX, STATED SO IT IS NOT OVERREAD: this closes the blind spot in nx_magic's scanner, which
produces the WORKLIST and the FLOOR VIEW. It does NOT change the number nx_magicratchet gates builds on:
that count comes from `nx_law_warden countfile` -> lw_line_lits, which is hex-blind by exactly the same
mechanism and is deliberately left alone here, because raising a count that already has 911 stored
baselines is the one edit that can refuse real builds estate-wide. Named, measured, not done blind.
SKIPPED BY CONSTRUCTION (the false-positive controls, unchanged except where noted): whole-line comments,
TRAILING comments after code, const/static DECLARATION lines, bytes inside string literals, digits that
continue an identifier (x2048, and now also a hex body that runs into a letter), named-index table writes
`a[NAME] = literal`, any value below the threshold, and NEW: a hex literal too wide to represent exactly
(see MG_HEX_SAFE_DIGITS -- it is COUNTED and REPORTED, never silently dropped, and never recorded as a
site because a site authorises `nx_magic apply` to REWRITE THAT TEXT and a wrong value there is source
corruption). A HEURISTIC THAT GATES A DESTRUCTIVE ACTION MUST BE WRONG IN THE DIRECTION OF DOING NOTHING.
100% sovereign. No hardware writes (Rule 26). license_tier: ORIGINAL
dependencies 1 imports · 3 importers
imports: nx_syscalls.nx
imported by: nx_magic.nxnx_magic_gate.nxnx_magicratchet.nx
structs
| none |
consts
| 42 | const MG_CAP: i64 = 1048576 |
| 43 | const MG_NL: i64 = 10 |
| 44 | const MG_QU: i64 = 34 |
| 45 | const MG_BSL: i64 = 92 |
| 46 | const MG_SLASH: i64 = 47 |
| 47 | const MG_US: i64 = 95 |
| 48 | const MG_SP: i64 = 32 |
| 49 | const MG_TAB: i64 = 9 |
| 50 | const MG_LSQ: i64 = 91 |
| 51 | const MG_RSQ: i64 = 93 |
| 52 | const MG_EQ: i64 = 61 |
| 53 | const MG_MAXSITES: i64 = 4096 |
| 54 | const MG_MAXVALS: i64 = 256 |
| 60 | const MG_FLOOR: i64 = 2 |
| 63 | const MG_ZERO: i64 = 48 |
| 64 | const MG_NINE: i64 = 57 |
| 65 | const MG_LC_A: i64 = 97 |
| 66 | const MG_LC_F: i64 = 102 |
| 67 | const MG_LC_X: i64 = 120 |
| 68 | const MG_LC_Z: i64 = 122 |
| 69 | const MG_UC_A: i64 = 65 |
| 70 | const MG_UC_F: i64 = 70 |
| 71 | const MG_UC_X: i64 = 88 |
| 72 | const MG_UC_Z: i64 = 90 |
| 73 | const MG_BASE_DEC: i64 = 10 |
| 74 | const MG_BASE_HEX: i64 = 16 |
| 75 | const MG_HEXDIG_OFF: i64 = 10 |
| 80 | const MG_HEX_SAFE_DIGITS: i64 = 15 |
| 86 | const MG_STAT_HEX: i64 = 0 |
| 87 | const MG_STAT_HEX_OVERSIZE: i64 = 1 |
| 88 | const MG_STAT_N: i64 = 2 |
| 89 | const MG_I64_BYTES: i64 = 8 |
| 323 | const MG_NAMES_CONF: *u8 = "knowledge/magic_names.conf" |
| 324 | const MG_NAMES_MAX: i64 = 512 |
| 325 | const MG_NAMES_FIELD: i64 = 96 // a needle or a name; the why column is read and not stored |
| 326 | const MG_NAMES_COL_VALUE: i64 = 0 |
| 327 | const MG_NAMES_COL_NEEDLE: i64 = 1 |
| 328 | const MG_NAMES_COL_NAME: i64 = 2 |
| 329 | const MG_NAME_W: i64 = 256 // one resolved name: prefix, underscore, name -- or the mechanical form |
| 330 | const MG_NAME_ANY: i64 = 42 // the * needle: any context |
| 331 | const MG_PIPE: i64 = 124 |
| 332 | const MG_HASH: i64 = 35 // a comment row in the conf |
| 333 | const MG_CR: i64 = 13 // a CRLF conf reads the same as an LF one |
| 334 | const MG_CTX: i64 = 60 // the context window `map` prints and the resolver reads |
| 338 | const MG_CTX_LEAD: i64 = 24 |
| 454 | const MG_KIND_CONF: *u8 = "knowledge/magic_kinds.conf" |
| 455 | const MG_KROW_UNIT: *u8 = "unit" |
| 456 | const MG_KROW_KIND: *u8 = "kind" |
| 457 | const MG_KROW_DERIVE: *u8 = "derive" |
| 458 | const MG_KIND_UNIT: *u8 = "UNIT" |
| 459 | const MG_KIND_FIXTURE: *u8 = "FIXTURE" |
| 460 | const MG_KIND_UNKNOWN: *u8 = "UNKNOWN" |
| 461 | const MG_GATE_SFX: *u8 = "_gate.nx" |
| 462 | const MG_PLACEHOLDER: *u8 = "_MAGIC_" |
| 463 | const MG_CONST_KW: *u8 = "const " |
| 464 | const MG_KCOL_TAG: i64 = 0 |
| 465 | const MG_KCOL_KEY: i64 = 1 |
| 466 | const MG_KCOL_VAL: i64 = 2 |
| 467 | const MG_KD_COLON: i64 = 58 |
functions
| 91 | func mg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 92 | func mg_is_ident(c: i64) -> i64 |
| 99 | func mg_is_digit(c: i64) -> i64 { if c >= MG_ZERO { if c <= MG_NINE { return 1 } } return 0 } |
| 103 | func mg_is_hexdigit(c: i64) -> i64 called by 1: main |
| 112 | func mg_hexval(c: i64) -> i64 called by 1: main |
| 119 | func mg_first_ns(q: *u8, ls: i64, le: i64) -> i64 |
| 129 | func mg_starts(q: *u8, ls: i64, le: i64, lit: *u8) -> i64 |
| 138 | func mg_skip_line(q: *u8, ls: i64, le: i64) -> i64 calls 1: mg_starts |
| 144 | func mg_read(path: *u8, b: *u8, cap: i64) -> i64 |
| 162 | func mg_distinct(sval: *i64, sites: i64, tbl: *i64, cap: i64) -> i64 |
| 181 | func mg_scan(q: *u8, n: i64, thr: i64, sline: *i64, scol: *i64, slen: *i64, sval: *i64, sls: *i64, sle: *i64, sbase: *i64, sstat: *i64) -> i64 |
| 347 | func mg_nm_int(s: *u8) -> i64 |
| 354 | func mg_nm_field(b: *u8, s: i64, e: i64, idx: i64, out: *u8, cap: i64) -> i64 |
| 368 | func mg_names_load(path: *u8) -> i64 |
| 402 | func mg_names_src() -> i64 { return mg_nm_src } |
| 403 | func mg_names_count() -> i64 { return mg_nm_n } |
| 404 | func mg_nm_name_at(row: i64) -> *u8 { return (mg_nm_arena as i64 + mg_nm_name[row]) as *u8 } |
| 405 | func mg_nm_needle_at(row: i64) -> *u8 { return (mg_nm_arena as i64 + mg_nm_needle[row]) as *u8 } |
| 407 | func mg_ctx_window(ls: i64, le: i64, col: i64, csp: *i64, cep: *i64) -> i64 |
| 420 | func mg_ctx_has(q: *u8, cs: i64, ce: i64, needle: *u8) -> i64 |
| 434 | func mg_name_lookup(v: i64, q: *u8, cs: i64, ce: i64) -> i64 |
| 472 | func mg_kinds_load(path: *u8) -> i64 |
| 481 | func mg_kinds_bytes() -> i64 { return mg_kd_n } |
| 483 | func mg_line_end(b: *u8, n: i64, i: i64) -> i64 |
| 489 | func mg_str_eq(a: *u8, b: *u8) -> i64 |
| 495 | func mg_copy(dst: *u8, src: *u8, cap: i64) -> i64 |
| 502 | func mg_ends(s: *u8, sfx: *u8) -> i64 |
| 513 | func mg_kind_of(path: *u8, v: i64, q: *u8, cs: i64, ce: i64, out: *u8, cap: i64) -> i64 |
| 547 | func mg_kind_derive(kind: *u8, out: *u8, cap: i64) -> i64 |
| 568 | func mg_seen_add(seen: *u8, so: i64, w: *u8) -> i64 |
| 582 | func mg_placeholder_decl(q: *u8, ls: i64, le: i64) -> i64 |
| 589 | func mg_placeholder_count(q: *u8, n: i64) -> i64 |