Skip to content

[finding] ci-cd-pipeline.md's "can never be required, structurally" bullet is a second unpinned current-state claim in the same section — true today, and live-e2e.yml is scheduled to falsify it #4170

Description

@yinlianghui

Found while implementing #4154 (PR pending), whose ruling asked for a sweep of the same ## Merge Queue section for other current-state enumerations of subscribers or checks. This is the only other one. Filed rather than bundled: it is a different fact, it is not wrong today, and fixing it needs its own decision — the same discipline that produced #4154 out of #3782, and #3782 out of #3279.

The claim

content/docs/guide/ci-cd-pipeline.md, last bullet of ## Merge Queue:

- **Some contexts can never be required, structurally**, and no amount of triggering changes that:
  **Changeset Bump Policy** (`changeset-guard.yml`, inverse path filter ...),
  **Bundle Analysis** (`performance-budget.yml`, path filter),
  **Live E2E (informational)** (`continue-on-error: true`, so it is green whatever happens ...),
  and **Close issues referenced in other repositories** (`cross-repo-issue-closer.yml`, ... only *after* a merge).

Measured on main@521a37bd0 — all four are TRUE

claim evidence
changeset-guard.yml inverse path filter .github/workflows/changeset-guard.yml:16-17 — pull_request.paths: ['.changeset/**']
performance-budget.yml path filter .github/workflows/performance-budget.yml:12-15 — pull_request.paths: packages/**, apps/console/**, pnpm-lock.yaml
live-e2e.yml continue-on-error: true .github/workflows/live-e2e.yml:60, job-level
cross-repo-issue-closer.yml runs after merge .github/workflows/cross-repo-issue-closer.yml:29-31 — pull_request: types: [closed]

So this is observation-class, not a defect: nobody is being misled today.

Why it is still worth recording

Three properties, none of them fatal alone:

  1. Nothing reads it. 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 just converged the sibling sentence in this section onto a pointer to a map an assertion reads, precisely because prose that nothing reads drifts silently. This bullet is the same shape one paragraph down, and scripts/__tests__/ci-cd-pipeline-doc.test.ts pins the workflow inventory, the job table, the lockfile-merge table and the size budgets — but not this.
  2. One of the four claims is scheduled to become false. live-e2e.yml's header (lines 13-20) says outright: "Do NOT add this job to required checks, and do not remove continue-on-error, until the lane has run clean for long enough to trust (watch the nightly schedule)." Promotion is the plan, not a hypothetical — and the day it happens this page will state that a lane which now blocks merges can never block them. That is the dangerous direction this page names for itself elsewhere (Docs:ci-cd-pipeline.md 的 Performance Budget / Size Check 两节与实际工作流不符(预算数字差 5.8 倍、记录了一个不存在的工作流) #3197, ci-cd-pipeline.md 的 ci.yml job 表格漂移:写「Seven jobs」并列了一个不存在的 dev-server job(实际 6 个) #3451: advertising or denying a guardrail wrongly is worse than saying nothing, because people stop checking).
  3. It is deliberately non-exhaustive ("Some contexts"), which is honest and is also why membership drift is not the risk here — the per-claim property is. A new never-requirable workflow arriving does not make the bullet false; continue-on-error leaving live-e2e.yml does.

Why it was not fixed in the #4154 PR

Different fact, and the fix is not a swap. #4154 had somewhere to point: MUST_SUBSCRIBE_MERGE_GROUP in scripts/__tests__/merge-queue-reporting.test.ts is a maintained list an assertion already reads. There is no equivalent for "structurally cannot be required" — it would have to be built, or the claims pinned one by one to the YAML properties they quote. Options, for whoever picks this up:

Leaning B: it pins what is actually claimed, and it is the option that goes red on the one change we already know is coming.

Not a defect, checked

Two other numbers in the same section are counts of the lists immediately under them — "The three steps have to happen in this order" and "Two things follow for anyone editing this directory". Both are visible at a glance and drift with the list they introduce, which is the shape #3451 explicitly allows ("the table is the list"). Left alone.


Generated by Claude Code

Activity

  1. self-assigned this
    on Aug 10, 2026
  2. yinlianghui commented on Aug 10, 2026

    @yinlianghui
    CollaboratorAuthor

    Claim: PM loop round 6 (rolling slot refill)
    Session: session_017Qqyix2QcnpUC9XeYVDzx3 · Branch: claude/issue-4170-never-required-pins · Worktree: objectui-issue-4170
    File surface: content/docs/guide/ci-cd-pipeline.md (the "can never be required, structurally" bullet) + scripts/__tests__/ (the pin). Serial constraints: PR #4171 (armed, same page) — stack on claude/issue-4154-merge-group-list if it has not merged at start; disjoint from #7100/#3586/#4145/#2794 in flight.
    Container & model: S, mode:subagent, model: opus

    Delegated ruling on the A/B/C fork (veto window open): B — keep the enumeration (it is load-bearing pedagogy: four workflows each demonstrating a DIFFERENT structural reason a gate cannot be required) and pin each of the four claims to the live YAML property it quotes (inverse paths / paths / continue-on-error / types:[closed]), so the bullet reds the day any property changes — including the change live-e2e's own header already schedules. The pin derives from the YAML, never restates it (the #4150/#4143 derived-expectation pattern); if a fifth structurally-unrequirable workflow arrives the pin must NOT demand its addition (the bullet is examples, not a census — assert the four named claims true, not the list complete; state that scope in the docblock).


    Generated by Claude Code

  3. yinlianghui commented on Aug 10, 2026

    @yinlianghui
    CollaboratorAuthor

    ACCEPT (objectui seat PM, session session_017Qqyix2QcnpUC9XeYVDzx3, review of record) — PR #4175, Option B as ruled.

    The pin's architecture is the part worth copying: STRUCTURAL_BLOCKS maps each filename to a CHECKER that reads the property out of the YAML on every run — no second hardcode anywhere — with the doc-quoting direction separated from the property direction (mutation F proved a page can rot independently of the YAML and gets its own red). Seven mutations, exactly one red each for A–F with per-claim attribution, and G's vacuity guard covering the delete-everything case. The examples-true-not-census-complete scope is stated where the next reader needs it, and live-e2e's scheduled falsification has its disposition written in advance (delete, not soften). The evidence-table refinement (pull_request_target, with the merged == true gate covered as the same claim's second half) is measurement improving the card rather than contradicting it.

    Process notes received: the ~30-40min heavy-lock holds from the #7100 whole-repo runs are an accepted cost of that card's size; the shared remote-tracking refs behavior is now twice-documented for future devs. Flipping ready + auto-merge.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions