cadrumo.adapters.persistence.storage.custody.capsule module

Immutable current-format capsule marker and one-rename publication seam.

class ProfileCustodyCapsuleSummaryWitness(capsule_path, commit, label)[source]

Bases: object

One coherent, read-only observation of a committed capsule summary.

Both records have already passed their canonical current-format and digest validation. The constructor additionally binds their identities together, so callers cannot accidentally combine a commit observation with another capsule’s label provenance.

Parameters:
capsule_path: Path
commit: ProfileCustodyCommit
label: ProfileCustodyCapsuleLabel
property profile_id: UUID

Return the UUID proven independently by both summary records.

inventory_committed_profile_custody_capsule(profile_id, *, settings=None, root=None)[source]

Return a bounded regular-file inventory without following any capsule link.

Return type:

ProfileCustodyInventory

Parameters:
write_profile_custody_deletion_marker(*, profile_id, transaction_id, inventory_digest, settings=None, root=None)[source]

Exclusively bind a prepared local deletion to its committed capsule.

Return type:

ProfileCustodyDeletionMarker

Parameters:
verify_profile_custody_deletion_tombstone(*, profile_id, transaction_id, inventory_digest, settings=None, root=None)[source]

Return only the exact transaction-owned tombstone proven safe to remove.

Return type:

Path

Parameters:
verify_profile_custody_deletion_marker(*, profile_id, transaction_id, inventory_digest, settings=None, root=None)[source]

Verify the prepared deletion marker while the capsule retains its UUID name.

Return type:

Path

Parameters:
profile_custody_deletion_path(*, profile_id, transaction_id, settings=None, root=None)[source]

Return the only transaction-owned tombstone path for one local deletion.

Return type:

Path

Parameters:
rename_profile_custody_capsule_for_deletion(*, profile_id, transaction_id, settings=None, root=None)[source]

Atomically move one committed capsule to its unique deleting tombstone.

Return type:

Path

Parameters:
remove_profile_custody_deletion_tombstone(*, profile_id, transaction_id, settings=None, root=None)[source]

Remove only a matching transaction tombstone without following links.

Return type:

None

Parameters:
publish_profile_custody_capsule(*, profile_id, transaction_id, publication_kind, password_envelope, sentinel, data_files, settings=None, root=None, published_at=None, stage_only=False, stage_initializer=None)[source]

Build a complete sibling staging capsule and optionally publish it with one rename.

stage_only is the transaction-owner seam: it leaves the exact durable, transaction-named sibling stage in place for journal verification before the sole final rename. It is not a second publication API.

Return type:

Path

Parameters:
inventory_staged_profile_custody_capsule(*, profile_id, transaction_id, settings=None, root=None)[source]

Inventory only the canonical stage owned by a create transaction.

Return type:

ProfileCustodyInventory

Parameters:
publish_staged_profile_custody_capsule(*, profile_id, transaction_id, settings=None, root=None)[source]

Perform the sole no-replace rename for an already verified stage.

Return type:

Path

Parameters:
recognize_current_profile_capsule(profile_id, *, settings=None, root=None, _trace=None)[source]

Recognize an exact UUID capsule through its marker and nothing else.

Return type:

Path | None

Parameters:
list_current_profile_custody_capsule_ids(*, settings=None, root=None)[source]

Project only UUIDs from current-marker observations.

A directory name is merely a candidate: it becomes visible only after the exact current-format commit has been opened and bound back to that UUID. Staging directories, deletion tombstones, retired buckets, links and malformed names therefore never enter the lifecycle surface. The summary inventory below consumes the same observations when label provenance is also required.

Return type:

tuple[UUID, ...]

Parameters:
list_current_profile_custody_capsule_summary_witnesses(*, settings=None, root=None)[source]

Observe each current capsule’s commit and UUID-bound label exactly once.

Discovery retains the bounded, anchored commit parse it performed instead of handing this reader a UUID that would require opening that marker again. The remaining read is only the label provenance required for the summary; no custody, recovery, session, encrypted-fact, or label-head authority is entered here.

Return type:

tuple[ProfileCustodyCapsuleSummaryWitness, ...]

Parameters:
profile_custody_staging_path(*, profile_id, transaction_id, settings=None, root=None)[source]

Return the one journal-addressable, permanently undiscoverable stage path.

Return type:

Path

Parameters:
load_committed_profile_custody_label_record(profile_id, *, settings=None, root=None)[source]

Load the provenance-authenticated label bound inside one committed capsule.

