nova-cache-0.3.1.0: CHANGELOG.md
# Changelog
## 0.3.1.0 — 2026-03-07
### Drop `memory` dependency, use `ram`
- **`memory` → `ram`** — Replaced `memory` package with `ram` (modern, minimal replacement). Same `Data.ByteArray` API, drops the heavy `basement` transitive dependency. Fixes build failure with `crypton >= 1.1` which switched from `memory` to `ram` internally — `Data.ByteArray.ByteArrayAccess` instances were no longer compatible across packages.
- **`crypton >= 1.1` required** — Lower bound bumped from `1.0` to `1.1` so that `crypton` and `nova-cache` both link against `ram` for `ByteArrayAccess` instances. Older `crypton` versions used `memory`, causing instance mismatches at link time.
- All imports remain `Data.ByteArray` — no source-level changes needed for downstream consumers.
## 0.3.0.0 — 2026-02-28
### Breaking changes
- **`decompressXz`** signature changed from `ByteString -> ByteString` to
`ByteString -> IO (Either String ByteString)` — catches lzma exceptions
instead of crashing on malformed input
- **`writeNarInfo`** / **`writeNar`** now return `IO Bool` instead of `IO ()` —
`False` indicates a rejected path (traversal, empty)
### Security
- **Request body size limit** — PUT endpoints reject bodies over 100 MB with
413 Payload Too Large (prevents memory exhaustion)
- **Constant-time auth comparison** — API key check uses `constEq` from
`Data.ByteArray` instead of `==` (prevents timing side-channel)
### Bug fixes
- **Safe UTF-8 decoding in NAR deserializer** — `decodeUtf8` replaced with
`decodeUtf8'`; malformed UTF-8 in symlink targets or directory entry names
now returns a parse error instead of throwing
### New features
- **`GET /narinfo-hashes`** endpoint — returns all cached narinfo hashes as
newline-delimited text, enabling efficient cache diffing
- **`listNarInfoHashes`** function added to `NovaCache.Store`
### Improvements
- Server logs warnings to stderr when narinfo signing fails (parse error or
sign error) instead of silently returning unsigned body
- Server returns 400 Bad Request when PUT paths fail sanitization instead of
silently discarding the upload
- README: license badge and footer corrected from MIT to BSD-3-Clause
- README: `parallel` input documented in seed action table
- README: `CACHE_API_KEY` and `SIGNING_KEY_FILE` env vars documented
- Seed action: replaced per-path HEAD checks with single `GET /narinfo-hashes`
call and local diff for dramatically faster cache seeding
## 0.2.4.1 — 2026-02-26
- License changed from MIT to BSD-3-Clause
## 0.2.4.0 — 2026-02-25
- New module: `NovaCache.Base64` — base64 encode/decode re-exported so
downstream consumers don't need a direct `base64-bytestring` dependency
- No changes to existing modules
## 0.2.3.0 — 2026-02-23
- Drop `unix` dependency — `checkExecutable` now uses cross-platform
`System.Directory.getPermissions` instead of `System.Posix.Files`
- Fixes Windows build (the `unix` package is not available on Windows)
- No API changes
## 0.2.2.0 — 2026-02-23
- Gate `NovaCache.Compression` and `lzma` dependency behind a `compression`
cabal flag (default on, backwards compatible)
- Consumers that only need hashing/NAR/narinfo can build with `-compression`
to avoid the system `liblzma` C dependency
- Compression tests moved to separate test suite (`nova-cache-compression-test`)
- No changes to any library source modules
## 0.2.1.0 — 2026-02-22
- Server: `validateNarInfo` wired into PUT handler — rejects malformed uploads
with 400 Bad Request and collected validation errors
- Server: `Cache-Control: public, max-age=31536000, immutable` on narinfo and
NAR GET responses for CDN edge caching
- Store: default priority changed from 30 to 50 (community cache fallback
behind cache.nixos.org at 40)
- Seed action: fix round-trip validation to account for server-side signing;
now verifies StorePath field, signature presence, and NAR fetchability
- Public binary cache documented with key and nix.conf instructions
## 0.2.0.0 — 2026-02-22
- New module: `NovaCache.Validate` — pure protocol validation layer
- `ValidationError` sum type with 10 constructors covering sizes, store paths,
hash formats, content hashes, and Ed25519 signatures
- `validateNarInfo` — field semantic validation (non-negative sizes, parseable
store paths/hashes/references), collects all errors instead of short-circuiting
- `validateNarHash` / `validateFileHash` — SHA-256 content hash verification
against declared narinfo values
- `validateSignature` — Ed25519 signature verification against a trusted public
key (at-least-one semantics, matching Nix behaviour)
- `validateFull` — composes all four stages, collecting errors across all
- 17 new tests (74 total across 9 groups)
- No new dependencies
## 0.1.0.0 — 2026-02-21
- Initial release (renamed from gb-nix-cache)
- Nix-base32 encoding/decoding
- SHA-256 hashing with Nix hash formatting
- Store path parsing and rendering
- NAR binary format serialization/deserialization
- NarInfo text format parsing/rendering
- Ed25519 signing and verification
- xz compression/decompression
- Filesystem storage backend
- Optional WAI cache server (behind `server` flag)
- Path traversal protection on all store operations
- Total port parsing (no partial `read`)
- 54 tests across 8 modules