Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ jobs:
# means a future shard-count change cannot deadlock the repo. `name:` and
# `if: always()` are therefore both load-bearing: this must not become
# `if: !cancelled()` (see dogfood-gate), and it must not be renamed.
# Both halves are now asserted rather than only written down: the `name:`
# literal by `check:required-contexts` (#6865), the `if: always()` and the
# attestation roster by `check:shard-attestation` (#6082).
#
# ── It COUNTS credentials; it does not read one aggregate word (#6082) ──
#
Expand Down Expand Up @@ -519,7 +522,8 @@ jobs:
# temporal conformance matrix holds to one standard. Its NAME still says
# "live PG + MySQL" on purpose: the name IS the required check, so renaming
# it would silently drop the gate wherever branch protection lists it — the
# same trap the dogfood shards note below.
# same trap the dogfood shards note below. `check:required-contexts` pins
# this literal, parenthetical and all (#6865).
temporal-conformance:
name: Temporal Conformance (live PG + MySQL)
needs: filter
Expand Down Expand Up @@ -960,7 +964,10 @@ jobs:
# EVERY pull request in the repo sat permanently BLOCKED (mergeable, all
# checks green, merge button dead). #3622's own comment called for updating
# branch protection; keeping the contract HERE instead means a future
# shard-count change cannot deadlock the repo a second time.
# shard-count change cannot deadlock the repo a second time — and since
# #6865 the bare name is pinned by `check:required-contexts` rather than
# only described here, so a rename fails in the ESLint job instead of in
# the queue.
#
# Also aggregates dogfood-verify (the CLI pass that used to ride shard 1),
# so the one required context still covers everything it covered before
Expand Down Expand Up @@ -1040,8 +1047,9 @@ jobs:
needs: filter
# See THE FILTER CONTRACT on the filter job's outputs (#4928). No
# aggregation gate stands behind this job — its own name IS the required
# context — so this `if:` is the only thing between a filter flake and a
# green "Build Core" that built nothing.
# context, pinned by `check:required-contexts` since #6865 — so this `if:`
# is the only thing between a filter flake and a green "Build Core" that
# built nothing.
if: ${{ !cancelled() && needs.filter.outputs.core != 'false' }}
runs-on: ubuntu-latest
timeout-minutes: 30
Expand Down Expand Up @@ -1273,7 +1281,8 @@ jobs:
#
# The NAME is the required-check contract — the same trap the dogfood shards
# note above: renaming it silently drops the gate wherever branch protection
# lists it, with every PR still green.
# lists it, with every PR still green. Pinned by `check:required-contexts`
# since #6865.
console-pin:
name: Console Pin Gate
needs: filter
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,32 @@ jobs:
- name: Shard attestation gate
run: pnpm check:shard-attestation

# Required-context name pin (#6865). A GitHub required status check is
# matched BY CHECK-RUN NAME, and a job's check-run name is its `name:`
# value — so eight job `name:` literals across this file and ci.yml are
# branch-protection contract, and until now nothing asserted them.
# Renaming one is a one-line edit whose consequence is silent and
# repo-wide: the old context never reports again (permanent pending, which
# wedges the PR and the queue), or it gets dropped from the settings to
# unwedge things and every gate that job carries degrades to advisory.
# That second shape is #5617 — PR #5584 merged with THIS job red for 19
# minutes, and four more merges repeated it the same night. ci.yml states
# the contract in prose in eight places and check:shard-attestation
# asserts the two aggregate gates' job IDS; neither pins a name literal,
# and this file had neither. The pin also holds each enrolled job to the
# shapes that let a bare name report at all (no matrix, no
# continue-on-error) and each enrolled workflow to the triggers a required
# context needs (`merge_group`, and a `pull_request` with no `paths:`) —
# the machine-readable form of #5617's audit exclusions. It deliberately
# does NOT judge job-level `if:`: four of the enrolled ci.yml jobs carry a
# filter-driven `if:` by design (#4928), and a skipped job still publishes
# a context. ⚠️ It cannot verify the required SET itself — Settings →
# Rulesets is unreadable from every agent seat (403) — so it asserts the
# repo-side half only, and the script's header says so at length.
# Reads two YAML files; sub-second.
- name: Required-context name pin
run: pnpm check:required-contexts

# #4248 packaging-hygiene guard. Without a `files` whitelist npm packs the
# whole package directory, and 20 of the 49 publishable packages declared
# none — so consumers installed TypeScript sources, unit tests and build
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"check:node-version": "node scripts/check-node-version.mjs",
"check:workflow-status-functions": "node scripts/check-workflow-status-functions.mjs --self-test && node scripts/check-workflow-status-functions.mjs",
"check:shard-attestation": "node scripts/check-shard-attestation.mjs --self-test && node scripts/check-shard-attestation.mjs",
"check:required-contexts": "node scripts/check-required-contexts.mjs --self-test && node scripts/check-required-contexts.mjs",
"check:published-files": "node scripts/check-published-files.mjs --self-test && node scripts/check-published-files.mjs",
"check:type-check-coverage": "node scripts/check-type-check-coverage.mjs --self-test && node scripts/check-type-check-coverage.mjs",
"check:type-check-debt": "node scripts/check-type-check-coverage.mjs --self-test && node scripts/check-type-check-coverage.mjs --re-measure",
Expand Down
Loading
Loading