aeat.application.bucket_maintenance._contracts module

Pydantic command + result records for BucketMaintenanceService.

Used by: _service to implement bucket operations.

The contract records sit at the package boundary so a programmatic caller (the CLI handler, a future MCP surface) gets the same typed input + output shape that the service consumes. Closed-value axes are typed as their core enums per the architecture-boundaries discipline. Every bucket selector is a BucketId.

class RenameBucketCommand(**data)[source]

Bases: BaseModel

Operator request to relabel a bucket.

bucket_id is the stable BucketId; only the operator-visible label moves. The service forwards the relabel to the profile-rename single-writer primitive, which holds the cross-store atomicity (encrypted record display_name and plaintext manifest label move together).

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • new_label (str)

bucket_id: BucketId
new_label: str
class RenameBucketResult(**data)[source]

Bases: BaseModel

Outcome of a successful rename.

Carries the prior label so the operator-facing emitter can render the before / after pair without re-reading the manifest. The occurred_at instant is the same instant carried by the BUCKET_RENAMED bucket event.

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • previous_label (str)

  • new_label (str)

  • occurred_at (datetime)

bucket_id: BucketId
previous_label: str
new_label: str
occurred_at: datetime
class DeleteBucketCommand(**data)[source]

Bases: BaseModel

Operator request to destructively erase a bucket.

confirmed=True is required at the service boundary so a programmatic caller observes the same guarantee the CLI --yes flag provides. The active bucket cannot be deleted; the operator must switch profiles first.

acknowledge_retention_override is the explicit legal-retention override: when a filed tax record is still inside its four-year LGT retention window (Ley 58/2003 art. 66/70) the erase is refused unless this flag is True AND retention_override_reason is a non-empty justification the audit trail records.

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • confirmed (bool)

  • acknowledge_retention_override (bool)

  • retention_override_reason (str | None)

bucket_id: BucketId
confirmed: bool
acknowledge_retention_override: bool
retention_override_reason: str | None
class DeleteBucketResult(**data)[source]

Bases: BaseModel

Outcome of a successful bucket erasure.

Carries the deleted bucket’s prior label so the operator-facing emitter can render a confirming line without re-reading anything. retention_override_used records whether a still-retained record was erased under the explicit legal-retention override, and latest_safe_erase_date names the instant the erased set would otherwise have become safe to erase (None when nothing was inside its window).

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • previous_label (str)

  • occurred_at (datetime)

  • retention_override_used (bool)

  • latest_safe_erase_date (datetime | None)

bucket_id: BucketId
previous_label: str
occurred_at: datetime
retention_override_used: bool
latest_safe_erase_date: datetime | None
class ArchiveBucketCommand(**data)[source]

Bases: BaseModel

Operator request to move a bucket into reversible dormancy.

Unlike DeleteBucketCommand, archive is a soft-only tombstone: it never removes the bucket directory, so RestoreBucketCommand can bring the same bucket back. confirmed=True mirrors delete’s boundary contract so a programmatic caller observes the same guarantee the CLI --yes flag provides. The active bucket cannot be archived; the operator must switch profiles first.

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • confirmed (bool)

bucket_id: BucketId
confirmed: bool
class ArchiveBucketResult(**data)[source]

Bases: BaseModel

Outcome of a successful bucket archive.

Carries the archived bucket’s label so the operator-facing emitter can render a confirming line without re-reading the manifest.

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • label (str)

  • occurred_at (datetime)

bucket_id: BucketId
label: str
occurred_at: datetime
class RestoreBucketCommand(**data)[source]

Bases: BaseModel

Operator request to bring an archived bucket back to active status.

Symmetric inverse of ArchiveBucketCommand. Refuses when the target bucket is not currently archived (tombstoned), so a restore never silently no-ops against an already-live bucket.

Parameters:

bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

bucket_id: BucketId
class RestoreBucketResult(**data)[source]

Bases: BaseModel

Outcome of a successful bucket restore.

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • label (str)

  • occurred_at (datetime)

bucket_id: BucketId
label: str
occurred_at: datetime
class BrowseBucketCommand(**data)[source]

Bases: BaseModel

Operator request to enumerate a bucket’s namespace inventory.

The current shape is namespace-level only: it returns each namespace and its row count without decrypting payloads. Key-level browse requires decryption and a SensitivityClass redaction policy, both deferred to a follow-up Step under the composition-pattern ADR.

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • namespace_filter (str | None)

bucket_id: BucketId
namespace_filter: str | None
class BucketNamespaceInventoryRow(**data)[source]

Bases: BaseModel

One row of the namespace-inventory browse result.

Parameters:
  • namespace (str)

  • row_count (int)

namespace: str
row_count: int
class BrowseBucketResult(**data)[source]

Bases: BaseModel

Namespace-level browse outcome.

Returns one row per namespace present in the bucket (optionally substring-filtered by namespace_filter), each carrying the stored-row count. Read-only; emits no bucket event.

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • rows (tuple[BucketNamespaceInventoryRow, ...])