The label is staged with the capsule and becomes visible only through the same commit proof as password material. A malformed or rewritten label is never silently replaced with an inferred directory or retired-manifest value.

Return type:

ProfileCustodyCapsuleLabel

Parameters:
replace_committed_profile_custody_envelope(profile_id, payload, *, expected_sha256, settings=None, root=None)[source]

CAS-replace a committed capsule’s password envelope, preserving its DEK epoch.

The write a passphrase rotation makes. Rotation re-wraps the SAME data key under a key derived from the new password, so exactly one capsule member changes: custody/envelope.v1.json. The caller holds the custody transaction lock and supplies the digest of the envelope it authenticated.

The DEK sentinel is deliberately not touched. Its associated data binds only (profile_id, dek_epoch), so an envelope that preserves the epoch leaves the committed sentinel – and an enrolled recovery envelope minted against that epoch – valid. Rewriting the sentinel here would invalidate an operator’s recovery code for a password change that never touched the key it protects.

That is why the epoch is enforced rather than trusted. A payload carrying a different dek_epoch describes a re-key, not a rotation: it would leave a sentinel and recovery envelope silently unopenable while every surface still reported success. It is refused here, at the write boundary, so the invariant cannot be lost by a caller that forgets it.

Parameters:
  • profile_id (UUID) – The committed capsule’s profile UUID.

  • payload (bytes) – Canonical JSON bytes of the re-wrapped envelope.

  • expected_sha256 (str) – Prefixed digest of the envelope being replaced.

  • settings (Settings | None) – Optional settings override.

  • root (Path | None) – Optional storage-root override.

Raises:

ProfileCustodyRecordError – When no committed capsule is recognized, the payload is not a valid envelope for this profile, the payload changes the DEK epoch, or the compare-and-swap witness is stale.

Return type:

None

install_committed_profile_custody_recovery_envelope(profile_id, payload, *, settings=None, root=None)[source]

Install a recovery envelope into a committed capsule that has none.

The write a recovery enrollment makes. It is exclusive: an already-enrolled capsule is refused rather than overwritten, so replacing a recovery code is an explicit revoke followed by a fresh enrollment, and the caller holds the custody transaction lock across both.

The envelope must name this capsule’s profile and its CURRENT DEK epoch. The epoch is enforced at the write boundary for the same reason the rotation write enforces it: a wrapper over another epoch would report as enrolled and never open anything.

Raises:

ProfileCustodyRecordError – When no committed capsule is recognized, the payload is not a valid recovery envelope for this capsule, or recovery is already enrolled.

Return type:

None

Parameters:
remove_committed_profile_custody_recovery_envelope(profile_id, *, expected_sha256, settings=None, root=None)[source]

Compare-and-remove the recovery envelope of a committed capsule.

The write a recovery revocation makes. expected_sha256 is the digest of the envelope the caller authenticated against; a stale witness refuses rather than removing a wrapper a concurrent enrollment just installed.

Raises:

ProfileCustodyRecordError – When no committed capsule is recognized, recovery is not enrolled, or the witness is stale.

Return type:

None

Parameters:
class ProfileCustodyRecoveryMaterial(capsule_path, password_envelope, sentinel, recovery_envelope)[source]

Bases: object

The exact recovery-proof read set: password custody plus the enrolled wrapper.

Parameters:
capsule_path: Path
password_envelope: ProfileCustodyEnvelope
sentinel: ProfileCustodySentinelRecord
recovery_envelope: ProfileCustodyRecoveryEnvelope
load_committed_profile_recovery_material(profile_id, *, settings=None, root=None)[source]

Read the enrolled recovery envelope beside its committed password custody.

The password material is read first through its own authority, so a capsule whose normal custody does not verify never reaches the recovery proof. The recovery envelope must then name the same profile and DEK epoch.

Raises:

ProfileCustodyRecordError – When the capsule is not committed, recovery is not enrolled, or the envelope does not belong to this capsule.

Return type:

ProfileCustodyRecoveryMaterial

Parameters:
load_staged_profile_custody_label_record(profile_id, transaction_id, *, settings=None, root=None)[source]

Load the provenance-authenticated label from a transaction-owned stage.

Recovery consumes the same bytes that eventual publication exposes. The inventory proof prevents a journal from binding a label that differs from the staged capsule it is about to publish.

Return type:

ProfileCustodyCapsuleLabel

Parameters:
load_committed_profile_password_material(profile_id, *, settings=None, root=None)[source]

Read normal-password authority without resolving the separate recovery path.

Return type:

ProfileCustodyPasswordMaterial

Parameters: