symfonic.memory.backends.postgres_eraser_roles¶
postgres_eraser_roles ¶
The eraser principal's role contract (CORE-199 D6).
A large forget's job is created, advanced and completed by a separate login, never by the turn runtime, the staged writer or the publisher: those read the job table only, so none of them can fence a live subtree or reopen one still being erased. This role holds exactly what the eraser's SQL needs:
memory_erase_jobs: SELECT, INSERT, DELETE, and UPDATE on the two cursor columns only, plus the phase and content cursor columns oncecore199_erase_content.sqladded them (re-runinstallafter it). It can never rewrite a job's tenant or prefix. CORE-426 adds permanent/state UPDATE after opt-in migration; its guard prevents reopening retirement.memory_erase_receipts: SELECT and INSERT; a receipt is never rewritten.memory_nodes,memory_edges,memory_workset_progress,memory_pending_claims: SELECT and DELETE. DELETE is also what lets it take the sweep's EXCLUSIVE lock. It cannot INSERT or UPDATE content.memory_erase_generations(CORE-199): SELECT, INSERT and UPDATE, since its first transaction advances the erased subtree's generation. The table's forward-only trigger, not the grant, keeps it from lowering or deleting a generation and so reopening a stale turn. The table is required (CORE-171): an eraser that could not advance it is not D6.
install runs as the table owner, after all three migrations. require_eraser
runs on the eraser's own connection at startup and refuses any drift,
missing or excess, as well as a login that could assume another role, run
DDL, bypass row security or own the tables. No SECURITY DEFINER function is
involved: every privilege is a plain, auditable grant.
EraserNotReady ¶
Bases: RuntimeError
The eraser login or its grants violate the D6 contract.
install
async
¶
Owner side, one transaction: reset eraser to exactly D6, then attest it.
Source code in src/symfonic/memory/backends/postgres_eraser_roles.py
require_eraser
async
¶
Eraser side, read-only: refuse startup unless this login holds exactly D6.