mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-01 15:43:06 -04:00
57 lines
3.3 KiB
Python
57 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""tools/t5_cards.py — BUILD the card fuel for a wave's own targets (P31 S63 T5).
|
|
|
|
Usage: t5_cards.py --wave .run/t5b [--out <wave>/cards.json]
|
|
|
|
WHY (byte-measured, P31 S63 wave t5a). `claude_wave_packs.py` looked cards up by BARE FUNCTION NAME
|
|
across `.run/wave_*_cards.json`; overlays share names at equal addresses, so 48 of 48 t5a targets
|
|
(and 15 of T4's 20) got ANOTHER binary's card — wrong banked twin, wrong TU neighbours, wrong
|
|
declarations. Nine agents independently reported discarding it. Keying by (binary, fn) fixes the
|
|
mis-attribution but leaves K-class ("never touched") targets with NO fuel at all, and `_fuel()`
|
|
then emits nothing: no `tu_ref`, no `decl_prior`. Yet t5a's agents cracked function after function
|
|
by finding an already-banked sibling in their own TU BY HAND ("in-TU twin ~150 lines earlier",
|
|
"structural twin in the SAME TU") — which is exactly what `tu_ref` is (§194-E, 62% of targets).
|
|
|
|
So this builds the two computable fields for the target ITSELF, from the same oracle
|
|
`build_wave_atlas` uses (`tools/wave_card_fuel.py`, R33):
|
|
tu_ref already-banked functions in the target's OWN TU, ranked by symbols shared with the
|
|
target's .s relocations
|
|
decl_prior the fleet's consensus signature for every symbol the .s references (§196) — kills
|
|
the two-arity A/B compile §195-A proved the asm cannot answer
|
|
`seed_ref` (the cross-TU banked twin) needs the atlas knn and is NOT built here: a card with no
|
|
seed_ref makes `_fuel` say "no banked twin — derive from the .s", which is TRUE, where the old
|
|
name-keyed card pointed confidently at an unrelated function. Coverage is printed (R32/R41)."""
|
|
import argparse, json, os, sys
|
|
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))); os.chdir(REPO)
|
|
sys.path.insert(0, 'tools')
|
|
import wave_card_fuel as F
|
|
import decl_prior as DP
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
ap.add_argument('--wave', required=True)
|
|
ap.add_argument('--out', default='')
|
|
a = ap.parse_args()
|
|
targets = json.load(open(os.path.join(a.wave, 'targets.json')))
|
|
idx = DP.load()
|
|
cards, n_tu, n_dp = [], 0, 0
|
|
for t in targets:
|
|
tu = t.get('tu') or F.home_tu(t['binary'], t['name'])
|
|
tu_ref = F.tu_neighbours(t['binary'], t['name'], tu, t['asm'])
|
|
try:
|
|
dp = DP.for_asm(t['asm'], tu, idx=idx, binary=t['binary'])
|
|
except Exception as e:
|
|
print(' decl_prior failed for %s/%s: %s' % (t['binary'], t['name'], str(e)[:80])); dp = []
|
|
n_tu += bool(tu_ref); n_dp += bool(dp)
|
|
cards.append({'fn': t['name'], 'binary': t['binary'], 'addr': t.get('addr'), 'nins': t['nins'],
|
|
'sub': t['sub'], 'tu_ref': tu_ref, 'decl_prior': dp})
|
|
p = a.out or os.path.join(a.wave, 'cards.json')
|
|
json.dump(cards, open(p, 'w'), indent=1)
|
|
print('cards: %d built for %s (tu_ref on %d/%d = %.0f%%; decl_prior on %d/%d = %.0f%%; seed_ref not built — '
|
|
'the pack will honestly say "no banked twin")'
|
|
% (len(cards), a.wave, n_tu, len(targets), 100.0 * n_tu / max(1, len(targets)),
|
|
n_dp, len(targets), 100.0 * n_dp / max(1, len(targets))))
|
|
print('wrote %s' % p)
|
|
if __name__ == '__main__':
|
|
main()
|