use AshArcadic.ReplicantSink, domains: [...], checkpoint_resource: MyGraph.Checkpoint, slot_name: "sirtify_graph" generates a Replicant.Sink implementation bound to a
host's config — the Postgres→ArcadeDB effect-once CDC mirror's delivery seam.
The generated module implements (../replicant/lib/replicant/sink.ex — the behaviour):
checkpoint/0→{:ok, checkpoint_resource.for_slot(slot_name)}— the durable integer watermark, ornil(never applied). Reads the baked checkpoint resource directly (no resolver index), so it is cheap and safe to call at pipeline start for the Ch3 start-mode decision.handle_transaction/1→ delegates toAshArcadic.Replicant.Apply.apply_transaction/2(the effect-once core: oneAsh.transactionco-committing the mirrored writes and the watermark advance).sink_kind/0→:state_mirror. The graph is a rebuildable projection; this gatesReplicant.Config's go-forward start guard (an empty-checkpoint:state_mirroris refused withoutgo_forward_only: trueOR a snapshot — see the Pipeline).handle_snapshot/2+handle_snapshot_complete/1→ the Ch3 bootstrap (both required, soReplicant.Sink.supports_snapshot?/1is true andsnapshot: trueis accepted; a partial impl is rejected:snapshot_unsupported). Delegated toAshArcadic.Replicant.Sink.Impl— see there for thefirst_for_table?redo-safety semantics.
Config (__config__/0)
The Replicant.Sink callbacks carry no pipeline context, so the config is baked into
the generated module: domains, checkpoint_resource, slot_name. The
AshArcadic.Replicant.Apply.config map (resolver_index + checkpoint + slot +
authorize?: false) is assembled by AshArcadic.Replicant.Sink.Impl.config/1, which
builds the resolver index ONCE (cached in :persistent_term keyed by slot) and fails
closed at build time on a duplicate/missing source_table — a mis-mapped mirror must
not silently start.
optional: true compile note
replicant is an optional: true dep. AshArcadic.Replicant.Apply / Sink.Impl /
Pipeline reference %Replicant.Transaction{} / %Replicant.Change{} structs and
Replicant.start_link/1 (hard compile-time dependencies), so those three modules are
compile-gated on if Code.ensure_loaded?(Replicant.Sink) — a non-CDC host builds
ash_arcadic without replicant and that subtree simply compiles away. A host that uses
the CDC sink adds {:replicant, "~> 0.3"} to its own deps; use AshArcadic.ReplicantSink
requires it (its @behaviour Replicant.Sink / delegation to Apply bind at the host's
compile). If a host adds replicant AFTER an initial non-CDC compile, run
mix deps.get && mix deps.clean ash_arcadic --build && mix compile so the gated subtree
recompiles with replicant present (mix deps.compile ash_arcadic --force alone can rebuild ash_arcadic
before replicant is compiled, leaving the gate false).