cadrumo.adapters.persistence.profile.snapshots module

Encrypted secure-object persistence for bucket-scoped snapshot payloads.

SecureSnapshotRepository is the one concrete backend behind the application-layer SnapshotRepository port. Each stored snapshot is a typed Envelope row written through SecureObjectRepository, addressed by an object key carrying the bucket id and the content-addressed snapshot id.

The repository is generic over its payload model and is driven entirely by caller-supplied data: the payload type, the namespace definition, the object-key grammar, the error types to raise, and a domain label used in diagnostics. That is what lets one implementation serve the live snapshot services, the M036 declaration lifecycle, and the M145 communication records without any of them sharing a payload shape.

It lives here, in the persistence adapter, rather than beside the port it implements: the secure-object coupling is then a same-layer adapters -> adapters.persistence.storage import instead of an application -> adapters one. This mirrors the treatment the prorrata register already receives.

Errors are injected rather than imported. A repository serving three different application packages should not depend on any one package’s error type. Taking the class as a constructor argument keeps the adapter self-contained and leaves every caller raising exactly what it raised before.

See also

application.live

Declares the SnapshotRepository port this class satisfies and the lifecycle service bases that consume it.

adapters.persistence.profile.prorrata_register

Sibling profile-local secure-object adapter whose placement this follows.

Core types: SensitivityClass.

class SecureSnapshotRepository(*, bucket_id, payload_model, namespace_definition, object_key, not_found_factory, ambiguous_prefix_factory, domain_label, input_error_cls, objects=None, enforce_payload_identity=True, classification_error_factory=None, version_error_factory=None, payload_validation_context=None)[source]

Bases: Generic

Generic secure-object snapshot repository for one runtime bucket.

The repository satisfies the SnapshotRepository structural contract used by the live snapshot services while replacing one-file-per-bucket JSONL stores with encrypted secure-object rows. Each row is a typed Envelope whose object key carries the bucket id and content-addressed snapshot id.

Parameters:
property bucket_id: str

Return the runtime bucket this repository is bound to.

exists(snapshot_id)[source]

Return whether a snapshot is stored under snapshot_id.

Return type:

bool

Parameters:

snapshot_id (str)

load(snapshot_id)[source]

Return the snapshot stored under snapshot_id.

Re-addresses the decrypted row: both its payload bucket and its snapshot id must agree with what was requested.

Return type:

TPayload

Parameters:

snapshot_id (str)

list_snapshots()[source]

Return every stored snapshot, refusing any row that is not its own.

load verifies the decrypted snapshot id against the id that was requested. Enumeration reached the same rows without that check, so a valid snapshot re-encrypted under another snapshot’s key was returned by list_snapshots/latest/resolve – and by every shared consumer built on them – while a targeted load of that key refused it. Both doors now re-address the row.

Raises:

CadrumoError – The caller-supplied input-error class, when a row’s payload bucket differs from the repository’s bucket, or when its snapshot id does not agree with the key it is stored under.

Return type:

tuple[TPayload, …]

resolve(snapshot_id)[source]

Return the one snapshot matching snapshot_id or a unique prefix.

Return type:

TPayload

Parameters:

snapshot_id (str)

save(snapshot)[source]

Persist snapshot as an encrypted secure-object row.

Return type:

None

Parameters:

snapshot (TPayload)

to_secure_object_write(snapshot)[source]

Return the secure-object upsert for snapshot without committing it.

Lets a caller commit a snapshot in the SAME unit of work as the bucket event that records it. A snapshot saved first and its event emitted afterwards can come to rest durable-but-unrecorded: the declaration survives while the history has no matching entry and no retryable marker names the gap.

Carries the identical envelope, classification and schema version save() would persist directly — both build it here, so the committed and the prepared forms cannot drift apart.

Return type:

SecureObjectWrite

Parameters:

snapshot (TPayload)

save_with_secure_object_writes(snapshot, extra_writes)[source]

Persist snapshot plus related secure objects in one unit of work.

The snapshot save and every extra write land or fail together in a single SQL transaction, so a lifecycle event co-emitted here can never drift from the snapshot it records.

Parameters:
  • snapshot (TPayload) – The snapshot payload to persist.

  • extra_writes (tuple[SecureObjectWrite, …]) – Additional SecureObjectWrite objects to commit atomically with the snapshot.

Return type:

None