aeat.domain.calculations.registry._schema module

Strict schema authority for AEAT registry definitions.

Each modelo revision carries an output_sensitivity field typed as SensitivityClass that governs the encryption tier applied to generated output envelopes.

class ProfilePredicateDefinition(**data)[source]

Bases: RegistryModel

Parameters:
  • field (str)

  • op (Literal['equals', 'not_equals'])

  • value (bool | int | str)

  • explanation (str)

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

field: str
op: Literal['equals', 'not_equals']
value: ProfileFactValue
explanation: str
legal_refs: LegalRefs
source_refs: SourceRefs
class LiveCrossReferenceDecision(**data)[source]

Bases: RegistryModel

Parameters:
  • id (CrossReferenceId)

  • evidence_tier (Literal['legal_authority', 'official_source_guidance', 'executable_parity_evidence', 'layout_authority'])

  • surface (Literal['open_simulator', 'integration_test_service', 'public_read_surface', 'authenticated_read_surface', 'authenticated_simulator', 'static_official_documentation'])

  • guard_policy_id (str)

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

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

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

  • synthetic_data_allowed (bool)

  • requires_authentication (bool)

  • requires_aeat_authorization (bool)

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • oracle_id (OracleId | None)

  • applicability_condition_mode (Literal['all', 'any'])

  • applicability_predicates (tuple[ProfilePredicateDefinition, ...])

id: CrossReferenceId
evidence_tier: EvidenceTier
surface: Literal['open_simulator', 'integration_test_service', 'public_read_surface', 'authenticated_read_surface', 'authenticated_simulator', 'static_official_documentation']
guard_policy_id: str
allowed_hosts: tuple[str, ...]
allowed_methods: tuple[str, ...]
forbidden_actions: tuple[str, ...]
synthetic_data_allowed: bool
requires_authentication: bool
requires_aeat_authorization: bool
legal_refs: LegalRefs
source_refs: SourceRefs
oracle_id: OracleId | None
applicability_condition_mode: Literal['all', 'any']
applicability_predicates: tuple[ProfilePredicateDefinition, ...]
class WorkbookParityReference(**data)[source]

Bases: RegistryModel

Parameters:
  • id (WorkbookParityRefId)

  • workbook_source (SourceRefId)

  • fixture_id (WorkbookFixtureId)

  • formula_coverage (Literal['formula_form', 'static_layout', 'record_design_layout', 'unsupported_binary_xls'])

  • runner_required (bool)

  • output_cells (Mapping[WorkbookOutputId, Annotated[str, BeforeValidator(func=~aeat.domain.calculations.registry._schema_scalars._validate_workbook_cell_ref_str, json_schema_input_type=PydanticUndefined)]])

  • tolerance (Annotated[Decimal, BeforeValidator(func=~aeat.domain.calculations.registry._schema_scalars._coerce_decimal, json_schema_input_type=PydanticUndefined)])

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

id: WorkbookParityRefId
workbook_source: SourceRefId
fixture_id: WorkbookFixtureId
formula_coverage: Literal['formula_form', 'static_layout', 'record_design_layout', 'unsupported_binary_xls']
runner_required: bool
output_cells: Mapping[WorkbookOutputId, WorkbookCellRefStr]
tolerance: DecimalValue
legal_refs: LegalRefs
source_refs: SourceRefs
class VerificationExpectationDefinition(**data)[source]

Bases: RegistryModel

Parameters:
  • id (VerificationExpectationId)

  • computed_casilla_ids (tuple[CasillaId, ...])

  • reconcile_when_present_casilla_ids (tuple[CasillaId, ...])

  • externally_grounded_casilla_ids (tuple[CasillaId, ...])

  • reconciliation_total_casilla_ids (Mapping[Literal['ingresar', 'devolver'], CasillaId])

  • tolerance (Annotated[Decimal, BeforeValidator(func=~aeat.domain.calculations.registry._schema_scalars._coerce_decimal, json_schema_input_type=PydanticUndefined)])

  • rounding (str)

  • min_coverage (Annotated[Decimal, BeforeValidator(func=~aeat.domain.calculations.registry._schema_scalars._coerce_decimal, json_schema_input_type=PydanticUndefined)])

  • discrepancy_causes (tuple[Literal['extraction_unreliable', 'unmodelled_rule', 'rounding', 'correctness_divergence'], ...])

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

