symfonic.capabilities.human.issuance¶
issuance ¶
Where the issuance table and the retirement horizon actually live.
The redemption store decides the winner. It cannot, on its own, make a ledger authoritative: the record of which tokens exist, and the date the platform said it would stop supporting the legacy ones, has to outlive one worker's memory. Keep them in a dict and three things break the moment a second worker exists or the first one restarts — a legitimately issued, unspent token is refused as unissued so every in-flight pause becomes unresumable, the horizon one node recorded is unknown to the next, and the drain proof counts one process's rows while reading as a statement about the deployment.
Two implementations, one port. :class:InProcessIssuanceRecords is the
single-process reference and says so: deployment_wide is False, and the
ledger refuses to call a drain proof proven on top of it.
:class:BackendIssuanceRecords puts the same three tables on the operator's
persistence backend, keyed so a restart and a second worker read what the first
one wrote.
This is deliberately a wider port than :class:~.contracts.ConditionalWritePort.
Redemption gets one verb because a port that also offered a read would invite the
read-then-write race LIB-TL-2 forbids; the issuance record has no such race to
lose, and it has to be read back, so it asks for the reads openly.
BackendIssuanceRecords ¶
The same three tables on the operator's persistence backend.
Source code in src/symfonic/capabilities/human/issuance.py
InProcessIssuanceRecords ¶
Three dicts. Correct for one process, and unwilling to claim more.
Source code in src/symfonic/capabilities/human/issuance.py
IssuedToken
dataclass
¶
IssuedToken(jti: str, scope_hash: str, name: str, issued_at: float, expires_at: float, legacy_pinned: bool = False, vector_hash: str = '')
One issuance row. Ids, times, and the one bit the drain gate reads.
RetirementHorizon
dataclass
¶
SCP-FRZ-2: the date, and the operator's reason for it.
TokenConsumption
dataclass
¶
One redemption row: who won, and when. Losers are not recorded here.