# AshReplicant v0.3.0 - Table of Contents > An Ash-native Replicant.Sink adapter: effect-once CDC mirroring into AshPostgres resources. ## Pages - [AshReplicant](readme.md) - [ash_replicant usage rules](usage-rules.md) - [Changelog](changelog.md) - [Contributing to AshReplicant](contributing.md) - [LICENSE](license.md) ## Modules - [AshReplicant](AshReplicant.md): 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. - [AshReplicant.Apply](AshReplicant.Apply.md): 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. - [AshReplicant.Apply.Scd2](AshReplicant.Apply.Scd2.md): 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. - [AshReplicant.Checkpoint](AshReplicant.Checkpoint.md): `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. - [AshReplicant.Resolver](AshReplicant.Resolver.md): Runtime resolution for the AshReplicant sink — the tenant/classification layer that keeps `replicant` tenant-blind. Pure functions over compiled resource metadata (no DB access) - [AshReplicant.Resource](AshReplicant.Resource.md): Spark resource extension marking a host AshPostgres resource as a CDC mirror target for `ash_replicant`. - [AshReplicant.Resource.Info](AshReplicant.Resource.Info.md): Introspection for the `AshReplicant.Resource` extension. - [AshReplicant.Resource.Verifiers.ValidateActionMultitenancy](AshReplicant.Resource.Verifiers.ValidateActionMultitenancy.md): 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`. - [AshReplicant.Resource.Verifiers.ValidateHistory](AshReplicant.Resource.Verifiers.ValidateHistory.md): Compile-verifier for `replicant do history_strategy :scd2 ... end` (surfaced as a Spark diagnostic; build-blocking under `--warnings-as-errors`). - [AshReplicant.Resource.Verifiers.ValidateMultitenancy](AshReplicant.Resource.Verifiers.ValidateMultitenancy.md): Compile-verifier for the `replicant` tenant sources (surfaced as a Spark diagnostic; build-blocking under `--warnings-as-errors`). Two arms. - [AshReplicant.Resource.Verifiers.ValidateSensitive](AshReplicant.Resource.Verifiers.ValidateSensitive.md): Compile-verifier for `replicant do sensitive [...] end` (surfaced as a Spark diagnostic; build-blocking under `--warnings-as-errors`). - [AshReplicant.Resource.Verifiers.ValidateTenantSource](AshReplicant.Resource.Verifiers.ValidateTenantSource.md): 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`. - [AshReplicant.Sink](AshReplicant.Sink.md): Generates a `Replicant.Sink` implementation bound to a host's config. - [AshReplicant.Sink.Impl](AshReplicant.Sink.Impl.md): 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. - [AshReplicant.Telemetry](AshReplicant.Telemetry.md): 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`. - Exceptions - [AshReplicant.Error](AshReplicant.Error.md): 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).