Conversation
…h gate
`check_pr_branch_filters.py` printed
merge-critical workflows checked: 15
workflow files present: 49
explicitly not merge-critical: 4
CLEAN: no merge-critical workflow filters pull_request by branch.
15 + 4 against 49, printed side by side and never subtracted. Thirty
files were read by nothing and the last line still said CLEAN.
Two of the thirty carried `pull_request: branches: [master]` -- the very
defect this check exists to detect. A branches filter on pull_request
means the gate does not run at all when a PR targets any other base, so
a stacked PR shows a green check list with that gate absent from it.
One of the two is corpus-ratchet, the expected-failure ledger.
Three parts:
the two filters are removed -- `paths:` selects by what changed and
stays, `branches:` selects by where the change is headed and is a hole;
the third bucket is printed with its arithmetic closing against the
file count, and the clean line says how many files remain unread
instead of promising more than it checked;
MAX_UNCLASSIFIED = 27, down only. Twenty-seven files cannot be
classified in the commit that finds them, and a gate red on the day it
lands teaches everyone to ignore red. The ceiling buys that the NEXT
workflow cannot land unread. The same read runs over the unclassified
files and is REPORTED, not failed: whether one should block a merge is
a human call, whether anybody looked is not. That count is 0 and is
printed as a zero rather than omitted.
Controls, each seen failing on purpose: a 28th unclassified workflow
gives UNCLASSIFIED ROSE 27 -> 28; a name in both lists gives IN BOTH
LISTS; restoring the filter on corpus-ratchet gives BRANCH-FILTERED
MERGE-CRITICAL WORKFLOWS. All restored, exit 0.
Also here: harness-scratch.yml, which #2955 held back because the gate
stayed red until #2949 removed the fifth carrier of that class. Both
have landed -- on master the command reports `none` and `--gate` exits
0. It carries no `paths:` filter and a push trigger on master, and its
header says why: emit-bitexact-gate.yml is pull_request with a paths
filter and no push, so it has never run on master, and when a change
made it fail there was no baseline to compare against. Historical
control: against the tree before #2955 the gate exits 1 and names all
five carriers.
The remaining 27 are a work list, not a verdict; l1-traceability.yml is
the one worth deciding first.
Closes #2957
Refs #2954
Refs #2919
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
The two list sizes and the file count were printed three lines apart and never subtracted: 15 + 4 against 49 present, so 30 workflow files were read by nothing and the summary still said CLEAN. Two of the thirty carried the defect the check exists to detect. Make the parts sum out loud; name the remainder as a third state; run the same read over it and report rather than fail; ceiling not refusal so the next addition cannot land unread; and let the final line state the scope it actually earned. Refs #2957 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
PR DashboardGenerated at: 2026-08-30 15:35:23 UTC
Summary
Seal Status
|
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
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.
The defect
scripts/ci/check_pr_branch_filters.py— the check behind Gate Topology — printed:It printed the two list sizes beside the file count and never subtracted them.
15 + 4 = 19against49present, so 30 files were read by nothing — and the lastline still said CLEAN.
Two of the thirty carried the defect it exists to detect
Read directly from the files, not inferred. A
branches:filter onpull_requestmeans thegate does not run at all when a pull request targets any other base: on a stacked PR
gh pr checksprints a green list with that gate simply absent from it. That is the exacthazard
gate-topology.yml's own header describes, "observed in this repository on2026-08-15 on three gates at once" — and one of the two is
corpus-ratchet, theexpected-failure ledger.
The check was not wrong about the 15 it read. It was wrong about what its clean line meant.
The repair
Three parts, and only the first is about the two files:
Remove the
branches:filter frompull_requestin both. Apaths:filter selects bywhat changed and stays;
branches:selects by where the change is headed.Print the third bucket. The summary now states all three counts and their sum against
the file count, on one line, so a reader can see the arithmetic close:
The final line no longer over-promises: "CLEAN: no merge-critical workflow filters
pull_request by branch, and 27 file(s) remain unread at a ceiling of 27."
A ceiling, not a refusal.
MAX_UNCLASSIFIED = 27, moving down only. Twenty-seven filescannot be classified in the commit that discovers them, and a gate that is red on the day it
lands teaches everyone to ignore red. What the ceiling buys is that the next workflow
added cannot land unread — classify it and the ceiling holds.
The same read is also run over the unclassified files and reported, not failed: whether
one of them ought to block a merge is a human call, but whether anybody looked is not.
That count is
0today and is printed as a zero rather than omitted.Controls
Each new failure direction was seen failing on purpose:
UNCLASSIFIED ROSE 27 -> 28, exit 1IN BOTH LISTS (1): seal-coverage.yml, exit 1branches: [master]oncorpus-ratchet.ymlBRANCH-FILTERED MERGE-CRITICAL WORKFLOWS (1), exit 1The third is the historical control: it is how the two offenders read before this change, and
the check reached exit 1 for them the moment they were classified — the classification is what
was missing, not the rule.
Also in this change:
tri harness scratch --gateis wired#2955 landed the command, its five-leg control and four repairs, and said the workflow was held
back only because the gate stayed red until #2949 removed the fifth carrier. Both have landed:
on master the command reports
noneand--gateexits 0, so the workflow goes in now.harness-scratch.ymlcarries nopaths:filter and apush: branches: [master]trigger,deliberately, and its header says why — the second reason is new and cost a measurement:
emit-bitexact-gate.ymlispull_requestwith apaths:filter and nopush:, so it hasnever run on master, and when a change made it fail there was no baseline to compare against.
Historical control for that gate too: against the tree as it stood before #2955,
--gateexits1 and names all five carriers; on master today it exits 0 with
none.The remaining 27
A work list, not a verdict. Nothing here claims they should be merge-critical — only that
nothing has read them:
l1-traceability.ymlis the one worth deciding first: it enforces law L1 and reports a contextthat appears on every pull request, and this check has never read its trigger block.
Related: #2919 is the other half of this — the gap between what the tree calls merge-critical
and what the ruleset actually requires. This issue is about a list that does not cover its own
directory; #2919 is about a list that does not match repository settings. Neither subsumes the
other.
Refs #2954
Refs #2919
Closes #2957 · Refs #2954 · Refs #2919
🤖 Generated with Claude Code