id: VerificationExpectationId
computed_casilla_ids: tuple[CasillaId, ...]
reconcile_when_present_casilla_ids: tuple[CasillaId, ...]
externally_grounded_casilla_ids: tuple[CasillaId, ...]
reconciliation_total_casilla_ids: Mapping[Literal['ingresar', 'devolver'], CasillaId]
tolerance: DecimalValue
rounding: str
min_coverage: DecimalValue
discrepancy_causes: tuple[Literal['extraction_unreliable', 'unmodelled_rule', 'rounding', 'correctness_divergence'], ...]
legal_refs: LegalRefs
source_refs: SourceRefs
class ApplicationLinkDefinition(**data)[source]

Bases: RegistryModel

Parameters:
  • id (ApplicationLinkId)

  • surface (Literal['calculation', 'filing', 'review', 'verification', 'approval', 'reconciliation', 'export', 'deadline', 'portal', 'extractor', 'workflow', 'communication', 'payer_delivery'])

  • consumer (str)

  • requires_snapshot (Literal[True])

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

id: ApplicationLinkId
surface: Literal['calculation', 'filing', 'review', 'verification', 'approval', 'reconciliation', 'export', 'deadline', 'portal', 'extractor', 'workflow', 'communication', 'payer_delivery']
consumer: str
requires_snapshot: Literal[True]
legal_refs: LegalRefs
source_refs: SourceRefs
class SupportRemovalDecisionDefinition(**data)[source]

Bases: RegistryModel

Parameters:
  • id (SupportRemovalDecisionId)

  • subject_type (Literal['export_layout', 'extraction_profile', 'filing_path', 'application_link', 'live_cross_reference', 'workbook_parity_ref', 'verification_expectation', 'deadline_window', 'filing_schedule'])

  • subject_id (str)

  • decision (Literal['remove_from_filing_grade'])

  • reason (Literal['missing_legal_authority', 'missing_official_source', 'unsafe_remote_state', 'unsupported_official_format', 'out_of_scope'])

  • evidence_note (str)

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

id: SupportRemovalDecisionId
subject_type: Literal['export_layout', 'extraction_profile', 'filing_path', 'application_link', 'live_cross_reference', 'workbook_parity_ref', 'verification_expectation', 'deadline_window', 'filing_schedule']
subject_id: str
decision: Literal['remove_from_filing_grade']
reason: Literal['missing_legal_authority', 'missing_official_source', 'unsafe_remote_state', 'unsupported_official_format', 'out_of_scope']
evidence_note: str
legal_refs: LegalRefs
source_refs: SourceRefs
class ConstructDefinition(**data)[source]

Bases: RegistryModel

Parameters:
  • id (ConstructId)

  • title (str)

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • casilla_ids (tuple[CasillaId, ...])

  • formulas (tuple[FormulaId, ...])

  • parameters (tuple[ParameterId, ...])

  • bindings (tuple[BindingId, ...])

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

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

  • relations (tuple[RelationId, ...])

  • export_layouts (tuple[ExportLayoutId, ...])

  • extraction_profiles (tuple[ExtractionProfileId, ...])

  • live_cross_references (tuple[CrossReferenceId, ...])

  • workbook_parity_refs (tuple[WorkbookParityRefId, ...])

  • verification_expectations (tuple[VerificationExpectationId, ...])

  • application_links (tuple[ApplicationLinkId, ...])

  • deadline_windows (tuple[DeadlineWindowId, ...])

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

  • support_removal_decisions (tuple[SupportRemovalDecisionId, ...])

  • dependency_classifications (tuple[DependencyClassificationId, ...])

