# Changelog
All notable changes to this crate are documented here. The format is
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
this crate adheres to [Semantic Versioning](https://semver.org/).
## [0.1.0] - 2026-10-24
The founding entry — the shipped composition's first release.
`alkgit-substrate` is the shipped backend composition for the
[`alkgit`](https://crates.io/crates/alkgit) protocol core: the complete
ADR-019 composition implementing alkgit's five-trait backend seam over
the alkstore + alkblobs substrate — reactive by default, engine-twinned
(sqlite / postgres / in-memory), schema-migrated, GC-wired, and carrying
the LFS surface (the `lfs` feature, default-on). The wire layer, the
backend traits, and the seam types are the core crate's; this crate
implements the storage beneath them. It carries no binary and no front
doors — the alkhttp `git`/`lfs` features and alkssh are family
infrastructure; a downstream app embeds the core (which serves the
wire), composes this crate's backends underneath, and brings its own
door.
The posture is **honest advertisement** (ADR-003 in the core's doc set
carries the family rule): public API surface is the crate-root
re-export list pinned in substrate.md §public API (the OQ-03
inventory), unimplemented surface declines loudly rather than serving
half-shapes, and the composition's postures are stated where a reader
needs them — the reactive halves are wired with no opt-out
(ADR-019 §5), receive-pack's pin bridge and mutation-marker machinery
are composition-internal (never re-exported), and the LFS lock server
(`lfs.locks`) is not served (the deferred OQ-21; its composition
validation is evidenced, the build deferred on client need).
### Added
**Wave 6 — the substrate foundation:**
- The crate scaffold and the feature placement (ADR-025's two-member
workspace): `sqlite` (default-on, the co-tenant registry/ref twin +
connection driver), `postgres` (optional, the fleet twin), `lfs`
(default-on, the ADR-022 surface's placement home).
- The registry adapter family: the trait pair
(`RegistryBackend`/`RegistryRead`/`RegistryWrite`), the in-memory
default adapter (`InMemoryRegistry`, stamp-free per ADR-024 §6), the
coherence contract's cached read provider (`CachedRegistryProvider` —
whole-table snapshot, wake/reconcile invalidation), and the core's
`GitRegistry`/`GitRegistryStore` implemented by all three engines
(the `HEAD_SEED_TARGET` both twins seed with).
- Schema migrations (ADR-024): one alkgit-owned stamp table versioning
the co-tenant schema as a unit; ordered hand-written monomorphic step
sets per engine; construction-run with loud failure (a half-migrated
store refuses service); concurrent-open-safe; additive-first. The
initial co-tenant schema ships in step 1 (the record/ref/marker rows,
the `registry_seq` singleton, the LFS rows — ADR-024 §5).
- The refs row table: the CAS-semantics reference impl
(`InMemoryRefTable`), the sqlite row-CAS twin (`SqliteRefTable` —
every `apply_updates` call one `BEGIN IMMEDIATE` transaction), the
postgres row-CAS twin (wave 7), the shared CAS kernel, table-layer
name validation (the core's deny-list reused; invalid name →
`funny refname` per-ref denial), and the unborn-HEAD symref row
shape. The twins carry the write-counter wrap (`VersionedRefTable`)
themselves — the liveness discipline's epoch half.
- The reactive halves (ADR-019 §5, wired — no opt-out): `Reactor` +
`AnnouncingRegistry` (announce publish/notify/enqueue, fail-soft
each), the wake runner, the stream consumer (cursor model +
per-seq idempotency), and the reconcile sweep closing the
crash-window. The channel names (`WAKE_CHANNEL`, `EVENTS_STREAM`,
`MAINTENANCE_QUEUE`, `MAINTENANCE_LOCK`) carry the alkstore streams
contract.
**Wave 7 — objects, packs, GC:**
- The object front (`ObjectFront`): the alkblobs git-object-family
wiring (`loose_form`/`oid_key`/`key_to_oid`) and the sync
`gix_object::Find`/`Exists` + `gix_pack::Find` front with per-session
`SessionFind` views and the one sync/async bridge
(`block_on` from blocking pipeline tasks, `block_in_place` in async
contexts).
- The real `GitPackGen` (`PackGen`): ADR-004's pipeline over the real
Find — the two-stage closure, the missing-objects abort, ADR-014 §5's
ack predicate as the real `common_haves` — in both serving shapes
(direct streaming; through-store ranged windows with mid-flight
digest verification over the shared `PackCache`).
- The GC liveness source (`RefClosure` — the full-graph walk over the
object front) with the refs-rows fingerprint seam (`RefRows`) and the
memoization discipline (durable fingerprint + write-counter
`VersionedRefTable`, bump-after-commit).
- The maintenance chain's consumer side (`MaintenanceChain`): the
`@every` sweep schedule registration, the supervised scheduler and
worker (claim loop, leader-TTL lock, `PackHousekeeping` release
path), the wake runner's restart, and the reconcile tick's driving
(`MaintenanceOpts`).
- The postgres refs row-CAS twin (the wave-7 N-c rider — the same
one-transaction CAS, the engine-swapped shape, advisory-lock
serialization).
**Wave 8 — receive-pack ingestion and the composition entry:**
- `GitPackIngest` (`PackIngest`): ADR-020 §2's ingestion composition —
the budgeted host working area's index (thin bases through the
substrate Find), unpack-to-loose under the decompressed-size cap with
guards riding the pin-bridge custody seam, the full-graph
connectivity walk from the pushed tips, and the working-area discard
(every failure the `unpack ng` leg).
- The composition entry (`SubstrateAssembly`): one fallible constructor
per assembly shape — `mem` (the completeness shape taking the
substrate engine handles), `sqlite` (the default single-host shape),
`postgres` (the fleet/durable-shared shape) — wiring the complete
backend per shape (registry pair + cached provider + reactor, the
wrapped refs table, the object front, both pack serving shapes, the
ingest, both liveness registrations, the maintenance chain).
`AssemblyOptions` and `PackServing` carry the knobs.
- End-to-end evidence against real `git` (push / clone / fetch over
every assembly shape) and the replication loop end-to-end (the
POC-X gates re-landed through the published serving machines).
**Wave 9 — LFS:**
- The pointer-lifecycle row store (`LfsRows`/`LfsRow`,
`InMemoryLfsRows`, `SqliteLfsRows`, `PgLfsRows` under the `lfs`
feature; ADR-022 §4): one row per `(repo_id, oid)` reference, the
refcount column's cross-reference re-protection contract, and the
repo-deletion removal legs riding the record-removal transactions
unconditionally. The epoch wrapper (`VersionedLfsRows`,
bump-after-commit) is carried by the twin assemblies themselves and
wired through the entry (no double wrap).
- The LFS media liveness source (`LfsMedia`/`lfs_media_key`) wired as
the composition's second registration (default — the fail-safe
posture, ADR-022 §6): sweep re-protects media while any row
references it, orphans reclaim, repo-deletion media follows the
machinery for free.
- The batch/transfer adapter (`LfsAdapter`, `LfsAdapterConfig`, the
`LfsGrantProvider`, the DTO family): the formable-key existence over
the ops control plane (`blobs/stat` through the DirectOps binding),
the pre-keyed put (mislabel refused, zero residue), and the download
byte path — per-window slice-digest verification with the
**whole-span oid check** (the resolved span budgeted by
`max_object_bytes`; F-S3's end-to-end oid conclusion as amended into
ADR-022 §2). The wired ownership provider is a required constructor
argument (the alkcall ADR-048 posture; the static fallback is
unreachable and battery-pinned so).
- End-to-end evidence against real `git-lfs` (round trips across the
engine matrix, token hand-off, auth refusals, range semantics, GC
sweep rows).
**Wave 10 — validation and release readiness:**
- The test-harness consolidation (one testutil home; zero public-API
change) and the per-piece parity class closed: the LFS twins carry
the `VersionedLfsRows` wrap (the refs twins' posture), the
through-store default-cache constructor documented as deliberate
per-piece probe surface, and the test-only `mem_registry` name
removed from the inventory (the entry's mem shape is the surface).
- The test-evidence rows: the big-media/ceiling door paths
(`TooLarge`→413 with the ceiling-edge partial span, the transfer-body
budget refusing before the adapter, the unrouted and doubled route
forms), the anonymous-refusal row (synthesized `anon` PUT refused at
the adapter — push always authenticated), the live-pg fleet battery
(the confirm-immediately custody posture proven slot-neutral), and
the `FleetTable` materialization exercised at the assembly rows.
- The feature-matrix hygiene one-pass: the off-matrix combos
(engine-less, lfs-alone, postgres-alone) now compile
warning-free alongside the documented matrix.
### Notes
- `lfs` is default-on but the composition is fully usable without
databases: the mem assembly (in-memory engines) runs the complete
reactive/GC machinery ephemeral.
- Object/refs rows are keyed sha1 (the pinned default, OQ-05); the
composition keys LFS media under the identity family's sha256
derivation (the LFS oid — ADR-022 §1) as the protocol requires.
[0.1.0]: https://git.alk.dev/alkdev/alkgit/releases/tag/alkgit-substrate-v0.1.0