symfonic.services.switching.envelope¶
envelope ¶
ENV / CUT-PIN — the authenticated pin envelope for checkpoints and tokens.
One envelope shape wraps both durable artifact families, because both can outlive the process that wrote them and both must answer "which generation produced this?" before anything reads their payload. Verification happens before any field is used — including the version fields a reader would like to dispatch on — so a forged envelope cannot steer its own decoding.
EnvelopeSigner ¶
EnvelopeSigner(keyset: Keyset, *, producer_package_version: str, clock: Callable[[], float] = time.time)
Mints and verifies pin envelopes against a keyset (ENV-2, ENV-6, KEY-5).
Source code in src/symfonic/services/switching/envelope.py
mint ¶
mint(*, pin: InvocationPin, payload: bytes, schema_id: str, envelope_version: int = 2) -> PinEnvelope
ENV-6 — refuse to mint when the active key is unavailable.
Source code in src/symfonic/services/switching/envelope.py
verify ¶
verify(envelope: PinEnvelope | None, *, pinless_policy: PinlessArtifactPolicy | None = None, schema_id: str = '') -> InvocationPin
Verify first, then dispatch on version. Never the other way round.
Source code in src/symfonic/services/switching/envelope.py
PinEnvelope
dataclass
¶
PinEnvelope(envelope_version: int, generation_vector_hash: str, schema_id: str, producer_package_version: str, created_at: float, key_id: str, pin: InvocationPin, payload: bytes, signature: str = '')
ENV-1 — the authenticated wrapper around an opaque payload.
describe ¶
A diagnostic line: ids and hashes only (SEC-CRED-2, KEY-6).
Source code in src/symfonic/services/switching/envelope.py
signing_input ¶
Every envelope field plus the payload — ENV-2 covers both.
Source code in src/symfonic/services/switching/envelope.py
PinlessArtifactPolicy
dataclass
¶
PinlessArtifactPolicy(accept: bool = False, attributed_vector_hash: str | None = None, reason: str = '')
CUT-PIN-1/2 — what happens to an artifact that carries no pin.
The default is refusal. Accepting one requires naming, at construction, the vector it should be attributed to and why — because the alternative is a baked-in default binding, which is the thing CUT-PIN-1 exists to forbid.