Skip to content

ci: run source-coverage on mods/** too -- 52 enrolled bytes the gate could never see - #2046

Merged
andrewboudreau merged 1 commit into
mainfrom
ci/source-coverage-mods-filter
Aug 30, 2026
Merged

ci: run source-coverage on mods/** too -- 52 enrolled bytes the gate could never see#2046
andrewboudreau merged 1 commit into
mainfrom
ci/source-coverage-mods-filter

Conversation

@andrewboudreau

Copy link
Copy Markdown
Collaborator

Two lines of YAML. The reason it is worth a PR is in the measurement, not the diff.

The gap

source-coverage.yml filters on src/**. But src/** is not the enrolled surface —
the enrolled surface is whatever config/**/delinks.txt names, and one of those names
is not under src/:

config/arm9/overlays/ov002/delinks.txt:1837
    mods/Player_ScaleByCharFactor.c:

52 bytes, and the only non-src/ path among the 10,973 ranges enrolled
tree-wide. A PR touching only mods/ matched neither paths: block, so the job never
ran. Not "ran and passed" — never ran. Same shape as the nearmiss/** gap closed in
#2040, and the reason it is worth chasing both: a check that does not run is rendered
identically to one that passed.

The tool itself is fine — I checked before assuming

I did not want to file a filter fix on a gate I had never seen fail, so I measured the
gate's failure branch first, at 859623fc0, in a wired worktree. Baseline: 2,067,148 B
source-built across 10,973 ranges, rombuild 106/106.

Deleting mods/Player_ScaleByCharFactor.c:

source_coverage.py -> exit 1, -52 B, blame names the file

Correct delta, correct blame. The tool was never the problem; only its trigger was.

Why I care about this particular gate

The same probe answered a question I had not seen answered anywhere: what actually
notices when dsd stops compiling a range from source and hands it back to the retail
cartridge?
The answer is that it depends on how it happens, and only one gate covers
the dangerous mode:

mutation rombuild source_coverage
clean tree 106/106, exit 0 2,067,148 B, exit 0
function body perturbed, still enrolled 105/106, exit 1, names it 2,067,148 B, exit 0 (correctly blind)
broken body and complete removed 106/106, exit 0 2,067,084 B (−64), exit 1

The third row is the one to look at. dsd refills from the cartridge on enrollment,
never on match outcome — so un-enrolling a range produces a byte-perfect ROM. Every
byte gate green, 64 bytes silently back on the cartridge, and source_coverage is the
only thing in the tree that says so. That is exactly the row this PR was about to let
through unnoticed for mods/.

Full battery, 11 mutations, correct on all 11 — including a re-partition that hid a
4-byte hole (caught, −4), a re-partition with identical bytes (correctly silent), a
misspelled complete (−64), an un-enrolled promoted TU (−1,472), and the real
promotion commit 5c0f8b85a (no false alarm).

Stated gaps

  • config_tu/ is never scanned. module_of() has explicit config_tu/ handling that
    was never wired to the scanner. 0 enrolled bytes there today, so this is latent, not
    live — filing separately rather than widening this PR.
  • 92 src/ files are unenumerated by any delinks entry. They contribute 0 B, so this is
    a coverage-ceiling gap, not a refill gap.
  • The metric counts enrollment, not matching, by design. Gutting a body while leaving
    complete in place gives exit 0 here — and 105/106 from rombuild, which is the
    correct division of labour between the two gates.

No compiled source touched, so there is no byte claim here and none is made. Pre-push
ran green: port_refcheck 405/405, check_src_tu 90/90, duplicate-sources 11199
stems none doubled.

`src/**` is not the whole enrolled surface.
config/arm9/overlays/ov002/delinks.txt:1837 enrolls
mods/Player_ScaleByCharFactor.c -- 52 bytes, and it is the only
non-src/ path among the 10,973 ranges enrolled tree-wide.

Measured: deleting that file makes source_coverage.py exit 1 with the
correct -52 delta and correct blame. But neither path filter matched
`mods/`, so a PR touching only mods/ never ran the job at all -- the
loss would have landed with nothing red. Same defect class as the
nearmiss/** filter gap closed in #2040: a missing check reads exactly
like a passing one.
@tangos-validator

tangos-validator Bot commented Aug 30, 2026

Copy link
Copy Markdown

✅ PR validation — Passed

noverify: no source/build-data changes in this PR

Each changed src/*.c|*.cpp is compiled and its relocated bytes compared to the binary data on a private build box. Passing requires every changed file to reproduce the ROM byte-for-byte with correct relocation targets — this catches WRONG-DEST relocations and non-reproducing near-misses that ledger-scoped linkcheck skips.

@andrewboudreau
andrewboudreau merged commit 6183a97 into main Aug 30, 2026
5 checks passed
@andrewboudreau
andrewboudreau deleted the ci/source-coverage-mods-filter branch August 30, 2026 22:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant