Repository navigation
refactor(ci): unify all Nix caching on one job+matrix-scoped action - #1296
Conversation
Replaces the arch-derived key suffix with the matrix entry id. github.job is identical across every matrix leg, so it cannot distinguish them on its own; the arm64 and x64 macOS builds additionally share one arm64 runner (same runner.os/runner.arch). Keying by `nix-<github.job>-<matrix.name>` makes each leg's cache unambiguous without leaning on runner.arch, which only happened to separate the Linux legs because they run on different-arch runners. The cache-scope is threaded from the matrix `name` through build-macos-nix-native-package and setup-nix into setup-macos-nix-cache.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ccusage-guide | 9d3016c | Commit Preview URL Branch Preview URL |
Jun 12 2026, 01:17 AM |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a new composite action ChangesNix cache scoping mechanism
Sequence Diagram(s)sequenceDiagram
participant Workflow
participant BuildAction as build-*-native-package
participant SetupNix as setup-nix
participant SetupNixCache as setup-nix-cache
Workflow->>BuildAction: invoke build action (may pass cache-scope: matrix.name)
BuildAction->>SetupNix: forward inputs.cache-scope
SetupNix->>SetupNixCache: forward inputs.cache-scope
SetupNixCache->>SetupNixCache: compute primary-key / restore-prefixes / purge-prefixes (using cache-scope and hashed inputs)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Caution
The release workflow will fail on merge because .github/workflows/release.yaml calls build-macos-nix-native-package without the now-required cache-scope input.
Reviewed changes — This PR refactors the macOS Nix cache keying strategy from runner.os-runner.arch-key-suffix to github.job-cache-scope, and renames key-suffix/cache-key-suffix to cache-scope across the action chain, so each matrix leg's cache is properly isolated on the shared arm64 macOS runner.
- Rename
key-suffix→cache-scopeacrosssetup-macos-nix-cache,setup-nix, andbuild-macos-nix-native-package - Switch cache key prefix from
runner.os-runner.archtogithub.job-cache-scopeinsetup-macos-nix-cache - Update
ci.yamlcaller to passcache-scope: ${{ matrix.name }}
🚨 Missing cache-scope in release.yaml
The release workflow at .github/workflows/release.yaml:58 calls build-macos-nix-native-package for the darwin matrix entries but does not pass cache-scope. The action now declares this input as required: true, so GitHub Actions will fail at workflow validation — the release won't run.
The matrix in release.yaml already uses matrix.name (e.g. build-mac-arm64, build-mac-x64), so the fix is the same one-liner as ci.yaml:
- uses: ./.github/actions/build-macos-nix-native-package
if: matrix.platform == 'darwin'
with:
arch: ${{ matrix.arch }}
binary: ${{ matrix.binary }}
cache-scope: ${{ matrix.name }}Technical details
# Missing `cache-scope` in `release.yaml`
## Affected sites
- `.github/workflows/release.yaml:60-62` — caller of `build-macos-nix-native-package` that omits now-mandatory `cache-scope`
## Required outcome
The `release.yaml` build-native-packages job must pass `cache-scope: ${{ matrix.name }}` to `build-macos-nix-native-package`, matching the `ci.yaml` call site.
## Suggested approach
Append the line `cache-scope: ${{ matrix.name }}` to the `with:` block at `release.yaml:60`.Big Pickle (free via Pullfrog for OSS) | 𝕏
actionlint flagged release.yaml for not supplying the new required cache-scope input on the macOS native-package action. Mirror ci.yaml and pass matrix.name. Co-authored-by: Codesmith <[email protected]>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/actions/setup-nix/action.yaml (1)
4-8: Add macOS runtime validation forcache-scopeinsetup-nixto prevent empty-scope cache keys.
setup-nixforwardsinputs.cache-scope(defaulting to'') tosetup-macos-nix-cache, whose cache keys includenix-${{ github.job }}-${{ inputs.cache-scope }}-..., so an omitted value on macOS would produce ambiguous prefixes. Current workflows avoid this by passingcache-scope: ${{ matrix.name }}viabuild-macos-nix-native-package, but future direct macOS calls could regress.🔧 Suggested fix: Validate `cache-scope` on macOS
+ - name: Validate cache-scope on macOS + if: runner.os == 'macOS' + shell: bash + run: | + if [ -z "${{ inputs.cache-scope }}" ]; then + echo "::error::cache-scope input is required when running on macOS" + exit 1 + fi + - uses: ./.github/actions/setup-macos-nix-cache if: runner.os == 'macOS' with: cache-scope: ${{ inputs.cache-scope }}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/actions/setup-nix/action.yaml around lines 4 - 8, Add a runtime validation that fails early on macOS when inputs.cache-scope is empty: in the action's runtime logic (the code path that forwards inputs.cache-scope to setup-macos-nix-cache) check runner.os / process.env.RUNNER_OS (or the equivalent runtime API) and if it is macOS and inputs.cache-scope is ''/falsy, throw/exit with a clear error message instructing callers to provide cache-scope (e.g., "cache-scope is required on macOS to avoid ambiguous cache keys"); ensure this check runs before calling setup-macos-nix-cache so we never construct keys like nix-${{ github.job }}- -... with an empty scope.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In @.github/actions/setup-nix/action.yaml:
- Around line 4-8: Add a runtime validation that fails early on macOS when
inputs.cache-scope is empty: in the action's runtime logic (the code path that
forwards inputs.cache-scope to setup-macos-nix-cache) check runner.os /
process.env.RUNNER_OS (or the equivalent runtime API) and if it is macOS and
inputs.cache-scope is ''/falsy, throw/exit with a clear error message
instructing callers to provide cache-scope (e.g., "cache-scope is required on
macOS to avoid ambiguous cache keys"); ensure this check runs before calling
setup-macos-nix-cache so we never construct keys like nix-${{ github.job }}-
-... with an empty scope.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: caa6b839-fc13-41bf-9c92-5a8899a06cb6
📒 Files selected for processing (4)
.github/actions/build-macos-nix-native-package/action.yaml.github/actions/setup-macos-nix-cache/action.yaml.github/actions/setup-nix/action.yaml.github/workflows/ci.yaml
ccusage
@ccusage/ccusage-darwin-arm64
@ccusage/ccusage-darwin-x64
@ccusage/ccusage-linux-arm64
@ccusage/ccusage-linux-x64
@ccusage/ccusage-win32-x64
commit: |
There was a problem hiding this comment.
1 issue found and verified against the latest diff
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/actions/build-macos-nix-native-package/action.yaml">
<violation number="1" location=".github/actions/build-macos-nix-native-package/action.yaml:15">
P1: New required `cache-scope` input breaks existing release workflow call that does not pass it.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
| Unique matrix-entry identifier (the matrix `name`) used to scope the | ||
| macOS Nix cache. arm64 and x64 share the same arm64 runner, so without a | ||
| per-leg scope the two builds clobber one cache. | ||
| required: true |
There was a problem hiding this comment.
P1: New required cache-scope input breaks existing release workflow call that does not pass it.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .github/actions/build-macos-nix-native-package/action.yaml, line 15:
<comment>New required `cache-scope` input breaks existing release workflow call that does not pass it.</comment>
<file context>
@@ -7,14 +7,18 @@ inputs:
+ Unique matrix-entry identifier (the matrix `name`) used to scope the
+ macOS Nix cache. arm64 and x64 share the same arm64 runner, so without a
+ per-leg scope the two builds clobber one cache.
+ required: true
runs:
using: composite
</file context>
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — prior review flagged release.yaml would fail workflow validation at merge time because build-macos-nix-native-package now requires cache-scope but the release caller omitted it. Commit 7687f09 adds the missing cache-scope: ${{ matrix.name }} to the release.yaml call site, matching the ci.yaml pattern.
- Add
cache-scopetorelease.yaml— one-line addition atrelease.yaml:63forwarding the matrix name as the cache scope
Big Pickle (free via Pullfrog for OSS) | 𝕏
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
|
Diagnosis: The check suite failed on commit Outcome: No fix needed — the issue was already resolved by subsequent commits on the PR branch. Commit Task list (5/5 completed)
|
Collapses the per-platform cache setups into a single cross-platform `setup-nix-cache` action and drops the Blacksmith sticky disk entirely. - `setup-nix-cache` (renamed from setup-linux-nix-action-cache) now installs Nix, restores/saves with cache-nix-action keyed by `nix-<github.job>-<cache-scope>`, sets both gc-max-store-size-linux and -macos so one action serves both OSes, and fixes single-user store ownership. cache-scope is the matrix `name`; github.job alone cannot separate matrix legs and runner.arch collides for the two macOS legs that share one arm64 runner. - Deletes setup-macos-nix-cache (folded in), setup-nix, and setup-linux-blacksmith-sticky-disk. - Routes every former sticky-disk consumer (npm-publish, perf comments, release publish, update-pricing, pullfrog) and both native-build actions through setup-nix-cache, threading cache-scope from the matrix name. The sticky disk was keyed per github.job, never shared a warm store across the jobs that mattered, and its weekly GC was a no-op; cache-nix-action's gc-max-store-size keeps every entry bounded without it.
Sticky disks are gone; the deps pin now exists to survive cache-nix-action's gc-max-store-size trim (which keeps only GC roots), not the sticky-disk trim.
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — prior pullfrog review confirmed the cache-scope fix in release.yaml. Since then, the PR goes further: unifying all Nix caching into a single setup-nix-cache action, removing 4 legacy actions and the Blacksmith sticky disk, and threading cache-scope through the Linux native build path alongside macOS.
- Unify Nix cache setup into
setup-nix-cache— replacessetup-linux-nix-action-cache,setup-macos-nix-cache,setup-nix, andsetup-linux-blacksmith-sticky-diskwith a single cross-platform action keyed bygithub.job+cache-scope - Add
cache-scopeto Linux build path —build-linux-native-packagenow requires and forwardscache-scope, matching the macOS pattern - Remove Blacksmith sticky disk — every former consumer now uses
setup-nix-cachewhosegc-max-store-sizebounds each cache entry - Update
pin-nix-depsrationale — referencescache-nix-actionGC instead of the removed sticky disk
Big Pickle (free via Pullfrog for OSS) | 𝕏
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/actions/setup-nix-cache/action.yaml (1)
30-31: Document/guard against cache restore/purge prefix collisions viacache-scopeCurrent workflow matrix
namevalues (build-linux-arm64,build-linux-x64,build-mac-arm64,build-mac-x64,build-windows-arm64,build-windows-x64) don’t introduce any obvious substring/prefix collisions with the restore/purge prefixnix-${{ github.job }}-${{ inputs.cache-scope }}-.Because
restore-prefixes-first-match(andpurge-prefixes) rely on that prefix, adding future scopes with prefix relationships could cause ambiguous restores. Document thatcache-scopemust not be a prefix/sub-prefix of another scope (or switch to a more unambiguous delimiter/encoding between scope and hash).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/actions/setup-nix-cache/action.yaml around lines 30 - 31, The restore/purge prefix using restore-prefixes-first-match and inputs.cache-scope can collide if cache-scope values are prefixes of one another; update documentation and add a guard: require/validate that inputs.cache-scope values are not a prefix of any other scope (or normalize/encode the scope with an unambiguous delimiter like "::" or base64) and switch restore-prefixes-first-match/purge-prefixes to use the encoded delimiter form; specifically update the action input validation and README to enforce the rule for inputs.cache-scope and update primary-key/restore-prefixes-first-match usage to concatenate a clearly delimited scope (e.g., nix-${{ github.job }}-<encoded-cache-scope>-${{ hashFiles(...) }}) so future scope names cannot create prefix collisions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In @.github/actions/setup-nix-cache/action.yaml:
- Around line 30-31: The restore/purge prefix using restore-prefixes-first-match
and inputs.cache-scope can collide if cache-scope values are prefixes of one
another; update documentation and add a guard: require/validate that
inputs.cache-scope values are not a prefix of any other scope (or
normalize/encode the scope with an unambiguous delimiter like "::" or base64)
and switch restore-prefixes-first-match/purge-prefixes to use the encoded
delimiter form; specifically update the action input validation and README to
enforce the rule for inputs.cache-scope and update
primary-key/restore-prefixes-first-match usage to concatenate a clearly
delimited scope (e.g., nix-${{ github.job }}-<encoded-cache-scope>-${{
hashFiles(...) }}) so future scope names cannot create prefix collisions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: ef396dc7-5612-41df-98b6-76393beaafcc
📒 Files selected for processing (12)
.github/actions/build-linux-native-package/action.yaml.github/actions/build-macos-nix-native-package/action.yaml.github/actions/pin-nix-deps/action.yaml.github/actions/setup-linux-blacksmith-sticky-disk/action.yaml.github/actions/setup-linux-nix-action-cache/action.yaml.github/actions/setup-macos-nix-cache/action.yaml.github/actions/setup-nix-cache/action.yaml.github/actions/setup-nix/action.yaml.github/workflows/ci.yaml.github/workflows/pullfrog.yml.github/workflows/release.yaml.github/workflows/update-pricing.yaml
💤 Files with no reviewable changes (4)
- .github/actions/setup-linux-blacksmith-sticky-disk/action.yaml
- .github/actions/setup-linux-nix-action-cache/action.yaml
- .github/actions/setup-macos-nix-cache/action.yaml
- .github/actions/setup-nix/action.yaml
✅ Files skipped from review due to trivial changes (2)
- .github/workflows/pullfrog.yml
- .github/actions/pin-nix-deps/action.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/actions/build-macos-nix-native-package/action.yaml
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
There was a problem hiding this comment.
1 issue found across 12 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/actions/build-macos-nix-native-package/action.yaml">
<violation number="1" location=".github/actions/build-macos-nix-native-package/action.yaml:15">
P1: New required `cache-scope` input breaks existing release workflow call that does not pass it.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Re-trigger cubic
ci.yaml and release.yaml both define a job named build-native-packages with identical matrix `name` values, so the previous `nix-<github.job>-<scope>-<hash>` key collided across the two workflows. The release-tag run could purge ci.yaml's entries via `purge-prefixes` (and vice versa). Prefix with github.workflow so each workflow keeps its own namespace. Co-authored-by: Codesmith <[email protected]>
ccusage-perf-comment and ccusage-rust-perf-comment were near-identical;
only --head-runtime, the output filename, and the comment marker differed.
Fold them into one job with a `runtime: [js, rust]` matrix, parameterised by
matrix.label/slug/head-runtime-arg. The displayed check names ("ccusage perf
comment" / "ccusage rust perf comment") are unchanged, and the cache is scoped
per runtime so the two legs do not share the job's cache key.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — one new commit (75fe0da) on top of the prior clean review adds github.workflow to the setup-nix-cache cache key prefix so workflows sharing a job id (e.g. build-native-packages in both ci.yaml and release.yaml) don't collide on cache entries.
- Add
github.workflowto cache key prefix —primary-key,restore-prefixes-first-match, andpurge-prefixesinsetup-nix-cache/action.yamlnow usenix-${{ github.workflow }}-${{ github.job }}-${{ inputs.cache-scope }}-...instead of justnix-${{ github.job }}-...
Big Pickle (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — new commit eb3a34d collapses the two previously separate perf-comment jobs (ccusage-perf-comment and ccusage-rust-perf-comment) into a single matrix job with js and rust legs, scoping each leg's Nix cache via matrix.runtime.
- Collapse perf-comment jobs into a runtime matrix —
ccusage-perf-commentnow runs two matrix legs (js/rust) instead of two standalone jobs, eliminating ~85 lines of duplicated step definitions while preserving the same behavior and output file names - Scope perf cache by runtime — passes
cache-scope: ${{ matrix.runtime }}tosetup-nix-cacheso the Nix store caches for js and rust legs don't collide
Big Pickle (free via Pullfrog for OSS) | 𝕏
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
The cache hit but every job still recompiled ~130 crates: gc-max-store-size makes cache-nix-action run `nix store gc` before saving, which dropped the unrooted crane cargoArtifacts so they were never cached. pin-nix-deps was a band-aid to root them, but it did not actually survive the trim. These runners are ephemeral (restore -> build -> save), so the store never accumulates across runs the way the old sticky disk did — there is nothing for gc-max-store-size to bound. Removing it lets cache-nix-action save the whole non-substitutable set (incl. the deps) as-is, so the next run restores them and skips the recompile. The pin is then redundant and is removed with its action. Stale entries from changed deps hashes still roll off via `purge`.
On an exact primary-key hit cache-nix-action skips saving, so the stale deps-less entry from the gc-max-store-size era would persist while the deps hash is unchanged. A version salt forces one miss, after which the gc-free save stores the deps and subsequent runs restore them without recompiling.
cache-nix-action skips saving on an exact primary-key hit, so a key based only on the deps hash kept the first run's (deps-less) store forever. Append github.sha to the primary key so every commit writes a fresh entry, and restore via the sha-less prefix to warm the deps from the newest prior entry. The cache backend is effectively unlimited, so one entry per commit is fine and `purge` rolls off the old ones. Replaces the v2 salt bust.
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
Mirror the nix cache: append github.sha so every commit saves a fresh entry (actions/cache skips saving on an exact key hit) and restore-keys warms from the newest prior entry.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — two new commits since the prior clean review at eb3a34d: dropping gc-max-store-size from setup-nix-cache and removing the vestigial pin-nix-deps action entirely, then busting cache keys with a nix-v2 salt so the new gc-free save takes effect on ephemeral runners.
- Drop
gc-max-store-sizeand deletepin-nix-deps— ephemeral runners don't accumulate store cruft across runs the way the old Blacksmith sticky disk did;gc-max-store-sizebefore save only deletes unrooted crane deps and forces recompiles, so it's removed.pin-nix-deps(which existed to root deps against that GC) is deleted along with all 3 callers inbuild-linux-native-packageandci.yaml - Bust cache with
nix-v2prefix — without a cache key change, stale entries withgc-max-store-sizebehavior would persist as exact primary-key hits and never be re-saved; thev2salt forces fresh entries
Big Pickle (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — two new commits on top of the prior clean review replace the nix-v2 version-salt approach with a github.sha-based key strategy and add a dedicated Windows cargo cache action.
- Replace
nix-v2salt with-${{ github.sha }}suffix — every commit now gets a unique primary key, ensuringcache-nix-actionalways saves a fresh entry;restore-prefixes-first-matchuses the hash prefix to warm from any prior commit with the same deps lockfiles - Add
setup-native-build-cachefor Windows cargo artifacts — new composite action caching~/.cargo/registry,~/.cargo/git, andrust/targetviaactions/cache, keyed byrunner.os/runner.arch/hashFiles/github.shawith hash-based and runner-based restore fallbacks; used only bybuild-windows-native-package
Big Pickle (free via Pullfrog for OSS) | 𝕏
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
* ci(release): shallow-clone the tag in native build jobs The native build jobs checked out the release tag with fetch-depth: 0, but nothing in the build path reads git history: CI builds the same outputs from a default shallow checkout. The full clone cost up to 41s on build-windows-x64 in run 38470996208, which finished within 20s of the slowest leg. * ci: keep the Linux Nix store on a Blacksmith sticky disk The cache-nix-action store cache misses most of the time. Across ~25 CI pushes to main between 2026-09-25 and 2026-10-13, the native build legs restored an entry in only 3-6 of ~19 runs each (macOS and Linux alike), and a hit roughly halves the build step (linux-arm64: 82s vs 213s). Blacksmith's Actions cache allows 25 GB per repository per week with LRU eviction, while the per-commit keys introduced in #1296 write a fresh 1.3-3 GB entry for every job on every run: ~12 GB per push to main, ~6 GB per PR run, up to 2.5 GB per hourly update-pricing run. #1296 assumed the backend was effectively unlimited; it is not. Even on a hit, restoring takes ~60s and the post-job save another ~40s. On Blacksmith Linux runners, mount /nix from a sticky disk instead. A job gets a copy-on-write clone of the last committed snapshot, so the whole store is present at mount time with no restore or save step and nothing counted against the cache quota. macOS and GitHub-hosted runners have no sticky disks and keep using cache-nix-action. #1296 dropped an earlier sticky-disk setup. This one avoids its problems: - Keys are per job and matrix leg but carry no workflow name, so release.yaml's build-native-packages mounts the disk ci.yaml keeps warm on every push to main instead of starting cold. autofix, which only runs on pull requests and so would never commit, borrows preflight's disk via the new disk-job input; both build the treefmt closure. - The old trim dropped Crane's cargoArtifacts because nothing rooted them (#1274, #1279). The Linux build now roots them inside /nix/var/nix/gcroots, which persists with the disk, and keep-derivations/keep-outputs make GC keep their build-time closure (toolchain, vendored sources) too. - The weekly GC workflow (#1295) mounted its own disk and never touched the real ones. Trimming now happens in the job that commits: once the disk is over half full, `nix-collect-garbage --delete-old` runs before the job adds to the store. Jobs without persistent roots go cold once per trim. Only runs on main that are not pull_request(_target) events commit, whatever `save` says, so pull request code (including forks) can read main's store but never write the store that main and releases build from. cache-nix-action keeps its existing behaviour, now also gated by `save`. Not confirmed from Blacksmith's documentation: the disk's capacity (hence the relative threshold and the `df` log on every run) and which snapshot wins when two runs commit the same key concurrently. Either outcome is a valid store for a cache. * ci(release): stop persisting the Nix store from release builds Release builds now mount the Linux sticky disk that CI commits on every push to main. Committing it from the release as well would only race those commits with an equivalent store. On macOS, the release's own cache-nix-action entries never survive to the next release under Blacksmith's cache eviction, yet each save took ~40s (build-mac-arm64 and build-mac-x64 in run 38470996208) before the job could finish and let the npm job start. Add a save-nix-cache input to both native build actions, forwarded to setup-nix-cache, skip rooting the Crane artifacts when nothing will be saved, and pass save-nix-cache: false from release.yaml. * ci: mount test's Nix sticky disk in the perf comment legs ccusage-perf-comment only runs on pull requests, and pull requests never commit a sticky disk, so its own per-leg keys would stay freshly formatted on every run. Mount the disk test commits on every push to main instead: it installs `just` and resolves the same flake inputs. Both legs mount it read-only, so the per-runtime cache-scope that kept their saves apart is no longer needed. Reported by pullfrog in review.

Summary
Unifies every Nix cache setup onto a single cross-platform action and removes the Blacksmith sticky disk entirely. Cache keys are now scoped by
github.job+ matrix key (matrix.name) instead ofrunner.os/runner.arch.Why
github.jobreturns the workflow job id (e.g.build-native-packages), which is identical for every matrix leg, so it can't separate them alone.runner.os/runner.archare identical for both — they were clobbering one cache (the ci(cache): scope macOS Nix cache key by target arch #1294 bug). The Linux legs only stayed separate because they happen to run on different-arch runners.nix-<github.job>-<matrix.name>-<hash>is unambiguous regardless of runner arch and generalises to any future matrix dimension.github.job, never shared a warm store across the jobs that mattered, and its weekly GC was a no-op. cache-nix-action'sgc-max-store-sizekeeps every entry bounded without it.What changed
setup-nix-cache(renamed fromsetup-linux-nix-action-cache): installs Nix + cache-nix-action keyed bynix-${{ github.job }}-${{ inputs.cache-scope }}-<hash>, sets bothgc-max-store-size-linuxand-macosso one action serves both OSes, and fixes single-user store ownership.setup-macos-nix-cache(folded in),setup-nix, andsetup-linux-blacksmith-sticky-disk.npm-publish, perf comments,releasepublish,update-pricing,pullfrog) and both native-build actions now usesetup-nix-cache, threadingcache-scopefrom the matrixname.pin-nix-depsrationale updated: the deps pin now exists to survive cache-nix-action's GC-root trim, not the sticky-disk trim.Cache keys change once, so caches re-warm a single time.
Summary by CodeRabbit