Skip to main content

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};