Files
alkblobs/CHANGELOG.md
T
glm-5.3-flash 2f3b0d4c27 review(wave-13): the first-consumer gate — review-002 dispositioned, gates green, the publish hold lifts
- C-1 verified end to end: the one-way door's bytes read against
  ADR-018 line by line and exact (registry 0x03/0x04, preimage-identity
  derivation, fleet threading per §Decision 7); interop green against
  the real git CLI
- C-2 verified: ADR-019's mint-boundary cap + the typed MINT_REFUSED
  answer; the attack shape on paper; "not silence" exceeded
- C-3/C-4 verified as chartered (busy_timeout=5000 pinned; KeyBytes)
- review-002 stamped closed with disposition pointers; the prototype
  branch poc-o-git-objects deleted after parity confirmation
- Minor inline fixes: the CHANGELOG [0.1.0] entry absorbs wave 13
  (verified counts 218 default / 473 all-features, ADR-018/019 refs),
  the README names the git-object family honestly
- Stamps: the plan's wave-13 row + frontmatter completed,
  AGENTS.md now publish-ready

Verification: cargo test default 155+54+7+2; cargo test
--all-features vs the live pglo-poc harness 338+125+7+3; both clippy
variants -D warnings clean; cargo fmt --check clean; cargo doc
--no-deps clean; fuzz corpus replay 7/7; cargo publish --dry-run
--allow-dirty green (94 files).
2026-10-18 00:27:05 +00:00

9.3 KiB

Changelog

All notable changes to this crate are documented here. The format is based on Keep a Changelog, and this crate adheres to Semantic Versioning.

0.1.0 - 2026-10-18

Initial release of the alkblobs family: content-addressed blob storage with one canonical content hash, tiered pluggable engines, GC built in, and the network ops surface riding alkcall as a feature.

The crate is the store layer only — no transport, no wire protocol in-core (ADR-001). Store never learns where bytes came from; transport, framing, and serialization live above the facade (in the feature-gated ops module) or nowhere. Keyed under the git-family oid derivation ("blob <len>\0" + content) — SHA-256 canonically, SHA-1 tolerated for existing repos (ADR-002) — with the git-object derivation family for git's non-blob objects (ADR-018) — and addressed through an algorithm-tagged Key encoding that is the crate's one-way door: parsers validate and reject, never guess.

