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 ended_at, the column V08 adds:
NULL until the row takes its first terminal write with the column
in place, then that write's time, never moved or cleared afterwards
(StatifierPersistence.Executions.ended?/1 names where that and the
status can disagree).
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).