alkgit_substrate/lib.rs
1//! alkgit-substrate: the shipped backend composition for the alkgit
2//! protocol core.
3//!
4//! The complete ADR-019 composition implementing alkgit's backend seam
5//! over the alkstore + alkblobs substrate — the engine-generic reactive
6//! halves, the coherence-contract cached read provider, the family
7//! adapter pattern with engine twins, the schema migrations, the GC
8//! wiring, and the LFS surface. The spec is `docs/architecture/
9//! substrate.md`; the crate/feature placement (the two-member workspace,
10//! `sqlite` on / `postgres` off / `lfs` on) is ADR-025. The composition
11//! consumes (identity, repo id, duplex stream, limits) and stays
12//! front-door-blind: doors are family infrastructure. The traits it
13//! implements and the seam types it imports —
14//! [`GitRegistry`](alkgit::GitRegistry),
15//! [`GitRegistryStore`](alkgit::GitRegistryStore), [`GitRefs`](alkgit::GitRefs),
16//! [`GitPackGen`](alkgit::GitPackGen), [`GitPackIngest`](alkgit::GitPackIngest),
17//! the [`RepoRecord`](alkgit::RepoRecord) record family — are all
18//! published by the core crate; this crate re-exports none of them.
19//!
20//! Public API surface is the crate-root re-export list (the convention);
21//! substrate.md §public API fixes the members — the exact Rust names are
22//! each implementation task's to pin under OQ-03's inventory.
23//!
24//! # The module map (per-module, one workstream one file)
25//!
26//! - [`error`] — the substrate open/construction error surface
27//! ([`OpenError`]): the fallible-constructor posture ADR-024 §1
28//! requires (construction fails loudly; a half-migrated store refuses
29//! service). Deliberately no conversion into the core's error types.
30//! - [`migrations`] — the ADR-024 machinery (both engines' homes since
31//! the wave-10 placement split: the co-tenant connection handles
32//! [`CoTenantSqlite`] (sqlite) and [`CoTenantPg`] (postgres, whose
33//! twin re-exports it) together, the migration runners, and the pg
34//! SQL plumbing) + the initial co-tenant schema.
35//! - [`registry`] — the registry adapter trait pair, the in-memory
36//! default adapter (stamp-free per ADR-024 §6), the cached read
37//! provider, the alkgit registry-pair impls, and the engine-neutral
38//! [`crate::registry::HEAD_SEED_TARGET`] pin both twins seed with.
39//! - [`refs`] — the refs co-tenant row table: the CAS-semantics
40//! reference impl ([`InMemoryRefTable`], engine-free), the sqlite
41//! row-CAS twin ([`SqliteRefTable`], the `sqlite` feature — every
42//! `apply_updates` call in one `BEGIN IMMEDIATE` transaction on the
43//! co-tenant `git_refs` rows) and the pg row-CAS twin
44//! (`PgRefTable`, the `postgres` feature — the same one
45//! transaction per call, the sqlite twin's engine-swapped, the wave-7
46//! N-c rider), the table-layer name validation
47//! (the core's `validate_ref_name` deny-list reused, the
48//! invalid-name → `funny refname` per-ref denial mapping pinned),
49//! and the unborn-HEAD symref row shape.
50//! - [`reactor`] — the reactive halves: the announce composition
51//! (publish/notify/enqueue, fail-soft each), the wake runner (the
52//! provider's invalidation trigger), the stream consumer (the
53//! cursor model + per-seq idempotency), the reconcile sweep (the
54//! crash-window closure), and the engine-generic construction wiring
55//! ([`Reactor`] from the engine handle + provider).
56//! - `sqlite` / `postgres` — the engine twins (`sqlite` on /
57//! `postgres` off per ADR-025), feature-gated module paths and so not
58//! linked here: a default-feature doc build does not see them.
59//! The postgres twin (`postgres`, `w6-registry-postgres`) carries
60//! the LISTEN/NOTIFY-leg asymmetry (no file-level bump exists — a
61//! lost hint leaves caches stale until the reconcile tick) and the
62//! env-gated live-pg harness tests.
63//! - [`odb`] — the object front: the alkblobs git-object-family
64//! wiring ([`loose_form`], [`oid_key`], [`key_to_oid`]) and the sync
65//! [`gix_object::Find`]/[`gix_object::Exists`] + [`gix_pack::Find`]
66//! Find front ([`ObjectFront`] constructed once with per-session
67//! [`SessionFind`] views, the miss-recording shape the
68//! `StorageError::ObjectMissing` abort maps back through) with the
69//! one sync/async bridge ([`ObjectFront::block_on`] from blocking
70//! pipeline tasks — never from async contexts,
71//! [`ObjectFront::block_in_place`] there).
72//! - [`packgen`] — the substrate `GitPackGen` implement ([`PackGen`]):
73//! ADR-004's pipeline over the real Find (the two-stage closure, the
74//! missing-objects abort), the ADR-014 §5 ack predicate as the real
75//! `common_haves`, and both serving shapes (direct streaming;
76//! through-store ranged windows with mid-flight digest verification
77//! over the [`PackCache`] request-digest cache), both serving straight
78//! into the frozen trait's sink.
79//! - [`ingest`] — the substrate `GitPackIngest` implement (`PackIngest`):
80//! ADR-020 §2's ingestion composition — the budgeted host working
81//! area's index (thin bases through the substrate Find), the
82//! unpack-to-loose under the decompressed-size cap with the guards
83//! riding the w8-pin-registry's custody seam, the full-graph
84//! connectivity walk from the pushed tips, and the working-area
85//! discard. Construction is the composition entry's (the working
86//! area's root is the entry's config knob); the exact public names
87//! join the OQ-03 substrate-side inventory with the entry task.
88//! - [`compose`] — the single composition entry
89//! ([`SubstrateAssembly`]): one fallible constructor per assembly
90//! (mem — the completeness shape taking the substrate engine
91//! handles; sqlite — the default single-host shape, config-opened
92//! co-tenant; postgres — the fleet/durable-shared shape, the
93//! feature), wiring the complete backend per shape: the registry
94//! pair + cached read provider + reactor (the assembly shapes,
95//! unified), the write-counter-wrapped refs table under the
96//! w8 custody/commit side, the object front, the pack serving
97//! shapes, the ingest, the registered ref-table-closure liveness
98//! source, and the maintenance chain.
99//! - [`liveness`] — the GC liveness source: the ref-table closure
100//! ([`RefClosure`], the [`alkblobs::LivenessSource`] implement — the
101//! full graph walk over the object front, parents included, gitlinks
102//! neither marked nor walked), the refs-rows seam ([`RefRows`], the
103//! durable refs fingerprint the memo keys on, POC-O's memoized-closure
104//! shape with the invalidation mechanism pinned: read-side durable
105//! fingerprint + the in-process write counter, the fleet posture
106//! stated), the write-counting refs wrapper ([`VersionedRefTable`]),
107//! and the registration wiring ([`RefClosure::register`]) — the
108//! maintenance chain's sweep dispatch requires it.
109//! - [`maintenance`] — the maintenance chain's consumer side
110//! ([`MaintenanceChain`]): the `@every` sweep schedule registration
111//! ([`SWEEP_SCHEDULE`]) + the supervised scheduler runner, the
112//! worker's claim loop over [`MAINTENANCE_QUEUE`] (the
113//! [`MaintenanceJob`]) dispatch:
114//! `Sweep` → the [`MAINTENANCE_LOCK`] leader lock + the store's
115//! sweep with the report as data; `PackHousekeeping` → the
116//! [`PackCache`] release path), and the runner supervision (the wake
117//! runner's restart on both stop shapes
118//! ([`Reactor::run_wake_runner`]'s collapsed quiet returns) and the
119//! reconcile tick's driving ([`MaintenanceOpts`]).
120//! - [`lfs`] — the LFS pointer-lifecycle row surface (the `lfs`
121//! feature; ADR-022 §4): the [`LfsRows`] trait over one row per
122//! reference, the [`InMemoryLfsRows`] reference impl + the engine
123//! twins ([`SqliteLfsRows`], `PgLfsRows`), the refcount semantics +
124//! the re-protection contract pinned, the repo-deletion removal legs
125//! riding the twins' record-removal transactions unconditionally and
126//! the mem shape's legs in the composition entry, the epoch wrapper
127//! ([`VersionedLfsRows`], the liveness discipline's
128//! bump-after-commit half — [`crate::liveness`]) carried by the
129//! twin assemblies themselves (the refs twins' posture —
130//! `lfs_rows()` hands the wrapped surface, `lfs_version()` the
131//! shared counter).
132//! - [`lfs_adapter`] — the storage-side batch/transfer adapter (the
133//! `lfs` feature; ADR-022 §1–3): the batch/checking mapping, the
134//! pre-keyed put / ranged-fetch byte paths with the whole-span oid
135//! verification, and the wired-provider posture ([`LfsGrantProvider`]
136//! — the facade seam is the embedder's; the adapter is door-side
137//! infrastructure, split documented in the module doc).
138//!
139//! The pending-pin registry and the receive flow's
140//! committed-ref side live in the composition-internal `pins` module
141//! (substrate.md §public API carries the receive-pack composition as
142//! internal to the trait impls — no re-export): the
143//! `PendingPinRegistry` (the pin bridge's registry half — retain from
144//! prepare, drain-with-correlation from apply, prune-stale from any
145//! apply, drop-on-abort), the `CommittedRefs` wrapped `GitRefs`
146//! implement (stale-prune → CAS → drain-only-after-commit, then the
147//! post-CAS marker + announce legs fail-soft), and the
148//! `RegistryMutations` legs surface (the mem shape's fused legs plus
149//! the engine-twin assemblies' impls).
150//!
151//! # The composition entry's pinned decisions (OQ-03 inventory,
152//! `compose`)
153//!
154//! `SubstrateAssembly` (`mem`/`sqlite`/`postgres` + accessors),
155//! `AssemblyOptions`, `PackServing` — the re-export list grows by
156//! exactly the entry surface.
157
158#![forbid(unsafe_code)]
159
160pub mod compose;
161pub mod error;
162pub mod ingest;
163#[cfg(feature = "lfs")]
164pub mod lfs;
165#[cfg(feature = "lfs")]
166pub mod lfs_adapter;
167pub mod liveness;
168pub mod maintenance;
169pub mod migrations;
170pub mod odb;
171pub mod packgen;
172mod pins;
173#[cfg(feature = "postgres")]
174pub mod postgres;
175pub mod reactor;
176pub mod refs;
177pub mod registry;
178#[cfg(feature = "sqlite")]
179pub mod sqlite;
180
181/// The test-only harness helper home (review 006 R-3) — compiled only
182/// under test, never public API surface.
183#[cfg(test)]
184pub(crate) mod testutil;
185
186pub use compose::{AssemblyOptions, PackServing, SubstrateAssembly};
187pub use error::OpenError;
188#[cfg(all(feature = "lfs", feature = "postgres"))]
189pub use lfs::PgLfsRows;
190#[cfg(all(feature = "lfs", feature = "sqlite"))]
191pub use lfs::SqliteLfsRows;
192#[cfg(feature = "lfs")]
193pub use lfs::{InMemoryLfsRows, LfsRow, LfsRows, VersionedLfsRows};
194#[cfg(feature = "lfs")]
195pub use lfs_adapter::{
196 LfsActions, LfsAdapter, LfsAdapterConfig, LfsAdapterError, LfsBatchObject, LfsBatchOperation,
197 LfsBatchRequest, LfsBatchResponse, LfsDownload, LfsGrantProvider, LfsHrefMint, LfsObjectAnswer,
198 LfsObjectError, LfsRange,
199};
200#[cfg(feature = "lfs")]
201pub use liveness::{lfs_media_key, LfsMedia};
202pub use liveness::{RefClosure, RefRow, RefRowState, RefRows, RefRowsSnapshot};
203pub use maintenance::{
204 MaintenanceChain, MaintenanceOpts, SweepVerdict, WorkerEvent, LOCKED_OUT_RETRY_SECS,
205 SWEEP_SCHEDULE,
206};
207#[cfg(feature = "sqlite")]
208pub use migrations::CoTenantSqlite;
209pub use odb::{key_to_oid, loose_form, oid_key, ObjectFront, SessionFind};
210pub use packgen::{PackCache, PackGen};
211#[cfg(feature = "postgres")]
212pub use postgres::{CoTenantPg, PgRegistry, PgRegistryAssembly, PgRegistryOptions, DEFAULT_SCHEMA};
213pub use reactor::{
214 AnnounceReport, AnnouncingRegistry, AppliedWatermark, MaintenanceJob, Reactor, RegistryEvent,
215 EVENTS_STREAM, MAINTENANCE_LOCK, MAINTENANCE_QUEUE, WAKE_CHANNEL,
216};
217#[cfg(feature = "postgres")]
218pub use refs::PgRefTable;
219#[cfg(feature = "sqlite")]
220pub use refs::SqliteRefTable;
221pub use refs::{InMemoryRefTable, VersionedRefTable, CAS_STALE_REASON};
222pub use registry::{
223 CachedRegistryProvider, InMemoryRegistry, RegistryBackend, RegistryRead, RegistryRow,
224 RegistryWrite, HEAD_SEED_TARGET,
225};
226#[cfg(feature = "sqlite")]
227pub use sqlite::{SqliteRegistry, SqliteRegistryAssembly};