Follow-ups from the review of #5009 (closed-PR cache sweep). None of these are needed for #5009 to merge; they track the parts of the cache-budget problem that PR deliberately does not solve.
Context (measured 2026-09-10)
PR-ref caches: 20 entries, 6881 MiB
repo usage: 23 entries, 9.88 GiB of 10 GiB
#5458 MERGED 1720 MiB ← the only part #5009 can reclaim
#5462 OPEN 396 MiB
#5539 OPEN 1323 MiB
#5542 OPEN 1720 MiB
#5547 OPEN 1720 MiB
Four open PRs each hold their own copy of the same qt-6.8.3-macos-clang64-… (1,297 MiB) and install-qt-action-windows-… (396 MiB) keys that refs/heads/main also holds. PRs can read base-branch caches, so they should have restored; they wrote because the repo sits at its allowance, LRU evicts main's copy between runs, and the next PR run misses and re-saves. Main's Qt entry was re-created the same day, confirming it had been evicted again. Loop: PR writes → over quota → main's dependency entries evicted → more PR writes. #5009 trims the closed-PR leg only; with 4+ PRs open the repo stays over 10 GiB regardless.
1. Dependency caches: restore on PR, save only on main
The durable fix. #5008 gave the compiler caches (ccache-linux-build-, sccache-windows-, ccache-macos-ci) a restore-on-PR / save-on-main split. The dependency caches still use plain actions/cache and therefore save on PR refs whenever they miss:
- Cache Qt (ci.yml,
qt-${QT_VERSION}-macos-clang64-…) — 1,297 MiB
- Cache FFTW3 (
${runner.os}-fftw3-3.3.5-…)
- Cache DeepFilterNet3 (Linux / Windows / macOS jobs)
- Cache qtkeychain (
qtkeychain-macos-arm64-…)
Switching each to actions/cache/restore + actions/cache/save with if: github.ref == 'refs/heads/main' means PR refs never hold dependency caches, main's copies stop being displaced, and the #5009 sweep has almost nothing to do.
Caveat: jurplel/install-qt-action with cache: true (Windows, 396 MiB per PR) has no restore-only mode. Either accept 396 MiB × open PRs, or move it to aqt + an explicit cache the way check-macos already does.
2. Should the sweep also run on workflow_run?
#5009 runs the sweep daily at 04:17 UTC. While the repo is over its allowance, a closed PR's dead entries compete with main's live ones for LRU until then; on a batch-merge afternoon that is several GiB of dead weight for up to a day, and GitHub's LRU ends up doing the sweep's job by also evicting main's compiler caches. The workflow_run: [CI] trigger already exists in cache-cleanup.yml with a full token (~35 fires/day). The sweep is idempotent and cheap (one list + one gh pr view per PR ref), so hanging it off that trigger too, with the schedule kept as the self-heal backstop, would cut dead time to minutes. Cost is ~35 short jobs/day. Decision, not a defect.
If #1 lands first, this mostly stops mattering.
3. Tag-ref caches
Caches on refs/tags/v* from the release workflows are swept by neither prune-main nor sweep-closed-prs. Low volume; recorded so it is not silently forgotten.
4. Record the usage-policy negative result
GET repos/aethersdr/AetherSDR/actions/cache/usage-policy returns 404 on this repo, so the per-repo size / retention policy is not exposed here. The cache-cleanup.yml header still invites investigating that route; a one-line note would save the next reader the trip.
Verification
gh cache list --limit 500 --json key,ref,sizeInBytes grouped by ref, after #1: no dependency keys on refs/pull/*/merge, and main's Qt / FFTW / DeepFilter / qtkeychain entries keep a stable createdAt across a week of PR runs.
Refs: #5008, #5009.
🤖 Generated with Claude Code
Follow-ups from the review of #5009 (closed-PR cache sweep). None of these are needed for #5009 to merge; they track the parts of the cache-budget problem that PR deliberately does not solve.
Context (measured 2026-09-10)
Four open PRs each hold their own copy of the same
qt-6.8.3-macos-clang64-…(1,297 MiB) andinstall-qt-action-windows-…(396 MiB) keys thatrefs/heads/mainalso holds. PRs can read base-branch caches, so they should have restored; they wrote because the repo sits at its allowance, LRU evicts main's copy between runs, and the next PR run misses and re-saves. Main's Qt entry was re-created the same day, confirming it had been evicted again. Loop: PR writes → over quota → main's dependency entries evicted → more PR writes. #5009 trims the closed-PR leg only; with 4+ PRs open the repo stays over 10 GiB regardless.1. Dependency caches: restore on PR, save only on main
The durable fix. #5008 gave the compiler caches (
ccache-linux-build-,sccache-windows-,ccache-macos-ci) a restore-on-PR / save-on-main split. The dependency caches still use plainactions/cacheand therefore save on PR refs whenever they miss:qt-${QT_VERSION}-macos-clang64-…) — 1,297 MiB${runner.os}-fftw3-3.3.5-…)qtkeychain-macos-arm64-…)Switching each to
actions/cache/restore+actions/cache/savewithif: github.ref == 'refs/heads/main'means PR refs never hold dependency caches, main's copies stop being displaced, and the #5009 sweep has almost nothing to do.Caveat:
jurplel/install-qt-actionwithcache: true(Windows, 396 MiB per PR) has no restore-only mode. Either accept 396 MiB × open PRs, or move it to aqt + an explicit cache the way check-macos already does.2. Should the sweep also run on
workflow_run?#5009 runs the sweep daily at 04:17 UTC. While the repo is over its allowance, a closed PR's dead entries compete with main's live ones for LRU until then; on a batch-merge afternoon that is several GiB of dead weight for up to a day, and GitHub's LRU ends up doing the sweep's job by also evicting main's compiler caches. The
workflow_run: [CI]trigger already exists incache-cleanup.ymlwith a full token (~35 fires/day). The sweep is idempotent and cheap (one list + onegh pr viewper PR ref), so hanging it off that trigger too, with the schedule kept as the self-heal backstop, would cut dead time to minutes. Cost is ~35 short jobs/day. Decision, not a defect.If #1 lands first, this mostly stops mattering.
3. Tag-ref caches
Caches on
refs/tags/v*from the release workflows are swept by neitherprune-mainnorsweep-closed-prs. Low volume; recorded so it is not silently forgotten.4. Record the usage-policy negative result
GET repos/aethersdr/AetherSDR/actions/cache/usage-policyreturns 404 on this repo, so the per-repo size / retention policy is not exposed here. Thecache-cleanup.ymlheader still invites investigating that route; a one-line note would save the next reader the trip.Verification
gh cache list --limit 500 --json key,ref,sizeInBytesgrouped by ref, after #1: no dependency keys onrefs/pull/*/merge, and main's Qt / FFTW / DeepFilter / qtkeychain entries keep a stablecreatedAtacross a week of PR runs.Refs: #5008, #5009.
🤖 Generated with Claude Code