Fourth trap in the same family, and the largest. A relocation's target NAME is
not its target: the same address can be spelled against different symbols with
different addends. January writes `_sense_ray_divergences+32` where we write
`_sense_ray_angles-4`. The comparator resolves that; comparing names does not.
_actor_move_initialize - which gate.py reports EXACT and relocdiff
--allow-structural reports as `sha equal, 0 differing rows` - leaked into the
structural tier purely on name differences. Making the exactness test "equal
normalized bytes AND equal relocation (address, type) list", with names
deliberately excluded because the comparator resolves them, removed 123 more
already-exact functions:
non-exact functions 423 -> 300
S1 184 -> 73 (151,253 -> 108,533 bytes)
T 107 -> 95 ( 90,128 -> 86,896 bytes)
T parked 67 -> 55 - the twelve csplit-relocation-alias parks
correctly vanish, since those functions
ARE exact after alias resolution, which
is exactly what that park class records
S2 is unchanged and so is the headline: 114 parked functions, 112,133 of
151,525 parked bytes, are not tie-shaped. That number has now survived four
independent corrections.
VALIDATED AGAINST THE GATE. On Lane A's eleven translation units the census now
reports exactly 33 non-exact functions and gate.py reports exactly 33 residuals,
with no disagreement in either direction. That cross-check is what caught both
this error and the previous one, and it is recorded as the first thing anyone
extending the tool should run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both research documents committed earlier reference scripts in scratch/, which
the repository excludes - the write-ups would have pointed at files that do not
survive. Copied them to tools/campaign/ with headers explaining what they are,
what they measure and where the companion write-up is.
Scope: these ADD two read-only diagnostics beside the analysis scripts that
already live there (board.py, flag_scan.py, alias_scan.py and friends). They
read build/split and build/base, write nothing, recompile nothing, are imported
by nothing and run in no build step. No existing tool, comparator, split target,
object or build file is modified, so the lane's "no build-tool modification"
constraint is untouched. If the owner would rather they did not live here,
deleting two new files breaks nothing.
frame_census.py 56 functions with a `sub esp,N` mismatch, 101,056 B,
35 of them parked
structural_split.py 423 non-exact functions split S1/S2/T; 114 parked
functions (112,133 of 151,525 parked bytes) are not
tie-shaped
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>