3 Commits

Author SHA1 Message Date
Drew T 96820256ce phase-36: re-draws c24 (func_8012956C: a phantom 4th argument + a switch) and c23 (func_80133784: the exit block inside a real loop, overturning b4's de-loop reading) closed, 252 bodies; R25 trim_arguments; argcheck reads K&R definitions (95 callees were invisible); the selftest asserts every dispatched family is registered (R22 218/218) 2026-09-10 16:45:14 -06:00
Drew T f3de70fce5 phase-36: R19 — the argument-restore generator: call signatures become engine work, not agent work
Six T7 agents independently reached score 0 by restoring an argument the decompiled source had dropped, and no generator
could reach the class because every other family rewrites statements that exist while this changes a call's ARITY. R19
closes that gap without cracking anything: it finds every call whose in-scope declaration is narrower than the callee's
real definition, then offers one candidate per value already in scope (each parameter, each local declared before the
call) and lets the byte oracle pick. The missing argument is never inferred.

- known-true check: run on the pre-bank text of func_8017A3D8, which agent a12 solved by hand, R19 emits that agent's
  exact fix and --try scores it 0 (OTHER; mine 53 ins, target 53) — MATCH.
- two spellings were wrong before that passed. It took the return type from the DEFINITION and produced
  ((void (*)(s32))f)(a) != 0, which cannot compile because the defining TU says void where this one says int — it now
  repairs the arity only and keeps the TU's declared return type. And it required a simple statement, so it found
  nothing on the very body it was written from: these calls live in  and  far more often
  than in a plain statement.
- it also sees the cast-wrapped form ((s32 (*)(void))f)(), which is how m2c usually spells a dropped argument, and
  replaces the whole wrapper rather than nesting a second cast.
- ranked FIRST in every residual class: it emits candidates only for calls whose declaration provably disagrees with the
  definition, so it costs nothing when it does not apply. The engine selftest's ordering invariant is updated to say so
  rather than being widened again.
- argcheck now carries each definition's return type, which the cast route needs.
- selftest: two positive assertions and two controls (the declared return type is kept; the definition's is refused; a
  call inside a return statement is seen; a matching declaration offers nothing).
2026-09-10 11:13:34 -06:00
Drew T 161d36cf36 phase-36: argcheck (the missing-argument census), a10's verdict downgraded on Drew's challenge, and R14's documented premise corrected on bytes
- tools/argcheck.py: every call site whose in-scope declaration is narrower than the callee's real definition. 15,626
  definitions read; 110,478 narrower declarations over 1,912 callees (86,701 K&R-empty, 23,777 positively narrow);
  471 of them sit in a body that still holds a NEEDED $4-$7 pin — 323 bodies, the targeted draw, written to
  .run/P36/engine/argcheck_draw.tsv.
  Checked against the six agent cracks it was built from: it finds a7, a12 and a25, and it CANNOT find a13, whose
  function is declared (void) in 131 of 138 sites AND defined (void) — a declaration comparison is blind to a definition
  that is uniformly wrong. The census is a lower bound and the residual stays the oracle; the docstring says so.
  Corrected before use: the scope column says which FIX is available, not whether the body can be banked — the cast route
  is body-only at either scope (a7 closed a file-scope case that way).

- Drew challenged a10's 'needed by construction' verdict: nobody wrote the pin, so a plain-C spelling must exist. He is
  right and the verdict is downgraded to its real scope — no spelling reaches the bytes in that TU's CURRENT declaration
  environment. That environment is demonstrably wrong there: the file declares extern s32 func_801789AC(s32 arg0) while
  the body calls it through a cast that drops the argument, the same class six agents cracked today. Restoring it was
  tested at once and scores 3, not 0, so it is not the whole answer — but a verdict taken inside a distorted environment
  is not a property of the function. func_80178970 moves to the structs/types phase list rather than being marked
  permanent, with its reading attached.

- R14's documented premise corrected on bytes (agent a15): MIPS defines only PROMOTE_PROTOTYPES, not PROMOTE_MODE
  (config/mips/mips.h:1153), so a narrowed parameter stays HImode and the extension still happens at the use. R14's
  banked closes stand on their bytes, not on that rationale.
2026-09-10 10:53:20 -06:00