Expand description
The single composition entry (wave 8) — the complete backend assembly (substrate.md §public API: “construction wired by a single composition entry that takes the substrate engine handles (the assembly-level one-statement engine choice)”; substrate.md §assembly shapes: “Engine choice is one assembly-level statement — three shapes, zero assembly code”).
SubstrateAssembly is the wired whole: the five backend-trait
implementations as Arc<dyn ...> (the core’s seam types —
GitRegistry, GitRegistryStore, GitRefs, GitPackGen,
GitPackIngest) plus the machinery’s handles the substrate doc’s
members list names (the object front, the reactor, the maintenance
chain, the applied watermark). One fallible constructor per
assembly, per the OpenError posture:
SubstrateAssembly::mem— the completeness shape. No engine dependency: the registry adapter, the refs table, and every wiring piece are the crate’s own base types, and the constructor takes the substrate engine handles — the alkstore engine the reactive halves ride and the alkblobs object pool the git-object family lives under (alkstore-mem+Store::mem_only()in the tests’ column; anyStorepairing for an embedder — the reactive composition is engine-generic, POC-R’s posture). Nothing opens, so the failure set is only the wiring legs (the liveness registration).SubstrateAssembly::sqlite— the default single-host assembly per substrate.md §assembly shapes row one: one sqlite file co-tenant by the registry/ref tables (crate::sqlite::SqliteRegistryAssembly’s constructor), the alkstore-sqlite engine, and the alkblobs dual-tier sqlite object store (dual_tier_sqlite_local— the large tier the through-store serving shape and over-threshold objects need; a sqlite fleet is a recorded non-option, alkblobs ADR-010 §3).:memory:never reaches an engine — the DQ-7 ruling holds by construction: every open rides the same file, so the ephemeral shape is the mem assembly, never sqlite-in-memory.- the
postgresconstructor — the fleet/durable-shared assembly (thepostgresfeature; substrate.md §assembly shapes row two): the DSN every open shares — the co-tenant connection (CoTenantPg, the registry’s own connection, the fourth pool of the assembly budget), the alkstore-postgres engine, and the alkblobs dual-tier postgres object store (dual_tier_postgres_local— pg kv + a local large tier; the consolidation pg-lo posture is a deployment choice the entry does not make for the embedder).
Wave 6’s per-piece constructors are unified behind the entry, not
duplicated: the engine-twin entries call the twin assemblies’
constructors and consume their exposed wiring; the complete-backend
wiring legs (the object front, the machinery custody share, the
pack serving shapes, the liveness registration, the maintenance
chain) run once in wire for all three shapes.
§The entry’s construction decisions (the task’s spec-level call,
recorded for the OQ-03 inventory)
- What the engine handles are (the opened-assembly-handle vs config question): the sqlite/pg entries open with config — the assembly-level engine statement is the constructor call itself (alkstore ADR-016’s deployment honesty; co-tenancy on one file / one DSN is guaranteed by construction, never an embedder duty) — and the mem entry takes the opened handles (no engine dependency, nothing to open).
- What the machinery returns: handles, not run tasks — the
reactor/chain runtime legs are returned for the embedder to
drive.
MaintenanceChain::runowns the supervision (the sweep schedule + the scheduler leg, the supervised wake runner, the reconcile tick, the worker claim loop) under one caller-owned stop token. No task spawns at construction; the entry constructs and wires. - Both pack serving shapes at the entry (the wave-7 posture,
assembly-level):
AssemblyOptions::pack_servingpicksPackServing::Direct(the default — no storage round-trip) orPackServing::ThroughStore(put-once + ranged windows with mid-flight digest verification; the request-digest cache is shared with the maintenance chain’s pack-housekeeping release path). The large tier the through-store shape requires is part of the engine-twin object stores by construction; a mem object pool without one rejects over-threshold packs through the store’s own put-time posture.
§The receive-pack flow, as wired
The entry’s refs leg is the w8 custody/commit side: the refs table
wrapped in the liveness write counter
(VersionedRefTable)) and then in
the composition-internal CommittedRefs — stale-prune → CAS →
drain-only-after-commit, then the per-push mutation-marker write +
post-commit announce (the RegistryMutations legs surface: the mem
shape’s fused legs or the engine-twin assemblies’ fused
record_mutation). The PackIngest
shares the pending-pin registry the wrapped refs impl drains —
constructed together, the custody seam’s one share (substrate.md
§object storage, “Pin custody across the frozen trait seam”). The
wire layer reaches the backend only through the trait objects, so
this assembly is the one place the receive flow’s legs exist. The
ref-table-closure liveness source is constructed over the front +
the wrapped table’s RefRows face + the same write counter and
registered on the object pool — zero registered sources make every
sweep abort (GcAbortCause::NoLivenessSources). The LFS media
source (lfs, the wave-9 wiring) registers beside it — the second
leg over the wrapped LFS rows surface and its assert counter, the
fail-safe default (ADR-022 §6: the lfs feature gates the
registration itself, so the source rides by construction and a
sweep never eats referenced media on a mixed deployment).
The twins’ record-transaction legs (the unborn-HEAD seed at record
creation, the repo’s ref rows leaving with its removal — substrate.md
§refs) ride the composition on the mem shape too now that the entry
wires it a refs table (MemSeededBackend; the twins carry their
own in-SQL copies).
§Names pinned here (the OQ-03 substrate-side inventory for this task)
SubstrateAssembly (mem/sqlite/postgres + the accessors),
AssemblyOptions, PackServing — plus the wave-9 rows task’s
accessor: lfs_rows() (the lfs feature’s row-op surface, the
LfsRows trait object whatever the shape — the rows surface the
entry wraps in the assert counter) and the wave-9 liveness task’s
lfs_registration() (the second registration leg’s token). The
receive-pack composition pieces themselves are deliberately not in
the inventory (substrate.md §public API: internal to the trait
impls).
Structs§
- Assembly
Options - The entry’s assembly-level options — the knobs the entry’s constructors carry. Everything else is the shipped default posture (the object stores’ thresholds and window delays are the twin constructors’ own defaults; constructor knobs are additive later — the two-way-door rule the HEAD seed pinned).
- Substrate
Assembly - The complete wired backend — the single composition entry’s product
(substrate.md §public API’s members): the five backend-trait
implementations as
Arc<dyn ...>plus the machinery’s handles.
Enums§
- Pack
Serving - The pack generation’s serving shape at the entry (substrate.md §object storage “Packs”: “Two serving shapes, both validated”).