AshReplicant.Checkpoint (AshReplicant v0.4.0)

Copy Markdown View Source

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.

One row per replication slot: slot_name (primary key) and the durable commit_lsn watermark. The sink upserts it in the same transaction as the mirrored changes, which is what gives effect-once (dup = 0) semantics.

A macro is required because an AshPostgres resource needs its host repo at compile time; ash_replicant cannot hardcode it.

Locking the checkpoint down with policies

The checkpoint is an internal watermark, not tenant data: nothing outside the sink should read or write it. By default the generated resource carries no authorizer (so policies do is not even a declarable section), which means a host that exposes it on a wire surface — a JSON:API route, an MCP tool — has no way to enforce that. Pass the policy authorizer to close that:

use AshReplicant.Checkpoint,
  repo: MyApp.Repo,
  domain: MyApp.Domain,
  authorizers: [Ash.Policy.Authorizer]

# ...then declare your own policies in the module body, e.g. system-only:
policies do
  default_access_type :strict

  policy always() do
    authorize_if MyApp.Checks.SystemActor
  end
end

The sink always reads and upserts the checkpoint with authorize?: false on both paths (its internal read_checkpoint and upsert_checkpoint helpers), so it bypasses policy — effect-once is unaffected by whatever policies the host declares, including none. With the authorizer present and no policies declared, the resource is fail-closed to every actor except the sink's authorize?: false path, which is the safe default for a watermark. authorizers: defaults to [], so omitting it reproduces the pre-0.4 resource exactly (no behaviour change for existing hosts).