Modules
An Ash-native Replicant.Sink adapter. Mirrors a source Postgres database's
committed CDC changes into AshPostgres resources with effect-once semantics
(dup = 0, loss = 0), resolving resource, tenant, and classification in the Ash
layer while keeping replicant tenant-blind.
Applies one %Replicant.Change{} to the mirror. An insert/update goes through a
single-row Ash action; a delete issues one atomic bulk_destroy over a PK-filtered
query; a :mirror truncate deletes the mirror table directly.
SCD2 (validity-windowed) apply strategy, dispatched from Apply.apply_change/3 when
Info.history_scd2?(resource). Each change CLOSES the current open version (an Ash
bulk_update through the host close action, tenant-scoped, so it never retires
another tenant's identically-keyed version) and OPENS a new version (host :create
upsert by the (business_key, valid_from_lsn) identity), inside the sink's outer
transaction (transaction: false). Op-dependent close predicate: the re-opened record's
close uses valid_from_lsn < lsn (don't clobber the version being re-opened at lsn); a
TERMINAL close — a delete, or the retired OLD key of a pk-changing update — uses
valid_from_lsn <= lsn (retire a version opened in the same commit too). Value-free: every
raising op is scrubbed to a structural reason.
use AshReplicant.Checkpoint, repo: MyApp.Repo, domain: MyApp.Domain generates the
bundled AshPostgres checkpoint resource (table ash_replicant_checkpoints) bound to
the host's repo and domain.
Value-free error for the sink boundary. Carries structure only — a reason atom,
the resource module, the op, and the offending error's struct-module NAME —
never a row value, changeset, or DB message. scrub/3 normalizes any raised or
returned error into this shape, so the fail-closed halt path leaks nothing
(including pre-encryption sensitive plaintext).
Runtime resolution for the AshReplicant sink — the tenant/classification layer
that keeps replicant tenant-blind. Pure functions over compiled resource
metadata (no DB access)
Spark resource extension marking a host AshPostgres resource as a CDC mirror
target for ash_replicant.
Introspection for the AshReplicant.Resource extension.
Compile-verifier (surfaced as a Spark diagnostic; build-blocking under
--warnings-as-errors): the sink-selected actions of a multitenant replicant
resource must not declare multitenancy :bypass / :bypass_all.
Compile-verifier for replicant do history_strategy :scd2 ... end (surfaced as a
Spark diagnostic; build-blocking under --warnings-as-errors).
Compile-verifier for the replicant tenant sources (surfaced as a Spark
diagnostic; build-blocking under --warnings-as-errors). Two arms.
Compile-verifier for replicant do sensitive [...] end (surfaced as a Spark
diagnostic; build-blocking under --warnings-as-errors).
Compile-verifier (surfaced as a Spark diagnostic; build-blocking under
--warnings-as-errors): a resource that declares non-global Ash multitenancy
must declare a replicant tenant source — tenant_attribute or tenant_mfa.
Generates a Replicant.Sink implementation bound to a host's config.
The config-parameterized sink implementation the use AshReplicant.Sink
macro delegates to. handle_transaction/2 is the effect-once core: one
Repo.transaction wrapping {dedup-check → single-pass apply → checkpoint
upsert}, value-free and fail-closed.
Value-free telemetry. Owns the metadata allowlist — the single enforcement
point for "no row value in telemetry". An off-allowlist key raises rather than
shipping a value downstream. Mirrors replicant/ash_arcadic.