Commit Graph

4 Commits

Author SHA1 Message Date
Drew T 3d1a79a70c fix(aprop): reloc --fix keyed by (binary,fn); lane gains rtu second-chance, MISMATCH auto-repair, borrow-tier decls
reloc_identity --fix's rowmap keyed rows by fn alone, so three same-named
func_8013BCDC rows across binaries all received ONE binary's draft — 2 of 4
'no textual occurrence' refusals were the tool editing the wrong file. Keyed
by (binary, fn): 4/4 repaired to AGREE/MATCH (byte-checked by re-run).

maintenance.sh: stage on status in {AGREE,UNRESOLVED} AND shape==MATCH keyed
(binary,fn); run reloc --fix on MISMATCH rows and re-check so repairs stage the
same pass; add rtu_second_chance for standalone COMPILE-FAILs (7/27 measured
TU-byte-MATCH, previously dropped unjudged).

aprop_autodraft decl_for gains the BORROW tier: when both home TU and seed are
silent, adopt a sibling TU's extern spelling under the same body-compatibility
guards — 'which TU may conflict' (home only) and 'where a guess may come from'
(anywhere) are different questions; refusing outright left 125 members undrafted.
2026-08-24 22:29:29 -06:00
Drew T 965ae3902e measure(phase-31): the AGREE re-gate lane is a 5% null — symbol verification does not rescue stored drafts (S52-12)
R37 probe: 20 shape-verified AND symbol-verified stored drafts, 5 gate groups -> 1 banked (5%),
statistically the same as the project's A10 stored-verdict law (~0-8%; T1 measured 0/23 on the same
kind of pile earlier this phase). The null is the finding: a stored draft's rejection is almost
never symbol identity, it is TU plumbing (§176d) or staleness. reloc_identity's real home is a
PRE-GATE check on FRESH drafts, not a backlog resurrection tool. The remaining 30 groups are not
worth 30 rebuilds -- lane closed rather than pursued because the tooling was new and interesting.

Also names the SYMBOL-COLLAPSE class in the fixer's refusal (one draft extern standing in for N
distinct globals; a textual rename moves every occurrence together, so it needs one extern per
site) and records the R38 self-note: the 0/23 prior was already in the phase log.
2026-08-15 09:50:48 -06:00
Drew T 0487c0c627 docs(phase-31): cookbook §176e — symbol identity is COMPUTABLE offline, plus reloc_identity --fix (S52)
§174 law 1c recorded match_one's relocation blindness as a caution to the reader ('check every
symbol by hand after MATCH'). It is a computation, not a human's job. Banks the arithmetic, the two
failure shapes it separates (uniform-delta stale seed symbols vs wrong field offset), the four
traps that bit me building it (splat-derived names absent from the symbol files; MIPS o32 REL keeps
the addend in the instruction; index alignment is a precondition; a nearest-symbol label needs a
tight window), and the honest limit measured the same session: symbol-verified + shape-verified is
still NOT sufficient for a bank -- the first re-gate group of five such drafts banked 0/5, because
what remains is TU plumbing (§176d), not identity.

--fix rewrites only unambiguously-wrong symbols (every mismatch naming a symbol must imply the SAME
corrected base) and refuses otherwise: 10 of 12 repaired, 2 correctly refused.
2026-08-15 09:46:10 -06:00
Drew T 594a87e173 feat(phase-31): reloc_identity.py — the oracle that disagrees with match_one about SYMBOL IDENTITY (S52)
match_one masks relocations (26-bit jal field, HI16/LO16 immediates), so it verifies instruction
SHAPE and is structurally blind to WHICH symbol each relocation names: a draft calling the wrong
function or touching the wrong global reports a clean MATCH (§174 law 1c; wave K burned 5 gate
attempts on two swapped globals). Until now only the whole-binary gate caught it, and it reports a
hash, not a cause.

But the target .s comment column carries the FINAL LINKED WORD, so the true address behind every
masked field is recoverable arithmetically, and config/symbols*.txt maps it back to a name. This
tool resolves what the DRAFT names, computes what the TARGET references, and compares -- /bin/bash, no
rebuild, and it names the fix instead of reporting a mismatch.

match_one --emit-streams additionally carries mine_relocs (kind/operand per index); existing
consumers read mine/tgt only.

THREE INSTRUMENT BUGS FOUND BY ITS OWN NEGATIVE CONTROLS, each fixed before any verdict was
believed (R35/R39):
- splat-derived func_/D_/jtbl_ names are not in the symbol FILES (their address IS their name), so
  the first run checked ZERO relocations on a draft whose every callee was correct -- a checker
  that looks clean while checking nothing (R32).
- the nearest-symbol fallback used a 0x4000 window and labelled func_8001C9D0 as 'SsGetMute+0xC50';
  a wrong label is worse than none. Tightened to 0x200 with an explicit splat-derived fallback.
- MIPS o32 uses REL relocations: THE ADDEND IS IN THE INSTRUCTION, not the reloc entry. Reading it
  off the operand string reported 0 for every struct-field/array access and fabricated mismatches
  (the +1/+2/+3 signature on func_801F0734 was a byte-array walk, not three symbol errors).
Also refuses to answer confidently when the streams are not index-aligned (shape differs), since a
single inserted instruction shifts every later index -- my own NC produced exactly that phantom.

NC: known-good drafts AGREE (3 and 5 relocs actually checked); a synthetic callee 4 bytes off is
caught while match_one still says MATCH; a misaligned mutant is downgraded to advisory.
2026-08-15 09:42:58 -06:00