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
10 changes: 6 additions & 4 deletions .github/workflows/gate-freshness.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Gate Freshness

# Alerts when a post-merge gate stops producing successful `main` runs.
# Alerts when a post-merge gate stops producing completed `main` results.
#
# THE FAILURE THIS EXISTS FOR (#7856): every heavy gate in this repo produced zero
# results on `main` for over two days. They were not failing and not cancelled --
Expand Down Expand Up @@ -74,9 +74,11 @@ jobs:

# Structural failure first, and unconditionally: prove the detector can still
# say no before trusting a green verdict from it. This plants a stale gate, a
# gate with no successful run at all, and -- the trap that made
# `gc-root-dominance` look healthy in #7856 -- a gate whose only recent
# successes are `pull_request` runs, then asserts the verdict for each.
# gate with no completed result at all, queued/in-progress/cancelled runs, and
# -- the trap that made `gc-root-dominance` look healthy in #7856 -- a gate
# whose only recent results are `pull_request` runs. It also proves that a
# completed failure is fresh execution evidence and is aged from completion,
# and that every configured job in a reusable-workflow call must complete.
#
# A green self-test means the detector works, not that nothing was tried.
- name: Self-test the freshness checker (can this gate still fail?)
Expand Down
25 changes: 17 additions & 8 deletions docs/src/testing/ci-gate-scheduling.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,18 @@ silently stops firing fails the same way.

`gate-freshness.yml` runs every two hours on `ubuntu-latest` and calls
`scripts/check_gate_freshness.py`, which asks the Actions API for each gate's most
recent **successful** non-PR run on the default branch and fails when it is older
than that gate's budget in `scripts/gate_freshness.json`. On failure it opens — or
updates, never duplicates — a single sticky issue, and closes it once every gate is
fresh again.
recent **completed** non-PR result on the default branch and fails when it is older
than that gate's budget in `scripts/gate_freshness.json`. Age starts when the result
completed, not when the run joined the queue. A completed failure counts as execution
evidence here and remains red in its own workflow; treating it as starvation too
conflates two diagnoses. On failure the checker opens — or updates, never duplicates
— a single sticky issue, and closes it once every gate is fresh again.

Reusable workflows do not get a separate Actions run: their jobs belong to the
caller. The `security-audit.yml` manifest entry therefore reads `test.yml` runs and
requires all five `security-audit / ...` jobs to complete. A caller that fails in an
unrelated job is still fresh security-audit evidence; a caller that skips even one of
the five is not.

```bash
python3 scripts/check_gate_freshness.py --self-test # proves it can still fail
Expand All @@ -201,10 +209,11 @@ is still draining. A gate whose budget you have to keep raising is a gate that i
still starving; raise the *capacity* or lower the *demand* instead.

**The checker is sabotage-tested, not merely exercised.** `--self-test` plants a
stale gate, a fresh gate, a gate with no successful run at all, and a gate whose only
recent success is a `pull_request` run (the exact shape that made `gc-root-dominance`
look healthy while its `main` arm was dark), and asserts the verdict for each. A
green `--self-test` means the detector works, not that nothing was tried.
stale gate, a fresh gate, a recent failed result, a gate with no completed result,
queued/in-progress/cancelled runs, and a gate whose only recent results are
`pull_request` runs (the exact shape that made `gc-root-dominance` look healthy while
its `main` arm was dark), and asserts the verdict for each. A green `--self-test`
means the detector works, not that nothing was tried.

## The queue in front of the schedule (#7966)

Expand Down
5 changes: 3 additions & 2 deletions docs/src/testing/ci-tiers.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,9 @@ merging. A crash may never be parked in the snapshot (`run_gap_tests.sh` refuses

Required status checks on `main`: **`pr-gate`** only. Adding, removing or renaming a
job in `test.yml` never needs a branch-protection edit again; the fan-in job carries
the verdict. `gate-freshness.yml` (`scripts/gate_freshness.json`) still watches
that each main-line sweep produces a *successful* run within its budget.
the verdict. `gate-freshness.yml` (`scripts/gate_freshness.json`) watches that each
main-line sweep produces a *completed* result within its budget; the gate's own run
carries whether that result passed or failed.

## Release

Expand Down
Loading
Loading