ci: eleven merge-critical gates were silent on stacked PRs - #2169
ci: eleven merge-critical gates were silent on stacked PRs#2169gHashTag wants to merge 1 commit into
Conversation
…#2167) A workflow declared `on: pull_request: branches: [master]` does not run when the pull request's base is any other branch. On a stacked PR every such gate is absent, and `gh pr checks` then prints a green list -- the green of a gate that never fired. This was observed here on 2026-08-15 on now-sync-gate, issue-gate and seal-staleness-warn simultaneously; a PR read as fully checked. The failure mode is silent by construction: nothing reports a gate that did not run. So the fix is a configuration test, not vigilance. Measured [measured], by parsing every workflow file rather than reading names: eleven merge-critical workflows carried the filter, not seven. The earlier count of seven came from a filtered grep and was wrong; it is corrected here rather than quietly replaced, because it had already been quoted downstream. build-paper, catalog-count-gate, check-now-freshness, coq-kernel, emit-bitexact-gate, fpga-build, notebook-gate, phi-loop-ci, schema-validation, seal-coverage, secret-scan `paths:` filters are kept -- they select by what changed, not by where it is headed. `push:` branch filters are kept as well: limiting post-merge runs is a cost decision, not a gating hole. scripts/ci/check_pr_branch_filters.py enumerates merge-critical workflows explicitly, in code. A test that inferred the list -- say, everything named `*-gate` -- would stop covering a gate the moment someone renamed it, which is the same silence in a new costume. Negative-tested: 11 violations reported before the patch, 0 after [measured]. gate-topology.yml deliberately carries no `branches:` filter, since one there would reproduce the defect the workflow exists to detect. Separately measured and deliberately NOT fixed: auto-merge-ready-prs.yml does not parse as YAML (ScannerError at line 62, a column-1 line terminating a block scalar), so GitHub cannot load it and it never runs. Repairing it would restore an automation that policy forbids, and deleting it is an owner decision. The test reports it as a warning: a gate that lands red and stays red for a reason nobody is permitted to fix teaches everyone to ignore red. Not claimed: that these gates are registered as required checks in branch protection. That lives in repository settings and cannot be read from the tree.
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
|
Baseline check on the red marks, so they are not read as this branch's doing.
The failing step is
So on this PR: no check fails because of the change. What the change did do is make Separately, PR #2168 turned up a real defect through its own title: see #2171. |
Closes #2167
The defect
A workflow declared
does not run at all when the pull request's base is another branch. On a
stacked PR every such gate is absent, and
gh pr checksprints a green list. Thatgreen is not the green a master-based PR would get — it is the green of a gate that
never fired.
Observed here on 2026-08-15:
now-sync-gate,issue-gateandseal-staleness-warnwere all invisible on a stacked PR at once, and the PR readas fully checked. The failure mode is silent by construction — nothing reports a
gate that did not run — so it needs a configuration test rather than vigilance.
Correction to the count
[measured]An earlier work order said seven workflows remained. That number came from
reading a filtered
grepand was wrong. Enumerated by parsing every workflowfile, the real number is eleven:
build-paper,catalog-count-gate,check-now-freshness,coq-kernel,emit-bitexact-gate,fpga-build,notebook-gate,phi-loop-ci,schema-validation,seal-coverage,secret-scan.The correction is recorded rather than quietly substituted, because the seven had
already been quoted downstream.
What is kept, and why
paths:filters — kept. They select by what changed, not by where the changeis headed.
push:branch filters — kept. Restricting post-merge runs is a cost decision,not a gating hole.
The test
scripts/ci/check_pr_branch_filters.pylists merge-critical workflowsexplicitly, in code, and fails when any of them filters
pull_requestbybranch. The list is deliberately not inferred: a rule like "everything named
*-gate" would stop covering a gate the moment someone renamed it — the samesilence in a new costume. Workflows that are not merge-critical are listed too,
each with its reason, so a future reader can disagree with the reason instead of
guessing at the omission.
Negative-tested
[measured]: 11 violations reported against the tree beforethe patch, 0 after. A test that had passed before the fix would have proved
nothing.
gate-topology.ymlcarries nobranches:filter, since one there would reproducethe very defect it detects.
Found, and deliberately not fixed
[measured]auto-merge-ready-prs.ymldoes not parse as YAML (ScannerErrorat line 62 —a column-1 line terminates a block scalar). GitHub cannot load it either, so it
never runs. It is left untouched: auto-merge is disabled by policy here, so
repairing the file would restore an automation that must not run, and deleting it
is an owner decision. The test reports it as a warning, not a failure — a gate
that lands red and stays red for a reason nobody is permitted to fix teaches
everyone to ignore red, which costs more than the file it flags.
Not claimed
This reads trigger configuration from the tree. It cannot verify that these
workflows are registered as required checks in branch protection, which lives in
repository settings.
Review note
Base is
master, so the gates listed above now actually run on this PR — which isitself the first end-to-end evidence that the change does what it says.