From 4a0ea0f6c6c479dfba49779af7e3cd8928a7181d Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Wed, 14 Oct 2026 12:05:46 -0400 Subject: [PATCH] ci: one job for the repository's script checks Six workflows, nine jobs on every push (lockfiles, tests-in-ci, workflow-hygiene, wai-section-refs, spec-refs, and no-vanity-metrics' four), each paying for a container and a checkout to run a script that reads the tree for a few seconds. On 2026-10-14 they were about half of the 119 jobs waiting for the linux-arm64 runner, queued behind the long standards-build legs; spec-refs held a place on the one x86_64 runner. repo-checks.yml runs them all in one job on linux-arm64, one step a check, in the same order with the same self-tests. Every step runs even after an earlier one fails (`!cancelled()`), so a red job names each failing check, and fails if any did. The public-name check still runs only on the push to main, where its pattern list is given. The two path filters (public text, WAI section references) are dropped: the checks take seconds, and a filter that is wrong skips a check silently. check-workflow-concurrency-selftest.sh takes the new file as its fixture (it removed the concurrency block from workflow-hygiene.yml, now gone); CHARTER.md names the new workflow. Locally: the concurrency self-test and check (24 workflows), the path-gate self-test, tests-in-ci, spec refs and vanity metrics pass, and the workflow parses (19 steps). Co-Authored-By: Claude Opus 5.5 --- .github/workflows/lockfiles.yml | 54 ----- .github/workflows/no-vanity-metrics.yml | 188 ------------------ .github/workflows/repo-checks.yml | 128 ++++++++++++ .github/workflows/spec-refs.yml | 45 ----- .github/workflows/tests-in-ci.yml | 44 ---- .github/workflows/wai-section-refs.yml | 62 ------ .github/workflows/workflow-hygiene.yml | 67 ------- CHARTER.md | 2 +- .../check-workflow-concurrency-selftest.sh | 2 +- 9 files changed, 130 insertions(+), 462 deletions(-) delete mode 100644 .github/workflows/lockfiles.yml delete mode 100644 .github/workflows/no-vanity-metrics.yml create mode 100644 .github/workflows/repo-checks.yml delete mode 100644 .github/workflows/spec-refs.yml delete mode 100644 .github/workflows/tests-in-ci.yml delete mode 100644 .github/workflows/wai-section-refs.yml delete mode 100644 .github/workflows/workflow-hygiene.yml diff --git a/.github/workflows/lockfiles.yml b/.github/workflows/lockfiles.yml deleted file mode 100644 index 158b41b71..000000000 --- a/.github/workflows/lockfiles.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: lockfiles - -# Every committed Cargo.lock is current: cargo would not change it. -# -# The workspaces in this tree depend on one another by path. A version bump in -# one leaves the lockfiles of its dependents behind, and nothing says so until -# a job that passes `--locked` fails on a change that never touched it. This -# job says so on the change that caused it, in about a minute: it resolves each -# workspace against its lock (scripts/check-lockfiles.sh), downloading no crate -# and building nothing. -# -# No `paths:` filter, on purpose. On this forge a filter matches the files of -# the push, not of the pull request, so a later push that touches no manifest -# would leave the head with no run of this check, and a stale lock would merge -# under a green list. The job is short enough to run on every push. - -# One run per branch at a time. A push supersedes the run before it. -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: - push: - branches: [main] - pull_request: - -# Runs on `linux-arm64`, not `linux`: these jobs read files and run scripts, so the CPU -# architecture does not matter to them, and the one `linux` (x86_64) runner is the -# fleet's bottleneck, with every Rust workspace's tests queued on it. -jobs: - current: - name: every Cargo.lock is current - runs-on: linux-arm64 - timeout-minutes: 15 - steps: - - uses: actions/checkout@v4 - - # The docker runner ships no Rust, so rustup is bootstrapped. - - name: Install Rust 1.98.0 - shell: bash - run: | - export PATH="$HOME/.cargo/bin:$PATH" - command -v rustup >/dev/null 2>&1 || \ - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0 - rustup toolchain install 1.98.0 --profile minimal - rustup default 1.98.0 - echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - - # The check must be able to fail, or it is decoration. - - name: The check fails closed (self-test) - run: ./scripts/check-lockfiles-selftest.sh - - - name: Every Cargo.lock is current - run: ./scripts/check-lockfiles.sh diff --git a/.github/workflows/no-vanity-metrics.yml b/.github/workflows/no-vanity-metrics.yml deleted file mode 100644 index 8f51fec8c..000000000 --- a/.github/workflows/no-vanity-metrics.yml +++ /dev/null @@ -1,188 +0,0 @@ -name: no-vanity-metrics - -# Blocks reintroduction of codebase-state numbers (crate counts, test -# counts, LOC, "N+ adapters", etc.) into READMEs and other Markdown -# surfaces. Those numbers drift on every code change and create -# permanent sync debt with the websites; the open-standards posture is -# "describe the shape, not the size." See CONTRIBUTING.md for the -# rationale and the opt-out marker. -# -# Two more jobs hold WAI's public text (wai/) to its writing rules -# (wai/CONTRIBUTING.md, *Public text*): no comparative or promotional phrasing -# (a public phrase list), and no company, vendor, customer or product names -# (patterns kept private, in the WAI_NAME_DENYLIST secret; prints locations -# only). Both checks fail closed: a grep error or a pattern that does not compile -# fails the job, and scripts/test-public-text-checks.sh proves it on every run. -# The secret is given to one step, on a push to main only: a pull request runs -# code from its own branch, and a step of it that held the list could print it to -# a public log. Without the secret, a push to main fails; a pull request shows a -# failed (continue-on-error) step saying the name check did not run. - -# One run per branch at a time. A push supersedes the run before it. -# -# There is one `macos` runner and it is the dev Mac, so every macOS job in this -# repo queues on it. With no concurrency group, a session pushing four versions -# of a branch queued four complete sets of runs and every one of them had to -# drain: on 2026-10-05 a PR's 21 contexts settled none in 70 minutes behind a -# backlog of 25 runs, and the queue grew faster than it cleared. Only the newest -# commit's verdict is wanted, so the older runs are cancelled. -# -# Verified on this forge (Forgejo 16.0.5) in `ci-test` before being added here: -# the key parses, and a newer push moves an older run to `cancelled` even while -# it is still queued, which is the case that matters. -# -# `cancel-in-progress: true` also applies to `main`. That is deliberate and -# safe here: main advances by merge commits whose tree contains the commits -# before them, so the newer run covers the older one's changes. -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: - pull_request: - paths: - - '**/*.md' - # The public-text checks below scan WAI's code comments and data too. - - 'wai/**/*.rs' - - 'wai/**/*.toml' - - 'wai/**/*.py' - - 'wai/**/*.sh' - - 'wai/**/*.js' - - 'wai/**/*.mjs' - - 'wai/**/*.json' - - 'wai/**/*.html' - - 'wai/**/*.css' - - 'wai/**/*.ttl' - - 'wai/**/*.h' - - 'wai/**/*.c' - - 'wai/**/*.txt' - - 'wai/**/.gitignore' - - '.github/workflows/no-vanity-metrics.yml' - - 'scripts/check-no-vanity-metrics.sh' - - 'scripts/check-comparative-prose.sh' - - 'scripts/check-public-names.sh' - - 'scripts/test-public-text-checks.sh' - push: - branches: - - main - paths: - - '**/*.md' - # The public-text checks below scan WAI's code comments and data too. - - 'wai/**/*.rs' - - 'wai/**/*.toml' - - 'wai/**/*.py' - - 'wai/**/*.sh' - - 'wai/**/*.js' - - 'wai/**/*.mjs' - - 'wai/**/*.json' - - 'wai/**/*.html' - - 'wai/**/*.css' - - 'wai/**/*.ttl' - - 'wai/**/*.h' - - 'wai/**/*.c' - - 'wai/**/*.txt' - - 'wai/**/.gitignore' - - '.github/workflows/no-vanity-metrics.yml' - - 'scripts/check-no-vanity-metrics.sh' - - 'scripts/check-comparative-prose.sh' - - 'scripts/check-public-names.sh' - - 'scripts/test-public-text-checks.sh' - -# Runs on `linux-arm64`, not `linux`: these jobs read files and run scripts, so the CPU -# architecture does not matter to them, and the one `linux` (x86_64) runner is the -# fleet's bottleneck, with every Rust workspace's tests queued on it. -jobs: - scan: - name: Scan committed Markdown for vanity metrics - runs-on: linux-arm64 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Run scanner - run: bash scripts/check-no-vanity-metrics.sh - - wai-comparative-prose: - name: WAI public text names no comparison - runs-on: linux-arm64 - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: The two public-text checks fail closed (self-test) - run: bash scripts/test-public-text-checks.sh - - name: Run the comparative-prose check - run: bash scripts/check-comparative-prose.sh - - wai-public-names: - name: WAI public text names no company or product - runs-on: linux-arm64 - steps: - - name: Checkout - uses: actions/checkout@v4 - # The list reaches this step only, and only on a push to main, whose code - # has been merged. Without the list the check cannot run, and that fails. - - name: Run the public-name check - if: github.event_name != 'pull_request' - env: - # Newline-separated patterns, never committed: a public list would - # publish the names it keeps out. - WAI_NAME_DENYLIST: ${{ secrets.WAI_NAME_DENYLIST }} - run: | - if [ -z "$WAI_NAME_DENYLIST" ]; then - echo "::error::WAI_NAME_DENYLIST is not set: the public-name check cannot run" - exit 1 - fi - bash scripts/check-public-names.sh - # A pull request never receives the list. The step fails visibly without - # failing the job; the push to main runs the check. - - name: The public-name check did not run on this pull request - if: github.event_name == 'pull_request' - continue-on-error: true - run: | - echo "::warning::the public-name check does not run on a pull request (its pattern list is never given to pull-request code); it runs on the push to main" - exit 1 - -# (touched to test that this very change supersedes its own queued runs) - # ── No library source file is unreachable from its crate root ───────────── - # - # An orphan `.rs` — one no `mod`, `#[path]` or `include!` ever names — is not - # merely untested. It is never compiled, so it is invisible to every check in - # this repository at once: cargo check, cargo test, clippy, the conformance - # suites. It cannot fail, because nothing asks it anything. - # - # This repo keeps finding that family: a feature-gated test run without - # `--features`, a platform-gated meter pinned to one runner, a conformance - # suite in `main()` that `cargo test` compiles and never runs. An orphan file - # is the strongest member — it does not even type-check. - # - # The hazard is the next reader, not the dead code. One such file documents - # itself as measuring energy via IOReport and in fact multiplies CPU seconds - # by a fixed watt figure; a reader who trusts that header gets a fabricated - # number. The script's baseline pins today's 25 so this does not go red on a - # pre-existing condition, and so the count can only ratchet down. - orphan-sources: - name: No new orphan source files - runs-on: linux-arm64 - steps: - - name: Checkout - uses: actions/checkout@v4 - - # Both directions, before trusting the result: a planted orphan must fail - # the check, and removing it must pass. A guard verified in only the - # passing direction is a guard that has never been seen to work. - - name: The check fails closed (self-test) - run: | - set -euo pipefail - probe=jcp/jcp-rs/crates/jcp-efficiency/src/_ci_orphan_probe.rs - printf 'pub fn never_compiled() -> u64 { 0 }\n' > "$probe" - if python3 scripts/check-orphan-sources.py >/dev/null 2>&1; then - rm -f "$probe" - echo "::error::the orphan check passed with a planted orphan present" - exit 1 - fi - rm -f "$probe" - python3 scripts/check-orphan-sources.py - - - name: Run the orphan-source check - run: python3 scripts/check-orphan-sources.py - diff --git a/.github/workflows/repo-checks.yml b/.github/workflows/repo-checks.yml new file mode 100644 index 000000000..1f2428230 --- /dev/null +++ b/.github/workflows/repo-checks.yml @@ -0,0 +1,128 @@ +# Repository checks: the script checks every change runs, in one job. +# +# Each of these is a script that reads the tree for a few seconds. They were six +# workflows and nine jobs (lockfiles, tests-in-ci, workflow-hygiene, wai-section-refs, +# spec-refs and no-vanity-metrics' four), and each job paid for a container and a +# checkout to run them. On 2026-10-14 the light checks were about half of the 119 jobs +# waiting for the linux-arm64 runner, queued behind the long standards-build legs, and +# spec-refs held a place on the one x86_64 runner. One job runs them all now, one step +# a check: every step runs even after an earlier one fails (`!cancelled()`), so a red +# job names each failing check in its own step, and the job fails if any did. +# +# The two path filters the old workflows had (public text on Markdown and wai/ sources, +# section references on the WAI documents) are gone: the checks take seconds, and a +# filter that is wrong skips a check silently. +name: repository checks + +on: + push: + branches: [main] + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + checks: + name: lockfiles, tests in CI, workflow hygiene, spec and section references, public text + runs-on: linux-arm64 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v5 + + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + + # check-lockfiles.sh runs `cargo` against every lockfile. + - name: Install Rust 1.98.0 + shell: bash + run: | + export PATH="$HOME/.cargo/bin:$PATH" + command -v rustup >/dev/null 2>&1 || \ + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0 + rustup toolchain install 1.98.0 --profile minimal + rustup default 1.98.0 + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" + + # ── Every Cargo.lock is current ────────────────────────────────────────── + - name: "lockfiles: the check fails closed (self-test)" + if: ${{ !cancelled() }} + run: ./scripts/check-lockfiles-selftest.sh + - name: "lockfiles: every Cargo.lock is current" + if: ${{ !cancelled() }} + run: ./scripts/check-lockfiles.sh + + # ── Every test file is run by a job or listed with its reason ──────────── + - name: "tests in CI: the check fails closed (self-test)" + if: ${{ !cancelled() }} + run: ./scripts/check-tests-in-ci-selftest.sh + - name: "tests in CI: every test file is run or listed, and none can run empty" + if: ${{ !cancelled() }} + run: python3 -I scripts/check-tests-in-ci.py + + # ── Every workflow supersedes its own queue; the path gate fails open ─── + - name: "workflow hygiene: the check fails closed (self-test)" + if: ${{ !cancelled() }} + run: ./scripts/check-workflow-concurrency-selftest.sh + - name: "workflow hygiene: every workflow is grouped per ref" + if: ${{ !cancelled() }} + run: ./scripts/check-workflow-concurrency.sh + - name: "workflow hygiene: the path gate fails open (self-test)" + if: ${{ !cancelled() }} + run: ./scripts/pr-touches-paths-selftest.sh + + # ── Code cites no section its SPEC lacks; WAI's cited sections exist ──── + - name: "spec references: the check can fail (self-test)" + if: ${{ !cancelled() }} + run: bash scripts/check-spec-refs-selftest.sh + - name: "spec references: every SPEC citation resolves" + if: ${{ !cancelled() }} + run: python3 scripts/check-spec-refs.py + - name: "section references: every section WAI's documents cite exists" + if: ${{ !cancelled() }} + run: python scripts/check-wai-section-refs.py + + # ── Public text: no vanity metrics, no comparison, no company names ───── + - name: "public text: no vanity metrics in committed Markdown" + if: ${{ !cancelled() }} + run: bash scripts/check-no-vanity-metrics.sh + - name: "public text: the two public-text checks fail closed (self-test)" + if: ${{ !cancelled() }} + run: bash scripts/test-public-text-checks.sh + - name: "public text: WAI's public text names no comparison" + if: ${{ !cancelled() }} + run: bash scripts/check-comparative-prose.sh + # The pattern list is a secret, never given to pull-request code: the check runs + # on the push to main. + - name: "public text: WAI's public text names no company or product (push to main)" + if: ${{ !cancelled() && github.event_name != 'pull_request' }} + env: + WAI_NAME_DENYLIST: ${{ secrets.WAI_NAME_DENYLIST }} + run: | + if [ -z "$WAI_NAME_DENYLIST" ]; then + echo "::error::WAI_NAME_DENYLIST is not set: the public-name check cannot run" + exit 1 + fi + bash scripts/check-public-names.sh + + # ── No library source file is unreachable from its crate root ─────────── + # An orphan `.rs` (one no `mod`, `#[path]` or `include!` names) is never compiled, + # so nothing else in this repository can see it. Both directions, before trusting + # the result: a planted orphan must fail the check, and removing it must pass. + - name: "orphan sources: the check fails closed (self-test)" + if: ${{ !cancelled() }} + run: | + set -euo pipefail + probe=jcp/jcp-rs/crates/jcp-efficiency/src/_ci_orphan_probe.rs + printf 'pub fn never_compiled() -> u64 { 0 }\n' > "$probe" + if python3 scripts/check-orphan-sources.py >/dev/null 2>&1; then + rm -f "$probe" + echo "::error::the orphan check passed with a planted orphan present" + exit 1 + fi + rm -f "$probe" + - name: "orphan sources: no new orphan source files" + if: ${{ !cancelled() }} + run: python3 scripts/check-orphan-sources.py diff --git a/.github/workflows/spec-refs.yml b/.github/workflows/spec-refs.yml deleted file mode 100644 index 4ac3cd8db..000000000 --- a/.github/workflows/spec-refs.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: spec citations resolve - -# Every `SPEC §N` a standard's code cites is a section that standard's SPEC.md -# has. See the header of scripts/check-spec-refs.py for why: a citation to a -# section that does not exist reads as authority it does not have, and the three -# instances found so far were each discovered by reading, long after they were -# written. -# -# Deliberately NO `paths:` filter, for two reasons. -# -# The check is one Python pass over the tree — about a second, no toolchain, no -# cargo — so running it on every change costs less than describing when to run -# it. And a correct filter here would have to name every standard's `**/*.rs` -# plus every `SPEC.md`; `standards-build.yml` records that `**`-prefixed globs -# do not match on this forge the way they do elsewhere, and that a gate which -# quietly fails to fire is worse than no gate, because it reports nothing and -# everyone reads that as green. An unfiltered cheap check cannot fail that way. -# -# The self-test runs first and on its own line. A check that cannot fail is -# decoration, and this one would be easy to break into permanent silence — a -# regex that stops matching finds nothing and exits 0. - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: - pull_request: - push: - branches: - - main - -jobs: - spec-refs: - name: Code cites no section its SPEC lacks - runs-on: linux - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: The check can fail (self-test) - run: bash scripts/check-spec-refs-selftest.sh - - - name: Every SPEC citation resolves - run: python3 scripts/check-spec-refs.py diff --git a/.github/workflows/tests-in-ci.yml b/.github/workflows/tests-in-ci.yml deleted file mode 100644 index 89dca38a8..000000000 --- a/.github/workflows/tests-in-ci.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: tests in CI - -# Every integration test of the reference crate is run by a job, and none can run -# empty. -# -# The conformance workflows name the tests they run, one `--test NAME` at a time. A test -# file nobody adds to a step never runs, and a feature-gated one compiled in a step that -# lacks its feature reports `ok` with no test in it. Both have happened here, silently. -# scripts/check-tests-in-ci.py requires that every test file is named by a step or -# listed, with its reason, in the crate's tests/NOT-IN-CI.txt, and that every -# feature-gated one declares its features in Cargo.toml, so that cargo refuses to build -# it without them. -# -# No `paths:` filter, on purpose. On this forge a filter matches the files of the push, -# not of the pull request, so a later push that touches no test would leave the head with -# no run of this check. The job takes seconds: it reads files and builds nothing. - -# One run per branch at a time. A push supersedes the run before it. -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: - push: - branches: [main] - pull_request: - -# Runs on `linux-arm64`, not `linux`: these jobs read files and run scripts, so the CPU -# architecture does not matter to them, and the one `linux` (x86_64) runner is the -# fleet's bottleneck, with every Rust workspace's tests queued on it. -jobs: - covered: - name: every test file is run by a job or listed with its reason - runs-on: linux-arm64 - timeout-minutes: 10 - steps: - - uses: actions/checkout@v4 - - # The check must be able to fail, or it is decoration. - - name: The check fails closed (self-test) - run: ./scripts/check-tests-in-ci-selftest.sh - - - name: Every test file is run or listed, and none can run empty - run: python3 -I scripts/check-tests-in-ci.py diff --git a/.github/workflows/wai-section-refs.yml b/.github/workflows/wai-section-refs.yml deleted file mode 100644 index 62844cbad..000000000 --- a/.github/workflows/wai-section-refs.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: WAI section references - -# Every section that SPEC.md, an extension or SECURITY.md cites in a WAI text exists: -# a link followed by §N, a link whose text holds §N, or an extension's name (or -# SPEC) in prose followed by §N, including references that break across lines. -# A citation of a section that was never written — as transparency §6's pointer -# to "jwp-receipts §7" was, before that section existed — fails the job. Research -# notes are dated records and are not read. The check is -# scripts/check-wai-section-refs.py; it needs Python and nothing else. - -# One run per branch at a time. A push supersedes the run before it. -# -# There is one `macos` runner and it is the dev Mac, so every macOS job in this -# repo queues on it. With no concurrency group, a session pushing four versions -# of a branch queued four complete sets of runs and every one of them had to -# drain: on 2026-10-05 a PR's 21 contexts settled none in 70 minutes behind a -# backlog of 25 runs, and the queue grew faster than it cleared. Only the newest -# commit's verdict is wanted, so the older runs are cancelled. -# -# Verified on this forge (Forgejo 16.0.5) in `ci-test` before being added here: -# the key parses, and a newer push moves an older run to `cancelled` even while -# it is still queued, which is the case that matters. -# -# `cancel-in-progress: true` also applies to `main`. That is deliberate and -# safe here: main advances by merge commits whose tree contains the commits -# before them, so the newer run covers the older one's changes. -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: - push: - branches: [main] - paths: - - 'wai/extensions/**' - - 'wai/SPEC.md' - - 'wai/SECURITY.md' - - 'scripts/check-wai-section-refs.py' - - '.github/workflows/wai-section-refs.yml' - pull_request: - paths: - - 'wai/extensions/**' - - 'wai/SPEC.md' - - 'wai/SECURITY.md' - - 'scripts/check-wai-section-refs.py' - - '.github/workflows/wai-section-refs.yml' - -# Runs on `linux-arm64`, not `linux`: these jobs read files and run scripts, so the CPU -# architecture does not matter to them, and the one `linux` (x86_64) runner is the -# fleet's bottleneck, with every Rust workspace's tests queued on it. -jobs: - section-refs: - name: cited sections exist - runs-on: linux-arm64 - steps: - - uses: actions/checkout@v5 - - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Every cited section exists - shell: bash - run: python scripts/check-wai-section-refs.py diff --git a/.github/workflows/workflow-hygiene.yml b/.github/workflows/workflow-hygiene.yml deleted file mode 100644 index f40794e6d..000000000 --- a/.github/workflows/workflow-hygiene.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: workflow hygiene - -# Properties of the workflows themselves, checked rather than remembered. -# -# Two properties today. The first: every workflow declares a concurrency group -# that varies by ref. None of them did until 2026-10-05, and the consequence was not -# a slow build — it was that CI stopped being usable for anyone. A session -# pushing four versions of a branch queued four complete sets of runs, all of -# which had to drain; one PR's 21 contexts settled none in 70 minutes behind a -# backlog of 25, and two PRs were merged on locally-executed equivalents -# because the gate could not run. One omitted block reintroduces that for the -# whole repo, invisibly: the workflow still passes, it just queues forever -# under load. -# -# **The path gate.** `scripts/pr-touches-paths.py` decides whether a -# path-filtered workflow's jobs do any work, from the pull request's own diff — -# because Forgejo matches a `paths:` filter against the push delta, so a rebase -# fires every path-filtered workflow in the repo (measured: a jcp-only change -# ran 2 workflows pushed fresh and 15 force-pushed after a rebase). A gate that -# decides whether tests run is load-bearing in the dangerous direction: a wrong -# `false` silently skips a workflow. Its self-test pins both directions and that -# every way of failing fails *open*. -# -# This job runs on `linux`, which is jetson-hub — deliberately not the dev Mac, -# which already serves 13 of this repo's 21 contexts through two runners. It -# needs no toolchain and finishes in seconds. - -on: - push: - branches: [main] - pull_request: - paths: - - '.github/workflows/**' - - 'scripts/check-workflow-concurrency.sh' - - 'scripts/check-workflow-concurrency-selftest.sh' - - 'scripts/pr-touches-paths.py' - - 'scripts/pr-touches-paths-selftest.sh' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -# Runs on `linux-arm64`, not `linux`: these jobs read files and run scripts, so the CPU -# architecture does not matter to them, and the one `linux` (x86_64) runner is the -# fleet's bottleneck, with every Rust workspace's tests queued on it. -jobs: - concurrency-groups: - name: every workflow supersedes its own queue - runs-on: linux-arm64 - steps: - - uses: actions/checkout@v4 - - # The check must be able to fail, or it is decoration. The self-test - # breaks the property both ways against a scratch copy and asserts the - # check rejects each. It lives in a script because embedding its Python - # in this `run:` block made the file invalid YAML, which would have meant - # no CI at all. - - name: The check fails closed (self-test) - run: ./scripts/check-workflow-concurrency-selftest.sh - - - name: Every workflow is grouped per ref - run: ./scripts/check-workflow-concurrency.sh - - # The path gate fails open in every failure mode, and still answers - # `false` for a diff that cannot affect the workflow. - - name: The path gate fails open (self-test) - run: ./scripts/pr-touches-paths-selftest.sh diff --git a/CHARTER.md b/CHARTER.md index d33695eb9..52a960ed2 100644 --- a/CHARTER.md +++ b/CHARTER.md @@ -40,4 +40,4 @@ A new standard joins this repository by: Codebase-state numbers (`N crates`, `N tests passing`, `N LOC`, `N+ adapters`) drift on every code change and create permanent sync debt between the website, the GitHub READMEs, and any downstream messaging. Marketing surfaces in this repository describe the **shape** of what's there, not the **size**. Spec versions, algorithm names, RFC numbers, license labels, and other identity-class facts are preserved — they are part of the contract. -A scanner enforces this: [`scripts/check-no-vanity-metrics.sh`](scripts/check-no-vanity-metrics.sh), run on every PR and `main` push by the [`no-vanity-metrics`](.github/workflows/no-vanity-metrics.yml) CI workflow. Contributors can wire it into a local pre-commit hook via [`scripts/install-hooks.sh`](scripts/install-hooks.sh). The scanner targets marketing / spec / governance Markdown; historical progress notes, changelogs, and external corpora are exempt by design. Lines that legitimately need a number (a reference to an external spec, codec, or RFC) opt out with `` at end of line. +A scanner enforces this: [`scripts/check-no-vanity-metrics.sh`](scripts/check-no-vanity-metrics.sh), run on every PR and `main` push by the [`repository checks`](.github/workflows/repo-checks.yml) CI workflow. Contributors can wire it into a local pre-commit hook via [`scripts/install-hooks.sh`](scripts/install-hooks.sh). The scanner targets marketing / spec / governance Markdown; historical progress notes, changelogs, and external corpora are exempt by design. Lines that legitimately need a number (a reference to an external spec, codec, or RFC) opt out with `` at end of line. diff --git a/scripts/check-workflow-concurrency-selftest.sh b/scripts/check-workflow-concurrency-selftest.sh index bb591153f..137d9ff4a 100755 --- a/scripts/check-workflow-concurrency-selftest.sh +++ b/scripts/check-workflow-concurrency-selftest.sh @@ -23,7 +23,7 @@ set -euo pipefail cd "$(dirname "$0")/.." root=$(pwd) -target=.github/workflows/workflow-hygiene.yml +target=.github/workflows/repo-checks.yml tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT -- 2.54.0 (Apple Git-157)