cas-kit 0.2.1

Content-addressed blob store: BLAKE3 addressing, bucketed layout, optional Zstd compression, packfiles, verify-on-read, mark-sweep GC with the cas-gc CLI.
Documentation
# Changelog

All notable changes to this project are documented here. Format: [Keep a
Changelog](https://keepachangelog.com/) — versions follow [semver](https://semver.org).

## [0.2.1] - 2026-09-12

### Added

- Perf-claims proof-back pass: `CLAIMS.md` maps every numeric/perf claim in
  the README to its proof artifact (16 backed, 1 newly proven, 0 removed).
- `benches/iai_cas.rs`: iai-callgrind instruction-count regression gate for
  the hot paths — `put_miss`, `put_hit` (dedup), `get_cold_verified`,
  `get_cache_hit` on a fixed 16 KiB blob. CI-only execution (needs
  valgrind); compiles everywhere.
- `tests/zero_alloc_dedup_hit.rs`: counting-global-allocator proof that a
  `put_blob` dedup hit allocates only a small size-independent constant
  (the hex-path plumbing) — no compression buffer, no re-store — turning
  the "second write returns immediately" README claim into a verified
  invariant on every `cargo test` run.

### Changed

- README: benchmark section now links `CLAIMS.md` and documents the
  iai-callgrind gate; the deduplication section cites its new proof
  artifacts. No API changes.

## [0.2.0] - 2026-09-11

### Added

- **Garbage collection** (`cas_kit::gc`): mark–sweep over a host-supplied
  live set (objects are opaque blobs, so roots *are* the live set — the
  module docs specify the reference model precisely). `mark` validates
  roots against physical presence and reports missing ones; `plan_sweep`
  classifies garbage; `sweep` executes in `DryRun` / `Trash` (recoverable
  copies under `<root>/trash/`, atomic per-file renames) / `Delete` modes.
  Pack-aware: all-garbage packs are removed, healthy packs untouched, and
  partial packs are rewritten with only the live objects they uniquely
  cover (refcount-aware against loose copies and healthy packs). Crash
  safety: rewrites are additive and ordered before removals, so an
  interrupted sweep can only defer reclamation, never lose live data.
- **`cas-gc` CLI** (`[[bin]]` in the same crate): `cas-gc --root <dir>
  mark <roots-file>` and `sweep <roots-file> --dry-run|--apply
  [--delete]`; newline-separated hex roots (`#` comments, `-` = stdin);
  human and `--json` output (scanned, live, garbage, missing roots,
  bytes reclaimable/reclaimed, trash path); exit codes 0/1/2.
- **Async GC wrappers** behind the optional, non-default `tokio` feature:
  `gc::mark_async` / `gc::sweep_async` via `spawn_blocking`.
- **Dedup benchmark** (`benches/dedup.rs`, criterion): 1000-file corpus
  (50% unique, 20% near-dupes, 30% exact dupes) measuring storage
  savings (30.0% whole-object), ingest throughput vs a plain-write
  baseline (~4.3× dedup overhead, dominated by zstd on incompressible
  data) and the dedup-hit path (~10× faster than cold ingest). Confirms
  whole-object granularity: near-dupes cost full storage pending future
  chunking.
- GC integration tests: overlapping-pack rewrite/dedup, dry-run
  immutability, trash recoverability, redundant-pack removal, orphan and
  unreadable-pack handling, sweeps concurrent with live-object readers,
  mark→sweep full cycle, async parity, and `cas-gc` CLI integration
  (tempdir fixtures, JSON output, exit codes).
- Criterion benchmark suite `benches/cas_bench.rs`: put (hash → compress →
  write), cold get with and without verify-on-read, and `PackFile::create`
  pack throughput, at 1 KiB / 1 MiB / 100 MiB blob sizes; incompressible
  payloads so numbers reflect zstd's worst case.
- `examples/file_store.rs`: content-addressed file store CLI (`add` / `get`
  / `list`) plus a self-contained demo of deduplication and verify-on-read
  corruption detection (including the blob-cache caveat that corrupted
  reads must bypass the in-memory cache to be observed).
- README: deduplication semantics, the garbage-collection guide
  (reference model, pack coverage rule, crash-safety and concurrency
  notes, `cas-gc` recipes), a dedup benchmark table, and FUSE noted as
  future work.
- `BlobStore::root()` accessor; `CasError::GcPathEscape` and
  `CasError::TaskJoin` variants.

## [0.1.0] - 2026-09-05

### Added
- Initial public release.