bucket_id: BucketId
rows: tuple[BucketNamespaceInventoryRow, ...]
class DiskUsageBucketCommand(**data)[source]

Bases: BaseModel

Operator request to measure a bucket’s on-disk footprint.

Reads only filesystem metadata (os.stat sizes) under <aeat_local_storage_root>/buckets/<bucket_id>/; it never opens the encrypted SQLite database or decrypts a secure-object payload, so no master key or active-bucket session is required. This makes the measurement safe to run against a non-active, even archived, bucket — the same non-active-safe posture preview_discard_sandbox() already relies on for its namespace preview.

Parameters:

bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

bucket_id: BucketId
class BucketDiskUsageSubdirRow(**data)[source]

Bases: BaseModel

One on-disk subdirectory’s byte total in a disk-usage report.

subdir names one of the bucket layout’s fixed subdirectories (db, blobs, audit); the row is emitted even when the subdirectory is empty (total_bytes=0, file_count=0) so a caller can rely on exactly the layout’s three rows always being present.

Parameters:
  • subdir (str)

  • total_bytes (int)

  • file_count (int)

subdir: str
total_bytes: int
file_count: int
class DiskUsageBucketResult(**data)[source]

Bases: BaseModel

Bucket on-disk footprint outcome.

total_bytes is the sum of every regular file under the bucket’s directory tree (db + blobs + audit, plus the bucket’s own manifest file); subdirs breaks that total down per fixed subdirectory. Read-only; emits no bucket event.

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • total_bytes (int)

  • subdirs (tuple[BucketDiskUsageSubdirRow, ...])

bucket_id: BucketId
total_bytes: int
subdirs: tuple[BucketDiskUsageSubdirRow, ...]
class ExportBucketCommand(**data)[source]

Bases: BaseModel

Operator request to export a bucket as a sealed archive.

The output_path is operator-specified; the service refuses to overwrite an existing target. The recovery_wrap_passphrase field is optional: when present the service derives a recovery-passphrase KEK and emits a 3-member archive (including recovery.wrap); when absent the service uses the bucket’s active KEK and emits a 2-member archive without recovery-wrap.

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • output_path (Path)

  • recovery_wrap_passphrase (str | None)

bucket_id: BucketId
output_path: Path
recovery_wrap_passphrase: str | None
class ExportBucketResult(**data)[source]

Bases: BaseModel

Outcome of a successful bucket export.

Carries the written archive path plus the manifest digest recorded in the sealed archive header. The digest is bound into the payload’s AEAD associated data, so import refuses a tampered header at decryption; operator emitters render the path so the operator can locate the file for backup or transfer.

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • output_path (Path)

  • manifest_digest (str)

  • recovery_wrap_present (bool)

  • occurred_at (datetime)

bucket_id: BucketId
output_path: Path
manifest_digest: str
recovery_wrap_present: bool
occurred_at: datetime
class ImportBucketCommand(**data)[source]

Bases: BaseModel

Operator request to import a sealed bucket archive.

The source_path is operator-specified. The service refuses when the archive’s bucket_id collides with an existing live profile unless force_replace is True; when the source archive carries a recovery-wrap member, the operator MUST supply the matching recovery_wrap_passphrase.

Parameters:
  • source_path (Path)

  • force_replace (bool)

  • recovery_wrap_passphrase (str | None)

source_path: Path
force_replace: bool
recovery_wrap_passphrase: str | None
class ImportBucketResult(**data)[source]

Bases: BaseModel

Outcome of a successful bucket import.

Carries the imported BucketId and the manifest digest the archive header declared. The digest is evidence of the sealed archive header that authenticated the payload; it is not recomputed against the freshly provisioned host manifest because import-host lifecycle timestamps legitimately differ.

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • manifest_digest (str)

  • archive_schema_version (int)

  • occurred_at (datetime)

bucket_id: BucketId
manifest_digest: str
archive_schema_version: int
occurred_at: datetime
class InspectBucketArchiveCommand(**data)[source]

Bases: BaseModel

Operator request to inspect a sealed bucket archive without restoring it.

Read-only: the source archive is neither decrypted nor written to. This lets an operator confirm which bucket a backup file holds, when it was written, and whether it carries a recovery-wrap member, without needing the sealing key.

Parameters:

source_path (Path)

source_path: Path
class InspectBucketArchiveResult(**data)[source]

Bases: BaseModel

Outcome of a successful sealed-archive inspection.

Every field is read from the archive’s plaintext header plus the on-disk file size; the AEAD-encrypted payload itself is never opened, so this result cannot report per-store row counts. manifest_digest is the header’s integrity anchor (unverified here — verification only happens during a real import, where it is authenticated as AEAD associated data at decryption).

Parameters:
  • bucket_id (Annotated[str, StringConstraints(strip_whitespace=True, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=128, pattern=None, ascii_only=None)])

  • manifest_digest (str)

  • recovery_wrap_present (bool)

  • archive_schema_version (int)

  • created_at (datetime)

  • size_bytes (int)

bucket_id: BucketId
manifest_digest: str
recovery_wrap_present: bool
archive_schema_version: int
created_at: datetime
size_bytes: int