# alkgit-substrate
The shipped backend composition for [`alkgit`](https://crates.io/crates/alkgit)
(https://git.alk.dev/alkdev/alkgit): the complete ADR-019 storage
composition implementing alkgit's five-trait backend seam over the
[alkstore](https://crates.io/crates/alkstore) +
[alkblobs](https://crates.io/crates/alkblobs) substrate — reactive by
default, engine-twinned, schema-migrated, GC-wired, with the LFS
surface under `lfs` (ADR-022).
The wire layer is not this crate's: alkgit serves the git smart
protocol (fetch/receive-pack) through backend-neutral machines, and the
doors (the alkhttp `git`/`lfs` features, alkssh) are family
infrastructure. This crate composes the storage underneath — git
objects in alkblobs, refs/registry in co-tenant rows, reactive halves
wired, no opt-out (ADR-019 §5). No binary; a downstream app embeds
alkgit, composes these backends, and brings its own door.
## The seams it implements
| `GitRegistry` | all three engines through `CachedRegistryProvider` (whole-table snapshot, wake/reconcile invalidation) |
| `GitRegistryStore` | in-memory adapter + the sqlite/postgres twins (one transaction per mutation, the `registry_seq` watermark transactionally exact) |
| `GitRefs` | the row-CAS tables (`InMemoryRefTable` + engine twins), each carrying the `VersionedRefTable` epoch wrap |
| `GitPackGen` | `PackGen` — ADR-004's pipeline over the real `Find` front; direct streaming or through-store ranged windows over the shared `PackCache` |
| `GitPackIngest` | `PackIngest` — budgeted index, unpack-to-loose, full-graph connectivity; every failure the `unpack ng` leg |
## The engine matrix (the three assembly shapes)
Engine choice is one assembly-level statement
(substrate.md §assembly shapes); the composition entry
(`SubstrateAssembly`) opens each shape with a single fallible
constructor — migrations run at construction and a half-migrated store
refuses service (ADR-024 §1):
| Ephemeral (tests / completeness) | `SubstrateAssembly::mem(store, blobs, options)` | in-memory engines; the complete reactive/GC machinery composes |
| Single-host (the default) | `SubstrateAssembly::sqlite(path, options)` (`sqlite` feature, default-on) | one co-tenant file: registry/ref/LFS rows + the alkstore-sqlite engine + the alkblobs kv tier (+ local large tier when LFS or through-store packs) |
| Fleet / durable-shared | `SubstrateAssembly::postgres(dsn, PgRegistryOptions, options)` (`postgres` feature) | schema-namespaced postgres: the same co-tenant tables over `alkstore-postgres`/`alkblobs` pg shapes |
```rust
use alkgit_substrate::{AssemblyOptions, PackServing, SubstrateAssembly};
// the single-host shape — one co-tenant sqlite file:
let assembly = SubstrateAssembly::sqlite(
"repo.db",
AssemblyOptions::new(work_root, large_root),
).await?;
// hand the faces to the core's serving machines (serve_duplex and
// friends take the marker + these trait objects):
let refs = assembly.refs(); // &Arc<dyn GitRefs>
let packgen = assembly.packgen(); // &Arc<dyn GitPackGen>
let ingest = assembly.ingest(); // &Arc<dyn GitPackIngest>
let registry = assembly.registry(); // &Arc<dyn GitRegistry>
```
The assembly manages as much of the machinery as exists to wire: the
reactor (post-commit announce + wake runner + stream consumer +
reconcile sweep), both liveness registrations (the ref-table closure
and, under `lfs`, the media rows), and the maintenance chain (the
sweep schedule, the supervised runner, `PackHousekeeping`). Working
assemblies: `substrate/tests/real_git.rs` (real git push/clone/fetch),
`substrate/tests/replication.rs`, `substrate/tests/real_lfs.rs`
(real git-lfs).
## LFS
Under the `lfs` feature (default-on — the fail-safe posture, ADR-022
§6): the pointer-lifecycle row store (`LfsRows` + engine twins), the
media liveness source (`LfsMedia`) wired into the sweep chain, and the
batch/transfer adapter (`LfsAdapter`) — the storage-side surface the
alkhttp `lfs` door consumes, with per-window slice-digest verification
plus the whole-span oid check and the wired ownership provider (never
the static fallback). An unregistered liveness source is the dangerous
default; there is no construction that composes LFS rows without their
sweep registration.
## Status
The composition is at its first release candidate posture; the
architecture docs are the authoritative contract —
[substrate.md](../docs/architecture/substrate.md) (the composition),
[lfs.md](../docs/architecture/lfs.md), and the ADRs
(019/020/022/024/025) pin every trait binding and public member the
publish freezes. The protocol core's README covers the wire layer and
the serving/consumer sketches.
## Documentation
- [Substrate spec](../docs/architecture/substrate.md) — the
authoritative composition contract (assembly shapes, §public API
freeze inventory).
- [LFS spec](../docs/architecture/lfs.md) + [ADR-022](../docs/architecture/decisions/022-lfs.md)
— the media surface (keying, door facts, liveness rows).
- [ADR-019](../docs/architecture/decisions/019-substrate-baseline.md),
[ADR-024](../docs/architecture/decisions/024-registry-schema-migrations.md),
[ADR-025](../docs/architecture/decisions/025-two-crate-workspace.md)
— the re-baseline, migrations, and the two-crate placement.
- [API docs](https://docs.rs/alkgit-substrate) — full crate
documentation.
- [Changelog](CHANGELOG.md)
## License
MIT OR Apache-2.0