id: ConstructId
title: str
legal_refs: LegalRefs
source_refs: SourceRefs
casilla_ids: tuple[CasillaId, ...]
formulas: tuple[FormulaId, ...]
parameters: tuple[ParameterId, ...]
bindings: tuple[BindingId, ...]
algorithm_providers: tuple[str, ...]
algorithm_bindings: tuple[str, ...]
relations: tuple[RelationId, ...]
export_layouts: tuple[ExportLayoutId, ...]
extraction_profiles: tuple[ExtractionProfileId, ...]
live_cross_references: tuple[CrossReferenceId, ...]
workbook_parity_refs: tuple[WorkbookParityRefId, ...]
verification_expectations: tuple[VerificationExpectationId, ...]
deadline_windows: tuple[DeadlineWindowId, ...]
filing_schedules: tuple[str, ...]
support_removal_decisions: tuple[SupportRemovalDecisionId, ...]
dependency_classifications: tuple[DependencyClassificationId, ...]
class DependencyClassificationDefinition(**data)[source]

Bases: RegistryModel

Parameters:
  • id (DependencyClassificationId)

  • source_modelo (ModeloId)

  • treatment (Literal['direct_annual_settlement', 'factual_evidence', 'non_dependency'])

  • taxpayer_files_source (bool)

  • conditional_on_economic_activity (bool)

  • target_constructs (tuple[ConstructId, ...])

  • relation_refs (tuple[RelationId, ...])

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

id: DependencyClassificationId
source_modelo: ModeloId
treatment: Literal['direct_annual_settlement', 'factual_evidence', 'non_dependency']
taxpayer_files_source: bool

Whether the taxpayer FILES the source modelo (True) or merely SUFFERS its withholding (False).

True (default) for modelos the taxpayer is the obligor of (e.g. 130/131 pagos fraccionados the autónomo files). False for retenciones the taxpayer SUFFERS but the PAYER files (e.g. 111/115/ 123/193) - the taxpayer cannot file these, so the M100 cross-period dependency on them is not a filing the taxpayer must evidence; the clean-state gate scopes such a dependency out as not-applicable (advisory), the value coming from the income certificate (operator override or a filed source where one exists). A regulated payee/payer distinction, grounded per the AEAT M100 dictionary and LIRPF art. 99 (retenciones e ingresos a cuenta).

conditional_on_economic_activity: bool

Whether the taxpayer files the source modelo ONLY when they have economic activity.

True for pagos-fraccionados modelos an autónomo files IFF they carry on an economic activity (130 estimación directa / 131 objetiva). The clean-state gate scopes such a dependency out as not-applicable when the taxpayer has DECLARED income categories that do not include actividad económica (a salaried/rental-only filer never files 130/131). Fail- closed: when economic-activity status is undeclared the dependency stays enforced. Only meaningful together with taxpayer_files_source = true. Grounded in LIRPF art. 99 / RIRPF art. 109 (pago fraccionado of actividades económicas).

target_constructs: tuple[ConstructId, ...]
relation_refs: tuple[RelationId, ...]
legal_refs: LegalRefs
source_refs: SourceRefs
class DeadlineWindowDefinition(**data)[source]

Bases: RegistryModel

Parameters:
  • id (DeadlineWindowId)

  • filing_year (int)

  • period (Annotated[Period, BeforeValidator(func=~aeat.domain.calculations.registry._schema._parse_deadline_window_period, json_schema_input_type=PydanticUndefined)])

  • period_kind (Literal['monthly', 'quarterly', 'annual', 'ad_hoc'])

  • opens_on (date)

  • closes_on (date)

  • payment_cutoff_on (date | None)

  • applicability_condition_mode (Literal['all', 'any'])

  • applicability_conditions (tuple[ProfilePredicateDefinition, ...])

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

