cadrumo.domain.user_profile.portable_export module

Portable-export bundle for cross-bucket user-profile transfer.

This module is isolated from domain.user_profile.values so the four heavy domain types it composes (CalculationRevision, WorkUnit, Transaction, ModeloRecord) and their transitive registry-parse cost do not enter sys.modules at user-profile package init. The UserProfileRecord is included via the profile field of UserProfilePortableExport. This module is the canonical definition site; the package initializer is inert and provides no alternate import path.

class CarriedSecureObject(**data)[source]

Bases: BaseModel

One decrypted secure-object row carried by a v3 bundle.

A bundle addresses each carried row by its natural object key (the store-derived identifier), never by the stored HMAC lookup digest: the digest is keyed by the per-bucket data-encryption key, so a source-bucket digest is unreadable in the recipient bucket (proven by the custody roundtrip tests). On import the carried payload is re-saved through the owning store’s save path, which re-derives the natural key under the recipient DEK and re-encrypts. The natural object_key is carried for coverage auditing and for the bespoke stores that re-save through the raw secure-object substrate.

payload_b64 is the canonical adapter-serialised form: for typed stores it is the Envelope JSON bytes the store persists, and for the attachment-blob store it is the raw decrypted blob bytes (which are not JSON). The owning store adapter is the sole interpreter of these bytes. classification carries the row’s SensitivityClass so import replays the same namespace sensitivity contract.

Parameters:

data (Any)

namespace: str
object_key: str
classification: SensitivityClass
schema_version: int
written_at: UtcInstant
payload_b64: str
property payload: bytes

Return the decrypted payload bytes carried by the bundle.

class CoverageManifest(**data)[source]

Bases: BaseModel

Namespace coverage declared by a portable-export bundle.

Parameters:

data (Any)

custody_profile: Literal['structured', 'full']
carried_namespaces: tuple[str, ...]
excluded_namespaces: tuple[str, ...]
row_counts_by_namespace: Mapping[str, int]
class UserProfilePortableExport(**data)[source]

Bases: BaseModel

User-directed portable profile export payload.

bundle_schema_version gates forward-compatible import: callers that read an export bundle compare this integer to their supported range before attempting to parse profile. Increment it when the serialised shape changes in a backward-incompatible way.

Which versions are accepted is the bundle lineage’s decision, not this model’s, so it is not restated here. This is the version-3 SHAPE: it carries profile plus the financial-history fields work_units, ledger_transactions, calculation_revisions, and filing_records. It also declares the v3 generic secure-object carry surface and coverage manifest; those fields default empty until the transport-aware serialise/deserialise phases populate them.

Encrypted-material blobs are NOT included: the export strips encrypted material and re-encrypts it under the recipient bucket’s DEK on import.

Parameters:

data (Any)

bundle_schema_version: int
exported_at: UtcInstant
profile: UserProfileRecord
work_units: tuple[_WorkUnit, ...]
ledger_transactions: tuple[_Transaction, ...]
calculation_revisions: tuple[_CalculationRevision, ...]
filing_records: tuple[_ModeloRecord, ...]
carried_objects: tuple[CarriedSecureObject, ...]
coverage_manifest: CoverageManifest