ReactiveDag.Attestation.Record (reactive_dag v0.16.0)

Copy Markdown View Source

An Ash resource extension for the attestation record store — the Ash-idiomatic storage pattern (as ash_authentication's token resource): the HOST defines the resource (choosing repo, table, domain, policies), this extension stamps the required shape onto it, and the library reaches it through config :reactive_dag, attestation_resource: MyApp.Attestation.Record.

defmodule MyApp.Attestation.Record do
  use Ash.Resource,
    domain: MyApp.Attestations,
    data_layer: AshPostgres.DataLayer,
    extensions: [ReactiveDag.Attestation.Record]

  postgres do
    table "attestation_records"
    repo MyApp.Repo
  end

  attestation_record do
    # OPTIONAL: derive the signer from the Ash actor. When set and an
    # actor is present, `who` is FORCED from it — impersonation becomes
    # structurally impossible at the write, not merely discounted at
    # read time by the eligibility check.
    who_from_actor fn actor -> to_string(actor.email) end
  end
end

What the extension stamps (each only if the host hasn't declared it):

  • the record attributes — cell_id / scope_kind / scope / who / polarity / reason / basis / basis_version / signed_at / meta under a UUID pk;
  • a :sign create action accepting them, carrying the change that applies who_from_actor and rejects a reasonless rejection;
  • a primary :read.

Being the host's resource, everything Ash composes onto it: policies (signing authorization in the same framework as the rest of the app), notifications (pub_sub a signing straight into a refresh), and generated migrations (mix ash.codegen) instead of a hand-written expected-shape blob.

Append-only is enforced, not conventional

A verifier REJECTS the resource at compile time if it declares any update or destroy action. Records are immutable history — a signer's current stance is their latest record, and whether it counts is computed at read time (ReactiveDag.Attestation.Evaluation); nothing about a record is ever edited. The audit trail is the point.

Summary

Functions

The host-configured who_from_actor function, or nil.

Functions

attestation_record(body)

(macro)

who_from_actor(resource_or_dsl)

The host-configured who_from_actor function, or nil.