Add a ledger convergence sweep - #172
Merged
Merged
Conversation
The two existing ledger gates check attribution, not arrival. commit-tracker-check.sh proves the cited sha is reachable; commit-tracker-overlap.py proves the cited commit touched a file the upstream commit touched. Both pass on a row that says ported while the change was never applied -- which is exactly what happened five times (355dd1c2f, 754c96a54, 3d24f58bf, e29fce695, bf03d0222), every one a renderer-staircase batch whose commit really did touch the right files. This asks the missing question, per FILE rather than per commit: does our copy match upstream's copy at the newest commit we claim to have ported for that file? Supersession stops being noise by construction -- if a later commit rewrote those lines they are not in the newest upstream state either -- and a hunk whose our-side lines carry a fork tag ([rc4l], [BB], ...) is a divergence someone signed for. SCOPED TO THE STAIRCASE, and that is load-bearing. Run over the whole tree it flagged 207 of 459 files and led with a 1975-line "divergence" in dobjtype.cpp against a sweeping "removed STACK_ARGS" commit -- all of it correct divergence, none actionable, because outside src/gl we port slices and never intend to converge. Inside the staircase we walk commit by commit precisely so our copy tracks upstream's, so the question is meaningful there. That is also where every miss the audit found lived. Scoped: 129 files, 39 findings, under a second. Validated against the two known misses rather than assumed: with #171 unmerged it independently reports gl_interface.cpp missing GL_CONTEXT_PROFILE_MASK and gl_texture.cpp missing the diagonal CHKPIX checks, and surfaces a third candidate in gl_texture.cpp I had not found by hand. Runs weekly rather than per-PR. The other gates read committed snapshots; this one needs upstream file content, so it needs the clone. A periodic full pass is also the right shape for the failure it hunts, which is silent and accumulates. ADVISORY for now -- 39 findings need triage before a flag can mean "stop", the same path overlap.py took.
rc4l
enabled auto-merge
August 3, 2026 15:13
A weekly artifact nobody opens is not a gate. Run it from the Actions tab when closing out a seam or after a batch of staircase ports, which is when its answer actually changes.
The ADVISORY switch decided an exit code that nothing reads -- the sweep
runs on demand, not in a gate -- so it was a knob with no effect. Gone.
Reviewing the sweep's findings turned up four more rows marked ported
whose code is not in the tree. These are reversed to pending rather than
quietly fixed, because the ledger claiming work that does not exist is
the problem being tracked:
a8398e70b FGLROptions never initialises brightfog, so the MAPINFO
option reads uninitialised memory.
baa775b31 gl_lightdata.cpp:334 indexes distfogtable[..][lightlevel]
with no clamp -- out of bounds for a light level outside
0..255.
b00b49c11 gl_sky.cpp still picks the skybox by hand instead of
sector_t::GetSkyBox(plane), which exists here, so the fix
was portable and simply not taken.
d79741574 ADynamicLight::SetOrigin has no 'moving' parameter, so the
relink-on-move fix is absent.
That makes nine ledger errors found in total, all in the renderer
staircase, all the same shape: a batch commit that touched the right
files while one of its changes never landed.
All three were recorded ported and were not in the tree; the convergence
sweep found them and this applies them for real.
a8398e70b FGLROptions declared brightfog but its constructor never
initialised it, so the MAPINFO option read whatever was on the
heap.
baa775b31 gl_lightdata.cpp indexed distfogtable[..][lightlevel] with no
clamp. The table is [2][256] and lightlevel is not guaranteed
in range, so this was an out-of-bounds read.
b00b49c11 gl_sky.cpp picked the skybox by hand and fell back to
level.DefaultSkybox itself. sector_t::GetSkyBox(plane) does
that fallback and also honours SECF_NOFLOORSKYBOX /
SECF_NOCEILINGSKYBOX, which the hand-rolled version ignored --
so this fixed a second bug the commit did not advertise.
d79741574 is NOT here, and my reversing it to pending was wrong.
ADynamicLight::SetOrigin already exists and already calls LinkLight(),
which is the substance of that commit. Only the 'moving' parameter is
absent, and that comes from an earlier upstream change to
AActor::SetOrigin that we never took -- so the row is adapted with the
remainder noted, not pending.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add a ledger convergence sweep
The two existing ledger gates check attribution, not arrival.
commit-tracker-check.sh proves the cited sha is reachable;
commit-tracker-overlap.py proves the cited commit touched a file the
upstream commit touched. Both pass on a row that says ported while the
change was never applied -- which is exactly what happened five times
(355dd1c2f, 754c96a54, 3d24f58bf, e29fce695, bf03d0222), every one a
renderer-staircase batch whose commit really did touch the right files.
This asks the missing question, per FILE rather than per commit: does our
copy match upstream's copy at the newest commit we claim to have ported
for that file? Supersession stops being noise by construction -- if a
later commit rewrote those lines they are not in the newest upstream
state either -- and a hunk whose our-side lines carry a fork tag
([rc4l], [BB], ...) is a divergence someone signed for.
SCOPED TO THE STAIRCASE, and that is load-bearing. Run over the whole
tree it flagged 207 of 459 files and led with a 1975-line "divergence" in
dobjtype.cpp against a sweeping "removed STACK_ARGS" commit -- all of it
correct divergence, none actionable, because outside src/gl we port
slices and never intend to converge. Inside the staircase we walk commit
by commit precisely so our copy tracks upstream's, so the question is
meaningful there. That is also where every miss the audit found lived.
Scoped: 129 files, 39 findings, under a second.
Validated against the two known misses rather than assumed: with #171
unmerged it independently reports gl_interface.cpp missing
GL_CONTEXT_PROFILE_MASK and gl_texture.cpp missing the diagonal CHKPIX
checks, and surfaces a third candidate in gl_texture.cpp I had not found
by hand.
Runs weekly rather than per-PR. The other gates read committed snapshots;
this one needs upstream file content, so it needs the clone. A periodic
full pass is also the right shape for the failure it hunts, which is
silent and accumulates.
ADVISORY for now -- 39 findings need triage before a flag can mean
"stop", the same path overlap.py took.