Repository navigation
[campaign] Estate CodeQL weekly→monthly sweep (cut 3, standards#233 Option B — ~206 repos) #288
Copy link
Copy link
Open
Labels
cicdCI/CD: workflows, actions, lockfiles, pins, runners, release gatesCI/CD: workflows, actions, lockfiles, pins, runners, release gatesmeta:campaignCoordinated multi-repo push with a defined end stateCoordinated multi-repo push with a defined end statepriority:p2Normal - queue itNormal - queue itscope:estateAffects many or all repos across the estateAffects many or all repos across the estatestatus:blockedCannot proceed until a dependency clearsCannot proceed until a dependency clears
Description
Campaign overview
Per-repo fan-out of the canonical CodeQL cron change shipped in standards#286 (cut 3, owner-decision Option B 2026-05-30): convert ~206 repos from weekly ('0 6 * * 1') to monthly ('0 6 1 * *') CodeQL scheduled runs.
Why
- 85% savings (~46k Actions-min/yr) without estate-wide stratification.
- Bounded 30-day CVE-detection floor for every repo.
- Single mechanical fan-out — same shape as cuts 1+2 (chore(scorecard-reusable): align example with canonical weekly schedule + document drift #230, GH Actions budget: convert 180 estate repos from daily to weekly scorecard schedule (cut 2 fan-out) #231).
Scope (audit 2026-05-28 + 2026-05-30)
| Schedule | Count | Action |
|---|---|---|
Weekly Monday 06:00 UTC ('0 6 * * 1') |
~206 | Convert to monthly via this sweep |
| Other weekly cadences | ~15 | Lower-priority follow-up |
| Already inline / non-reusable | varies | Out of scope for this sweep |
Mechanical change per repo
schedule:
- - cron: '0 6 * * 1' # weekly Monday 06:00 UTC
+ - cron: '0 6 1 * *' # monthly 1st 06:00 UTCPR-trigger runs (push + pull_request) unchanged — every PR still gets CodeQL.
Constraints
- GitHub PR-create secondary rate-limit: ~5 PRs / 30min (operator memory).
- Estimated total: 206 PRs × 6min stagger = ~21 hours of background sweep time.
- Multi-session execution; resume by re-auditing repos still on
'0 6 * * 1'. - Skip
echo-types/(owner hands-off). - Per-PR ownership gate: each repo must satisfy
owner=hyperpolymath, isFork=false, parent=null.
Sequencing
- ✅ Canonical change:
standards#286(OPEN, auto-merge armed 2026-05-30) - ⏳ Sweep execution: gated on canonical merging + the scorecard sweep
standards#282completing (to avoid rate-limit collision) - ⏳ Long-tail (~15 repos on non-canonical weekly cadences): follow-up after main sweep
Acceptance
- 206 PRs land (or skipped where no-op)
- Estate-wide CodeQL audit shows monthly cron everywhere or documented exception
- 6-week budget review confirms ~46k min/yr savings landed
Cross-references
- Canonical change:
hyperpolymath/standards#286 - Decision:
hyperpolymath/standards#233(Option B selected 2026-05-30) - Prior cuts:
standards#230(cut 1),standards#231(cut 2) - Memory:
session_2026_05_28_gh_actions_budget_cuts_1_2_3.md
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
cicdCI/CD: workflows, actions, lockfiles, pins, runners, release gatesCI/CD: workflows, actions, lockfiles, pins, runners, release gatesmeta:campaignCoordinated multi-repo push with a defined end stateCoordinated multi-repo push with a defined end statepriority:p2Normal - queue itNormal - queue itscope:estateAffects many or all repos across the estateAffects many or all repos across the estatestatus:blockedCannot proceed until a dependency clearsCannot proceed until a dependency clears
Activity
hyperpolymath commentedon May 30, 2026
cicd triage 2026-05-30: campaign progress check. Owner-decision (Option B) executed via #286 + #233; cross-estate fan-out remains the open work (~206 repos). Sweep paused on GH Actions budget — memory:
project_estate_fake_action_sha_punch_list_2026_05_30notes round-2 PR-creation deferred for the same reason. Resume next billing cycle. Leaving open withcicdlabel.hyperpolymath commentedon May 31, 2026
Restructure 2026-05-31 — separate standing recurring sweep from one-off fan-out
Per owner direction to split the campaign so #288 can close once the one-off work is done, the recurring/standing elements have been spun out into dedicated trackers:
[standing]Estate CodeQL cron drift detection + 6-week budget review. Does not close. Owns the monthly re-audit for drift back to weekly, plus the ~2026-07-15 6-week budget delta.[campaign]Long-tail non-canonical CodeQL cron sweep (~86 files / 30 repos). One-off follow-up for non-'0 6 * * 1'cadences that [campaign] Estate CodeQL weekly→monthly sweep (cut 3, standards#233 Option B — ~206 repos) #288 doesn't cover.Audit 2026-05-31 (fresh, code-search backed)
Re-ran the estate audit via
gh api search/codefororg:hyperpolymath+filename:codeql.yml+cron+ per-file fetch-and-classify:'0 6 * * 1'weekly canonical'0 6 1 * *'monthly canonicalhyperpolymath/standardstop-level (per #286)The 220-file count (across 118 unique repos) is up from the 2026-05-28 baseline of ~206 — likely a mix of (a) monorepo subpath workflows the prior audit didn't enumerate and (b) ~14 weekly-cron drift entries that arrived since the original audit. Classification data in
/tmp/codeql-audit/classified-merged.tsv(sweep machine).Scope clarification for #288 (this issue)
In scope (one-off): convert
'0 6 * * 1'→'0 6 1 * *'across 118 repos / 220codeql.ymlfiles. One PR per repo (each PR may touch multiple paths where the repo is a monorepo).Out of scope (moved):
Top per-repo file counts (informational)
Ownership-gate audit (clean)
All 118 candidate repos satisfy the per-PR ownership gate:
owner == hyperpolymath✅ (118/118)isFork == false✅ (118/118)parent == null✅ (118/118)archived == false✅ (118/118)No carve-outs needed —
echo-typesis not in the candidate list (no weekly-croncodeql.yml).Execution
Sweep starting 2026-05-31 from this comment. Paced 6 min/PR (10 PRs/h) per the ~5 PRs / 30min secondary-rate-limit. Estimated ~12 hours background runtime.
/tmp/codeql-sweep.sh(extended to handle monorepo subpaths + clone repos that aren't locally checked out)/tmp/codeql-sweep-progress.tsv(repo/status/pr/notes)This issue will close when the sweep completes and zero
'0 6 * * 1'codeql.yml files remain in the estate.hyperpolymath commentedon May 31, 2026
Sweep launched 2026-05-31T07:12Z
Background fan-out running. 118 unique repos / 220 codeql.yml files in scope. 7 PRs already landed (1 manual seed + 6 from the early interactive batch). 111 remaining, paced at 6 min/PR.
Estimated completion: ~2026-05-31T18:33Z (~11h 20m).
What's running
/tmp/codeql-audit/run-sweep.sh(PID file/tmp/codeql-audit/run-sweep.pid)/tmp/codeql-audit/sweep.sh— fresh-clones from origin into/tmp/codeql-sweep-work/<basename>(never touches local working trees — a 2026-05-31 audit found 125 of 291 local clones divergent from origin)/tmp/codeql-audit/sweep-progress.tsv(TSV: repo / status / pr / notes)/tmp/codeql-audit/run-sweep.logSafety properties
git diff --cached --name-only.sweep-progress.tsvand skips repos already markedok/skip; can be relaunched safely.owner=hyperpolymath, isFork=false, parent=null, archived=false.Early-batch PRs (filed interactively pre-launch)
Closeout protocol
Once the sweep finishes:
gh api search/codefor'0 6 * * 1'incodeql.ymlorg-wide) — expect 0 hits.gh pr list --search "head:ci/codeql-monthly-cron-288 author:@me" --state all --limit 200.Long-tail
#324and recurring drift#323continue.ci(codeql): cron weekly→monthly (cut 3, standards#233 Option B) (#71)
ci(codeql): cron weekly→monthly (cut 3, standards#233 Option B) (#503)
ci(codeql): cron weekly→monthly (cut 3, standards#233 Option B) (#156)
ci(codeql): cron weekly→monthly (cut 3, standards#233 Option B) (#39)
ci(codeql): cron weekly→monthly (cut 3, standards#233 Option B) (#26)
ci(codeql): cron weekly→monthly (cut 3, standards#233 Option B) (#26)
ci(codeql): cron weekly→monthly (cut 3, standards#233 Option B) (#50)
ci(codeql): cron weekly→monthly (cut 3, standards#233 Option B) (#52)
ci(codeql): cron weekly→monthly (cut 3, standards#233 Option B) (#34)
ci(codeql): cron weekly→monthly (cut 3, standards#233 Option B) (#26)
60 remaining items
ci(codeql): cron weekly→monthly (cut 3, standards#288) (#67)
ci(codeql): cron weekly→monthly (cut 3, standards#288) (#54)
ci(codeql): cron weekly→monthly (cut 3, standards#288) (#241)
ci(codeql): cron weekly→monthly (cut 3, standards#288) (#125)
ci(codeql): cron weekly→monthly (cut 3, standards#288) (#146)
ci(codeql): cron weekly→monthly (cut 3, standards#288) (#212)
ci(codeql): cron weekly→monthly (cut 3, standards#288) (#62)
ci(codeql): cron weekly→monthly (cut 3, standards#288) (#127)
hyperpolymath commentedon Aug 25, 2026
2026-08-25 — sweep is demonstrably incomplete
18 of 60 sampled repos are still on the old
0 6 * * 1cron:empty-linter,plasma-parser-writer,kitchenspeak,session-sentinel,bitfuckit,laminar,proof-of-work,snapcreate,valence-shell,trope-checker, and others.Horizon: 60-repo sample, not the full ~206. The remaining tail is unmeasured — the real figure is at least 18, not exactly 18.
Verified 2026-08-25.
hyperpolymath commentedon Aug 27, 2026
Re-measured 2026-08-27 — the estimate is wrong in both directions
Both prior figures (body ~206 repos; the 05-31 comment 220 files / 118 repos) were
gh api search/code-bounded, and code search caps silently. Enumerate-then-filter over 420 repos:'0 6 * * 1'(weekly)'0 6 1 * *'(monthly)496 of the 642 are monorepo subpaths —
asdf-tool-plugins(207) anddeveloper-ecosystem(124) alone hold 331. GitHub only executes workflows at the repo root, so those cost nothing and rewriting them saves nothing.So "206 PRs × 6 min = 21 hours" is wrong twice over: 168 repos need a PR, but two monorepo PRs clear half the files — and half the files were never costing anything.
The canonical #286 is MERGED (2026-05-30), so the pattern to propagate exists.
Recommend: rescope to the 146 root-level files and re-derive the savings estimate.
ci(codeql): cron weekly→monthly (cut 3, standards#288)
ci(codeql): cron weekly→monthly (cut 3, standards#288)