symfonic.services.privacy.legacy¶
legacy ¶
Lifting the shipped erasure participants into the row-20 registry.
T2.3.7's recording store already registers with
symfonic.services.shadow.privacy.PRIVACY_DELETION_PARTICIPANTS, and
SEC-PRIV-5 makes its coverage release-blocking. Asking every existing
participant to be rewritten against the new port before the new port has a
consumer would be the wrong order: the migration-window answer is an adapter,
so the registry PRIV-1 wants is the union of both contracts and no store falls
between them.
The adapter is honest about what it cannot do. The legacy contract has an erase
and a count and no export, so :meth:LegacyParticipantAdapter.export_subject
returns a fragment marked exportable=False rather than an empty one — an
empty fragment would tell an operator the store held nothing about the subject,
which is a different and much worse claim.
LegacyParticipantAdapter ¶
A TenantErasureParticipant seen through the row-20 port.
The legacy contract is keyed by tenant_id alone, so the adapter passes
the subject's tenant segment and documents the consequence: erasing a
sub-tenant through a legacy participant erases the whole tenant's rows in
that store. That is the conservative direction — over-erasure of the
caller's own subtree, never under-erasure — and it is recorded here rather
than discovered later.
Source code in src/symfonic/services/privacy/legacy.py
adapt_legacy_registry ¶
Register every legacy participant with into; return the ids added.
Takes the registry structurally (participants()) so this module does not
import the shadow package — the erasure path must not acquire a dependency
on the cutover machinery in order to sweep it.