code wiki / _hdl_build / nx_magic.nx

nx_magic.nx source

↩ module page · 615 lines · 33446 B

1// nx_magic.nx -- the MISSING FIXER for law L001 (CLAUDE rule 11, debt seq274 sev8). 2// nx_law_warden DETECTS the breach (2348 inline literals over 600 organs) and cap-autonomy FILES it, 3// but nothing turned a breach into a one-step SAFE edit -- so the operator kept watching workstreams 4// "hit these as bugs and just give them a NEW NUMBER". This organ closes that half. 5// nx_magic map <file.nx> [threshold] -> JSON: every offending line+col+value+context, UNCAPPED 6// nx_magic propose <file.nx> [threshold] -> JSON: the const block + per-value site counts 7// nx_magic apply <file.nx> [threshold] -> ATOMIC rewrite: hoist each distinct value to a named 8// const inserted AFTER the last import and BEFORE the 9// first func (the forward-ref law: a const must be 10// declared above every reader), then replace the sites. 11// SEMANTIC-NEUTRALITY IS PROVABLE, NOT ASSERTED: hoisting a literal to a const must compile to the 12// SAME code, so the caller's proof is a BYTE-IDENTICAL elf on rebuild. Not identical => the transform 13// is NOT neutral => revert. (nx_magic never builds; it stays a pure, reviewable text transform.) 14// SKIPPED BY CONSTRUCTION (false-positive control): comments -- BOTH whole-line and TRAILING-after-code 15// (the trailing case was unhandled until 2026-08-14; this line said "comment lines" and meant it), 16// const/static DECLARATION lines, 17// bytes inside string literals, digits that are part of an identifier (x2048), and any value below 18// the threshold. BOTH BASES SINCE 2026-08-25: decimal AND 0x/0X hex. This line used to read "Decimal only 19// -- hex is DECLARED out of envelope (nearly all hex here is < 1024)", and a declared blind spot is still 20// a blind spot when the number it produces is published as a rule-11 count. MEASURED on 21// buildroot/runtime/_hdl_build/nx_activities_gate.nx at floor 2: 41 sites / 26 distinct INCLUDING a 22// decimal 420 -- and NOT the four `0x1ed` literals four lines away in the same file, which are the same 23// number. The scanner itself now lives in nx_magic_lib.nx so it can be mutation-proven in-process 24// (nx_magic_gate); its header carries the mechanism and the scope of what this does NOT change. 25// IDEMPOTENT: a value whose const already exists is not re-hoisted, so a second apply is a no-op. 26// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 27import "nx_syscalls.nx" 28import "nx_magic_lib.nx" 29const MG_MAGIC_1024: i64 = 1024 30const MG_MAGIC_4096: i64 = 4096 31 32const MG_OUT: i64 = 1048576 33const MG_COMMA: i64 = 44 34const MG_COLON: i64 = 58 35const MG_LB: i64 = 123 36const MG_RB: i64 = 125 37const MG_DEF_THRESHOLD: i64 = 1024 38// MG_FLOOR, MG_MAXVALS, MG_MAXSITES, the byte constants, the line-scan helpers, mg_read and mg_scan 39// itself all moved to nx_magic_lib.nx on 2026-08-25 and arrive via the import above. TWO reasons, and 40// the second is the one that pays: (a) inside a program with main() the scanner was unreachable to 41// nx_gate_bite, so the estate's rule-11 ruler had never had a tooth on it; (b) nx_magicratchet now 42// computes the floor view by CALLING that scanner in-process instead of forking a second ruler, so the 43// number on a build refusal and the number in this JSON cannot drift apart. 44const MG_STDERR: i64 = 2 45const MG_EXIT_USAGE: i64 = 2 46const MG_EXIT_ABSENT: i64 = 4 47const MG_FMODE: i64 = MODE_0644 48// MG_CTX and MG_CTX_LEAD moved to nx_magic_lib.nx (2026-09-05): the purpose-name resolver reads the SAME window 49// `map` prints, so the two can never disagree about what a reader saw when a literal was named. 50 51func mg_werr(s: *u8) -> i64 { sys_write(MG_STDERR, s, mg_slen(s)); return 0 } 52func mg_eqs(a: *u8, b: *u8) -> i64 { 53 var i: i64 = 0 54 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } 55 if b[i] != (0 as u8) { return 0 } 56 return 1 57} 58func mg_b(d: *u8, o: i64, c: i64) -> i64 { d[o] = c as u8; return o + 1 } 59func mg_cat(d: *u8, o: i64, s: *u8) -> i64 { 60 var oo: i64 = o 61 var i: i64 = 0 62 while s[i] != (0 as u8) { d[oo] = s[i]; oo = oo + 1; i = i + 1 } 63 return oo 64} 65func mg_catn(d: *u8, o: i64, v: i64) -> i64 { 66 let t: *u8 = sys_mmap(32) 67 var m: i64 = v 68 var k: i64 = 0 69 if m < 0 { d[o] = 45 as u8; o = o + 1; m = 0 - m } 70 if m == 0 { t[0] = 48 as u8; k = 1 } 71 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 72 var oo: i64 = o 73 var i: i64 = 0 74 while i < k { d[oo] = t[k-1-i]; oo = oo + 1; i = i + 1 } 75 return oo 76} 77func mg_atoi(s: *u8) -> i64 { 78 var v: i64 = 0 79 var i: i64 = 0 80 while s[i] != (0 as u8) { 81 let c: i64 = s[i] as i64 82 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } 83 i = i + 1 84 } 85 return v 86} 87// mg_is_ident / mg_is_digit / mg_first_ns / mg_starts / mg_skip_line / mg_read now live in 88// nx_magic_lib.nx beside the scanner that uses them -- they are the SAME functions, moved, not rewritten. 89// Detect the file's dominant const PREFIX (chars before the first '_' of a const name) so generated 90// names stay idiomatic to the organ instead of importing a foreign convention. Falls back to "K". 91func mg_detect_prefix(q: *u8, n: i64, out: *u8) -> i64 { 92 var i: i64 = 0 93 var done: i64 = 0 94 while i < n { 95 var le: i64 = i 96 var s: i64 = 1 97 while s == 1 { if le >= n { s = 0 } else { if q[le] == (MG_NL as u8) { s = 0 } else { le = le + 1 } } } 98 if done == 0 { 99 if mg_starts(q, i, le, "const " as *u8) == 1 { 100 let st: i64 = mg_first_ns(q, i, le) + 6 101 var p: i64 = st 102 var go2: i64 = 1 103 while go2 == 1 { 104 go2 = 0 105 if p < le { if q[p] != (MG_US as u8) { if mg_is_ident(q[p] as i64) == 1 { p = p + 1; go2 = 1 } } } 106 } 107 if p > st { if p < le { if q[p] == (MG_US as u8) { 108 var k: i64 = 0 109 while k < p - st { out[k] = q[st+k]; k = k + 1 } 110 out[p-st] = 0 as u8 111 done = 1 112 } } } 113 } 114 } 115 i = le + 1 116 } 117 if done == 0 { out[0] = 75 as u8; out[1] = 0 as u8 } 118 return 0 119} 120// build the generated const name for a value into out: <PFX>_MAGIC_<value> 121func mg_name_for(pfx: *u8, v: i64, out: *u8) -> i64 { 122 var o: i64 = mg_cat(out, 0, pfx) 123 o = mg_cat(out, o, "_MAGIC_" as *u8) 124 o = mg_catn(out, o, v) 125 out[o] = 0 as u8 126 return o 127} 128// does the file already contain "const <name>" (idempotency + collision guard)? 129func mg_has_const(q: *u8, n: i64, name: *u8) -> i64 { 130 let nl: i64 = mg_slen(name) 131 var i: i64 = 0 132 while i < n { 133 var le: i64 = i 134 var s: i64 = 1 135 while s == 1 { if le >= n { s = 0 } else { if q[le] == (MG_NL as u8) { s = 0 } else { le = le + 1 } } } 136 if mg_starts(q, i, le, "const " as *u8) == 1 { 137 let st: i64 = mg_first_ns(q, i, le) + 6 138 if st + nl <= le { 139 var k: i64 = 0 140 var ok: i64 = 1 141 while k < nl { if q[st+k] != name[k] { ok = 0; k = nl } else { k = k + 1 } } 142 if ok == 1 { if st + nl < le { if mg_is_ident(q[st+nl] as i64) == 0 { return 1 } } else { return 1 } } 143 } 144 } 145 i = le + 1 146 } 147 return 0 148} 149// json-safe slice copy (context snippets can carry quotes/backslashes) 150func mg_cat_json(d: *u8, o: i64, q: *u8, a: i64, b: i64) -> i64 { 151 var oo: i64 = o 152 var i: i64 = a 153 while i < b { 154 var c: i64 = q[i] as i64 155 if c == MG_QU { c = 39 } 156 if c == MG_BSL { c = MG_SLASH } 157 if c < 32 { c = MG_SP } 158 d[oo] = c as u8 159 oo = oo + 1 160 i = i + 1 161 } 162 return oo 163} 164 165// THE SCANNER MOVED TO nx_magic_lib.nx ON 2026-08-25, taking its whole comment history with it, and it 166// gained a second BASE while it was there. Two things this file must not do any more: re-implement it, 167// and print an envelope that says decimal_only. Both are handled in main() below against the lib's own 168// MG_STAT_* channel, so the notation counts come from the scanner rather than from a claim about it. 169func main(argc: i64, argv: *i64) -> i64 { 170 if argc < 3 { mg_werr("usage: nx_magic map|propose|apply <file.nx> [threshold]\n" as *u8); sys_exit(MG_EXIT_USAGE); return MG_EXIT_USAGE } 171 let verb: *u8 = argv[1] as *u8 172 let path: *u8 = argv[2] as *u8 173 var thr: i64 = MG_DEF_THRESHOLD 174 if argc > 3 { thr = mg_atoi(argv[3] as *u8) } 175 if thr < 1 { thr = MG_DEF_THRESHOLD } 176 177 let q: *u8 = sys_mmap(MG_CAP) 178 let n: i64 = mg_read(path, q, MG_CAP - 1) 179 if n <= 0 { mg_werr("SOURCE ABSENT/EMPTY (fail-closed): " as *u8); mg_werr(path); mg_werr("\n" as *u8); sys_exit(MG_EXIT_ABSENT); return MG_EXIT_ABSENT } 180 181 let sline: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 182 let scol: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 183 let slen: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 184 let sval: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 185 let sls: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 186 let sle: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 187 let sbase: *i64 = sys_mmap(MG_MAXSITES * MG_I64_BYTES) as *i64 188 let sstat: *i64 = sys_mmap(MG_STAT_N * MG_I64_BYTES) as *i64 189 let sites: i64 = mg_scan(q, n, thr, sline, scol, slen, sval, sls, sle, sbase, sstat) 190 191 // THE HIDDEN POPULATION (2026-08-14). Measured cost of NOT reporting this: a seat read `sites:0` 192 // at the default 1024 and published ELEVEN organs as "rule-11 clean"; re-measured at floor 2, 193 // nx_skullgen alone was 426 sites / 93 distinct. The count was never wrong -- the sentence it 194 // invited was. With floor_sites printed beside it, a thresholded zero CANNOT be read as clean. 195 // It also fixes the TWIN defect: a two-sided band (`g < 800` / `g > 1200`) puts one edge above 196 // the bar and one below, so the default view named HI and silently hid LO. The floor view has both. 197 let fline: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 198 let fcol: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 199 let flen: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 200 let fval: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 201 let fls: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 202 let fle: *i64 = sys_mmap(MG_MAXSITES * 8) as *i64 203 let fbase: *i64 = sys_mmap(MG_MAXSITES * MG_I64_BYTES) as *i64 204 let fstat: *i64 = sys_mmap(MG_STAT_N * MG_I64_BYTES) as *i64 205 let floor_sites: i64 = mg_scan(q, n, MG_FLOOR, fline, fcol, flen, fval, fls, fle, fbase, fstat) 206 let fdv: *i64 = sys_mmap(MG_MAXVALS * MG_I64_BYTES) as *i64 207 // ONE distinct counter for the whole rule-11 lane. The hand-rolled loop that used to sit here was 208 // the second copy of it; nx_magicratchet needing the same number would have made a third, and three 209 // copies of a counting loop is how two organs come to disagree about one population. mg_distinct 210 // lives in nx_magic_lib.nx beside the scanner whose output it counts. 211 let floor_distinct: i64 = mg_distinct(fval, floor_sites, fdv, MG_MAXVALS) 212 // NO SILENT CAPS: mg_scan stops recording at MG_MAXSITES, so say so rather than publish a 213 // truncated floor count as a total. 214 var floor_trunc: i64 = 0 215 if floor_sites >= MG_MAXSITES { floor_trunc = 1 } 216 217 // distinct values (insertion-ordered) 218 let dval: *i64 = sys_mmap(MG_MAXVALS * 8) as *i64 219 let dcnt: *i64 = sys_mmap(MG_MAXVALS * 8) as *i64 220 var nd: i64 = 0 221 var i2: i64 = 0 222 while i2 < sites { 223 var found: i64 = 0 224 var j: i64 = 0 225 while j < nd { if dval[j] == sval[i2] { dcnt[j] = dcnt[j] + 1; found = 1; j = nd } else { j = j + 1 } } 226 if found == 0 { if nd < MG_MAXVALS { dval[nd] = sval[i2]; dcnt[nd] = 1; nd = nd + 1 } } 227 i2 = i2 + 1 228 } 229 230 let pfx: *u8 = sys_mmap(256) 231 mg_detect_prefix(q, n, pfx) 232 let nm: *u8 = sys_mmap(256) 233 let out: *u8 = sys_mmap(MG_OUT) 234 235 // PURPOSE NAMES (2026-09-05): every site is named ONCE, here, from knowledge/magic_names.conf when a row claims its 236 // value AND its context window, else the mechanical <PFX>_MAGIC_<v>. Consts are then deduped by NAME, not by value, 237 // so one value carrying two meanings (8 as bytes-per-i64 beside 8 as a shift count) gets two consts. Every verb 238 // below reads this one resolution, so map, propose and apply cannot disagree about a name. 239 let names_rows: i64 = mg_names_load(MG_NAMES_CONF) 240 // KIND AND DERIVATION (operator 2026-09-17): every offender row says what the number IS and where a number of that 241 // kind should COME FROM, from knowledge/magic_kinds.conf. The derive buffer is sized from the table itself. 242 let kinds_bytes: i64 = mg_kinds_load(MG_KIND_CONF) 243 let kindw: *u8 = sys_mmap(MG_NAME_W) 244 let derivew: *u8 = sys_mmap(kinds_bytes + 1) 245 // placeholder-named constants (<PFX>_MAGIC_<value>) are literals wearing a name: counted on their own axis 246 let placeholders: i64 = mg_placeholder_count(q, n) 247 // the kinds this report has seen, so each derivation sentence is printed ONCE and not once per row 248 let kseen: *u8 = sys_mmap(kinds_bytes + MG_NAME_W + 1) 249 var kso: i64 = 0 250 let sname: *u8 = sys_mmap(MG_MAXSITES * MG_NAME_W) 251 let snamed: *i64 = sys_mmap(MG_MAXSITES * MG_I64_BYTES) as *i64 252 let csp: *i64 = sys_mmap(MG_I64_BYTES) as *i64 253 let cep: *i64 = sys_mmap(MG_I64_BYTES) as *i64 254 var named_sites: i64 = 0 255 var ri: i64 = 0 256 while ri < sites { 257 let slot: *u8 = (sname as i64 + ri * MG_NAME_W) as *u8 258 mg_ctx_window(sls[ri], sle[ri], scol[ri], csp, cep) 259 let row: i64 = mg_name_lookup(sval[ri], q, csp[0], cep[0]) 260 if row >= 0 { 261 var so: i64 = mg_cat(slot, 0, pfx) 262 so = mg_cat(slot, so, "_" as *u8) 263 so = mg_cat(slot, so, mg_nm_name_at(row)) 264 slot[so] = 0 as u8 265 snamed[ri] = 1 266 named_sites = named_sites + 1 267 } else { mg_name_for(pfx, sval[ri], slot); snamed[ri] = 0 } 268 ri = ri + 1 269 } 270 let dname: *u8 = sys_mmap(MG_MAXVALS * MG_NAME_W) 271 let dnval: *i64 = sys_mmap(MG_MAXVALS * MG_I64_BYTES) as *i64 272 let dncnt: *i64 = sys_mmap(MG_MAXVALS * MG_I64_BYTES) as *i64 273 let dnsrc: *i64 = sys_mmap(MG_MAXVALS * MG_I64_BYTES) as *i64 274 var nn: i64 = 0 275 var di: i64 = 0 276 while di < sites { 277 let slot2: *u8 = (sname as i64 + di * MG_NAME_W) as *u8 278 var found2: i64 = 0 279 var j2: i64 = 0 280 while j2 < nn { if mg_eqs((dname as i64 + j2 * MG_NAME_W) as *u8, slot2) == 1 { dncnt[j2] = dncnt[j2] + 1; found2 = 1; j2 = nn } else { j2 = j2 + 1 } } 281 if found2 == 0 { if nn < MG_MAXVALS { 282 let dslot: *u8 = (dname as i64 + nn * MG_NAME_W) as *u8 283 let dl: i64 = mg_cat(dslot, 0, slot2) 284 dslot[dl] = 0 as u8 285 dnval[nn] = sval[di] 286 dncnt[nn] = 1 287 dnsrc[nn] = snamed[di] 288 nn = nn + 1 289 } } 290 di = di + 1 291 } 292 293 if mg_eqs("map" as *u8, verb) == 1 { 294 var o: i64 = mg_b(out, 0, MG_LB) 295 o = mg_cat(out, o, "\"tool\":\"nx_magic\",\"verb\":\"map\",\"file\":\"" as *u8) 296 o = mg_cat(out, o, path) 297 o = mg_cat(out, o, "\",\"threshold\":" as *u8) 298 o = mg_catn(out, o, thr) 299 o = mg_cat(out, o, ",\"floor\":" as *u8) 300 o = mg_catn(out, o, MG_FLOOR) 301 o = mg_cat(out, o, ",\"floor_sites\":" as *u8) 302 o = mg_catn(out, o, floor_sites) 303 o = mg_cat(out, o, ",\"floor_distinct\":" as *u8) 304 o = mg_catn(out, o, floor_distinct) 305 o = mg_cat(out, o, ",\"floor_truncated\":" as *u8) 306 o = mg_catn(out, o, floor_trunc) 307 // THE NOTATION COUNTS TRAVEL WITH THE SITE COUNTS (2026-08-25). Without them a reader cannot 308 // tell a file that genuinely has no hex from one this scanner used to be unable to see. 309 o = mg_cat(out, o, ",\"hex_sites\":" as *u8) 310 o = mg_catn(out, o, sstat[MG_STAT_HEX]) 311 o = mg_cat(out, o, ",\"floor_hex_sites\":" as *u8) 312 o = mg_catn(out, o, fstat[MG_STAT_HEX]) 313 o = mg_cat(out, o, ",\"hex_oversize_skipped\":" as *u8) 314 o = mg_catn(out, o, fstat[MG_STAT_HEX_OVERSIZE]) 315 o = mg_cat(out, o, ",\"sites\":" as *u8) 316 o = mg_catn(out, o, sites) 317 o = mg_cat(out, o, ",\"distinct_values\":" as *u8) 318 o = mg_catn(out, o, nd) 319 // PURPOSE NAMES (2026-09-05): the table, its rows and how many sites it claimed travel in the envelope, so a 320 // reader can tell a file the table does not know from one where every literal already has a name 321 o = mg_cat(out, o, ",\"distinct_names\":" as *u8) 322 o = mg_catn(out, o, nn) 323 o = mg_cat(out, o, ",\"names_conf\":\"" as *u8) 324 o = mg_cat(out, o, MG_NAMES_CONF) 325 o = mg_cat(out, o, "\",\"names_rows\":" as *u8) 326 o = mg_catn(out, o, names_rows) 327 o = mg_cat(out, o, ",\"named_sites\":" as *u8) 328 o = mg_catn(out, o, named_sites) 329 o = mg_cat(out, o, ",\"const_prefix\":\"" as *u8) 330 o = mg_cat(out, o, pfx) 331 o = mg_cat(out, o, "\",\"rows\":[" as *u8) 332 var k2: i64 = 0 333 while k2 < sites { 334 if k2 > 0 { o = mg_b(out, o, MG_COMMA) } 335 o = mg_cat(out, o, "{\"line\":" as *u8) 336 o = mg_catn(out, o, sline[k2]) 337 o = mg_cat(out, o, ",\"col\":" as *u8) 338 o = mg_catn(out, o, scol[k2]) 339 o = mg_cat(out, o, ",\"value\":" as *u8) 340 o = mg_catn(out, o, sval[k2]) 341 // `value` is always DECIMAL, whatever the source wrote. Publishing the base beside it is what 342 // stops a reader hunting for the literal `493` in a file that spells it 0x1ed. 343 o = mg_cat(out, o, ",\"base\":" as *u8) 344 o = mg_catn(out, o, sbase[k2]) 345 o = mg_cat(out, o, ",\"proposed_const\":\"" as *u8) 346 // ONLY a name the purpose table claims is proposed. A mechanical PFX_MAGIC_value name was an invitation to rename, 347 // so an unclaimed site proposes NO const: the field stays (rule 19) and is empty, and name_src says why. 348 if snamed[k2] == 1 { o = mg_cat(out, o, (sname as i64 + k2 * MG_NAME_W) as *u8) } 349 o = mg_cat(out, o, "\",\"name_src\":\"" as *u8) 350 if snamed[k2] == 1 { o = mg_cat(out, o, "table" as *u8) } else { o = mg_cat(out, o, "none-derive-it-see-kind" as *u8) } 351 o = mg_cat(out, o, "\",\"context\":\"" as *u8) 352 // CENTRE THE WINDOW ON THE SITE (2026-08-14). This always started at the LINE HEAD and 353 // capped at MG_CTX, so a site reported at col 86 arrived showing chars 0..60 -- its own 354 // position outside its own evidence. MEASURED COST: deciding whether nx_skullgen's 72 355 // `100` sites were division denominators (safe to hoist to a unit const) or clamps and 356 // coordinates (NOT safe) left 13 of 72 UNVERIFIABLE from this output, and the 2 that 357 // were visible turned out to be a clamp floor -- so the unverifiable 13 could each have 358 // been a silent source corruption. ★A TOOL THAT REPORTS A POSITION IT CANNOT SHOW YOU 359 // CANNOT AUTHORISE AN EDIT AT THAT POSITION. 360 var cs: i64 = sls[k2] 361 var ce: i64 = sle[k2] 362 if ce - cs > MG_CTX { 363 if scol[k2] > MG_CTX_LEAD { cs = sls[k2] + scol[k2] - MG_CTX_LEAD } 364 ce = cs + MG_CTX 365 if ce > sle[k2] { ce = sle[k2] } 366 } 367 o = mg_cat_json(out, o, q, cs, ce) 368 // `col` is relative to the LINE start, but the window may no longer begin there, so the 369 // offset is published rather than left for the reader to guess: the site sits at 370 // context[col - context_start]. Additive field; nothing existing moves. 371 o = mg_cat(out, o, "\",\"context_start\":" as *u8) 372 o = mg_catn(out, o, cs - sls[k2]) 373 // what the number IS: the remedy is a DERIVATION of that kind, never a rename (the sentence per kind follows the rows) 374 mg_kind_of(path, sval[k2], q, cs, ce, kindw, MG_NAME_W) 375 kso = mg_seen_add(kseen, kso, kindw) 376 o = mg_cat(out, o, ",\"kind\":\"" as *u8) 377 o = mg_cat(out, o, kindw) 378 o = mg_cat(out, o, "\"}" as *u8) 379 k2 = k2 + 1 380 } 381 // THE ENVELOPE NOW TELLS THE TRUTH. These two fields read 1 and 1 from the day this organ shipped 382 // until 2026-08-25; the FIELD NAMES are deliberately kept (rule 19: adding a field is safe, 383 // renaming one breaks every consumer) and their VALUES corrected, so a reader who was checking 384 // `decimal_only` gets the answer rather than a missing key. 385 // the derivation of every kind the rows carry, ONCE each; then the placeholder axis; then the remedy in one sentence 386 o = mg_cat(out, o, "],\"derivations\":{" as *u8) 387 var kp: i64 = 0 388 var kfirst: i64 = 1 389 while kp < kso { 390 let kw: *u8 = (kseen as i64 + kp) as *u8 391 if kfirst == 0 { o = mg_cat(out, o, "," as *u8) } 392 kfirst = 0 393 o = mg_cat(out, o, "\"" as *u8) 394 o = mg_cat(out, o, kw) 395 o = mg_cat(out, o, "\":\"" as *u8) 396 mg_kind_derive(kw, derivew, kinds_bytes + 1) 397 o = mg_cat_json(out, o, derivew, 0, mg_slen(derivew)) 398 o = mg_cat(out, o, "\"" as *u8) 399 kp = kp + mg_slen(kw) + 1 400 } 401 o = mg_cat(out, o, "},\"placeholder_consts\":" as *u8) 402 o = mg_catn(out, o, placeholders) 403 o = mg_cat(out, o, ",\"remedy\":\"DERIVE each number from the resource it describes: a literal hoisted into a named const is a rename and is not a fix. Only a UNIT is answered by a constant.\"" as *u8) 404 o = mg_cat(out, o, ",\"envelope\":{\"decimal_only\":0,\"hex_out_of_envelope\":0,\"bases\":\"decimal+0x-hex\",\"hex_safe_digits\":" as *u8) 405 o = mg_catn(out, o, MG_HEX_SAFE_DIGITS) 406 o = mg_cat(out, o, ",\"site_cap\":" as *u8) 407 o = mg_catn(out, o, MG_MAXSITES) 408 o = mg_cat(out, o, ",\"truncated\":" as *u8) 409 var tr: i64 = 0 410 if sites >= MG_MAXSITES { tr = 1 } 411 o = mg_catn(out, o, tr) 412 o = mg_cat(out, o, ",\"skipped\":\"comment+const/static-decl+in-string+identifier-digits+named-index-table-write+hex-wider-than-hex_safe_digits\"}" as *u8) 413 o = mg_b(out, o, MG_RB) 414 o = mg_b(out, o, MG_NL) 415 sys_write(1, out, o) 416 sys_exit(0) 417 return 0 418 } 419 420 if mg_eqs("propose" as *u8, verb) == 1 { 421 var o: i64 = mg_b(out, 0, MG_LB) 422 o = mg_cat(out, o, "\"tool\":\"nx_magic\",\"verb\":\"propose\",\"file\":\"" as *u8) 423 o = mg_cat(out, o, path) 424 // ★★★★★★A ZERO WITHOUT ITS BAR IS A FALSE ALL-CLEAR, AND THIS VERB WAS THE ONE STILL GIVING 425 // ONE. The floor view above is computed on EVERY call and was printed by `map` ALONE -- so the 426 // very incident recorded in its comment (a seat read `sites:0` at the default and published 427 // ELEVEN organs as rule-11 clean) stayed reproducible through `propose`. MEASURED 2026-08-17 on 428 // nx_artifactdrift: `propose` said sites:0 with no threshold shown, `propose <file> 2` said 49. 429 // ★★★★★A FIX WIRED INTO ONE VERB AND NOT ITS SIBLING IS HALF A FIX -- AND THE HALF LEFT UNDONE 430 // WAS THE VERB WHOSE WHOLE PURPOSE IS "TELL ME WHAT TO FIX", SO THE SILENT ZERO LANDED EXACTLY 431 // ON SOMEONE TRYING TO DO THE RIGHT THING. Same values, already in scope; additive fields only. 432 o = mg_cat(out, o, "\",\"threshold\":" as *u8) 433 o = mg_catn(out, o, thr) 434 o = mg_cat(out, o, ",\"floor\":" as *u8) 435 o = mg_catn(out, o, MG_FLOOR) 436 o = mg_cat(out, o, ",\"floor_sites\":" as *u8) 437 o = mg_catn(out, o, floor_sites) 438 o = mg_cat(out, o, ",\"floor_distinct\":" as *u8) 439 o = mg_catn(out, o, floor_distinct) 440 o = mg_cat(out, o, ",\"floor_truncated\":" as *u8) 441 o = mg_catn(out, o, floor_trunc) 442 // Same fields as `map`, for the same reason its floor fields are here: a fix wired into one verb 443 // and not its sibling is half a fix, and the half left undone is always the one that ships. 444 o = mg_cat(out, o, ",\"hex_sites\":" as *u8) 445 o = mg_catn(out, o, sstat[MG_STAT_HEX]) 446 o = mg_cat(out, o, ",\"floor_hex_sites\":" as *u8) 447 o = mg_catn(out, o, fstat[MG_STAT_HEX]) 448 o = mg_cat(out, o, ",\"hex_oversize_skipped\":" as *u8) 449 o = mg_catn(out, o, fstat[MG_STAT_HEX_OVERSIZE]) 450 o = mg_cat(out, o, ",\"sites\":" as *u8) 451 o = mg_catn(out, o, sites) 452 o = mg_cat(out, o, ",\"consts\":[" as *u8) 453 // PURPOSE NAMES (2026-09-05): one const per distinct NAME (a value that means two things is two rows), each 454 // saying whether the table named it or the mechanical form stood in -- the worklist is the mechanical rows 455 var k3: i64 = 0 456 while k3 < nn { 457 if k3 > 0 { o = mg_b(out, o, MG_COMMA) } 458 let pn: *u8 = (dname as i64 + k3 * MG_NAME_W) as *u8 459 o = mg_cat(out, o, "{\"name\":\"" as *u8) 460 o = mg_cat(out, o, pn) 461 o = mg_cat(out, o, "\",\"value\":" as *u8) 462 o = mg_catn(out, o, dnval[k3]) 463 o = mg_cat(out, o, ",\"sites\":" as *u8) 464 o = mg_catn(out, o, dncnt[k3]) 465 o = mg_cat(out, o, ",\"name_src\":\"" as *u8) 466 if dnsrc[k3] == 1 { o = mg_cat(out, o, "table" as *u8) } else { o = mg_cat(out, o, "mechanical" as *u8) } 467 o = mg_cat(out, o, "\",\"already_declared\":" as *u8) 468 o = mg_catn(out, o, mg_has_const(q, n, pn)) 469 o = mg_b(out, o, MG_RB) 470 k3 = k3 + 1 471 } 472 o = mg_cat(out, o, "],\"distinct_names\":" as *u8) 473 o = mg_catn(out, o, nn) 474 o = mg_cat(out, o, ",\"names_conf\":\"" as *u8) 475 o = mg_cat(out, o, MG_NAMES_CONF) 476 o = mg_cat(out, o, "\",\"names_rows\":" as *u8) 477 o = mg_catn(out, o, names_rows) 478 o = mg_cat(out, o, ",\"named_sites\":" as *u8) 479 o = mg_catn(out, o, named_sites) 480 o = mg_cat(out, o, ",\"note\":\"a name_src=table const says WHY (knowledge/magic_names.conf claimed its value and its context); a name_src=mechanical row RESTATES the value, and apply NO LONGER hoists it: a rename is not a fix. DERIVE that number from the resource it describes -- nx_magic map gives each site its KIND and says where a number of that kind comes from; a table row is right only for a UNIT or a character code\"" as *u8) 481 o = mg_b(out, o, MG_RB) 482 o = mg_b(out, o, MG_NL) 483 sys_write(1, out, o) 484 sys_exit(0) 485 return 0 486 } 487 488 if mg_eqs("apply" as *u8, verb) == 1 { 489 if sites == 0 { 490 mg_werr("NO-OP no sites at or above threshold\n" as *u8) 491 sys_exit(0) 492 return 0 493 } 494 // insertion point = end of the LAST import line (consts must precede every reader) 495 var ins: i64 = 0 496 var li: i64 = 0 497 while li < n { 498 var le: i64 = li 499 var s: i64 = 1 500 while s == 1 { if le >= n { s = 0 } else { if q[le] == (MG_NL as u8) { s = 0 } else { le = le + 1 } } } 501 if mg_starts(q, li, le, "import " as *u8) == 1 { ins = le + 1 } 502 li = le + 1 503 } 504 let nb: *u8 = sys_mmap(MG_OUT) 505 var o: i64 = 0 506 var c1: i64 = 0 507 while c1 < ins { nb[o] = q[c1]; o = o + 1; c1 = c1 + 1 } 508 // const block (skip any value already declared -> idempotent) 509 // PURPOSE NAMES (2026-09-05): one const per distinct NAME; a table-named const carries NX-NAMED and says WHY, 510 // a mechanical one keeps the NX-UNNAMED placeholder marker below so nobody mistakes it for a finished fix 511 var added: i64 = 0 512 var named_added: i64 = 0 513 var k4: i64 = 0 514 while k4 < nn { 515 let an: *u8 = (dname as i64 + k4 * MG_NAME_W) as *u8 516 // ONLY a name the purpose table CLAIMED becomes a const (operator 2026-09-17: a mechanical <PFX>_MAGIC_<value> 517 // const is a RENAME, not a fix -- 13,375 such declarations were measured estate-wide the day apply stopped 518 // minting them, up from 11,739 a month earlier: the NX-UNNAMED marker below never slowed the inflow) 519 if dnsrc[k4] == 1 { if mg_has_const(q, n, an) == 0 { 520 o = mg_cat(nb, o, "const " as *u8) 521 o = mg_cat(nb, o, an) 522 o = mg_cat(nb, o, ": i64 = " as *u8) 523 o = mg_catn(nb, o, dnval[k4]) 524 if dnsrc[k4] == 1 { 525 o = mg_cat(nb, o, " // NX-NAMED: knowledge/magic_names.conf claimed this value in this context, so the name says WHY; keep it unless the meaning is wrong" as *u8) 526 named_added = named_added + 1 527 } else { 528 // THE MARKER MUST TRAVEL WITH THE ARTEFACT, NOT THE PROPOSAL (2026-08-15). 529 // `propose` already states that these names are mechanical and that renaming them is 530 // the owner judgement rule-11 asks for -- but that note lives in JSON read once at 531 // apply time, while the const it describes lives in the source forever. MEASURED: 532 // 262 declarations of `*_MAGIC_1048576` for that ONE value, and 11,739 value-named 533 // consts estate-wide. A placeholder that does not SAY it is a placeholder reads as a 534 // finished fix, which is exactly why nobody ever came back to them. 535 o = mg_cat(nb, o, " // NX-UNNAMED: mechanical, collision-free placeholder -- this name RESTATES the value and so carries no meaning. Replace it with a domain term that says WHY, or add a row to knowledge/magic_names.conf so every organ inherits the meaning." as *u8) 536 } 537 o = mg_b(nb, o, MG_NL) 538 added = added + 1 539 } } 540 k4 = k4 + 1 541 } 542 // body with each site replaced by its const name 543 var si: i64 = 0 544 var p2: i64 = ins 545 var left: i64 = 0 546 // skip any site lying before the insertion point (import lines carry no literals, but the 547 // scan is whole-file, so the site cursor must start aligned with the copy cursor) 548 var guard: i64 = 1 549 while guard == 1 { 550 guard = 0 551 if si < sites { if sls[si] + scol[si] < ins { si = si + 1; guard = 1 } } 552 } 553 while p2 < n { 554 var isite: i64 = 0 555 if si < sites { if sls[si] + scol[si] == p2 { isite = 1 } } 556 if isite == 1 { 557 // a site the purpose table claims takes its name; every other site KEEPS ITS LITERAL, so the ratchet keeps 558 // counting it until the number is DERIVED from the resource it describes 559 if snamed[si] == 1 { 560 o = mg_cat(nb, o, (sname as i64 + si * MG_NAME_W) as *u8) 561 } else { 562 var cp: i64 = 0 563 while cp < slen[si] { nb[o] = q[p2 + cp]; o = o + 1; cp = cp + 1 } 564 left = left + 1 565 } 566 p2 = p2 + slen[si] 567 si = si + 1 568 } else { 569 nb[o] = q[p2] 570 o = o + 1 571 p2 = p2 + 1 572 } 573 } 574 // atomic: tmp + fsync + rename (a reader never sees a torn source) 575 let tmpp: *u8 = sys_mmap(MG_MAGIC_1024) 576 var to: i64 = mg_cat(tmpp, 0, path) 577 to = mg_cat(tmpp, to, ".mgtmp" as *u8) 578 tmpp[to] = 0 as u8 579 let fd: i64 = sys_openat_wr(tmpp, MG_FMODE) 580 if fd < 0 { mg_werr("apply: cannot open tmp\n" as *u8); sys_exit(1); return 1 } 581 sys_write(fd, nb, o) 582 sys_fsync(fd) 583 sys_close(fd) 584 sys_renameat(tmpp, path) 585 let m: *u8 = sys_mmap(MG_MAGIC_4096) 586 var mo: i64 = mg_cat(m, 0, "MAGIC-APPLIED file=" as *u8) 587 mo = mg_cat(m, mo, path) 588 mo = mg_cat(m, mo, " consts_added=" as *u8) 589 mo = mg_catn(m, mo, added) 590 mo = mg_cat(m, mo, " named_by_table=" as *u8) 591 mo = mg_catn(m, mo, named_added) 592 mo = mg_cat(m, mo, " mechanical=" as *u8) 593 mo = mg_catn(m, mo, added - named_added) 594 mo = mg_cat(m, mo, " names_rows=" as *u8) 595 mo = mg_catn(m, mo, names_rows) 596 mo = mg_cat(m, mo, " sites_replaced=" as *u8) 597 mo = mg_catn(m, mo, sites - left) 598 mo = mg_cat(m, mo, " left_for_derivation=" as *u8) 599 mo = mg_catn(m, mo, left) 600 mo = mg_cat(m, mo, " (those keep their literal: nx_magic map names each one's KIND and where a number of that kind comes from)" as *u8) 601 mo = mg_cat(m, mo, " bytes=" as *u8) 602 mo = mg_catn(m, mo, o) 603 mo = mg_cat(m, mo, " -- NEUTRALITY IS UNPROVEN UNTIL YOU REBUILD AND BYTE-COMPARE THE ELF\n" as *u8) 604 sys_write(1, m, mo) 605 sys_exit(0) 606 return 0 607 } 608 609 mg_werr("usage: nx_magic map|propose|apply <file.nx> [threshold]\n" as *u8) 610 sys_exit(MG_EXIT_USAGE) 611 return MG_EXIT_USAGE 612} 613// build-provenance 2026-09-05: purpose-names resolver landed (seven chained edits); the first /api/build after them staged a 614// 40062 B artifact carrying NONE of the new strings for a source whose src_sha256 had changed -- the stale build-cache 615// artifact defect measured three times today. This line changes the closure so the cache key cannot match the fossil.