Uh oh!
There was an error while loading. Please reload this page.
test(ci): derive the merge_group subscription floor from REQUIRED_CONTEXTS - #6187
Merged
Merged
Conversation
`MUST_SUBSCRIBE_MERGE_GROUP` was a hand-maintained membership list, and it had fallen behind twice: it named six workflows while eight produced an unfiltered blocking check, and by now seven against ten. The floor is now derived from `REQUIRED_CONTEXTS` in `scripts/dependabot-merge-gate.mjs` — the repository's other written-down answer to "is this check blocking and does it report on every pull request?" — via the same workflow parser `dependabot-merge-gate.test.ts` already used, extracted to `scripts/__tests__/workflow-checks.ts` so there is one parser rather than two. The hand-maintained map keeps carrying the reasons; a new assertion holds it to being a subset of the derived floor, so the two declarations cannot cross silently. Part of #6160 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019b5UBNMtTzKbVtZZGvFuxe
yinlianghui-tw
marked this pull request as ready for review
August 24, 2026 23:43
yinlianghui-tw
enabled auto-merge
August 24, 2026 23:43
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 25, 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 freeto 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.
Fixes#6160
MUST_SUBSCRIBE_MERGE_GROUPinscripts/__tests__/merge-queue-reporting.test.tswas ahand-maintained membership list, and it had already fallen behind twice. The card measured six
named workflows against eight producing an unfiltered blocking check; on
maintoday it is sevenagainst ten —
doc-component-types.yml,doc-snippet-types.ymlanddoc-fence-languages.ymlallproduce a
REQUIRED_CONTEXTScheck and none of them was inside the floor. Nothing was broken ondisk: all three really do subscribe
merge_group. What was missing was the assertion that they keepdoing so.
Per the ruling on the card this takes option 2: the floor now derives from
REQUIRED_CONTEXTSin
scripts/dependabot-merge-gate.mjs. That is not mechanising an unmechanisable judgement — themap's old header was right that "may this context be required?" is a property of repository
settings, and
REQUIRED_CONTEXTSis already a human's written-down answer to exactly that question,elsewhere in this repo. Deriving from it stops one judgement being written down twice. The
hand-maintained map keeps carrying the reasons; it stops carrying the membership.
The precondition, measured in both directions before any assertion was written
A derived floor is an improvement only while it is a superset of what the map named — one that
silently narrowed would read as more coverage while asserting less, which is this card's own defect
one level up.
b37d3f0fdMUST_SUBSCRIBE_MERGE_GROUPalso produces aREQUIRED_CONTEXTScheck (the derivation loses nothing)REQUIRED_CONTEXTScheck is onmainand subscribesmerge_group(the derived floor is satisfiable today)Both readings are clean, so the derivation strictly widens: 7 workflows → 10.
The containment is not left as a measurement taken once.
loses nothing the hand-maintained map namedpins it as an assertion, so the two declarations cannot cross later without going red: a mapentry naming a workflow that produces no required context fails, and the fix is to add the check to
REQUIRED_CONTEXTSor drop the entry — never to re-grow a hand-maintained membership.What changed
scripts/__tests__/workflow-checks.ts(new) — the check-name → workflow-file parser, movedverbatim out of
dependabot-merge-gate.test.tsso there is one parser rather than two. It isa module rather than an export of the test file because importing a
*.test.tsfrom another*.test.tsre-registers itsdescribeblocks inside the importer, running the same suite twiceunder the wrong filename.
scripts/__tests__/dependabot-merge-gate.test.ts— imports those helpers instead of definingthem. No assertion changed.
scripts/__tests__/merge-queue-reporting.test.ts— the derived floor and three assertions(below), plus a re-headed map explaining what it still carries.
content/docs/guide/ci-cd-pipeline.md— the page stated "nothing derives the set" and toldauthors to add an entry to the map. This change makes both sentences false, so they are corrected
in place: name the context in
REQUIRED_CONTEXTSand the workflow is inside the floor from thatmoment. No workflow names and no cardinality were added, so the ci-cd-pipeline.md's "Five workflows subscribe" merge_group list is short by one (skills-paths.yml, since #3735) — the #3261 shape, one subsystem over #4154 pins still hold.
union of the map and the derived floor. Same defect class, same file, same gate family — scanning
only the map would have let the page freely enumerate the three subscribers the map had fallen
behind by, i.e. the drift would hide in precisely the gap this PR exists to close. Evidence it is
a widening and not a fix in disguise:
doc-component-types.yml,doc-snippet-types.yml,doc-fence-languages.ymlandpre-install-import-graph.ymleach appear 0 times in the## Merge Queuesection, so the widened scan is green on today's prose.⛔ No workflow YAML was edited.
The context the floor protects (cited in the test header)
A required context that does not report on a queue build does not fail the queue — it stalls
it until the ruleset's 60-minute status-check timeout. That is #3523: while nothing subscribed, the
queue's required set could only be empty, so it rebuilt each PR on the current
mainand merged itunvalidated. On 2026-08-07 three pull requests (#3503, #3510, #3516) merged with
Type Checkatconclusion=failure, onto amainleft with a type error by #3498; a hot fix followed in #3505.Non-vacuity — three ablations, direction predicted before running
No build leg exists for any of them: these assertions read
.github/workflows/*from disk andimport
../dependabot-merge-gate.mjsby relative source path — no packageexportsresolutionand no vitest alias, so nothing resolves through a
dist/. Each mutation was proven on disk bygrepping the anchor text before and after (never the editor's exit code), each script carried a
trap '<restore>' EXIT INT TERM, restoration usedgit checkout HEAD -- <path>and was proven withan empty
git diff HEAD.1 — positive control (not optional): delete
merge_group:fromdoc-component-types.yml.Predicted: the NEW assertion reds; the EXISTING map assertion stays green, because that file is not
in the map — the gap is the card. Observed exactly that.
merge_grouplines 1 → 0;Tests 1 failed | 17 passed:2 — delete it from
docs-links.yml. Predicted: the EXISTING assertion must still red, provingworking coverage was not replaced by weaker coverage; the new one reds too, since that file produces
Internal Docs Link Check. Observed both:Tests 2 failed | 16 passed (18).3 — add a synthetic
REQUIRED_CONTEXTSentry naming a workflow that does not subscribe.'Hook Self-Tests'(hook-selftests.yml:pull_request, nomerge_group). Predicted: the derivedfloor reds naming that workflow, i.e. it tracks the other declaration rather than a snapshot of it —
and
dependabot-merge-gate.test.tsreds separately on the duplicate classification, expected noisefrom a synthetic entry. Observed:
Tests 3 failed | 50 passed (53), the floor naminghook-selftests.yml (produces Hook Self-Tests).Verification — all on
2cdacf420(the final commit), exit codes captured by redirect before any pipeRoot vitest only (objectui#3378).
vitest runon the three affected test filesTest Files 3 passed (3)/Tests 85 passed (85)pnpm type-check:scriptspnpm lint:root✖ 28 problems (0 errors, 28 warnings)— 186 files linted, all 28 warnings pre-existing and in untouched filespnpm check:control-bytes✅ check-control-bytes: OK (scanned 5110 tracked text file(s); skipped 85 binary).pnpm docs:check-linksLinks are valid across 15 scan roots.pnpm check:doc-types✅ Every documented component type is registered.pnpm check:doc-fences✅ check:doc-fences — every TypeScript block in 223 document(s) is fenced ts/tsx/typescript…pnpm check:doc-snippets(afterpnpm build,43 successful)Every covered documentation snippet compiles against the built types.—251 of 251 block(s) judged, 0 failednode scripts/check-changeset-presence.mjs✅ No source of a released package changed in this range, so no changeset is owed.Declared narrowing.
pnpm lint(turbo run lint) and the fullpnpm testfarm were not runlocally; CI runs both. The lint narrowing is measured rather than assumed: the population comes from
eslint's own config resolution (186 files,
--format jsoncount), it includes all three.tsfilesthis PR touches, and
eslint.config.jsconfigures no type-aware linting (noproject/projectService), so this diff cannot move the verdict on any file it did not touch.pnpm exec vitest run scripts/was also run in full:Tests 1934 passed, with two 15-secondtimeouts in
check-changeset-presence.test.tsandcheck-i18n-en-drift.test.ts— both build realgit fixture repos, both pass in isolation (
Tests 75 passed (75), exit 0), and neither file istouched by this diff or reads anything it changes. Load flakes, per AGENTS.md §测试纪律.
Generated by Claude Code
Generated by Claude Code