TU: promote seven policy-free translation units (#1993 slice 1) - #2023
Conversation
Slice 1 of the #1993 re-cut: the subset of that PR's promotions that carries zero `compiler_only_output` rows, so none of the sixteen coined-name `deadstrip` claims the cartridge contradicts is anywhere near it. Promoted: ov004/dScMgBase_c 8 functions ov006/MgBingoBallSlotsShot 2 ov006/MgMushroomRoulette 2 ov006/MgPairAGoneAndOn 2 ov006/MgPicturePoker 3 ov006/MgTrampolineTerror 2 ov006/MgWhichWiggler 2 `tools/tu_promote.py` replaced 21 per-function `delinks.txt` entries with 7 whole-TU `complete` entries, `git mv`'d the 7 sources out of `src_tu/` at R100, `git rm`'d the 21 absorbed one-function sources, set each manifest entry to `status: promoted`, and added 21 `attribution.json` overrides. Byte-neutrality, proven by expanding every entry's start/end into a per-section byte set across all 114 `delinks.txt` at the merge base and here: ov004 280 -> 273 entries 48,004 bytes coverage identical ov006 1851 -> 1844 entries 401,340 bytes coverage identical Byte sets are identical for the `complete`-only view and the all-entries view, section headers are unchanged, no entry lost its `complete` marker, and the other 112 files are untouched. Every rewritten range is a contiguous merge of adjacent ranges with the same outer endpoints. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WdCK1xgrJdiJzPCh3bAJfQ
The CONVERTED criteria are file-wide. `src/actors/dScMgBase_c.cpp` carries all eight functions of the ov004 linker run, and the four that were never CONVERTED still use raw offset arithmetic, `unk_<off>` fields and mangled `_Z` free-function declarations -- so the four that WERE banked stop passing the moment they share a file with them. A reconstructed TU must additionally spell vague-linkage symbols directly or its range will not link, so `no_mangled_refs` can never pass for one. Same shape as #1996's ov002/daObjAbuku_c rows. No readable code was reverted and no byte changed. `--update` also folded in five lines of pre-existing baseline staleness this change did not cause: `src/_ZN7dBase_c{18AfterInitResourcesEj,5SpawnEjP7fBase_cii,D0Ev,D1Ev}.cpp` were absorbed into `src/actors/ActorDerived.cpp` by a promotion that already landed and were never re-banked (none of the four exists on `origin/main` either), and `src/actors/ActorDerived.cpp` itself qualifies but was unbanked. The tool classifies those four as moves, not removals, so they carry no `--reason` and no exceptions row. The baseline is a whole-tree regeneration; there is no way to bank fewer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WdCK1xgrJdiJzPCh3bAJfQ
✅ PR validation — PassedCommitted merge passes; 21 contributor credit reassignment(s) noted, not a blocker. Full merge validation
Contributor credit moved (21)
Byte-verified means the range carries Warnings: contributor attribution changed, not a blocker (21 changed, 0 lost -- src/actors/dScMgBase_c.cpp: andrewboudreau -> github-actions[bot]; src/actors/dScMgBase_c.cpp: andrewboudreau -> github-actions[bot]; src/actors/dScMgBase_c.cpp: andrewboudreau -> github-actions[bot]; +18 more); 21 address range(s) left the byte-verified set while enrolled totals held steady: ov004:0x020b04e8-0x020b04ec, ov004:0x020b04ec-0x020b04f4, ov004:0x020b04f4-0x020b0618, ov004:0x020b0618-0x020b0620, ov004:0x020b0620-0x020b0840, +16 more; 14 more function(s) now claim a match that nothing compiles; enroll them in a delinks.txt to have the ROM build check them. Per-file link-check detailAll 7 changed file(s) compile to the ROM byte-for-byte with correct relocation targets.
The private worker commits a test merge, builds the stock ROM profile, compares every executable module, measures matched and source-built code, checks contributor lineage, and verifies affected relocations. The mod profile is opt-in and is not part of this merge gate. |
Promotion loses no vtable/RTTI record — checked in both directionsA known hazard for TU promotion is that an This slice was checked symmetrically rather than assumed safe. Each side was compiled with After — the 7 promoted TUs: Before — all 21 absorbed one-function sources at the merge base: every one reports So the count is 0 before and 0 after: there is no record for the promotion to lose. The Two notes on the file counts, since they can look off at a glance:
|
Reconciling the validator's
|
| TU | fns | range bytes | first fn | remaining fns |
|---|---|---|---|---|
dScMgBase_c.cpp |
8 | 1,360 | 4 | 7 → 1,356 |
MgBingoBallSlotsShot.cpp |
2 | 224 | 220 | 1 → 4 |
MgMushroomRoulette.cpp |
2 | 176 | 172 | 1 → 4 |
MgPairAGoneAndOn.cpp |
2 | 176 | 148 | 1 → 28 |
MgPicturePoker.cpp |
3 | 236 | 192 | 2 → 44 |
MgTrampolineTerror.cpp |
2 | 492 | 396 | 1 → 96 |
MgWhichWiggler.cpp |
2 | 168 | 104 | 1 → 64 |
| total | 14 → 1,596 |
14 functions and 1,596 bytes — the reported deltas to the unit. These are precisely the
non-first functions of each promoted TU, nothing else.
Those bytes are still compiled and still compared to the cartridge. The whole-TU entry
carries complete and spans the identical address range, so the ROM build builds all 1,360
bytes of dScMgBase_c and diffs them. Three independent facts agree:
- the delinks byte sets are identical before and after, compared as sets per section;
source_coverage.pyreports net +0 B, nothing handed back to the cartridge;- the validator's own note says the enrolled totals held steady — only the
per-function attribution moved.
The validator's own wording, 14 more function(s) now claim a match that nothing compiles,
is the part that is misleading here: something does compile them — the TU does. Its
range→function resolution is exact-start matching, not containment.
This is inherent to TU promotion, not to this slice. Any promotion of N functions into
one TU will show -(N − 1) functions and the corresponding bytes on these two rows while
losing no verification whatsoever. Worth knowing before the later, larger #1993 slices land,
since those will show much bigger negative numbers for the same benign reason. The row that
would actually catch bytes being handed back to the cartridge is source-built coverage, and
it is flat.
Gatekeeper review — one change requested, then this mergesThe promotion itself is sound and I re-verified it independently rather than Requested change: drop the
|
| tree | #2001's ratchet | fix needed |
|---|---|---|
main + #2001 |
RED — 4 MOVED paths lose the rescue |
the legacy_source-keyed rescue I posted on #2001 |
main + #2023 as-is + #2001 |
RED — src/actors/ActorDerived.cpp IDENTITY UPGRADE INCOMPLETE |
the posted fix does not cover this |
main + #2023 swap reverted + #2001 |
RED — 4 MOVED paths |
the posted fix — and I verified the composition is EXIT 0 with it applied |
The reason is that banking src/actors/ActorDerived.cpp as a whole-file row is an
over-credit under the new metric: that file's members include func_02013edc, which is
not a real function name. Main's file-wide scorer judges the path (ActorDerived.cpp
— a real name) and passes it; the per-member scorer judges the symbol and does not.
So this PR banks a row #2001 immediately has to unwind. Cheaper not to bank it.
Concretely: restore those four src/_ZN7dBase_c*.cpp entries, delete
src/actors/ActorDerived.cpp, set "count": 2549. --check stays green.
What I verified is clean
- No erosion. Merge-tree coverage
.text 1,941,060 + .init 125,712 = 2,066,772 B,
byte-identical toorigin/main.entries11,025 -> 11,011 is the documented
consolidation artifact — 21 per-symbol entries collapsing into 7 TU entries. - Converted ratchet PASS on the merge result, not just on the branch. Worth saying
plainly: nothing in CI gates a merge result —pr-validate.ymlis
pull_request_target-only and there is no ROM build on a main push. - The seven promoted files are identical blobs to their
src_tuoriginals with no
copy left behind, so the promotion cannot have changed a byte of source. - The four new
converted-backslide-exceptions.jsonlrows are the honest instrument
here, not a fudge.src/actors/dScMgBase_c.cppreally does carry four
never-converted siblings from the same linker run, so the file-wide criteria really
cannot pass. I checked the claim rather than taking the reason text on trust: 384
lines, 32 mangled_Zdeclarations, 15 raw pointer casts, 4unk_<off>fields. The
reasons are specific and true, and no readable code was reverted.
One thing to be clear-eyed about, not a blocker
These are not readable C++ yet. Three of the seven, measured:
| file | lines | extern "C" |
func_/Unk_ defs |
raw casts | mangled _Z |
|---|---|---|---|---|---|
MgBingoBallSlotsShot.cpp |
57 | 4 | 2 | 1 | 4 |
MgPicturePoker.cpp |
72 | 13 | 1 | 2 | 6 |
dScMgBase_c.cpp |
384 | 1 | 2 | 15 | 32 |
I am not asking for that to change here, because the trade goes the right way under
the project's own ordering — byte-match first, readability last. src_tu/ is not in the
build, so today these 513 lines are gated by nothing at all; promoting them puts them
under the ROM link. That is a real verification gain bought with four rows of
readability credit, and it is the documented cost of TU promotion.
But it does set the follow-up: the four never-converted dScMgBase_c siblings are now
the thing standing between this class and its four CONVERTED rows coming back. Worth an
issue so later slices do not each quietly spend a few more rows without anyone tracking
the total.
Verdict
Make the five-line converted-baseline.json revert and I will merge on the next green.
Main moved to 0cf57c268 while this sat, so a revalidation is happening regardless —
the revert costs nothing extra. Nothing else on this PR needs to change.
Addendum — a second fix, found on adversarial re-reviewI had a second pass run against this branch independently (fresh It also found something I missed. All seven promoted files still carry the generator's SHADOW bannerEvery one of the seven says, at the top:
After this PR all seven are enrolled I checked the tree's convention rather than assuming one. Of the six TUs already promoted into
So stripping on promotion is the convention, 5-1, and Comment-only, zero byte risk. But leaving it means seven canonical, ROM-linked sources each open by telling the next reader they are scratch files that contribute nothing — and this PR would take the tree from one such file to eight, which is the point where it stops being an oversight and starts being the norm. So the ask on this PR is now two things, both text-only
Neither needs a rebuild. Same commitment as before: make these and I will merge on the next green. One thing to keep an eye on afterwards
I also filed #2029 for the CONVERTED-credit question raised by the four exception rows here — that is a trend to track, not a blocker on this PR. |
… banner Two text-only fixes requested in review on #2023. No byte of compiled output moves: the seven .cpp diffs are comment-only (proved by comparing the comment-stripped token streams -- all seven hash identically before and after), and config/converted-baseline.json is not an input to any compiler. config/converted-baseline.json -- `tiers_ratchet.py --update` regenerates the whole tree and swept three unrelated things into this PR's delta: * it DROPPED src/_ZN7dBase_c{18AfterInitResourcesEj,5SpawnEjP7fBase_cii,D0Ev, D1Ev}.cpp, four paths an already-landed promotion absorbed into src/actors/ActorDerived.cpp and never re-banked; * it ADDED src/actors/ActorDerived.cpp, which qualifies but was unbanked; * it re-sorted src/_ZN11daDsnBase_c16CleanupResourcesEv.cpp, which sits out of `sorted()` order on main because `--update` is the only writer and the row predates it. None of the three is caused by this PR, and each is a pre-existing baseline staleness that belongs in its own change. The file is now rebuilt from the merge base (eabf1a0) by hand -- there is no targeted regeneration entry point; `--update` writes the whole tree from `sorted(current)` or nothing -- so this PR's own delta on it is exactly five lines: the four src/_ZN11dScMgBase_c*.cpp paths that ov004/dScMgBase_c really did absorb, and the count. 2553 - 4 = 2549, and `count` equals len(converted) as it does at every other revision. The seven promoted files -- the tubuild `create` banner claimed "NOT ENROLLED, NOT CANONICAL", "contributes nothing to the ROM build" and "a STARTING POINT". After this PR each of the seven is enrolled and canonical and contributes its range to the link, so all three statements are false. Replaced with the shape the already-promoted TUs use (src/actors/daObjAbuku_c.cpp from #1996, and daKpFr_c.cpp / daKrpa_c.cpp): a "Production translation unit for <ov>/<Class>" line over the unchanged reverse-source-order note and the unchanged assembled-from list. Nothing reads the banner text -- tools/tubuild.py only writes it -- and the separate "Local shadow declarations ... NOT reconciled" comment is left alone because it is still true. src/actors/daObjPathLift_c.cpp keeps its SHADOW banner. It is the one promoted TU that was never stripped, a standing oversight rather than a precedent, and not this PR's file to touch. Verified in a worktree off a13cfc3: tiers_ratchet.py --check PASS baseline 2549 current 2546 (+1 gained, not yet banked) (4 moved into a promoted TU) langmode_audit.py --json byte-identical before and after check_dead_references.py exit 0, output identical before and after Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WdCK1xgrJdiJzPCh3bAJfQ
Two review fixes applied on the authoring session's behalfPosted by the gatekeeper. The authoring session is gone, so I made exactly the two changes I asked for, on top of Fix 1 —
|
swept in by --update |
why it is unrelated |
|---|---|
dropped src/_ZN7dBase_c{18AfterInitResourcesEj,5SpawnEjP7fBase_cii,D0Ev,D1Ev}.cpp |
absorbed into src/actors/ActorDerived.cpp by a promotion that already landed. None of the four exists at the merge base, on this branch, or on origin/main. Pre-existing staleness. |
added src/actors/ActorDerived.cpp |
qualifies, but was never banked — again from that earlier promotion, not this one. |
re-sorted src/_ZN11daDsnBase_c16CleanupResourcesEv.cpp |
sits out of sorted() order on main; --update silently moved it. Reverted too, which is why the delta is 5 lines and not 7. |
This PR's own delta on the file is now exactly five lines — the four paths ov004/dScMgBase_c genuinely absorbed, plus the count:
@@ -7,7 +7,7 @@
"no_codegen_trick",
"no_mangled_refs"
],
- "count": 2553,
+ "count": 2549,
"converted": [
"src/ARMMathLoadState.c",
"src/ARMMathSaveState.c",
@@ -545,10 +545,6 @@
"src/_ZN11dScMgBase_c15graphCallback_c14GraphCallback1Ev.cpp",
"src/_ZN11dScMgBase_c15graphCallback_c14GraphCallback2Ev.cpp",
"src/_ZN11dScMgBase_c15graphCallback_c14GraphCallback3Ev.cpp",
- "src/_ZN11dScMgBase_c16OnPendingDestroyEv.cpp",
- "src/_ZN11dScMgBase_c18AfterInitResourcesEj.cpp",
- "src/_ZN11dScMgBase_c6RenderEv.cpp",
- "src/_ZN11dScMgBase_c8BehaviorEv.cpp",
"src/_ZN11dScMgBase_cD0Ev.cpp",
"src/_ZN11dScMgBase_cD1Ev.cpp",
"src/_ZN11dScMgBase_cD2Ev.cpp",Count sanity check: 2549 is correct. count is written as len(converted) by the generator, and it equals the entry count at every revision I checked — merge base 2553/2553, this branch 2546/2546, origin/main 2553/2553. The rebuilt file is 2549 field / 2549 entries, 0 duplicates, trailing newline present, LF blob (CRLF=0 measured on the staged blob). 2553 − 4 = 2549. ✅
⚠️ A correction to my own review. I asked for "a five-line delta relative toorigin/main's version". That is not achievable, and my framing was wrong.origin/mainhas moved 31 commits past this branch's merge base, and #2012 renamedWaterfallMist→daObjWaterfall_cin the interim — soorigin/main's baseline carriessrc/_ZN16daObjWaterfall_c*.cppwhere this branch still carriessrc/_ZN13WaterfallMist*.cpp. Chasing a literal five-line diff againstorigin/mainwould have meant importing main's rename into this PR, which would be wrong. The five-line delta is measured against the merge base — i.e. against what this PR actually changes — which is what I meant. The rename resolves at merge time.
Fix 2 — the stale SHADOW banner is stripped from all seven
All seven opened with byte-identical banner text (lines 2–11, differing only in the ov00X/Name (N function(s)) line) asserting three things this PR makes false: NOT ENROLLED, NOT CANONICAL, contributes nothing to the ROM build, and a STARTING POINT.
I mirrored the shape the already-promoted TUs use rather than inventing one. src/actors/daObjAbuku_c.cpp (#1996) is the closest precedent — same tubuild origin, same promotion shape — and daKpFr_c.cpp / daKrpa_c.cpp do the same thing: drop the shadow paragraph, keep an accurate provenance header above the unchanged reverse-source-order note and the unchanged assembled-from list.
//cpp
- /* SHADOW translation unit -- generated by tools/tubuild.py create.
- * ov004/dScMgBase_c (8 function(s))
+ /* Production translation unit for ov004/dScMgBase_c (8 function(s)).
*
- * NOT ENROLLED, NOT CANONICAL. This file contributes nothing to the ROM
- * build. It is a STARTING POINT (plan sec 7.3): local shadow declarations
- * below were carried verbatim from the legacy files, not reconciled against
- * real project headers -- that judgement call is left to a human/LLM review,
- * the way pilot #1 reconciled PoleLift::Render and ::CleanupResources by hand
- * (see notes/tu-reconstruction-pilot-report.md sec 5.2).
+ * Enrolled and canonical: this file's licensed text ranges are linked into
+ * the ROM build. Originally generated by tools/tubuild.py create.
*
* FUNCTION ORDER IS DELIBERATELY THE REVERSE OF THE ROM'S -- mwccarm 2004/b56Identical edit in all seven. //cpp stays the first bytes of the file. The separate /* Local shadow declarations ... NOT reconciled against real project headers */ comment further down is left alone — those declarations are still there and that comment is still true.
Nothing reads the banner. tools/tubuild.py (lines 736–740) is the only mention of the text anywhere in tools/, config/ or .github/, and it only writes it.
src/actors/daObjPathLift_c.cpp still has its SHADOW banner. Per my review that is a standing oversight, not a precedent, and not this PR's file — left untouched.
Optional item — skipped, because it was already done
I asked for a comment naming which member required #pragma opt_strength_reduction off. src/actors/dScMgBase_c.cpp already carries one, directly above the pragma:
/* FILE-GLOBAL, and deliberately so: the last state set anywhere applies to
every function in the TU. Carried over from
src/_ZN11dScMgBase_c14BeforeBehaviorEv.cpp, the only member of the real
0x020b04e8..0x020b2adc run that had one. */
#pragma opt_strength_reduction offIndependently confirmed against the legacy sources at the merge base: _ZN11dScMgBase_c14BeforeBehaviorEv.cpp carries the pragma at line 50, and the other seven members of the run (12BeforeRenderEv, 16OnPendingDestroyEv, 18AfterInitResourcesEj, 19BeforeInitResourcesEv, 21AfterCleanupResourcesEj, 6RenderEv, 8BehaviorEv) carry zero pragma lines between them. The existing comment is accurate and matches the TUBUILD WARNING text; a second one would be noise. No change made.
Verification
git diff a13cfc343..HEAD --stat — exactly the eight expected files, nothing else:
config/converted-baseline.json | 9 ++++++---
src/actors/MgBingoBallSlotsShot.cpp | 11 +++--------
src/actors/MgMushroomRoulette.cpp | 11 +++--------
src/actors/MgPairAGoneAndOn.cpp | 11 +++--------
src/actors/MgPicturePoker.cpp | 11 +++--------
src/actors/MgTrampolineTerror.cpp | 11 +++--------
src/actors/MgWhichWiggler.cpp | 11 +++--------
src/actors/dScMgBase_c.cpp | 11 +++--------
8 files changed, 27 insertions(+), 59 deletions(-)
The seven .cpp diffs are comment-only — proved, not asserted. I stripped // and /* */ comments from each file before and after (honouring string and char literals), dropped blank lines, and hashed the remaining token stream. Not one non-comment line was added, removed, or changed:
MgBingoBallSlotsShot code-lines 26 -> 26 sha fec77b5348d26421 -> fec77b5348d26421 IDENTICAL
MgMushroomRoulette code-lines 32 -> 32 sha 2aa163ceac10f419 -> 2aa163ceac10f419 IDENTICAL
MgPairAGoneAndOn code-lines 31 -> 31 sha d62ae46c0b246d33 -> d62ae46c0b246d33 IDENTICAL
MgPicturePoker code-lines 37 -> 37 sha 3084555cc1199420 -> 3084555cc1199420 IDENTICAL
MgTrampolineTerror code-lines 71 -> 71 sha 631870f6eaa11dad -> 631870f6eaa11dad IDENTICAL
MgWhichWiggler code-lines 24 -> 24 sha 44e3a32c26154d4c -> 44e3a32c26154d4c IDENTICAL
dScMgBase_c code-lines 232 -> 232 sha 40f9c1e61716d55c -> 40f9c1e61716d55c IDENTICAL
ALL SEVEN NON-COMMENT CONTENT IDENTICAL: True
Gates, run in the worktree, verbatim:
$ python tools/tiers_ratchet.py --check
CONVERTED ratchet PASS baseline 2549 current 2546 (+1 gained, not yet banked) (4 moved into a promoted TU)
(exit 0)
$ python tools/check_dead_references.py
check_dead_references: 367 prose file(s), 3308 repo-rooted path reference(s), 132 that do not resolve
1 baselined reference(s) now resolve -- run --update to shrink the baseline (not a failure)
no new dead references
(exit 0)
The 1 baselined reference(s) now resolve line is pre-existing at a13cfc343 — I captured check_dead_references output with the seven files reverted to HEAD and the two runs are byte-identical. Not introduced here, and the tool itself calls it "not a failure".
On tiers_ratchet: 4 moved into a promoted TU is the four restored dBase_c paths being correctly resolved through the manifest as moves, not backslides — exactly how origin/main is green today. +1 gained, not yet banked is ActorDerived.cpp. Both are the pre-existing staleness, now correctly left for its own change instead of riding along here.
langmode_audit.py --check takes a baseline path that lives in the chaos-data repo, so running it locally would only have produced a stale-baseline verdict. Instead I ran the stronger equivalent for a text-only change — --json before and after — and the output is byte-identical. Zero langmode delta.
Pre-push hook, not bypassed (no --no-verify):
port-refcheck: 405 checked - all references resolve
duplicate-sources: 11237 stems, none doubled
check_src_tu_compiles: 89/89 translation unit(s) compiled in 3.8s
No ROM build was run, deliberately: build/ is shared with several live sessions and a concurrent run reports fake failures. Both changes are text-only and cannot move a byte of compiled output — the seven .cpp edits are provably comment-only, and converted-baseline.json is not a compiler input. The validator's own run on 41a52556c is the byte authority here.
Not merged. Over to the next green.
Slice 1 of the #1993 re-cut.
#1993 tried to promote 26 translation units in one shot and stalled on 32
compiler_only_outputrows across 16 coined-name classes — rows banked as plaindeadstripthat assert "the cartridge never carried a separate copy" when the cartridgedoes carry the record under the class's real name. The verdict on those rows is
here; the
audit that found all 32 is
here. Per
that assessment the PR is being re-cut into slices rather than conflict-resolved.
This is the subset with no such rows at all. All seven manifest entries have no
compiler_only_outputkey, absent as well as empty — verified againstorigin/main's blobfor each entry before any change was made. That is the entire reason this slice can land
ahead of the sixteen renames: there is no policy row here to get wrong.
dScMgBase_cMgBingoBallSlotsShotMgMushroomRouletteMgPairAGoneAndOnMgPicturePokerMgTrampolineTerrorMgWhichWigglertu_promote --dry-run, and the #2016 precondition#2016 repointed 38 stale
legacy_sourceextensions. Without it,tu_promote --dry-runrefused nine entries with
has 0 entries in delinks.txt, expected exactly 1. On currentmainthat refusal is gone: the dry run over all seven ids reports zero refusals,nothing suppressed.
The real run: 7 promoted, 21 functions consolidated, 21 attribution overrides added.
Byte-neutrality
A promotion that quietly narrows a range produces a byte-perfect ROM, so no other gate
can see it. This one was checked directly rather than inferred.
Every entry in every
config/**/delinks.txtwas expanded from itsstart/endinto a setof individual byte addresses per section, at the merge base and at this tree, and the sets
compared for equality — not the totals, the sets. Done twice: once over
completeentriesonly (the bytes the build actually compiles) and once over every entry regardless.
completebytesAlso asserted, and all true:
completemarker. Every path that carriedcompleteat the baseand still exists as an entry still carries it; the rest were absorbed and are gone as
entries entirely.
endpoints:
0x020b04e8..0x020b0a38replaces eight abutting entries covering exactlythat, and so on for the six ov006 TUs. This is visible in the diff.
tools/source_coverage.pyfrom #2013 agrees independently:Other gates, run locally
prepush_attribution --base origin/maincheck_src_tu_compilessrc/homecheck_src_tuport_refcheckcheck_duplicate_sourcestiers_ratchet --checktest_tierscheck_dead_referenceslangmode_audit --checkcheck_header_offsets--no-verifyrombuild.pywas deliberately not run.build/is shared across worktrees and threeother agents held live file locks throughout (
tu-pushblock-genuine,tu-ctmecha05-genuine,tu-kurumajiku-prod-cppown, two of them on other modules'delinks.txt). A concurrent build manufactures fake failures for everyone sharing thedirectory, and the lock service has no build-directory resource to serialise on. The 106/106
module-fidelity check is left to the validator, which runs it in isolation.
The two commits, and one disclosure
Commit 1 is
tu_promote.py's output, unedited: 7 whole-TUcompleteentries replacing21 per-function ones, 7
git mvat R100 (all seven show| 0in--stat), 21 absorbedone-function sources
git rm'd, 7 manifest entries set tostatus: promoted, 21attribution.jsonoverrides.attribution.jsonshows a 1,609-line diff for 21 added keys. That is not 1,609 changes:rewrite_attributionends withdict(sorted(ov.items())), andmain's overrides block wasnot in sorted order, so the whole block is re-emitted. Compared key-by-key as JSON:
903 → 924 overrides, 21 added, 0 removed, 0 changed, and
aliasesandnoteareuntouched. Worth flagging as a tooling nuisance — a shared ledger that a tool re-sorts
conflicts with every concurrent PR that touches it.
Commit 2 banks the four CONVERTED paths
ov004/dScMgBase_cabsorbed. The criteria arefile-wide, and the promoted TU carries all eight functions of the linker run — the four that
were never CONVERTED still use raw offset arithmetic,
unk_<off>fields and mangled_Zdeclarations, so the four that were banked stop passing the moment they share a file with
them. Same shape as #1996's
ov002/daObjAbuku_crows; byte-match outranks readability, noreadable code was reverted, no byte changed.
One disclosure on that commit:
--updateregenerates the whole baseline, so it also foldedin five lines of pre-existing staleness this change did not cause.
src/_ZN7dBase_c{18AfterInitResourcesEj,5SpawnEjP7fBase_cii,D0Ev,D1Ev}.cppwere absorbedinto
src/actors/ActorDerived.cppby a promotion that already landed and were neverre-banked — none of the four exists on
origin/maineither — andActorDerived.cppitselfqualifies but was unbanked. The tool classifies those four as moves, not removals, so they
carry no
--reasonand no exceptions row. Net2553 → 2546 (+1 / −8): four mine, bankedwith a reason; four pre-existing moves; one pre-existing addition. There is no way to bank
fewer.
What this PR does not do
[SUPERSEDED — reference only] TU: promote 27 reconstructed translation units (restack of #1880 -> #1882 -> #1884 -> #1914) #1993 needs are a separate slice.
include/.src/content changes. The onlysrc/changes are the seven R100 renames (0 lineschanged) and the deletion of the 21 absorbed one-function files. No
src_tu/source wasedited on the way through.
tools/changes, so the validator's tool-restore behaviour is not in play.compiler_only_outputrows added, reworded, or removed anywhere.🤖 Generated with Claude Code