cadrumo.adapters.persistence.storage.custody.capsule_records module

Canonical current-format capsule marker and label records.

class ProfileCustodyCapsuleLabel(**data)[source]

Bases: _ProfileCustodyCapsuleLabelPayload

UUID-bound, revisioned canonical label provenance in capsule data.

The label remains separately readable while a profile is locked, but is never a loose presentation string: its strict canonical record binds it to one capsule UUID and carries both content and self-authentication digests.

Parameters:

data (Any)

content_digest: PrefixedContentDigest
self_digest: str
property content_payload: dict[str, object]

Return the fields content_digest itself commits to.

This is the NARROWER of the label’s two digest scopes: content only, excluding both digest fields. It exists separately from self_payload because the label carries two independently checkable claims — “this content is what it says it is” and “this whole record, digests included, has not been altered” — and each needs its own excluded-field view to stay self-consistent.

property self_payload: dict[str, object]

Return the fields self_digest itself commits to.

The WIDER of the two scopes: everything except self_digest, including content_digest. Chaining self_digest over content_digest is what lets a caller detect a content_digest swapped onto a label it was never computed for, not just a tampered label field.

property computed_content_digest: str

Recompute the digest a tamper check compares against content_digest.

property computed_self_digest: str

Recompute the digest a tamper check compares against self_digest.

canonical_json_bytes()[source]

Serialise to the exact canonical bytes this label’s identity is pinned to.

Return type:

bytes

classmethod create(*, profile_id, label, label_revision=1, previous_label_digest=None)[source]

Build the one valid construction path: content digest, then self digest, then re-validate.

The two digests are computed in sequence — content_digest first, then self_digest over the payload WITH that content digest already attached — so the chained relationship the validators check is the same order construction actually performs, never assembled out of order.

Return type:

ProfileCustodyCapsuleLabel

Parameters:
  • profile_id (UUID)

  • label (str)

  • label_revision (int)

  • previous_label_digest (str | None)

class ProfileCustodyCommit(**data)[source]

Bases: _ProfileCustodyCommitPayload, CustodyDigestModel

Minimal immutable marker that is the sole current-format discovery proof.

Parameters:

data (Any)

self_digest: str
classmethod create(*, profile_id, transaction_id, publication_kind, published_at=None)[source]

Build the one valid construction path, stamping the publication instant and digest together.

published_at defaults to now rather than being left for a caller to supply separately, so the commit instant and the digest computed over it can never be set by two different code paths that drift.

Return type:

ProfileCustodyCommit

Parameters:
  • profile_id (UUID)

  • transaction_id (UUID)

  • publication_kind (Literal[ProfilePublicationKind.ENROLL, ProfilePublicationKind.RESTORE])

  • published_at (datetime | None)

class ProfileCustodyDeletionMarker(**data)[source]

Bases: CustodyDigestModel

Transaction ownership proof carried with a capsule during local deletion.

Parameters:

data (Any)

schema_version: Literal[1]
owner: Literal['application-local-custody']
profile_id: UUID
transaction_id: UUID
inventory_digest: str
self_digest: str
classmethod create(*, profile_id, transaction_id, inventory_digest)[source]

Build the one valid construction path for a deletion ownership proof.

inventory_digest is supplied by the caller rather than derived here, because it commits to the capsule INVENTORY state at deletion time — a fact this marker records, not one it can compute from its own fields.

Return type:

ProfileCustodyDeletionMarker

Parameters:
  • profile_id (UUID)

  • transaction_id (UUID)

  • inventory_digest (str)

parse_profile_custody_commit(value)[source]

Parse only one bounded canonical commit marker.

Return type:

ProfileCustodyCommit

Parameters:

value (bytes)

parse_profile_custody_capsule_label(value)[source]

Parse exactly one bounded, UUID-bound canonical label provenance record.

Return type:

ProfileCustodyCapsuleLabel

Parameters:

value (bytes)

class ProfileCustodyPasswordMaterial(capsule_path, commit, envelope, sentinel, access_trace)[source]

Bases: object

The exact normal-password read set, intentionally excluding recovery material.

Parameters:
capsule_path: Path
commit: ProfileCustodyCommit
envelope: ProfileCustodyEnvelope
sentinel: ProfileCustodySentinelRecord
access_trace: tuple[ProfileCustodyPasswordReadOperation, ...]
parse_profile_custody_deletion_marker(value)[source]

Parse a deletion marker and reject one whose stored bytes are not its own canonical form.

The byte-identity check (not just the digest check the model validator already runs) catches a marker re-encoded differently from how ProfileCustodyDeletionMarker.create() would have produced it — the same non-canonical-bytes hazard parse_profile_custody_commit() guards against for commits.

Return type:

ProfileCustodyDeletionMarker

Parameters:

value (bytes)