check:partof-closing-keyword prescribes a discharge that this repository's configuration makes unreachable. Found while landing PR #17454; it is not that PR's problem and not fixable inside it.
Measured
repo setting squash_merge_commit_message = COMMIT_MESSAGES
squash_merge_commit_title = COMMIT_OR_PR_TITLE
ruleset 12119582 (main, ACTIVE) merge_queue rule, merge_method = SQUASH
Every merge to main goes through the queue, squashed, and the queue composes the commit message from the repo setting — there is no per-merge override. So the landed message is the concatenation of the branch's commit messages: in the gate's own words, "a text no one writes and no one reviews, which carries every trailer its inputs carried and can contradict itself where its parts did not."
Why that is the gate's problem specifically
scripts/check-partof-closing-keyword.mjs refuses when commits carry card trailers, and for a branch that is already pushed it states plainly:
BRANCH ALREADY PUSHED … no author action clears this red.
What DISCHARGES it is the merge — a merge whose squash message is the PR BODY.
That discharge requires squash_merge_commit_message = PR_BODY. With COMMIT_MESSAGES it cannot happen, so the check is red on a condition nobody can satisfy and no merge can discharge.
⚠️ And it is not among main's required checks (TypeScript Type Check, Build Core, Test Core, Dogfood Regression Gate), so it blocks nothing. A gate that can neither be satisfied nor block is a gate with no teeth — it reports a real hazard into a channel nothing acts on.
The hazard it is reporting, which is real
PR #17454 carries ten commits with Refs #17440 trailers. Under COMMIT_MESSAGES all ten land concatenated on main. GitHub reads trailers in that landed message, so a card relation declared once in a PR body arrives ten times in a text nobody authored. The gate's header cites a measured precedent — the squash of PR 16247, fc3fb7c4619 — where exactly this closed a card from inside a bullet no one read as a declaration.
The decision
This is a repository setting, so it is the maintainer's. Two coherent positions:
- Set
squash_merge_commit_message to PR_BODY. The gate's discharge becomes reachable, the landed message is a text someone wrote and reviewed, and the trailers in individual commits stop mattering. ⚠️ It changes what every future squash lands, not just this PR's — that is the whole point, and also the thing to weigh.
- Leave it, and retire or re-scope the gate. If the concatenated message is accepted deliberately, then a check that refuses it, cannot be satisfied, and blocks nothing should not stay in that state — ⛔ an unsatisfiable non-blocking gate trains readers to ignore red.
⛔ What should not happen is the current state persisting by default: a gate describing a real hazard, prescribing a remedy the configuration forbids, and gating nothing.
No code change is proposed here. Filing so the choice is recorded rather than rediscovered by the next person who reads that red.
check:partof-closing-keywordprescribes a discharge that this repository's configuration makes unreachable. Found while landing PR #17454; it is not that PR's problem and not fixable inside it.Measured
Every merge to
maingoes through the queue, squashed, and the queue composes the commit message from the repo setting — there is no per-merge override. So the landed message is the concatenation of the branch's commit messages: in the gate's own words, "a text no one writes and no one reviews, which carries every trailer its inputs carried and can contradict itself where its parts did not."Why that is the gate's problem specifically
scripts/check-partof-closing-keyword.mjsrefuses when commits carry card trailers, and for a branch that is already pushed it states plainly:That discharge requires
squash_merge_commit_message = PR_BODY. WithCOMMIT_MESSAGESit cannot happen, so the check is red on a condition nobody can satisfy and no merge can discharge.main's required checks (TypeScript Type Check,Build Core,Test Core,Dogfood Regression Gate), so it blocks nothing. A gate that can neither be satisfied nor block is a gate with no teeth — it reports a real hazard into a channel nothing acts on.The hazard it is reporting, which is real
PR #17454 carries ten commits with
Refs #17440trailers. UnderCOMMIT_MESSAGESall ten land concatenated onmain. GitHub reads trailers in that landed message, so a card relation declared once in a PR body arrives ten times in a text nobody authored. The gate's header cites a measured precedent — the squash of PR 16247,fc3fb7c4619— where exactly this closed a card from inside a bullet no one read as a declaration.The decision
This is a repository setting, so it is the maintainer's. Two coherent positions:
squash_merge_commit_messagetoPR_BODY. The gate's discharge becomes reachable, the landed message is a text someone wrote and reviewed, and the trailers in individual commits stop mattering.⛔ What should not happen is the current state persisting by default: a gate describing a real hazard, prescribing a remedy the configuration forbids, and gating nothing.
No code change is proposed here. Filing so the choice is recorded rather than rediscovered by the next person who reads that red.