Skip to content

ci(lint): run the two most frequently red gates first - #15148

Merged
baozhoutao merged 3 commits into
mainfrom
claude/issue-13690-lint-gate-order-minimal-permutation
Sep 4, 2026
Merged

ci(lint): run the two most frequently red gates first#15148
baozhoutao merged 3 commits into
mainfrom
claude/issue-13690-lint-gate-order-minimal-permutation

Conversation

@claude

@claude claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #13690

Maintainer ruling C (2026-09-03, director seat, decision batch #24, 「其他同意」): the minimal permutation — move the two gates that produced 78% of current-shape reds to immediately after the six setup steps, record the ordering intent in the workflow header, and move nothing else.

The change

Lint & Repo Gates runs 142 steps sequentially and aborts at the first non-zero exit, so the unmeasured tail of a red run is 142 − failing position (measured mean ~65 steps). The measurement this ruling rests on executed all 134 gate steps and found zero gate-to-gate dependency edges: 134/134 exit 0, 134/134 write no files, and the only in-job data channel is STORE_PATH, between setup steps 4 and 5. The order is therefore a free variable, and this is a permutation rather than a refactor.

Two steps move, in this order:

step before after
Docs anchors resolve to real headings 51 7
ADR anchors + number uniqueness (governed code names its decision) 73 8

Each moves together with its own leading comment block. Everything that sat between the old positions shifts up to fill the gap — old 7–50 by +2, old 52–72 by +1 — and every step from old position 74 on keeps the position it had. The workflow header gains one sentence recording the ordering intent, so that a later author does not undo the ordering as tidying.

⛔ Nothing else moves: no slow-gate reshuffle, no job split, no continue-on-error, no change to the required contexts (the A/B of the earlier box stay ruled out), and no gate over gate order was added.

The green path is unaffected: a green run's wall clock is the sum of its steps and so is order-independent. Only red runs change, and they change by reporting earlier.

Correctness proof — the deliverable, not the diff

1. Multiset identity of the job's steps. Both revisions of lint.yml are parsed with a real YAML parser; the lint job's steps list is projected to (name, uses, run, every other key), sorted, and diffed. Run against origin/main fcc42e6c1 and this branch's head:

/tmp/.../main-lint.yml: 142 steps in job 'lint'
.github/workflows/lint.yml: 142 steps in job 'lint'
step count: before=142 after=142
multiset mismatches: 0

steps whose position changed: 67
  51 -> 7  Docs anchors resolve to real headings
  73 -> 8  ADR anchors + number uniqueness (governed code names its decision)
  7 -> 9  ESLint
  8 -> 10 Slot-lookup ratchet
  ... (the remaining 63 rows are the same +2 / +1 shift, ending at 72 -> 73)

The step multiset is identical; only positions change, and the two intended moves are the only ones that are not a shift.

2. Line-level multiset identity. Independently of the parser, the raw diff of the permutation commit is 65 insertions and 65 deletions whose line multisets are equal (git diff -U0, added lines sorted vs removed lines sorted, diff exits 0 on an empty result). Not one byte of any step body, comment or blank line was rewritten — the lines were only re-ordered. The header sentence is the one addition on top of that, in its own hunk outside the steps: list.

3. Every consumer of lint.yml stays green. Run on this branch's head (62060678f), after merging origin/main fcc42e6c1, exit codes captured before any pipe:

  • the full derived family — node scripts/pm/dispatch-gates.mjs --commands, 34 families, all exit=0. It includes check:required-contexts, check:workflow-status-functions, check-aggregator-roster, check-step-collectors, check-self-test-workflow-commands, check-self-test-wired, check:pm-dispatch-gates, check:type-check-coverage, check:type-check-debt, check:stall-guard-budget/headroom, check:nul-bytes and the rest;
  • node scripts/check-ci-filter-parity.mjs and its --self-test (invoked here the way lint.yml invokes them; there is no check:ci-filter-parity manifest key), node scripts/check-published-list-mirrors.mjs, node scripts/pr-labels.mjs --self-test, pnpm check:single-claim-paths — all exit=0;
  • node scripts/check-required-contexts.mjs --verify-required-set against the live ruleset: Lint & Repo Gates is still required and still pinned by the registry; the job's name: is untouched by this diff;
  • the always-runs tail inside this very job, which no derivation names a family for: the verify-lock, os-regen-merge, .claude/hooks/*.selftest.sh and reference-carrier self-tests — all exit=0.

check:type-check-debt first answered exit 3 (PREREQUISITE NOT MET, an environment classification and neither a pass nor a red); the dependency closure was built and it was re-run to a real exit=0 — 17 ledger entries re-measured, none above its recorded number.

Declared narrowing: pnpm lint (eslint . --no-inline-config) was not run whole-repo. It is a measurement rather than an omission: eslint's own configuration resolution reports File ignored because no matching configuration was supplied for .github/workflows/lint.yml (from --format json on that exact path), the flat config declares no yml/yaml file population at all, and the diff touches exactly one file — that one. Type-aware linting is not enabled, so no untouched file's verdict can depend on this file's content. CI runs the whole sweep regardless.

One prose effect, deliberately left alone

The comment block above Tenant-audit census matches the tree says the gate "lives in THIS job, next to its sibling" — the sibling being Docs anchors resolve to real headings, which this PR moves to position 7. The two are no longer adjacent. ⛔ The ruling says nothing else moves and the proof is that nothing else changed, so that sentence is left exactly as it is rather than tidied inside this diff.

Landing

⚠️ Draft on purpose. The ruling calls for "one PR in a queue lull — lint.yml is the hottest conflict file". origin/main was merged immediately before this PR was opened (a real merge commit; no rebase, no force-push) to keep the conflict window small. ⛔ This seat has not flipped it ready and has not armed auto-merge; the PM holds the arm until the queue is quiet. If it sits long enough for main to move again, merge main again before landing.

skip-changeset: a workflow file publishes nothing from any released package.

🤖 Generated with Claude Code

https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk


Generated by Claude Code

`Lint & Repo Gates` runs 142 steps sequentially and aborts at the first
non-zero exit, so the unmeasured tail of a red run is (142 - failing
position). The #13690 measurement found ZERO gate-to-gate dependency
edges in this job — 134/134 gate steps exit 0 and write no files — so
the order is a free variable and this is a permutation, not a refactor.

Per the maintainer ruling of 2026-09-03 (option C, the minimal
permutation), the two gates that produced 78% of current-shape reds move
to immediately after the six setup steps, in that order:

  Docs anchors resolve to real headings                     51 -> 7
  ADR anchors + number uniqueness (governed code ...)       73 -> 8

Everything between them shifts up to fill the gap; steps after position
73 are untouched. The workflow header gains one sentence recording the
ordering intent so a later author does not undo it as tidying.

Nothing else moves: no slow-gate reshuffle, no job split, no
`continue-on-error`, no change to the required contexts, and no gate
over gate order.

Correctness proof — the multiset of the job's 142 steps (`name`, `run`
body and every other key) is identical before and after; only positions
change. At the raw-text level the diff is 65 insertions / 65 deletions
whose line multisets are equal.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
…mutation

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
…mutation

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
@baozhoutao
baozhoutao marked this pull request as ready for review September 4, 2026 04:34
@baozhoutao
baozhoutao enabled auto-merge September 4, 2026 04:35
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 4, 2026
Merged via the queue into main with commit b1b723e Sep 4, 2026
27 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-13690-lint-gate-order-minimal-permutation branch September 4, 2026 05:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants