Refuse silent mixed-version migration and old-reader rollback.
The installer/operator must drain and upgrade every graph/vector reader
and Working writer before resuming. Old readers can revive expired content;
old Working writers omit expiry registration. A compatible forward repair
is the only admitted rollback policy against TTL-bearing tables. Credential
rotation and fleet fencing remain the operator's release responsibility.
The Python value is an explicit declaration, not evidence of these actions.
Source code in src/symfonic/memory/backends/postgres_working_expiry_fleet.py
| def require_expiry_fleet_attestation(guard, attestation):
"""Refuse silent mixed-version migration and old-reader rollback.
The installer/operator must drain and upgrade every graph/vector reader
and Working writer before resuming. Old readers can revive expired content;
old Working writers omit expiry registration. A compatible forward repair
is the only admitted rollback policy against TTL-bearing tables. Credential
rotation and fleet fencing remain the operator's release responsibility.
The Python value is an explicit declaration, not evidence of these actions.
"""
if type(attestation) is not WorkingExpiryFleetAttestation or (
attestation.schema != guard.schema
or attestation.working_host_role != guard.working_host_role
or attestation.drained is not True
or attestation.readers_upgraded is not True
or attestation.working_writers_upgraded is not True
or attestation.rollback_policy != 'forward_only'
or type(attestation.evidence_ref) is not str or not attestation.evidence_ref.strip()
):
raise RuntimeError('Working expiry requires explicit drained upgraded fleet attestation')
|