id: DeadlineWindowId
filing_year: int
period: Annotated[Period, BeforeValidator(_parse_deadline_window_period)]
period_kind: Literal['monthly', 'quarterly', 'annual', 'ad_hoc']
opens_on: date
closes_on: date
payment_cutoff_on: date | None
applicability_condition_mode: Literal['all', 'any']
applicability_conditions: tuple[ProfilePredicateDefinition, ...]
legal_refs: LegalRefs
source_refs: SourceRefs
class ModeloScheduleDefinition(**data)[source]

Bases: RegistryModel

Parameters:
  • id (str)

  • period_kind (Literal['monthly', 'quarterly', 'annual', 'ad_hoc'])

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

  • profile_condition_mode (Literal['all', 'any'])

  • profile_conditions (tuple[ProfilePredicateDefinition, ...])

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

id: str
period_kind: Literal['monthly', 'quarterly', 'annual', 'ad_hoc']
periods: tuple[str, ...]
profile_condition_mode: Literal['all', 'any']
profile_conditions: tuple[ProfilePredicateDefinition, ...]
legal_refs: LegalRefs
source_refs: SourceRefs
class DataBindingDefinition(**data)[source]

Bases: RegistryModel

Parameters:
id: BindingId
source: BindingSourceKind
selector: BindingSelector | Mapping[str, object]
aggregation: BindingAggregation | None
typed_enum: BindingTypedEnumKind | None

Closed-set enum class name a consumer routes the binding value through.

LIVE field (do NOT remove). Typed as the closed BindingTypedEnumKind reference (F8 — was a bare str); declared in registry TOML for the bindings that bridge a closed-membership substrate axis — "censo_event_kind" (M036), "CCAA" and "EstimacionDirectaModalidad" (M100), "LegalEntityForm" (M200) — and surfaced by the operator-facing bindings list CLI table (_modelo_discovery_cli.py), the ModeloBindingQueryRow query projection, the borrador binding resolver, and the Sheets-pull edit router. Because a StrEnum serialises to its value, those str consumers stay byte-compatible. It is the closed-set annotation on the binding, distinct from the input_channel (how a formula consumes the value); a binding may carry a typed_enum yet still be a numeric decimal channel. The loader’s raw TOML token is hydrated to its member by _coerce_typed_enum() at the boundary (an unknown token raises). Gated by test_schema_hygiene.py::test_renta_typed_binding_candidates_declare_substrate_enum_class.

legal_refs: LegalRefs
source_refs: SourceRefs
source_citations: tuple[SourceCitation, ...]
aeat_prefilled: bool
class FormulaDefinition(**data)[source]

Bases: RegistryModel

Parameters:
  • id (FormulaId)

  • target_casilla_id (CasillaId)

  • expression (FormulaExpression)

  • rounding (Annotated[RegistryRoundingCode | None, BeforeValidator(func=~aeat.domain.calculations.registry._schema_rounding._coerce_rounding_code, json_schema_input_type=PydanticUndefined)])

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_citations (tuple[SourceCitation, ...])

id: FormulaId
target_casilla_id: CasillaId
expression: FormulaExpression
rounding: RegistryRoundingCodeValue
legal_refs: LegalRefs
source_refs: SourceRefs
source_citations: tuple[SourceCitation, ...]
class VerificationPredicateDefinition(**data)[source]

Bases: RegistryModel

A cross-casilla invariant that must hold for VERIFICADO_COMPLETO to be granted.

Layer 2 of the hybrid verification strategy. Layer 1 handles single-casilla required gates via CasillaDefinition.required; this class handles multi-casilla structural invariants (e.g. if ingresos is non-zero then rendimiento neto must also be present).