Added

  • The Store facade — put/get/stat/read_range/has/list, with the write verifying the stored artifact as a whole before it publishes and verification-on-get on the kv tier's materialized reads (the windows themselves carry no check; read_range returns the ADR-006 slice digest for the caller to carry out-of-band) (ADR-006). Known-length and unknown-length puts share one signature (the unknown-length path buffers past the threshold in memory, then continues into the large tier's stage — a non-restartable source is a normal case, never an error). No new: the store is built through named constructors declaring one of three ADR-pinned modes — mem_only, kv_only, or dual_tier — with size-threshold dispatch the pure function routing between a store's kv tier and its large tier (default threshold 128 KiB, constructor-tunable; ADR-003).
  • Pins and batches — pin-before-publish: an entry cannot appear in a sweep's view without already carrying its pin. The put's RAII Pin guard releases on drop; Batch groups a multi-put write (manifest writes are the shape) under one batch-scoped pin group, committed or dropped together (ADR-005).
  • The GC protocol — sweep (mark phase / delete window / commit phase, aborts report as data with nothing deleted), direct delete, and liveness registration in two forms (ADR-005, ADR-008): the in-process callback and, for fleets, the named liveness table the constructor declares.
  • Five engines over two tiers (ADR-003, ADR-007, ADR-009) — features gate engines, each pulling only its own driver cluster (ADR-013); tiers are constructor composition, not features:
    • kv sqlite (feature sqlite, default-on): WAL + synchronous=NORMAL, prepared statements, read paths tolerate the no-tables-yet database; the durable single-host tier.
    • kv postgres (feature postgres): pooled connections, prepared statements, ON CONFLICT DO NOTHING CAS — the fleet host.
    • kv mem (feature mem, default-on): dependency-free ephemeral implementation; never a production story, never fleet-valid — the contract-reference engine every other engine's conformance tests mirror.
    • large local (ungated, dependency-free): flat sharded files, stage-then-commit-rename, pread reads; the publish is fsync- durable and no-replace (ADR-015).
    • large pg-lo (feature pg-lo): postgres Large Objects — descriptorless windowed reads, LO creation transactional (zero crash orphans), staged into a held transaction; one large-object consumer per database is the co-tenancy constraint the orphan_reap_permitted declaration carries (ADR-016).
  • Fleet GC — DB-backed pins, sweep-window rows, and the sweep lease host on the fleet's kv-tier engine (postgres): the lease is an atomic test-and-set advisory lock (at most one sweep in flight per pool; ADR-008, ADR-013); deletes are windowed and re-arbitrated at execution so the sweep-vs-put race resolves without data loss; constructors declare fleet: true explicitly (never inferred) against the composite fleet-validity predicate (ADR-012).
  • The ops module (feature ops, default-off) — the network surface riding alkcall (ADR-001): blobs/fetch (the binary data-plane Sub op, ranged-fetch addressing over the fanout registry) and blobs/put (the verified offer/stream/commit Sink op), plus the JSON control-op family (stat, have, delete) and the pin-token layer: the token is a CSPRNG capability over the pin, minted custodial (non-fleet) or renewable (fleet), renewed and confirmed through the store core's renewal access — the one crate-internal seam the module consumes. Authorization rides alkcall's AccessControl seam — no in-band invented scheme (ADR-014, ADR-017).
  • Fuzzing — fuzz/, a sidecar workspace excluded from the root workspace, pinning nightly inside itself: two libFuzzer targets over the parse surfaces (key_encoding over the key/algorithm parser cluster, ops_ingress over the ranged-fetch bounds ingress and token decode), and a stable-toolchain companion crate (fuzz/shared) replaying the committed corpora as a plain cargo test gate.
  • The git-object derivation family — the hash registry extends with 0x03 (git-object-sha-1) and 0x04 (git-object-sha-256) (ADR-018): the preimage-identity derivation over git's own loose-object form (<type> <len>\0 + content stored as the value), so the digest is byte-identical to git's oid of the object — trees, commits, and tags included — with verification-on-get, dedup, and external-oid addressing intact. Lands as the public put_git_object(algorithm, len, stream) put seam (known-length only, family members only), threaded through the fleet put paths uniformly, and CLI-validated byte-exact against real git hash-object.
  • The token registry's admission posture (ADR-019) — an admission cap at the mint boundary (OpsConfig::token_registry_max_entries, default 65,536 entries, usize::MAX the uncapped form), refusing — never evicting — with the new Error::RegistryFull refusal member and the blobs/put declared answer MINT_REFUSED (the committed digest in the details; no token, no custody taken). Bounds the non-confirming upload loop (unbounded registry growth plus never-expiring custody on a non-fleet store) at the store; the non-fleet custody posture is documented embedder-facing, the fleet TTL named as the safe posture for doors that cannot prove confirm.
  • Borrowed-key overloads — Key::key_bytes() returning the fixed-capacity KeyBytes (a stack Copy wrapper deref-coercing to &[u8], byte-identical to as_bytes) drops the per-call heap allocation from the serving paths' re-encode sites.

Changed

  • sqlite contention posture explicit — PRAGMA busy_timeout = 5000 is set at open as a pinned constant (matching the family's explicit alkstore-sqlite value), joining the durability posture as stated contract: co-tenant assemblies on one sqlite file no longer ride rusqlite's implicit default by coincidence.
  • alkcall bumped to 0.10 (the gateway ownership-seam release; additive for this crate's native-wire use — no code changes).

Verified

  • The full verification block against the live harness (postgres:16-alpine on localhost:15432): 218 tests pass on the default feature set (mem + sqlite — unit 155, conformance 54, git-interop 7, README examples 2); 473 pass under --all-features — the pg columns run against the live harness (their server-less default is a clean skip); both clippy configurations (--all-targets --all-features, -D warnings), cargo fmt --check, and cargo doc --no-deps are clean; the fuzz corpus-replay gate passes (cargo test --manifest-path fuzz/shared/Cargo.toml, 7/7) — campaigns run via fuzz/run-detached.sh per fuzz/README.md.