Files
alkgit/substrate/CHANGELOG.md
T
glm-5.3-flash 57fbda05ec chore(release): alkgit-substrate 0.1.0
The publish bump (substrate/w10-publish) over the green wave-10 gate:

- manifest: version 0.0.1 -> 0.1.0 (the composition's first publish)
- CHANGELOG: the 0.1.0 entry dated 2026-10-24; the stale
  "manifest reads 0.0.1" note dropped
- fields re-checked (license/repository/description/rust-version 1.88,
  the ADR-025 placement table: sqlite on, lfs on, postgres optional;
  the alkgit pin reads the published 0.1.0); cargo package --list
  shows 32 files — sources, tests, README, the two LICENSE files,
  CHANGELOG; no stray material

Verification: cargo test (workspace), cargo test -p alkgit,
cargo test -p alkgit-substrate, cargo test --all-features, both
clippies (-D warnings), cargo fmt --check, cargo doc --no-deps
(0 warnings), the fuzz corpus gate (13/13), the live-pg harness run
(-p alkgit-substrate --features postgres, 0 skips), and
cargo publish --dry-run --allow-dirty — all green.
2026-10-24 22:21:45 +00:00

9.4 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-24

The founding entry — the shipped composition's first release. alkgit-substrate is the shipped backend composition for the 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.