Commit aaee1af
fix(ci): staleness gate fails on named defects, not on the calendar (#522)
The Governance staleness gate is currently failing **294 of 350 consumer
repos** — and it is failing them for the wrong reason.
## What is actually happening
All 294 pin the *same* SHA, `d7c22711` (2026-06-26). Nothing is wrong
with any of them individually. `standards` moves ~2.6 commits/day, so a
consumer exhausts both window budgets (≤50 commits **or** ≤14 days)
about a fortnight after any propagation, and goes red on a timer.
`aspasia` is the clean natural experiment — same pin, nothing changed in
the repo:
| run | pin age | verdict |
|---|---|---|
| 2026-07-09 | 32 commits / 12d | `::notice`, passing |
| 2026-07-21 | 63 commits / 24d | `::error`, hard fail |
Holding the fleet green under that rule means re-pinning ~300 repos
every fortnight — on the order of **7,800 PRs/year**.
A gate that fails everyone on a timer is not a guard. It trains the
estate to ignore it, and it buries the findings that matter: the same
sweep shows **148 real `Workflow security linter` failures** and **74
anti-pattern failures**, all of which read as noise once the fleet is
uniformly red.
## What changes
**1. Age outside the window is now a `::notice`, not an error.** The
window is still computed and still reported, so
`propagate-workflow-pins.sh` and the Hypatia `sha_bump_propagation` rule
keep their signal.
**2. A named deny-list (`KNOWN_BAD_BEFORE`) replaces age as the hard
failure.** Each entry is `<reusable>:<fix-sha>`; a pin that is a strict
ancestor of the fix carries that defect and is rejected **at any age**.
This is what the window was only ever a proxy for, and it is strictly
better in *both* directions — a **recent** pin carrying the defect is
now caught, and an old pin carrying none is no longer punished by the
calendar.
The first entry is `e9c8888769a7` (#441). Before it,
`hypatia-scan-reusable` and the `validate-hypatia-baseline` job cached
the built Hypatia scanner under a keyless key while the build steps were
guarded by `if [ ! -d ]` — so *the first scanner build ever cached was
reused forever* and scanner fixes never took effect. A pin older than
this reports a **false green**.
> 1 parent f9dca6d commit aaee1af
3 files changed
Lines changed: 366 additions & 20 deletions
File tree
- docs/decisions
- scripts
- tests
Lines changed: 61 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
145 | 145 | | |
146 | 146 | | |
147 | 147 | | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
148 | 152 | | |
149 | 153 | | |
150 | 154 | | |
| |||
162 | 166 | | |
163 | 167 | | |
164 | 168 | | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
0 commit comments