mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-27 14:02:04 -04:00
610a13c21c
0 banked. Four tool fixes, one byte-neutral header correction (committed separately), and the three
families resolve to a SINGLE root problem — plus a defect I introduced and caught by measuring.
FOUR TOOL FIXES, each verified by a verdict MOVING rather than by assertion:
1. gather_externs prefers FILE-scope decls. Its contract says "file-scope extern decls" but
`^[ \t]*extern` also matches an INDENTED one — a block-scope decl inside some OTHER function, not
even in scope at the exemplar's own definition. Carried to file scope in the sibling,
`extern void func_80155FF8(void *, u8);` (ov_SC01_077 L1213) landed above that sibling's
DEFINE_func_80155FF8() macro and collided. ORDERED, not filtered — an indented decl stays the
fallback it always was, so a symbol declared only block-scope is unaffected.
2. reconcile_def_sig keeps the BODY's param names (the T60 fix, cookbook §109).
3. §85 return-axis precondition — refuses when callers consume the return (reuses
conform_decls.consumers, R33).
4. Param-use guard — refuses to retype a parameter the body indexes/dereferences (func_8014D610's
header says `void *a2` where the byte truth is `u16 *param_3` and the body does param_3[0]).
A DEFECT I INTRODUCED, CAUGHT BY MEASURING: func_8016163C read as a clean DIFF after T60 and I
reported it as "genuine codegen". It is not. match_one says SIZE-MISMATCH: draft 58 ins vs target 78
(delta -20, ratio 0.74, bucket redraft). Both overlays are 78 ins and extract_unit is fine —
--fix-def-sig demoted the return s32 -> void and gcc deleted the computation feeding it as dead. My
§85 check only asked whether CALLERS consume the return, never whether the BODY returns a value. The
tool manufactured a different-sized function and the verdict blamed the draft. Guard added. A "clean
DIFF" appearing right after a transform is a suspect, not a result.
THE CONVERGENCE: engine_core.h declares all three with types that contradict the byte truth —
func_80156044 int vs void (FIXED, byte-neutral, R22 140/140), func_8016163C void vs s32,
func_8014D610 void(s32,void*,void*) vs s32(s32,s32,u16*). Both remaining flips measure 0 §85
consumers. The fix is to correct the HEADER, not to bend the drafts.
AND ONE MORE LAYER: with its header fixed, func_80156044's verdict moved to `redefinition of
func_80155FF8` — extract_unit lifted a unit spanning TWO definitions and the sibling already defines
the wrapper via the shared macro. A unit-boundary defect, a fourth distinct cause. Three fixes peeled
three layers off one family.
phase-ends/ — the living record
PhaseEnd_Phase[N].md— written at each phase boundary (format defined inPROJECT_CONTEXT.md). Append-only history: build log, deviations, commit message, rules added, changelog. Never deleted.CURRENT_PHASE.md— the in-phase autonomous log: approved phase plan, per-task checkboxes, current task pointer, blockers. Created at phase start, updated after every task, absorbed into the PhaseEnd file and deleted at phase close. This is the crash/compaction recovery point.- Sessions read
PROJECT_CONTEXT.md, then everyPhaseEnd_*.mdin numeric order, thenCURRENT_PHASE.md(if present) — in that order, every session.