cadrumo.application.modelo.reconciliation module¶
Modelo reconciliation: compare work-unit state and computed result against evidence.
modelo_reconcile accepts a modelo work unit and either an AEAT justificante
PDF or a filed declaración PDF, then produces a ModeloReconciliationReport.
For a justificante, the report records whether the work unit’s modelo, period,
ejercicio, and active-profile tax id match the receipt, AND — where the
revision declares reconciliation_total_casilla_ids and a persisted
calculation revision exists — whether the receipt’s printed total equals the
canonical computed result casilla
(aeat-calculation-aggregation). A filed-amount divergence
surfaces as a typed total diff carrying the reconciling expectation’s legal
grounding; where the total could not be reconciled (no map, no revision, no
printed total) a totals_not_reconciled advisory discloses it so an
identity-only matches is never a silent false green.
For a filed declaración, the same header comparison runs, and — for the
modelos enrolled in _DECLARATION_CASILLA_RECONCILE_MODELOS — every
casilla the registry’s verification policy reconciles is compared, one by one,
against the persisted revision’s casilla_values via
application.modelo.reconcile_casilla.detect_casilla_divergences().
A divergence surfaces as a typed casilla diff
(ModeloReconciliationDiffKind.CASILLA). A modelo not yet enrolled in
casilla-level declaration reconcile is refused with
ReconciliationDeclaracionSourceUnsupportedError rather than silently
degrading to header-only comparison.
The path-based service is local-only: it never contacts AEAT and never invokes
require_live_read — the computed result is read from the already-persisted
CalculationRevision, never a fresh calculation.
Authenticated live pulls use modelo_reconcile_bytes after storing captured
justificante bytes in secure storage.
Both paths persist their outcome twice over, in ONE unit of work: a
ModeloReconciliationRecord carrying the grounded diffs and the
advisories into the encrypted reconciliation record store selected by the
bound ModeloReconciliationPersistencePort, and a slim MODELO_RECONCILED
BucketEvent carrying the verdict and the divergence
count. The detail lives in the record because a bucket-event payload value is
capped at 500 characters and one grounded Modelo 100 casilla diff already
encodes to a median 303 — two divergences were unpersistable for 99.6% of that
modelo’s casillas, and 175 overflowed on the first. reconcile list
reports which fields diverged by reading the record store.
Core types:
RegistrySnapshot.
- class ModeloReconciliationCommand(**data)[source]¶
Bases:
BaseModelStrict input contract for
modelo_reconcile.source_pathpoints to the operator-supplied evidence file andsource_kindrecords how that file must be parsed. Justificante PDFs are supported for every modelo; declaration PDFs are supported (casilla-level) only for modelos in_DECLARATION_CASILLA_RECONCILE_MODELOS— an unenrolled modelo is refused before parsing.- Parameters:
data (Any)
- work_unit_id: WorkUnitId¶
- source_kind: ModeloReconciliationEvidenceKind¶
- source_path: Path¶
- actor: str¶
- class ModeloReconciliationBytesCommand(**data)[source]¶
Bases:
BaseModelStrict input contract for reconciling secure-storage justificante bytes.
Used by authenticated live pulls after the captured justificante has already been persisted in secure storage. The raw bytes remain in memory;
source_refis the non-file secure-storage reference recorded in the reconciliation event.- Parameters:
data (Any)
- work_unit_id: WorkUnitId¶
- source_kind: ModeloReconciliationEvidenceKind¶
- source_bytes: bytes¶
- source_ref: str¶
- actor: str¶
- class ModeloReconciliationReport(**data)[source]¶
Bases:
BaseModelOutcome of
modelo_reconcile.The verdict summarises the comparison at the work-unit level. The diff list enumerates the disagreements — header-field (modelo, period,
ejercicio, tax id), the filed justificantetotalagainst the computed result casilla where reconciled, and (for a declaración source on an enrolled modelo) each per-casilladivergence; empty onmatches. The advisory list carries non-blocking disclosures (a total or casilla set that could not be reconciled, an identity anchor that could not be verified); advisories never flip the verdict.- Parameters:
data (Any)
- work_unit_id: WorkUnitId¶
- bucket_id: BucketId¶
- source_kind: ModeloReconciliationEvidenceKind¶
- source_path: str¶
- verdict: ModeloReconciliationVerdict¶
- diffs: tuple[ModeloReconciliationDiff, ...]¶
- advisories: tuple[ModeloReconciliationAdvisory, ...]¶
- reconciled_at: datetime¶
- narrative: str¶
- exception ReconciliationEvidenceInvalidError(message=None, *, context=None, translated_message=None)[source]¶
Bases:
CadrumoErrorRaised when the supplied external evidence cannot be parsed.
Raised for malformed justificantes. The CLI surfaces it as a refusal with the canonical recovery hint; downstream consumers branch on it without string-matching the message.
- Parameters:
- Return type:
None
- code¶
- exception ReconciliationDeclaracionSourceUnsupportedError(message=None, *, context=None, translated_message=None)[source]¶
Bases:
CadrumoErrorRaised when a declaración reconcile targets a modelo not yet enrolled.
Casilla-level declaración reconciliation is enrolled one modelo at a time in
_DECLARATION_CASILLA_RECONCILE_MODELOS; a modelo outside that set refuses cleanly rather than silently degrading to a header-only compare.- Parameters:
- Return type:
None
- code¶
- modelo_reconcile(command, *, operation)[source]¶
Reconcile a modelo work unit against a justificante or declaración PDF file.
Local-only: never contacts AEAT and never invokes
require_live_read.For a justificante, compares the neutral observation returned by the bound
ReconciliationEvidenceParserPort. The receipt totals ARE reconciled against the persisted revision’s computed result where the revision declaresreconciliation_total_casilla_ids.For a declaración, consumes the parser port’s structural observation and — for modelos enrolled in
_DECLARATION_CASILLA_RECONCILE_MODELOS— compares every registry-reconciled casilla against the persisted revision’scasilla_values, surfacing each divergence as a typedcasilladiff. A modelo outside that set raisesReconciliationDeclaracionSourceUnsupportedError.Emits
MODELO_RECONCILEDinto the bucket-event-history catalogue. The verdict is included in the event payload so downstream auditors can replay the reconciliation timeline without re-parsing the evidence.- Return type:
- Returns:
- Parameters:
command (ModeloReconciliationCommand)
operation (PinnedAuthorityOperation)
- modelo_reconcile_bytes(command, *, operation)[source]¶
Reconcile secure-storage evidence bytes without materialising a plaintext file.
Declaración reconciliation is not offered on this bytes path, but not because a filed declaración’s bytes cannot exist here: the filed-history sweep (
application.live) already captures filed declaración observations, complete with per-casilla values and their own artefact bytes, into secure storage. What this command still lacks is a way to reconcile THOSE bytes: it accepts only justificante-shaped evidence a caller uploads. A pulled declaración never needs uploading in the first place — its per-casilla values are already reconciled against the taxpayer’s own local calculation byapplication.modelo.pulled_filing_reconcile.pulled_filing_divergence_findings(), which reads both sides out of the same bucket the sweep already populated. Usemodelo_reconcile()with a local declaración PDF file for casilla-level reconcile of a declaración held only on disk.- Return type:
- Returns:
The
ModeloReconciliationReportcomparing the parsed justificante metadata to the work unit and active profile.- Parameters:
command (ModeloReconciliationBytesCommand)
operation (PinnedAuthorityOperation)
- reconcile_parsed_justificante(*, work_unit, source_kind, source_ref, actor, justificante, operation)[source]¶
Reconcile parsed justificante evidence with the selected work unit.
- Return type:
- Parameters:
work_unit (WorkUnit)
source_kind (ModeloReconciliationEvidenceKind)
source_ref (str)
actor (str)
justificante (Justificante)
operation (PinnedAuthorityOperation)
- reconcile_parsed_declaracion(*, work_unit, source_kind, source_ref, actor, declaracion, operation)[source]¶
Reconcile parsed declaration evidence with the selected work unit.
- Return type:
- Parameters:
work_unit (WorkUnit)
source_kind (ModeloReconciliationEvidenceKind)
source_ref (str)
actor (str)
declaracion (ReconciliationDeclaracionObservation)
operation (PinnedAuthorityOperation)
- reconcile_receipt_totals(*, work_unit, justificante, revision, operation)[source]¶
Reconcile the receipt total against the canonical computed result casilla.
Resolves the registry snapshot for
work_unit, reads thereconciliation_total_casilla_idsmap its verification expectations declare (the same mapcalculation_result_summaryconsumes), and compares the receipt’s printed total againstrevision.casilla_values[target_casilla]at the expectation’s declared tolerance.revisionis the persisted revision the caller asserts was presented;Nonemeans no such revision exists. A divergence is a typedtotaldiff carrying the reconciling expectation’slegal_refs/source_refs. Every branch that cannot perform the comparison returns atotals_not_reconciledadvisory instead of silently passing.- Parameters:
work_unit (
WorkUnit) – The filing coordinate whose snapshot is resolved.justificante (
Justificante) – The stored receipt carrying the printed total.revision (
CalculationRevision|None) – The presentedCalculationRevision, orNonewhen none exists.operation (
PinnedAuthorityOperation) – The generation-pinned authority the snapshot is read under.
- Return type:
tuple[list[ModeloReconciliationDiff],list[ModeloReconciliationAdvisory]]- Returns:
The typed diffs and advisories the comparison produced.