fix(tri): paginate the check-runs that decide "safe to merge", and scope a flag to its call - #3047
Merged
Merged
Conversation
…ope a flag to its call
`tri pr ready` answers "is this pull request safe to merge", prints
VERDICT: safe to merge, and with --merge runs `gh pr merge` on that
verdict. It built the answer from commits/{sha}/check-runs?per_page=100 --
one page, no --paginate. A failing check at position 101 is invisible,
the verdict reads safe, and the merge happens.
It does not bite today: 19 check-runs on master against a page of 100.
That is the character of the class -- latent, and one busy branch away.
The cure was already in the same file: prcheck.rs paginates its
pulls/{n}/files fetch and says why. Four sibling fetches did not, which
is the shape section 437 named -- a fix does not travel. All four now
paginate. They are not one defect: failures_of makes a red check beyond
the page invisible and the verdict safe; in_flight lets pending read 0 so
the merge proceeds; completed_of turns a green check into "never ran";
the 15-commit loop makes a baseline check look absent so a failure looks
new.
Pagination changed what one of them means. With --paginate a
`jq '...|length'` prints one number PER PAGE, and the old
`.trim().parse().unwrap_or(0)` would have parsed two pages as nothing and
reported ZERO pending -- the exact false "finished" that function's own
doc comment exists to prevent, arriving through the cure rather than the
disease. The counts are summed.
One honest subtraction: the summing helper's first doc comment claimed
that skipping an unparseable line differs from counting it as zero. In a
sum it does not, a mutation swapping them survived every test, and the
claim is removed rather than left standing.
Separately, `tri gates fetches` classified each fetch by reading the
ENCLOSING FUNCTION, and that subject is wrong in both directions.
False bare: red.rs's `fn now` holds two fetches and one is_lower_bound,
applied to a streak from a different fetch, so the census called the
workflow listing guarded on a check that never looks at it.
False complete: paginating one of the four fetches in prcheck.rs's
`ready` marked all four complete. A flag is an argument of a CALL, so the
scan now runs from the site out to its own argument brackets; a site with
no call around it classifies on its own line and borrows nothing.
And a guard string inside a test module is not evidence. fn_spans ends a
function at the next top-level fn, so a function last in its file
swallows the test modules after it -- red.rs is 253 lines, `fn now`
starts at 134, and two #[cfg(test)] modules sit at 198 and 223 inside its
span. Test lines were excluded from being SITES and not from being
EVIDENCE, and one exclusion without the other is worse than neither.
Where the subject cannot be read the census now asks instead of
answering: "a guard, but two fetches -- which one does it cover?" names
five sites, four of them the benign two-branch shape and one the real
mis-attribution, stated as a question and folded into neither total.
Skill sections 468 and 469.
Refs #2994
Contributor
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
This was referenced Sep 3, 2026
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.
A verdict that gates an irreversible action must not stand on a page
tri pr readyanswers is this pull request safe to merge, printsVERDICT: safe to merge, and with--mergerunsgh pr mergeon that verdict. It built the answer fromcommits/{sha}/check-runs?per_page=100— one page, no--paginate. A failing check at position 101 is invisible, the verdict reads safe, and the merge happens.It does not bite today: 19 check-runs on master against a page of 100. That is the whole character of this class — latent, and one busy branch away.
The cure was already in the same file.
prcheck.rspaginates itspulls/{n}/filesfetch and says why. Four sibling fetches did not — the shape §437 named, a fix does not travel. All four now paginate.They are not one defect:
failures_of--mergemergesin_flightcompleted_ofPagination changed what one of them means
With
--paginateajq '…|length'prints one number per page. The old code did.trim().parse().unwrap_or(0)on it, so two pages of checks would have parsed as nothing and reported zero pending — the exact false "finished" that function's own doc comment was written to prevent, arriving through the cure rather than the disease. The counts are summed instead.One honest subtraction: the summing helper's first doc comment claimed that skipping an unparseable line differs from counting it as zero. In a sum it does not — a mutation swapping them survived every test, and the claim is removed rather than left standing.
The unit of a flag is the call, not the function
tri gates fetchesclassified each bounded fetch by reading the enclosing function for guard words. That subject is wrong in both directions, and this pass found both.False bare.
red.rs'sfn nowholds two fetches and oneis_lower_bound, and the guard is applied to a streak returned by a different fetch. The census called the workflow listing guarded on a check that never looks at it.False complete. Adding
--paginateto one of the four fetches inprcheck.rs'sreadymarked all four complete. A flag is an argument of a CALL — the scan now runs from the site out to the brackets that open and close its own argument list, and a site with no call around it classifies on its own line, borrowing nothing.A guard string inside a test module is not evidence.
fn_spansends a function at the next top-levelfn, so a function LAST in its file swallows every test module after it:red.rsis 253 lines,fn nowstarts at 134, and two#[cfg(test)]modules at 198 and 223 sit inside its span. Test lines were already excluded from being sites and were not excluded from being evidence — and one of those exclusions without the other is worse than neither.Where the subject cannot be read, the census asks instead of answering:
Five lines read by hand in a minute to find the one that matters. Stated as a question in the output, folded into neither total.
cargo test -p tri— 534 passed, 0 failedtri pr ready 3043run end-to-end against the live API after the changeRefs #2994