cadrumo.domain.modelos.calculation_revision module¶
One calculation attempt under a modelo work unit.
A work unit owns many calculation revisions. Each calculate
invocation produces a fresh, content-addressed
CalculationRevision. The work unit carries pointer fields
that disambiguate which revision is the most recent (current)
and which one is the filed answer (filed). Without those
pointers, multiple drafts under the same work unit have no canonical
selection — every consumer (year-aggregation, amendment delta,
forward-period carry-forward) needs to know which one is THE
revision. Formula provenance for every computed casilla is carried
through CasillaObservation entries in the typed observations
envelope.
Lifecycle states:
BORRADOR— newly calculated; mutable in the sense that re-runningcalculatecreates a new revision rather than editing this one. Multiple borradores can coexist.VERIFICADO_COMPLETO—verifyran cleanly: all required casillas resolved, zero blocking findings, source trace persisted. The revision is immutable from this point on; any recalculation produces a fresh borrador instead.PRESENTADO— paired with aModeloRecord. The revision is the currently-effective filed answer for its (bucket, modelo, year, period) tuple. Exactly one presentado revision per tuple at any time.PRESENTADO_SUPERSEDIDO— a later verified revision was filed against the same tuple. The revision and its filing record remain in the audit trail.DESCARTADO— operator abandoned the revision before filing.
Two CalculationRevisions can never share a calculation_revision_id;
the id is the SHA-256 of the inputs + binding overrides + computed
casilla values (plus the parent work_unit_id), so structurally
identical re-runs produce the same id and re-running calculate
with the same data is naturally idempotent.
- class CalculationRevisionState(*values)[source]¶
Bases:
StrEnumClosed enumeration of calculation-revision lifecycle states.
- BORRADOR¶
- VERIFICADO_COMPLETO¶
- PRESENTADO¶
- PRESENTADO_SUPERSEDIDO¶
- DESCARTADO¶
- SEALED_REVISION_STATES: frozenset[CalculationRevisionState]¶
States in which a revision is no longer a mutable draft, because something was verified or filed.
CalculationRevisionState.BORRADORandCalculationRevisionState.DESCARTADOare excluded.CalculationRevisionState.PRESENTADO_SUPERSEDIDOIS included – a superseded filing still occurred.This is NOT the same as the narrower “currently authoritative” set, which additionally excludes
CalculationRevisionState.PRESENTADO_SUPERSEDIDO.
- CURRENT_SEALED_REVISION_STATES: frozenset[CalculationRevisionState]¶
A revision an operator-facing action may select as the CURRENT result – sealed AND not superseded.
This is
SEALED_REVISION_STATESminusCalculationRevisionState.PRESENTADO_SUPERSEDIDO. The two must never be substituted for one another: this narrower set is for surfaces that hand a revision to an operator or a third party as the current state of a filing, while the broaderSEALED_REVISION_STATESremains correct for surfaces that need every sealed revision including superseded ones.The operations replay path (
application.modelo.operation_definitions’s export operation) deliberately uses the broaderSEALED_REVISION_STATESinstead of this set, because a journalled export replay must reproduce its own history even after the revision it names has been superseded. This narrower set exists for the operator-facing surfaces that must not do that – as one of them puts it, “a superseded revision is stale and must not be handed to an accountant as current” (seeapplication.modelo.review_package).
- empty_row_source_identities()[source]¶
- Return type:
dict[TypeAliasType,RowSourceIdentity]
- empty_row_casilla_provenance()[source]¶
- Return type:
dict[TypeAliasType,DirectRowMaterializationProvenance]
- class CalculationRevisionIdentityInputs[source]¶
Bases:
TypedDictThe complete, target-id-free input set for a calculation revision hash.
-
row_source_identities:
Mapping[TypeAliasType,RowSourceIdentity]¶
-
row_casilla_provenance:
Mapping[TypeAliasType,DirectRowMaterializationProvenance]¶
-
m210_gross_income_source_mode:
M210GrossIncomeSourceMode|None¶
-
detail_rows:
Sequence[Modelo184MemberRow|Modelo232VinculadaRow|Modelo349OperadorRow|Modelo349RectificacionRow|Modelo347ContraparteRow|Modelo210AgrupacionRentaRow]¶
-
source_issues:
Sequence[CalculationSourceIssue]¶
-
source_provenance:
Sequence[CalculationSourceRef]¶
-
filing_instance_evidence:
FilingInstanceEvidence|None¶
-
m303_regimen_simplificado_annual_summary_handoff:
M303RegimenSimplificadoAnnualSummaryHandoff|None¶
-
amendment_identity:
CalculationRevisionAmendmentIdentity|None¶
-
row_source_identities:
- calculation_revision_identity_inputs(*, work_unit_id, input_values_by_casilla_id, binding_overrides, row_binding_values=None, row_source_identities=None, row_casilla_values=None, row_casilla_provenance=None, casilla_values, relation_overrides=None, source_transaction_ids=(), m210_official_tipo_renta_code=None, m210_gross_income_source_mode=None, borrador_snapshot_id=None, bindings_sourced_from_borrador=(), detail_rows=(), source_issues=(), source_provenance, filing_instance_evidence, m303_regimen_simplificado_annual_summary_handoff=None, amendment_identity=None, cleared_casilla_ids=())[source]¶
Build the one complete target-id-free calculation-revision identity input.
Every revision-id derivation flows through this builder. The annual-summary handoff is deliberately represented here, rather than selectively added by its producer or read-side verifier, so a future identity consumer cannot silently omit the cross-model calculation input.
- Return type:
- Parameters:
work_unit_id (str)
row_binding_values (Mapping[BindingId, Mapping[str, str]] | None)
row_source_identities (Mapping[RowBindingKey, RowSourceIdentity] | None)
row_casilla_provenance (Mapping[RowCasillaKey, DirectRowMaterializationProvenance] | None)
m210_official_tipo_renta_code (str | None)
m210_gross_income_source_mode (M210GrossIncomeSourceMode | None)
borrador_snapshot_id (str | None)
bindings_sourced_from_borrador (Sequence[BindingId])
detail_rows (Sequence[Modelo184MemberRow | Modelo232VinculadaRow | Modelo349OperadorRow | Modelo349RectificacionRow | Modelo347ContraparteRow | Modelo210AgrupacionRentaRow])
source_issues (Sequence[CalculationSourceIssue])
source_provenance (Sequence[CalculationSourceRef])
filing_instance_evidence (FilingInstanceEvidence | None)
m303_regimen_simplificado_annual_summary_handoff (M303RegimenSimplificadoAnnualSummaryHandoff | None)
amendment_identity (CalculationRevisionAmendmentIdentity | None)
- derive_calculation_revision_id(*, work_unit_id, input_values_by_casilla_id, binding_overrides, row_binding_values=None, row_source_identities=None, row_casilla_values=None, row_casilla_provenance=None, casilla_values, relation_overrides=None, source_transaction_ids=(), m210_official_tipo_renta_code=None, m210_gross_income_source_mode=None, borrador_snapshot_id=None, bindings_sourced_from_borrador=(), detail_rows=(), source_issues=(), source_provenance, filing_instance_evidence, m303_regimen_simplificado_annual_summary_handoff=None, amendment_identity=None, cleared_casilla_ids=())[source]¶
Return the deterministic SHA-256 id for a calculation attempt.
- Return type:
- Parameters:
work_unit_id (str)
row_binding_values (Mapping[BindingId, Mapping[str, str]] | None)
row_source_identities (Mapping[RowBindingKey, RowSourceIdentity] | None)
row_casilla_provenance (Mapping[RowCasillaKey, DirectRowMaterializationProvenance] | None)
m210_official_tipo_renta_code (str | None)
m210_gross_income_source_mode (M210GrossIncomeSourceMode | None)
borrador_snapshot_id (str | None)
bindings_sourced_from_borrador (Sequence[BindingId])
detail_rows (Sequence[Modelo184MemberRow | Modelo232VinculadaRow | Modelo349OperadorRow | Modelo349RectificacionRow | Modelo347ContraparteRow | Modelo210AgrupacionRentaRow])
source_issues (Sequence[CalculationSourceIssue])
source_provenance (Sequence[CalculationSourceRef])
filing_instance_evidence (FilingInstanceEvidence | None)
m303_regimen_simplificado_annual_summary_handoff (M303RegimenSimplificadoAnnualSummaryHandoff | None)
amendment_identity (CalculationRevisionAmendmentIdentity | None)
- class CalculationSourceRef(**data)[source]¶
Bases:
BaseModelOne resolver-level source-object trace persisted on a calculation revision.
The calculation source mesh (
cadrumo.application.aggregation) resolves each registry binding source through an enrolled resolver and produces a typedCalculationSourceProvenancerow per contributing source object. This is the DOMAIN-side, persistence-shaped projection of that provenance: it carries exactly the resolver→source-object→fingerprint trace that lets an audit reader reconstruct which resolver mesh and which upstream source objects produced a revision, and whether those objects have since drifted.It deliberately does NOT carry
legal_refs/source_refs— those are the per-casilla regulatory grounding already carried byCasillaObservationon the same revision; duplicating them here would fragment the grounding across two surfaces.source_casilla_idsis NOT grounding and the rationale above does not extend to it. It is a subject IDENTITY – which casilla(s), if any, this source object’s resolution feeds – and nothing else on the revision carries it for the general (non-row-materialized) case; dropping it here was an omission the application-sideCalculationSourceProvenancedid not itself make (it already carries the field). An empty tuple is honest when the originating resolver call site did not associate this row with a casilla — it is not fabricated as a claim of “no subject”, only carried as “not linked at resolution time”.- Variables:
resolver_id – Exact canonical resolver identity that produced this row.
resolved_binding_source – Canonical binding source owned by the resolver.
contributor_source_kind – Upstream taxonomy token for this source node.
contributor_binding_source – Canonical
BindingSourceKindwhencontributor_source_kindbelongs to the binding taxonomy;Nonefor an external or non-binding contributor.lineage_role – Whether this row is the resolver-owned primary or supporting contributor.
source_ref – Stable reference to the contributing source object (e.g.
collectible_invoice:{invoice_id}).fingerprint – Data-dependent digest of the contributing source object when the resolver produced one;
Nonewhen the resolver emits a reference without a content digest.source_casilla_ids – Casilla identities this source object’s resolution feeds, when the originating resolver associated one; empty when it did not. Carried straight from
- Parameters:
data (Any)
source_casilla_ids.- dependency_treatment: The registry’s declared dependency treatment for
this carry, empty when the revision declares none. Unlike
legal_refs/source_refsthis carries no grounding duplicated elsewhere on the revision — it is the sole persisted trace of whether a carry is afactual_evidencefact to reconcile against or adirect_annual_settlementfigure that settles the return, and an audit reader has no other way to recover that distinction after the fact. Carried here rather than gated here: the value is NOT withheld on the basis of its treatment.
- resolver_id: str¶
- resolved_binding_source: BindingSourceKind¶
- contributor_source_kind: str¶
- contributor_binding_source: BindingSourceKind | None¶
- lineage_role: CalculationSourceLineageRole¶
- source_ref: str¶
- parent_source_ref: str | None¶
- fingerprint: str | None¶
- source_casilla_ids: tuple[CasillaId, ...]¶
- dependency_treatment: str¶
- class CalculationSourceIssue(**data)[source]¶
Bases:
BaseModelOne durable unresolved source condition found while calculating a revision.
Resolver diagnostics are useful calculate-time operator feedback, but a filing-grade verification runs later against the persisted calculation revision. This narrow envelope carries a source condition that reached no binding, without misrepresenting it as source provenance for a computed output.
Two conditions qualify, and both must survive to the persisted revision because both describe a value absent from the filing.
unrouted_observationis a row no binding consumes at all.unrouted_declarable_quantityis an independent quantity that consumed rows carry and no binding drawing that quantity reaches — the row-keyed screens are silent on it by construction, so a verify or export gate that saw only the row condition would read their silence as confirmation.- Parameters:
data (Any)
- reason: Literal['unrouted_observation', 'unrouted_declarable_quantity']¶
- binding_source: BindingSourceKind¶
- message: str¶
- resolver_id: str | None¶
- source_ref: str | None¶
- class CalculationRevision(**data)[source]¶
Bases:
BaseModelOne calculation attempt attached to a work unit.
- Variables:
calculation_revision_id – Lowercase 64-char SHA-256 derived from the parent work_unit_id plus the inputs, overrides, and casilla outputs. Content-addressed: structurally identical re-runs produce the same id.
work_unit_id – Parent work unit id (also content-addressed).
registry_snapshot_ref – Complete registry coordinate selected for the parent work unit and used to materialize this revision.
state – Lifecycle state from
CalculationRevisionState.input_values_by_casilla_id – Mapping of canonical input casilla values captured at calculation time. The string values are decimal strings or short literals from the registry input contract.
binding_overrides – Mapping of operator-supplied binding overrides applied during this calculation. Empty when no binding overrides were used.
row_binding_values – Mapping of row-indexed binding values produced by source meshes for repeating export records. Kept separate from
binding_overridesso the row coordinate remains structured.row_source_identities – Opaque source identities and content fingerprints keyed by the exact binding and row coordinate. Registry row-set identities additionally retain their exact selector grouping.
relation_overrides – Mapping of relation values applied during this calculation. Kept separate from
binding_overridesso BindingId-keyed snapshots never carry RelationId keys.source_transaction_ids – Stable ledger transaction ids that contributed to this revision through bucket-local aggregation. Empty for calculations that did not consume ledger transactions.
m210_official_tipo_renta_code – The raw, official two-digit M210 tipo-de-renta code selected for this revision’s ledger projection. It remains distinct from the conceptual
tipo_rentatoken used by the formula rate path, so an audit can distinguish official codes that share one rate concept.cleared_casilla_ids – Casillas the caller explicitly withdrew a previously declared MANUAL value from. Structurally distinct from a casilla that was simply never supplied, even though both are absent from
input_values_by_casilla_id.casilla_values – Mapping of computed casilla values (decimal output). The values that would be exported to AEAT if this revision were filed.
created_at – UTC timestamp of revision creation.
updated_at – UTC timestamp of the most recent state transition. Equals
created_aton a fresh draft.verified_at – UTC timestamp at which the revision transitioned to
VERIFICADO_COMPLETO.Nonefor non-verified revisions.verified_by – Actor label captured at verification time.
Nonefor non-verified revisions.filed_at – UTC timestamp at which the revision was filed.
Nonefor non-filed revisions.filed_by – Actor label captured at filing time.
Nonefor non-filed revisions.superseded_at – UTC timestamp at which a later filed revision superseded this one.
Noneunlessstate is PRESENTADO_SUPERSEDIDO.discarded_at – UTC timestamp captured when the revision is moved to
DESCARTADO.Noneotherwise.discarded_by – Actor label captured when the revision is moved to
DESCARTADO.Noneotherwise.discard_reason – Audit reason captured when the revision is moved to
DESCARTADO.Noneotherwise.
- Parameters:
data (Any)
- calculation_revision_id: CalculationRevisionId¶
- work_unit_id: WorkUnitId¶
- registry_snapshot_ref: RegistrySnapshotRef¶
- state: CalculationRevisionState¶
- input_values_by_casilla_id: Mapping[CasillaId, str]¶
- binding_overrides: Mapping[BindingId, str]¶
- row_binding_values: Mapping[BindingId, Mapping[str, str]]¶
- row_source_identities: Mapping[RowBindingKey, RowSourceIdentity]¶
- row_casilla_values: Mapping[RowCasillaKey, Decimal]¶
- row_casilla_provenance: Mapping[RowCasillaKey, DirectRowMaterializationProvenance]¶
- relation_overrides: Mapping[RelationId, str]¶
- source_transaction_ids: tuple[CalculationRevisionId, ...]¶
- m210_official_tipo_renta_code: str | None¶
- m210_gross_income_source_mode: M210GrossIncomeSourceMode | None¶
- borrador_snapshot_id: SnapshotId | None¶
- bindings_sourced_from_borrador: tuple[BindingId, ...]¶
- cleared_casilla_ids: tuple[CasillaId, ...]¶
- casilla_values: Mapping[CasillaId, Decimal]¶
- observations: tuple[CasillaObservation, ...]¶
- unresolved_outcomes: tuple[RegistryCalculationUnresolvedOutcome, ...]¶
- ledger_filing_snapshot: LedgerFilingSnapshot | None¶
- ledger_filing_evidence: LedgerFilingEvidence | None¶
- filing_instance_evidence: FilingInstanceEvidence | None¶
- m303_regimen_simplificado_annual_summary_handoff: M303RegimenSimplificadoAnnualSummaryHandoff | None¶
- source_provenance: tuple[CalculationSourceRef, ...]¶
- source_issues: tuple[CalculationSourceIssue, ...]¶
- detail_rows: tuple[ModeloDetailRow, ...]¶
- created_at: datetime¶
- updated_at: datetime¶
- verified_at: datetime | None¶
- verified_by: ModeloActorLabel | None¶
- filed_at: datetime | None¶
- filed_by: ModeloActorLabel | None¶
- superseded_at: datetime | None¶
- discarded_at: datetime | None¶
- discarded_by: ModeloActorLabel | None¶
- discard_reason: OperatorReason | None¶
- amendment_identity: CalculationRevisionAmendmentIdentity | None¶
- amendment_reason: OperatorReason | None¶
- calculation_revision_identity_inputs_from_revision(revision)[source]¶
Project one persisted
CalculationRevisionthrough the sole hash-input builder.Read-side integrity checks and the model’s own invariant both use this function. It prevents those consumers from independently enumerating the identity fields and thereby omitting a newly added calculation input.
- Return type:
- Parameters:
revision (CalculationRevision)
- derive_calculation_revision_id_from_revision(revision)[source]¶
Derive a
CalculationRevisionid from its complete canonical input set.- Return type:
- Parameters:
revision (CalculationRevision)
- class CalculationRevisionCatalogue(**data)[source]¶
Bases:
BaseModelImmutable catalogue of every calculation revision in storage.
- Parameters:
data (Any)
- revisions: Mapping[str, CalculationRevision]¶
- get(calculation_revision_id)[source]¶
Return the revision under this id, or
Nonewhen the catalogue holds none.- Return type:
- Returns:
The
CalculationRevisionforcalculation_revision_id, orNoneif the catalogue does not carry it.- Parameters:
calculation_revision_id (CalculationRevisionId)
- values()[source]¶
Return a view of every revision in the catalogue.
- Returns:
A view over the catalogue’s
CalculationRevisionrecords.
- for_work_unit(work_unit_id)[source]¶
Return every revision attached to one work unit.
- Return type:
- Returns:
Tuple of
CalculationRevisionrecords for the given work unit.- Parameters:
work_unit_id (str)
- exception LedgerFilingCoverageError(message=None, *, context=None, translated_message=None)[source]¶
Bases:
ModeloErrorRaised when a persisted revision’s snapshot and evidence contributor sets diverge.
A ledger-derived revision bundles a
ledger_filing_snapshot(the fingerprinted contributor set) and aledger_filing_evidence(the typed fact basis). The two are projected from the samesource_transaction_idsand MUST cover the same contributors. A divergence on read-back means a contributor row was silently dropped after persistence; this gate surfaces it on load rather than letting the filing artefact ship an unexplainable casilla.- Parameters:
- Return type:
None
- code¶
- assert_revision_snapshot_evidence_coverage(revision)[source]¶
Cross-check a loaded revision’s snapshot and evidence contributor coverage.
- Parameters:
revision (
CalculationRevision) – TheCalculationRevisionloaded from persistence.- Return type:
Post-roundtrip validator (per the modelo-export-evidence-parity discipline): when both
ledger_filing_snapshotandledger_filing_evidenceare present, theirrowscontributor (transaction_id) sets MUST be equal. A revision with neither (a non-ledger or borrador revision) passes trivially. RaisesLedgerFilingCoverageErrornaming the divergent contributors.