Expand description
The reactive halves — the engine-generic reactor (ADR-019 §5, substrate.md §the reactive halves, POC-R’s validated composition).
Per record/mutation write, after the durable commit, the writing side announces its effects independently and fail-soft:
- Publish → the durable change feed (
EVENTS_STREAM, keyed by repo id) — per-consumer durable cursors, monotone saves, replay from head; per-seq idempotency is the consumer’s rule (keyed publishes are carried metadata, not partitioning/dedup — the alkstore streams contract). - Notify → the wake hint (
notify/listenonWAKE_CHANNEL) — the invalidation trigger for every cached provider. Publish precedes notify (the durable carrier before the latency hint). - Enqueue → the maintenance queue (
MAINTENANCE_QUEUE) — the housekeeping job riding the scheduler chain. Wave 6 landed the enqueue producer side only (the recorded interpretation, gate-confirmed); the consumer side — the chain (schedule → queue → worker claim → leader TTL lock → sweep dispatch) and the liveness sources — lives incrate::maintenanceandcrate::liveness.
Every leg is fail-soft: its loss is exactly what the reconcile
sweep exists to close — Reactor::reconcile re-reads
rows_since(applied_watermark) → snapshot install → watermark
advance, idempotent by construction (pure reads, monotone
watermark), callable on demand and driven by the maintenance
chain’s scheduler tick. No
cross-store transaction machinery exists anywhere: alkstore’s
TxHandle carries no consumer SQL, so an announce is always
post-commit.
§The sqlite/postgres asymmetry (designed-in, ADR-019 §5)
- sqlite: the co-tenant file is itself the invalidation bus —
alkstore’s watcher
data_versionpoll fans a wake tolistenreceivers on any commit to the file, including alkgit’s own registry writes on their own connection, including cross-process (~3.2 ms measured, POC-R). A lost hint cannot exist while any write lands; the reconcile sweep is a correctness backstop, not a latency bound. The post-commit notify is redundant but kept — for semantics and for postgres. - postgres: LISTEN/NOTIFY is load-bearing — no file-level
bump exists. A lost/failed notify leaves caches stale until the
reconcile tick: the tick’s cadence is the real staleness bound
on postgres. (The live-pg asymmetry probe rides
substrate/w6-registry-postgres’s tests.)
§The construction wiring
Reactor is constructed from the assembly’s engine handle
(Arc<dyn alkstore::Store>) + the registry write side + the cached
provider (CachedRegistryProvider) — the per-piece constructor
the engine-twin adapter constructors wire (and the wave-8 single
composition entry will unify; the recorded interpretation, flagged
for the gate). Constructing the struct is infallible — every
consumed surface is a fallible call at use time; the adapter-twin
constructors own the loud-failure assembly posture
(OpenError).
§Names pinned here (the OQ-03 substrate-side inventory for this
wave’s members)
WAKE_CHANNEL, EVENTS_STREAM, MAINTENANCE_QUEUE,
MAINTENANCE_LOCK, RegistryEvent (the change-feed payload:
Put/Mutation/Removed — Mutation is the per-push marker’s
kind), MaintenanceJob (the maintenance-queue payload vocabulary),
AnnounceReport, AppliedWatermark, Reactor, and the announced
writing surface (AnnouncingRegistry — the durable write side +
the reactor’s post-commit announce, the wrapper the engine-twin
assembly constructors compose).
Structs§
- Announce
Report - The announce’s per-leg report — fail-soft outcomes as observation data, never an error: every leg’s loss is the reconcile sweep’s closure, so a suppressed announce carries no error path.
- Announcing
Registry - The announced write side — the reactive composition’s writing
surface: the durable registry write side folded with the reactor,
so every mutation’s post-commit announce (
Reactor::announce, fail-soft each) fires right after its durable commit. This is the wrapper the engine-twin assembly constructors compose — the pair’s durable contract below is unchanged (announce is never the pair’s; the wrapper is the caller, and the announce’s machinery is the reactor’s). - Applied
Watermark - The consumer-side high-water mark — the maximum sequence this composition has applied (stream events or a reconcile sweep). Monotone: per-repo keys reorder nothing (the feed is global FIFO by offset), but a reconcile may apply a sequence a live event never carried; a watermark only advances, so the composition converges to the durable side’s own truth.
- Reactor
- The reactor — the composition’s wired reactive halves, constructed from the substrate engine handle + the registry write side + the cached provider (the assembly-level pieces; the wave-8 composition entry unifies the whole backend’s construction).
Enums§
- Maintenance
Job - The maintenance-queue payload vocabulary — what the enqueue leg lands and what the wave-7 worker dispatches on; additions extend the set.
- Registry
Event - The registry mutation event — the durable change feed’s payload.
Every variant carries the mutation’s sequence number: the
consumer’s per-seq idempotency key and the reconcile watermark’s
currency. The
Mutationvariant is the per-push mutation-marker event’s kind (ADR-019 §7 — pushes do not modifyRepoRecord; the marker write’s announce carries the bare mutation).
Constants§
- EVENTS_
STREAM - The durable change feed — the record/mutation event log. Keyed publishes carry the repo id as metadata (per-seq idempotency, not the key, is the consumer’s dedup). The feed is the notify leg’s durable carrier: a wake is latency, an event is correctness. Contract stamp: ADR-019 §5 (the durable event leg).
- MAINTENANCE_
LOCK - The named TTL lock the sweep dispatch takes for cross-process GC exclusion (a locked-out sweep is a skip + short retry, a value not an error — the chain’s consumer side pins the usage, wave 7; ADR-019 §6).
- MAINTENANCE_
QUEUE - The maintenance queue — the enqueue leg’s target and (from wave 7) the chain the scheduler fires and the maintenance worker claims from. Contract stamp: ADR-019 §5 (the maintenance enqueue leg’s target; §6 — the chain consumes it).
- WAKE_
CHANNEL - The wake channel — the notify/listen channel the announce’s notify leg signals and the wake runner listens on. Wakes are opaque best-effort hints (coalesced, replay-free, possibly repeated); consumers re-read — the wake receiver’s idempotency obligation is the provider’s whole-table refresh (a swap, delta-free). Contract stamp: ADR-019 §5 (the notify wake leg).