You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
scripts/ci/branch-protection-required-checks.json (SSOT) lists all stable ci.yml job names (12), enforced 1:1 against ci.yml by tools/ci-protection-check.
These already diverged before #84 (the 3 UI jobs were in the SSOT-12 but never required). Consequence: scripts/ci/sync-branch-protection.sh --apply is a footgun — it pushes the full SSOT (12) to required_status_checks, over-requiring the optional/label-gated jobs (which then "skip" and could block merges). After #84, the live required set (7) is curated via direct API and is NOT durable against a sync --apply.
This was documented in ci.yml's header (#84) but not fixed — tracked here as standalone tech debt (kept out of #84 to keep the cost-cut PR small with clean test boundaries).
Design (per user 拍板)
SSOT schema: add a per-job tier, e.g. required: true|false or tier: required|optional, so the JSON distinguishes the required subset from optional-but-present jobs.
tools/ci-protection-check: keep enforcing ci.yml job-name ↔ SSOT drift (no orphan/missing names, across BOTH tiers), but treat only the required subset as branch-protection contexts.
scripts/ci/sync-branch-protection.sh --apply: sync only the required subset to required_status_checks (never the optional/label-gated jobs).
Regression test: an optional / label-gated job (e.g. ui-screenshots, build-macos) must NOT end up in the synced required contexts; a drift in either tier is still caught.
Problem
The CI gate tooling conflates two concepts:
scripts/ci/branch-protection-required-checks.json(SSOT) lists all stable ci.yml job names (12), enforced 1:1 against ci.yml bytools/ci-protection-check.required_status_checksis a curated subset (7 after the spec-1.22 CI-cost chore ci(workflows): gate macOS + perf-smoke off regular PRs (Actions cost) #84; the label-gated UI jobs + build-macos + perf-smoke are optional).These already diverged before #84 (the 3 UI jobs were in the SSOT-12 but never required). Consequence:
scripts/ci/sync-branch-protection.sh --applyis a footgun — it pushes the full SSOT (12) torequired_status_checks, over-requiring the optional/label-gated jobs (which then "skip" and could block merges). After #84, the live required set (7) is curated via direct API and is NOT durable against async --apply.This was documented in ci.yml's header (#84) but not fixed — tracked here as standalone tech debt (kept out of #84 to keep the cost-cut PR small with clean test boundaries).
Design (per user 拍板)
required: true|falseortier: required|optional, so the JSON distinguishes the required subset from optional-but-present jobs.tools/ci-protection-check: keep enforcing ci.yml job-name ↔ SSOT drift (no orphan/missing names, across BOTH tiers), but treat only therequiredsubset as branch-protection contexts.scripts/ci/sync-branch-protection.sh --apply: sync only therequiredsubset torequired_status_checks(never the optional/label-gated jobs).Acceptance
required_status_checksbecomes durable againstsync --apply(= the 7 cheap-ubuntu jobs; build-macos / perf-smoke / ui-visual / ui-screenshots / ci-ui-review optional).ci-protection-checkstill catches any job-name drift across both tiers.make gategreen; chore-tier review (single-route + 用户 拍板).Context