overengineeringstudio / overengineeringstudio/effect-utils
fix(nix-cli): nix:hash misses staleness when upstream flake input rev changes without lockfile change
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 82
- Forks
- 2
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 121
Description
Problem
The nix:hash task uses lockfileHash (SHA256 of pnpm-lock.yaml) as a fast staleness proxy. When an upstream flake input bumps its rev, mk-pnpm-cli build logic may change (e.g. different prepared install-tree structure from #410), producing a different pnpmDepsHash — but the downstream pnpm-lock.yaml doesn't change. The lockfileHash check passes, the full rebuild is skipped, and the stale hash persists.
Minimal reproduction
https://github.com/schickling-repros/2026-03-effect-utils-nix-hash-staleness
git clone https://github.com/schickling-repros/2026-03-effect-utils-nix-hash-staleness
cd 2026-03-effect-utils-nix-hash-staleness
bash repro.sh
Output:
=== Step 2: Simulate nix:hash staleness check (from nix-cli.nix) ===
Stored lockfileHash: sha256-KbJNMXX8ps/itgbCSyYR4wMAF895Ho60vW5Dhy14dCc=
Current lockfileHash: sha256-KbJNMXX8ps/itgbCSyYR4wMAF895Ho60vW5Dhy14dCc=
RESULT: lockfileHash matches → nix:hash considers hash UP TO DATE
BUG: The pnpmDepsHash is actually STALE because effect-utils rev
changed (aaaa111 → bbbb222), which alters mk-pnpm-cli build
logic. But lockfileHash only fingerprints pnpm-lock.yaml,
which didn't change.
Root cause
The lockfileHash fingerprint detects when pnpm-lock.yaml changes. But it doesn't detect when:
- Upstream
mk-pnpm-cli.nix/mk-pnpm-deps.nixbuild logic changes - Upstream workspace structure changes (new/removed packages in staged workspace)
- Nix FOD inputs change due to flake input rev bumps
All of these alter the FOD output hash without touching pnpm-lock.yaml.
Affected repos
Any downstream repo with cliPackages entries using mk-pnpm-cli from effect-utils as a flake input.
Suggested fix
Option A: Include flake input revs in staleness fingerprint (recommended)
Extend the quick check to also fingerprint the resolved upstream rev from flake.lock or devenv.lock. If the upstream rev changed since the last nix:hash run, force a full rebuild.
Implementation sketch:
- Add a
flakeInputsHashfield to the hashSource metadata - In
update_fingerprint_hashes, compute a fingerprint of relevant flake input revs - In the quick check, compare stored vs current — if different, trigger full rebuild
Option B: Store upstream rev alongside pnpmDepsHash
Add an upstreamRev field to each cliPackages entry. The nix:hash task compares stored vs current and rebuilds when they differ.
Option C: Skip quick check in CI/automation context
Pass NIX_HASH_FORCE_REBUILD=1 to force nix:hash to always do the full build. Quick fix but doesn't address the general case.
Tradeoffs
- A is the most principled — extends the existing fingerprint pattern, works for any upstream change
- B is more explicit but requires downstream repos to maintain the rev field
- C is the quickest fix, only works for automated runs
Filed by an automated assistant on behalf of @schickling
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with nix-cli.nix and the update_fingerprint_hashes logic described in the issue; inspect how flake.lock or devenv.lock input revisions could be included in the existing hashSource metadata. Use repro.sh to verify that changing an upstream revision triggers a full rebuild instead of accepting the stored pnpmDepsHash.
Written by the indexing model from the issue text.
Assessment
- Domain
- build-system, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100