Compile-time Ecto configuration on the host's own module (ADR-0002).
A host declares its persistence module once:
defmodule MyApp.Persistence do
use StatifierPersistence.Ecto, repo: MyApp.Repo
endand gets, with zero further options: the resolved configuration
readable via MyApp.Persistence.__statifier_persistence__/1, and
four Ecto schema modules - MyApp.Persistence.Chart,
MyApp.Persistence.Position, MyApp.Persistence.Execution,
MyApp.Persistence.Input - over the statifier_charts /
statifier_positions / statifier_executions / statifier_inputs
tables
with UXID string primary keys (chart_ / pos_ / exec_ / input_
prefixes).
Every knob is compile-time, on this use, never in application env
(ADR-0002 decision 3), and the migrations helper consumes the same
resolved configuration so schemas and DDL cannot disagree. See
StatifierPersistence.Ecto.Config for the options (:key,
:table_prefix, :tables, :prefix, :blob_type,
:leading_columns).
The engine identity columns (content_hash, session_id, execution_id)
are stored verbatim as strings and are never touched by the
configured key scheme - ADR-0002 decision 1.
The chart schema also carries retired_at and retired_by, the two
tombstone columns V07 adds (ADR-0012 decision 6). Both are nil on
every chart that has not been retired, which is every chart until a
host asks for one to be; a row carrying a retired_at has had its
identity_blob and chart_blob nulled, and both chart doors answer
for it with the retired arm rather than with its bytes.
The execution schema also carries metadata, the optional opaque map of
host identities ADR-0006 grants, as a jsonb column (V02 of the
migrations helper). It holds identities only, never personal data:
:blob_type does not reach it, so anything filed there is at rest in
the clear no matter how the blob columns are configured.
:blob_type reaches the payload columns and nothing else:
identity_blob, chart_blob, position_blob, outcome_blob, and
input_blob on the inputs table (ADR-0010 decision 4). A host
wanting encryption at rest for those columns passes a custom
Ecto.Type or Ecto.ParameterizedType there and gets it applied
with zero further wiring. The identity and lookup columns
(content_hash, session_id, execution_id, status, failure, and
the input log's seq and door) stay plain regardless - the identity guard and the unique indexes
depend on reading them back verbatim, and metadata stays jsonb
regardless for the same reason: it is the column a host queries
(ADR-0006 decision 3).
The inputs table is ADR-0010's per-execution input log: one row per input
the interpreter saw, carrying the execution it belongs to, its dense
zero-based seq, the public door it entered by, and the opaque
input_blob. A nil input_blob is decision 6's closed marker. The
log holds document payload - an event's data is the host's own
values - which is why :blob_type reaches input_blob and why
turning the log on is a data-retention decision rather than a
debugging switch (StatifierPersistence.Storage.Adapter's moduledoc).