Contents Menu Expand Light mode Dark mode Auto light/dark, in light mode Auto light/dark, in dark mode Skip to content
Pre-alpha Breaking changes are expected. Verify Agencia Estatal de Administración Tributaria (AEAT) deadlines before filing. Updates Latest download Report an issue
CADRUMO docs
Getting started CLI reference How it works API
EN
  • English
  • Español
  • Català
  • Magyar
Cadrumo documentation - local Spanish tax preparation
  • Getting started
  • Get Cadrumo
  • Install Cadrumo
  • Quickstart
  • Connect an agent (MCP)
  • First quarterly filing
  • The income-tax year
  • The IVA year

Your profile

  • Set up a profile
  • Authenticate with AEAT
  • Maintain census facts
  • Which modelos apply to you
  • Protect data access

Your calendar

  • Filing calendar
  • AEAT notifications
  • Filing readiness

Your ledger

  • Work with transactions
  • Classify transactions
  • Classify with an LLM
  • Attach invoices and receipts
  • Manage business invoices
  • Correct mistakes
  • IVA prorrata deductions

Your filings

  • The filing workflow
  • Modelo 036 (censo)
  • Modelo 100 (Renta)
  • Modelo 130 (IRPF instalment)
  • Modelo 303 (IVA)
  • Modelo 349 (intra-community)
  • Modelo 390 (IVA summary)
  • Calculation inputs
  • Google Sheets review
  • Verify a filing
  • File at AEAT
  • Reconcile a filing

Help

  • Troubleshooting
  • Publish runtime authority
  • Disclaimer

Reference

  • CLI reference
  • Cadrumo reference
  • Glossary
  • Casilla reference
  • Legal reference

How it works

  • Overview

Project

  • Updates and downloads
  • Architecture
  • Authoring guide
  • API
    • cadrumo package
      • cadrumo.adapters package
      • cadrumo.application package
        • cadrumo.application.aeat_sync package
        • cadrumo.application.aggregation package
        • cadrumo.application.auth package
        • cadrumo.application.bienes_inversion package
        • cadrumo.application.bucket_maintenance package
        • cadrumo.application.calculations package
        • cadrumo.application.command_search package
        • cadrumo.application.corpus_search package
        • cadrumo.application.evidence package
          • cadrumo.application.evidence.bundle_text module
          • cadrumo.application.evidence.models module
          • cadrumo.application.evidence.payloads module
          • cadrumo.application.evidence.ports module
          • cadrumo.application.evidence.profile_legal_hold module
          • cadrumo.application.evidence.service module
        • cadrumo.application.export package
        • cadrumo.application.filing package
        • cadrumo.application.flows package
        • cadrumo.application.inventory package
        • cadrumo.application.invoices package
        • cadrumo.application.ledger package
        • cadrumo.application.live package
        • cadrumo.application.modelo package
        • cadrumo.application.operations package
        • cadrumo.application.operator_actions package
        • cadrumo.application.operator_output package
        • cadrumo.application.operator_surface package
        • cadrumo.application.overview package
        • cadrumo.application.prorrata_register package
        • cadrumo.application.review package
        • cadrumo.application.search package
        • cadrumo.application.storage package
        • cadrumo.application.storage_management package
        • cadrumo.application.transactions package
        • cadrumo.application.user_profile package
        • cadrumo.application.wizard package
        • cadrumo.application.workflow package
        • cadrumo.application._state_projection_readiness module
        • cadrumo.application.auth_credentials module
        • cadrumo.application.bucket_deletion_contracts module
        • cadrumo.application.bucket_event_repository module
        • cadrumo.application.cli_exception_preconditions module
        • cadrumo.application.config_reset module
        • cadrumo.application.config_reset_models module
        • cadrumo.application.config_reset_repository module
        • cadrumo.application.diagnostic_models module
        • cadrumo.application.diagnostics module
        • cadrumo.application.diagnostics_ports module
        • cadrumo.application.diagnostics_run_health module
        • cadrumo.application.diagnostics_run_health_ports module
        • cadrumo.application.diagnostics_telemetry module
        • cadrumo.application.errors module
        • cadrumo.application.exchange_rate_provider module
        • cadrumo.application.foreign_asset_thresholds module
        • cadrumo.application.journal_repository module
        • cadrumo.application.local_reader module
        • cadrumo.application.local_reader_operation module
        • cadrumo.application.persistence_errors module
        • cadrumo.application.preflight module
        • cadrumo.application.profile_deletion_hold_contract module
        • cadrumo.application.profile_preconditions module
        • cadrumo.application.provisioning module
        • cadrumo.application.provisioning_browser module
        • cadrumo.application.provisioning_contracts module
        • cadrumo.application.provisioning_fitness module
        • cadrumo.application.provisioning_host module
        • cadrumo.application.provisioning_runtime module
        • cadrumo.application.state_projection module
        • cadrumo.application.state_projection_auth module
        • cadrumo.application.state_projection_ports module
        • cadrumo.application.storage_write_policy module
        • cadrumo.application.workbench_capture_memory module
        • cadrumo.application.workbench_generation module
      • cadrumo.core package
      • cadrumo.domain package
      • cadrumo.entrypoints package