expression uses a minimal predicate DSL:

  • advisory_when_positive(["casilla_id"]) — single-casilla positive advisory: FIRES (ADVISORY shown) iff the one named casilla value is strictly > 0. A zero or absent value holds trivially (no advisory). ADVISORY-only: no BLOCKING_RULE branch is implemented (a positive box is not itself an error — the advisory only prompts an operator review). Authored for the Modelo 100 anualidades por alimentos a favor de los hijos (casilla 0527), whose separate-escala treatment (LIRPF art. 64 for the state scale, art. 75 for the autonomic scale) is applied in the current cuota chain without the statutory mínimo-por-descendientes gating, so a payer declaring anualidades may be under-taxed; the advisory surfaces a non-blocking prompt to review the cuota pending the full separate-escala modelling, per no-silent-under-declaration. Routes through the generic single-casilla-list validation (exact arity 1) at registry build. See the advisory_when_positive branch in _evaluate_advisory_predicate_fires.

  • all_nonzero(["id1", "id2", ...]) — every listed casilla value must be non-zero (i.e. the filing invariant requires them all to be present and non-zero simultaneously).

  • any_nonzero(["id1", "id2", ...]) — at least one listed casilla value must be non-zero.

  • at_most_one_positive(["id1", "id2", ...]) — no more than one listed casilla may be strictly positive. Missing values read as zero. Authored for alternative result lanes such as Modelo 202 art. 40.3 claves 18/26, where the downstream formula uses both zero-default lanes but the official instruction permits only one positive lane.

  • cap_le_when_positive(["limited_id", "ceiling_id"]) — when the ceiling casilla is strictly positive, the limited casilla MUST NOT exceed the ceiling, enforcing AEAT cap rules like Modelo 131 C11 ≤ C10 and Modelo 130 C15 ≤ C14 (“en ningún caso podrá figurar… un importe superior a la cantidad positiva consignada”). Predicate holds when ceiling ≤ 0; the cap applies only when the operator’s gross liability is positive.

  • implies_nonzero(["antecedent_id", "consequent_id"]) — material implication with a strictly-positive antecedent test: predicate holds iff casilla_values[antecedent] <= 0 OR casilla_values[consequent] != 0. Authored for AEAT cuota-mínima invariants of the shape “cuando C01 sea positivo, C07 debe ser distinta de cero” (M131 EO cuota mínima, M130/M303 régimen simplificado analogues). The antecedent is strictly-positive rather than non-zero to mirror the regulatory phrasing; a casilla with a negative value does not trigger the implication. A missing consequent value evaluates to Decimal(0) and therefore violates the predicate when the antecedent is positive. Added by the dsl-conditional-predicate ADR.

  • implies_any_nonzero(["antecedent_id", "c1_id", "c2_id", ...]) — the N-consequent generalisation of implies_nonzero: predicate holds iff casilla_values[antecedent] <= 0 OR at least one listed consequent is non-zero. Authored for the Modelo 303 official-Diseño contradiction where a computed total (iva.cuota-devengada-total, iva.cuota-deducible-total) is strictly positive but every constituent official numbered box (the dr303 base/cuota tranche cells the operator transcribes to the AEAT sede) is still zero — a silent under-declaration the verify gate would otherwise grant with zero findings. ADVISORY (the official numbered boxes are an operator-entered layer the calculate path does not auto-populate, so the contradiction is surfaced as a non-blocking alert rather than a refusal). The first consequent slot onward is the constituent set; a single consequent reduces to implies_nonzero.

  • profile_field_required("profile_field_name", "applicability_filter") — profile-state-aware conditional non-zero requirement. Returns True (predicate holds) when the named applicability_filter evaluates False against the TaxpayerProfile, OR when the named profile field is present and non-empty. Returns False (predicate violated) only when the applicability filter activates AND the profile field is None / empty. A sibling of implies_nonzero per the dsl-conditional-predicate ADR — the conditional non-zero requirement is the same semantic shape, but the gating signal is profile state (e.g. fiscal_residency, ue_eee_status) rather than another casilla value. First use site: M210 representante-fiscal gate per m210-irnr-full-engine ADR §D2.5 (TRLIRNR Art 10).

  • profile_flag_enabled("profile_field_name") — profile-state advisory: predicate FIRES (ADVISORY shown) iff the named boolean TaxpayerProfile field is true. ADVISORY-only. Authored for the Modelo 130 Art. 109 activity-income coverage profile fact: the legal 70% threshold is an income-coverage/profile fact, not a ratio between retenciones amount and gross income casillas.

  • casilla_equals_implies_nonzero(["antecedent_casilla_id", "literal", "consequent_casilla_id"]) — categorical-conditional material implication: predicate FIRES (ADVISORY shown) iff the operator-entered raw text value of the named antecedent (TEXT) casilla equals the literal AND the named consequent (Decimal) casilla is zero. A missing or differing antecedent value holds trivially (no advisory), same convention as the numeric-antecedent operators. ADVISORY-only: no BLOCKING_RULE branch is implemented, mirroring the existing equals (BLOCKING-only) / advisory_when_ratio_ge (ADVISORY-only) asymmetry. Authored for the M210 IRNR inmobiliaria branch, the one no-silent-under-declaration shape implies_nonzero cannot express because its trigger is a categorical equality (tipo_renta == "inmobiliaria") rather than a numeric antecedent. See the m210-categorical-conditional-predicate ADR.

  • deduccion_requires_adquisicion_before(["amount_casilla_id", "acquisition_date_casilla_id", "construction_date_casilla_id", "cutoff_iso"]) — eligibility-conditional advisory: FIRES (ADVISORY shown) iff the named amount (Decimal) casilla is strictly positive (a deducción is claimed) AND no pre-cutoff eligibility signal is recorded, i.e. the acquisition-date TEXT casilla does NOT hold a date strictly before cutoff_iso AND the construction-date TEXT casilla is empty. A claimed amount with a pre-cutoff acquisition date, a non-empty construction date, or a zero/absent amount holds trivially (no advisory). ADVISORY-only: no BLOCKING_RULE branch is implemented, mirroring the casilla_equals_implies_nonzero / advisory_when_ratio_ge ADVISORY-only convention. Authored for the Modelo 100 deducción por inversión en vivienda habitual, whose transitional régimen (LIRPF DT 18ª) admits only dwellings acquired before 01-01-2013 (or pre-2013 construction); a post-2013 acquirer claiming the abolished deducción would silently over-declare the deducción (under-declare tax), the no-silent-under-declaration shape neither implies_nonzero (numeric antecedent) nor casilla_equals_implies_nonzero (categorical text equality) can express because its trigger is a DATE threshold.

  • casilla_equals_implies_diverges(["antecedent_casilla_id", "literal", "casilla_a_id", "casilla_b_id"]) — categorical-conditional divergence check: predicate FIRES (ADVISORY shown) iff the operator-entered raw text value of the named antecedent (TEXT) casilla equals the literal AND the two named (Decimal) casillas differ by more than one cent. A missing or differing antecedent value, or two casillas within a cent of each other, holds trivially (no advisory). Sibling of casilla_equals_implies_nonzero (that operator’s consequent test is “== 0”; this operator’s is “casilla_a != casilla_b”). ADVISORY-only: no BLOCKING_RULE branch is implemented, mirroring the casilla_equals_implies_nonzero / advisory_when_computed_diverges ADVISORY-only convention. Authored for the M131/M100 estimación-objetiva índice corrector de exceso (b.3): Orden HAC/1347/2024 Anexo II instrucción 2.3 declares the índice corrector de exceso INCOMPATIBLE with the índices correctores especiales (a.2 autotaxi, a.4 transporte de mercancías/mudanzas) for the activities that carry both — a no-silent-under-declaration shape neither implies_nonzero (numeric antecedent) nor advisory_when_computed_diverges (no categorical gate) can express because the trigger combines a categorical epígrafe equality with a Decimal-pair divergence.

Parameters:
  • predicate_id (str)

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • expression (str)

  • finding_kind (Literal['BLOCKING_RULE', 'ADVISORY'])

predicate_id: str
legal_refs: LegalRefs
expression: str
finding_kind: Literal['BLOCKING_RULE', 'ADVISORY']
class ModeloRevision(**data)[source]

Bases: RegistryModel

A single versioned form layout and calculation ruleset for one modelo.

The orden_aplicabilidad field names the legal-catalogue LegalReference id(s) of the ordenes ministeriales that approve or amend this revision’s form for its declared applicability window (e.g. ["orden-hac-277-2026:art-3"] for M100 ejercicio 2025).

The field is mandatory at validation time: every revision must cite the Ordenes that approve or amend the form for its applicability window. See the period-revision-resolution ADR, Ruling 4 / D3.

Parameters:
id: RevisionId
label: str | None
valid_from: date
valid_to: date | None
period_selector: PeriodSelector
legal_refs: LegalRefs
source_refs: SourceRefs
orden_aplicabilidad: tuple[LegalRefId, ...]
parameters: tuple[ParameterDefinition, ...]
casillas: tuple[CasillaDefinition, ...]
formulas: tuple[FormulaDefinition, ...]
bindings: tuple[DataBindingDefinition, ...]
algorithm_providers: tuple[AlgorithmProviderDefinition, ...]
algorithm_bindings: tuple[AlgorithmBindingDefinition, ...]
relations: tuple[RelationDefinition, ...]
export_layouts: tuple[ExportLayoutDefinition, ...]
extraction_profiles: tuple[ExtractionProfileDefinition, ...]
live_cross_references: tuple[LiveCrossReferenceDecision, ...]
workbook_parity_refs: tuple[WorkbookParityReference, ...]
verification_expectations: tuple[VerificationExpectationDefinition, ...]
deadline_windows: tuple[DeadlineWindowDefinition, ...]
filing_schedules: tuple[ModeloScheduleDefinition, ...]
support_removal_decisions: tuple[SupportRemovalDecisionDefinition, ...]
constructs: tuple[ConstructDefinition, ...]
dependency_classifications: tuple[DependencyClassificationDefinition, ...]
completeness_manifest: CalculationCompletenessManifest | None
verification_predicates: tuple[VerificationPredicateDefinition, ...]
continuidad_validation: Literal['advisory', 'strict']
casilla_continuidad_evolutions: tuple[CasillaContinuidadEvolutionDefinition, ...]
class ModeloDefinition(**data)[source]

Bases: RegistryModel

Parameters:
  • id (ModeloId)

  • title (str)

  • official_name (str)

  • tax_domain (Annotated[TaxDomain, BeforeValidator(func=~aeat.domain.calculations.registry._schema.<lambda>, json_schema_input_type=PydanticUndefined)])

  • cadence (Literal['monthly', 'quarterly', 'annual', 'ad_hoc', 'profile_based'])

  • jurisdiction (Literal['ES-AEAT'])

  • calculation_class (Literal['filing', 'informative', 'summary'])

  • output_sensitivity (Annotated[SensitivityClass, BeforeValidator(func=~aeat.domain.calculations.registry._schema_base._coerce_sensitivity_class, json_schema_input_type=PydanticUndefined)])

  • capabilities (Annotated[frozenset[Literal['borrador', 'renta_ledger_default']], ~pydantic.functional_validators.BeforeValidator(func=frozenset, json_schema_input_type=PydanticUndefined)])

  • legal_refs (Annotated[tuple[LegalRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • source_refs (Annotated[tuple[SourceRefId, ...], FieldInfo(annotation=NoneType, required=True, metadata=[MinLen(min_length=1)])])

  • revisions (Mapping[RevisionId, ModeloRevision])

id: ModeloId
title: str
official_name: str
tax_domain: Annotated[TaxDomain, BeforeValidator(lambda v: TaxDomain(v) if isinstance(v, str) else v)]
cadence: Literal['monthly', 'quarterly', 'annual', 'ad_hoc', 'profile_based']
jurisdiction: Literal['ES-AEAT']
calculation_class: CalculationClass
output_sensitivity: SensitivityClassField
capabilities: Annotated[frozenset[ModeloFilingCapability], BeforeValidator(frozenset)]
legal_refs: LegalRefs
source_refs: SourceRefs
revisions: Mapping[RevisionId, ModeloRevision]
has_capability(name)[source]

Return whether this modelo declares the given capability.

Return type:

bool

Parameters:

name (Literal['borrador', 'renta_ledger_default'])

class RegistryCatalogues(**data)[source]

Bases: RegistryModel

Parameters:
legal: Mapping[LegalRefId, LegalReference]
sources: Mapping[SourceRefId, SourceReference]
parameters: Mapping[str, LegalParameter]
convenio: ConvenioAuthority
class RegistryVerificationPolicy(expectation_ids, computed_casilla_ids, reconcile_when_present_casilla_ids, externally_grounded_casilla_ids, tolerance, min_coverage)[source]

Bases: object

Folded verification policy across a snapshot’s verification expectations.

Owns the registry-grounded projection (union of computed casilla ids, the union of reconcile-when-present casilla ids, the strictest tolerance, the strictest coverage floor) so the application verification surface consumes it rather than re-deriving the fold.

computed_casilla_ids are the coverage-gated reconciliation targets: a filing that fails to reconcile them below min_coverage is NEEDS_REVIEW. reconcile_when_present_casilla_ids are value-reconciled when the filing prints them (a filed-vs-computed divergence surfaces a discrepancy) but are excluded from the coverage denominator, so enrolling a situational casilla can never lower coverage and flip a legitimate filing’s verdict.

externally_grounded_casilla_ids is the third, orthogonal axis: of the casillas a filing reconciles (computed_casilla_ids or reconcile_when_present_casilla_ids), which have an AEAT-authoritative independent oracle expected value backing their reconciliation, rather than only the app’s own engine.

Parameters:
  • expectation_ids (tuple[VerificationExpectationId, ...])

  • computed_casilla_ids (frozenset[CasillaId])

  • reconcile_when_present_casilla_ids (frozenset[CasillaId])

  • externally_grounded_casilla_ids (frozenset[CasillaId])

  • tolerance (Decimal)

  • min_coverage (Decimal)

expectation_ids: tuple[TypeAliasType, ...]
computed_casilla_ids: frozenset[TypeAliasType]
reconcile_when_present_casilla_ids: frozenset[TypeAliasType]
externally_grounded_casilla_ids: frozenset[TypeAliasType]
tolerance: Decimal
min_coverage: Decimal
class RegistrySnapshot(**data)[source]

Bases: RegistryModel

Parameters:
modelo: ModeloDefinition
revision: ModeloRevision
filing_period: Period | None
filing_year: int
period: str
legal: Mapping[LegalRefId, LegalReference]
sources: Mapping[SourceRefId, SourceReference]
extraction_profiles: Mapping[ExtractionProfileId, ExtractionProfileDefinition]
live_cross_references: Mapping[CrossReferenceId, LiveCrossReferenceDecision]
workbook_parity_refs: Mapping[WorkbookParityRefId, WorkbookParityReference]
verification_expectations: Mapping[VerificationExpectationId, VerificationExpectationDefinition]
deadline_windows: Mapping[DeadlineWindowId, DeadlineWindowDefinition]
filing_schedules: Mapping[str, ModeloScheduleDefinition]
support_removal_decisions: Mapping[SupportRemovalDecisionId, SupportRemovalDecisionDefinition]
constructs: Mapping[ConstructId, ConstructDefinition]
dependency_classifications: Mapping[DependencyClassificationId, DependencyClassificationDefinition]
convenio: ConvenioAuthority
verification_policy()[source]

Fold this snapshot’s verification expectations into one policy.

Returns the registry-grounded RegistryVerificationPolicy (union of computed casilla ids, strictest tolerance, strictest coverage floor).

Raises:

RegistryValidationError – When the snapshot declares no verification expectations.

Return type:

RegistryVerificationPolicy

filing_period_from_scope(filing_year, period)[source]

Return a core Period when the registry token is a real filing-period code.

Return type:

Period | None

Parameters:
  • filing_year (int)

  • period (str)