Skip to content

Commit 59ec97f

Browse files
committed
Drop the weekly scheduled-quality workflow; keep waiver expiry as a manual check
The owner's verification-cost standard allows no new CI workflows or schedules. The 30-day warning already prints in every make verify run, and make check-waiver-expiry stays runnable by hand. README, CONTRIBUTING, the Makefile comment and the script docstring now say so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UpksNcNFYPn6dR3UscZj4Z
1 parent 68c7387 commit 59ec97f

6 files changed

Lines changed: 15 additions & 40 deletions

File tree

‎.github/workflows/scheduled-quality.yml‎

Lines changed: 0 additions & 31 deletions
This file was deleted.

‎CONTRIBUTING.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ make check-generated
6666

6767
## Quality checks
6868

69-
These scripts enforce the catalog-level rules from `docs/example-quality-rubric.md`. Run them together with `make quality-checks`.
69+
These scripts enforce the catalog-level rules from `docs/example-quality-rubric.md`. Run them together with `make quality-checks`. CI does not schedule a waiver-expiry run; before a release or once a month, run `make check-waiver-expiry`, which fails while any waiver has 30 days or fewer left.
7070

7171
| Script | What it gates |
7272
| --- | --- |
@@ -79,7 +79,7 @@ These scripts enforce the catalog-level rules from `docs/example-quality-rubric.
7979
| `scripts/check_prose_duplication.py` | No verbatim repeated paragraphs, no cell prose copied from the intro, no duplicate note bullets. |
8080
| `scripts/check_inline_links.py` | Inline `[text](target)` links in prose resolve to real `/examples` or `/journeys` pages. |
8181
| `scripts/score_example_criteria.py` | Heuristic criterion scores per example; fails when a curated score exceeds the heuristic by more than the delta bound, so the score registry cannot inflate without the page changing. |
82-
| `scripts/check_quality_scores.py` | Curated scores meet the 9.0 target / 8.5 hard minimum, waivers carry future expiry dates and are dropped when stale, and the journey-section average stays above its floor. |
82+
| `scripts/check_quality_scores.py` | Curated scores meet the 9.0 target / 8.5 hard minimum, waivers carry future expiry dates (with a warning in their last 30 days) and are dropped when stale, and the journey-section average stays above its floor. |
8383
| `scripts/check_no_figure_rationales.py` | No-figure opt-outs carry a reason and an unexpired `review_after` date. |
8484
| `scripts/check_journey_outcomes.py` | Every journey section declares learner outcomes. |
8585
| `scripts/audit_example_graph.py --check` | The `see_also` graph has no broken targets, self-links, over-linked pages, or orphaned examples. |

‎Makefile‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,9 @@ score-example-criteria:
9292
check-quality-scores:
9393
$(PY) scripts/check_quality_scores.py
9494

95-
# Scheduled (weekly) gate: fail while a quality waiver has 30 days or fewer
96-
# left, so the expiry surfaces before it turns every pull request red.
95+
# Manual gate, not run in CI: fail while a quality waiver has 30 days or fewer
96+
# left, so an expiry can be caught before it turns every pull request red.
97+
# `make verify` (CI) already prints a warning inside the same 30-day window.
9798
check-waiver-expiry:
9899
$(PY) scripts/check_quality_scores.py --fail-within-days 30
99100

‎README.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ JPEGs under `public/og/` with headless Chrome (set `CHROME_PATH` if needed).
228228
footgun, notes, program/cell, prose-duplication, inline-link, scoring,
229229
figure, journey, and example-graph gates.
230230

231+
`make check-waiver-expiry` is a manual check, not run in CI: it fails while
232+
any quality waiver has 30 days or fewer left. `make quality-checks` (and so CI)
233+
only prints a warning in that window, then fails once the waiver has expired.
234+
231235
`src/example_sources_data.py` is generated and committed so Cloudflare Workers can load examples in production. Do not edit it by hand.
232236

233237
For a Python version migration, update `python_version` and `docs_base_url` in `src/example_sources/manifest.toml`, then run:

‎scripts/check_quality_scores.py‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
and a waiver whose example has recovered to target is flagged as stale
1111
so the registry only ever describes live editorial debt.
1212
13-
A waiver that expires within WAIVER_WARNING_DAYS prints a warning. The
14-
weekly scheduled workflow runs `--fail-within-days 30`, so an approaching
15-
expiry turns that run red a month before it would fail every pull request.
13+
A waiver that expires within WAIVER_WARNING_DAYS prints a warning in every
14+
CI run. `make check-waiver-expiry` (manual, not in CI) runs
15+
`--fail-within-days 30`, so an approaching expiry fails that command a month
16+
before it would fail every pull request.
1617
"""
1718
from __future__ import annotations
1819

@@ -84,7 +85,7 @@ def main(argv: list[str] | None = None) -> int:
8485
"--fail-within-days",
8586
type=int,
8687
default=None,
87-
help="treat waivers expiring within N days as errors (the scheduled run uses 30)",
88+
help="treat waivers expiring within N days as errors (make check-waiver-expiry uses 30)",
8889
)
8990
parser.add_argument("--as-of", help="evaluate expiry as of this ISO date instead of today (UTC)")
9091
args = parser.parse_args(argv)

‎tests/test_quality_checks.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ def test_waiver_expiry_warns_thirty_days_ahead(self):
290290
self.assertIsNone(mod.expiry_warning(expires, today=datetime.date(2026, 12, 1)))
291291
self.assertIsNone(mod.expiry_warning("never", today=datetime.date(2026, 11, 1)))
292292

293-
def test_expiring_waiver_warns_on_prs_and_fails_the_scheduled_run(self):
293+
def test_expiring_waiver_warns_on_prs_and_fails_the_expiry_gate(self):
294294
import datetime
295295

296296
mod = _scripts_import("check_quality_scores")

0 commit comments

Comments
 (0)