Back to top
View this page
Edit this page
Home/Python API overview/cadrumo package/cadrumo.application package/cadrumo.application.evidence package/cadrumo.application.evidence.profile_legal_hold module

cadrumo.application.evidence.profile_legal_hold module¶

Canonical legal-case owner facts for local profile-deletion holds.

This module owns legal-case snapshots. It deliberately exposes no cleared/held switch: the custody transaction can only project whether the authoritative snapshot names any open case. The user-profile facade does not re-export this mutation owner.

LEGAL_HOLD_OWNER_DIRNAME: Final[str]¶

This owner’s directory name, read from its one declaration in the taxonomy.

The storage path registry spells the same segment in this format’s grammar, so the name is declared once and read in both places rather than typed in each.

LEGAL_HOLD_SNAPSHOT_SCHEMA_VERSION: Final[int]¶

Current on-disk schema version of LegalHoldCaseSnapshot documents.

class LegalHoldCaseSnapshot(**data)[source]¶

Bases: BaseModel

Durable legal-owner fact: exactly the known open case identifiers.

Parameters:

data (Any)

schema_version: int¶
profile_id: UUID¶
open_case_ids: tuple[str, ...]¶
observed_at: datetime¶
self_digest: PrefixedContentDigest¶
property canonical_payload: dict[str, object]¶

Return this snapshot’s canonical JSON-shaped payload, digest field excluded.

property computed_self_digest: str¶

Return the digest recomputed from this snapshot’s canonical payload.

canonical_json_bytes()[source]¶

Return this snapshot serialised as canonical JSON bytes.

Return type:

bytes

classmethod from_open_cases(*, profile_id, open_case_ids, observed_at)[source]¶

Build a snapshot from the given open case identifiers, computing its digest.

Return type:

LegalHoldCaseSnapshot

Parameters:
  • profile_id (UUID)

  • open_case_ids (tuple[str, ...])

  • observed_at (datetime)

class LegalHoldCaseAuthority(*, root=None, local_record_store=None)[source]¶

Bases: object

Legal-owner mutation and projection surface, outside deletion ownership.

Parameters:
  • root (Path | None)

  • local_record_store (ProfileCustodyLocalRecordStore | None)

record_open_case_snapshot(*, profile_id, open_case_ids, observed_at)[source]¶

Persist a legal case-owner observation; outcome derives from the cases.

Return type:

LegalHoldCaseSnapshot

Parameters:
  • profile_id (UUID)

  • open_case_ids (tuple[str, ...])

  • observed_at (datetime)

project(profile_id, *, now)[source]¶

Load canonical legal facts and derive the hold without caller disposition input.

Return type:

ProfileDeletionHoldOwnerProjection

