symfonic.memory.backends.postgres_memory_erase_log¶
postgres_memory_erase_log ¶
The serialized, hash-chained erase log beside the generations (CORE-171).
A physical copy of the memory cluster cannot be told from the live cluster
from inside it, so the proof that a database holds every acknowledged forget
is the log's head, anchored outside the backup domain
(postgres_erase_anchor). This module is the in-database half.
Every generation advance appends one row in the erase's own transaction. The
append trigger locks the log, so log order is commit order, assigns
seq = head + 1 and digest = sha256(prior digest || row), where the
row includes its transaction ID and a nonce the trigger draws (callers cannot
choose either): row N's digest commits to the full prefix history 0..N, so two
lineages that differ anywhere below N cannot share it, and a copy replaying
the very same forgets, through any login, cannot reproduce it. Row 0 is
written by the install and binds the generation rows present then.
The append function runs as the log's owner (SECURITY DEFINER, search_path pinned to pg_catalog, EXECUTE revoked from PUBLIC): an INSERT-only login may append, only the owner may take the serializing lock, and no caller's search_path reaches its body. Every check attests both triggers' exact function (owner, body, pinned search_path) before it trusts the log.
A deferred constraint trigger on the generations refuses, at commit, any
generation insert or update without its log row from the same transaction:
an earlier release's advance SQL fails closed and deletes nothing. The
log admits no update, delete or truncate. A database owner or superuser can
still rewrite both; that is the stated tamper boundary.
advance
async
¶
Advance scope's generation and append its log row; return its seq.
Inside the erase's own transaction, after the graph lock and before it commits. The append waits on the log lock, so concurrent forgets of one memory database commit one at a time.
Source code in src/symfonic/memory/backends/postgres_memory_erase_log.py
digest_at
async
¶
Row seq's chained digest, or None when this database lacks it.
Source code in src/symfonic/memory/backends/postgres_memory_erase_log.py
head
async
¶
The committed head (seq, digest) this connection sees.
Source code in src/symfonic/memory/backends/postgres_memory_erase_log.py
log_table
async
¶
The log beside memory_erase_generations, or refuse UNLOGGED.