Parameters:
  • profile_id (UUID)

  • now (datetime)

path(profile_id)[source]¶

Return the on-disk path of the legal case snapshot for profile_id.

Return type:

Path

Parameters:

profile_id (UUID)

try_record_legal_hold_snapshot(*, bucket_id, open_case_ids, observed_at)[source]¶

Record one profile’s known open legal cases, and never raise doing it.

The deletion preflight cannot read a profile’s encrypted records – it runs against profiles it has not unlocked – so this plaintext snapshot is how the legal-hold position stays knowable without the key. Mirrors try_record_filing_retention_snapshot() exactly: same best-effort contract, same reason a caller that exists to do something else must never be refused over a deletion-support record.

The sole caller today is profile registration, recording () – and that empty tuple is a fact, not a shrug. Genuinely external legal holds (a court order, live litigation, an adviser instruction) are unknowable to this system and must never be defaulted to cleared; writing an empty snapshot for THAT kind of hold at registration would be manufacturing consent nobody gave. But a profile at the instant of registration has no filings, no expedientes, no records of any kind – there is structurally nothing yet for an outside hold to be a hold ON. “Zero known open cases” is therefore not an unverified assumption of clearance at registration the way it would be later; it is the same class of fact try_record_filing_retention_snapshot already records for a brand-new profile’s filing history (“no filings exist” rather than “nobody checked”).

This does NOT close the legal-hold gap for a profile’s later life. Once a profile has real filings or captured AEAT expedientes, “zero known open cases” recorded once at registration goes stale the moment either changes, and nothing today refreshes it – there is no capture-time producer for AEAT expedientes and no operator affirmation surface for a genuinely external hold. A future producer at expedientes-capture time, and an operator-affirmation surface with a freshness bound, remain open work; this function only ever asserts what is true at the instant it is called.

Swallowing is safe only while absence fails CLOSED: with no snapshot the hold assessment refuses, which blocks a deletion rather than permitting one. An empty RECORDED snapshot is a different thing from an absent one and must stay so.

Return type:

bool

Returns:

True when the snapshot was written, False when it was not. The caller is expected to ignore it; it exists so a test can assert the write happened rather than inferring it.

Parameters:
  • bucket_id (str)

  • open_case_ids (Iterable[str])

  • observed_at (datetime)

Project notices

Cadrumo is pre-alpha, local-first software. It is not tax advice, is not affiliated with the Agencia Estatal de Administración Tributaria (AEAT), and never replaces official AEAT tools or advice from a qualified professional.

Stay current

  • Critical updates
  • Latest download
  • Release notes

Get help

  • Report an issue
  • CLI reference
  • How it works

Trust and responsibility

  • Disclaimer
  • Events and deadlines
  • Repository
Next
cadrumo.application.evidence.service module
Previous
cadrumo.application.evidence.ports module
Copyright © 2026, the Cadrumo authors
Made with Sphinx and @pradyunsg's Furo
On this page
  • cadrumo.application.evidence.profile_legal_hold module
    • LEGAL_HOLD_OWNER_DIRNAME
    • LEGAL_HOLD_SNAPSHOT_SCHEMA_VERSION
    • LegalHoldCaseSnapshot
      • LegalHoldCaseSnapshot.schema_version
      • LegalHoldCaseSnapshot.profile_id
      • LegalHoldCaseSnapshot.open_case_ids
      • LegalHoldCaseSnapshot.observed_at
      • LegalHoldCaseSnapshot.self_digest
      • LegalHoldCaseSnapshot.canonical_payload
      • LegalHoldCaseSnapshot.computed_self_digest
      • LegalHoldCaseSnapshot.canonical_json_bytes()
      • LegalHoldCaseSnapshot.from_open_cases()
    • LegalHoldCaseAuthority
      • LegalHoldCaseAuthority.record_open_case_snapshot()
      • LegalHoldCaseAuthority.project()
      • LegalHoldCaseAuthority.path()
    • try_record_legal_hold_snapshot()