cadrumo.application.user_profile.cotejo_apply module

Cotejo censal apply: adopt artefact values, record deferred divergences.

The setup flow’s phase-8 compare-select reconciliation of a Certificado de Situación Censal (procedure G313) against the profile answers commits through the one sanctioned write path here. Adopted certificate values persist as ordinary effective-dated UserProfileFact rows stamped with the non-official artefact provenance token; deferred axes persist as censo.divergencia.{n}.* divergence rows recording the unadopted certificate evidence. Exactly one CENSO_APPLIED bucket event marks the apply-commit (never one per fact). Re-running the cotejo replaces the whole divergence namespace: stale rows the fresh set does not re-declare are cleared (value=None) in the same atomic commit, mirroring the descendant count-shrink clearing pattern.

A later profile read surfaces one warning Notice while any divergence row is open, so a deferred divergence is never silently resolved; the notice rides the envelope notices channel like every other diagnostic.

CENSO_DIVERGENCE_PREFIX

Schema field family the deferred divergence rows persist under, indexed as censo.divergencia.{n}.{axis,artefact_value,source}. This is the object-field-with-indexed-subpaths shape the renta_family.descendiente family established: every indexed subpath validates against the single censo.divergencia schema field.

CENSO_DIVERGENCE_NOTICE_CODE

Notice code for the open-divergence advisory a profile read surfaces.

class CensoDivergence(**data)[source]

Bases: BaseModel

One deferred cotejo axis: a certificate value the operator did not adopt.

axis is the reviewed profile-schema path whose evidence diverged, and the operator keeps their own answer there.

artefact_value is the stringified certificate value left unadopted; source is the non-official artefact provenance token. A divergence row carries no AEAT-verified stamp — it records unadopted evidence, never an official fact.

Parameters:

data (Any)

axis: str
artefact_value: str
source: str
divergence_facts(divergences)[source]

Project deferred divergences into the indexed censo.divergencia.{n}.* facts.

Return type:

tuple[UserProfileFact, ...]

Parameters:

divergences (Sequence[CensoDivergence])

open_censo_divergences(record)[source]

Reconstruct the open divergence rows from a record’s facts.

Reads the last-value-wins projection so a cleared (value=None) row never resurfaces, groups the indexed censo.divergencia.{n}.* subpaths back into typed rows in index order, and skips any incomplete index (a missing axis or artefact value).

Parameters:

record (UserProfileRecord | None) – The UserProfileRecord whose facts are projected for open censo.divergencia.* rows, or None.

Return type:

tuple[CensoDivergence, ...]

censo_divergence_notice(record)[source]

Return the warning Notice for open cotejo divergences, or None.

A non-blocking advisory surfaced on profile reads: it never silently resolves an open divergence. Returns None when no divergence row is open so a clean profile carries no notice.

Parameters:

record (UserProfileRecord | None) – The UserProfileRecord whose open divergence rows are summarised into the notice, or None.

Return type:

Notice | None

apply_cotejo(state, *, adopted=None, divergences=None, reviewed_proposal=None, profile_decode_context)[source]

Commit a cotejo reconciliation: adopt certificate values, record divergences.

Publishes, in one revision-bound record command:

  • clearing facts (value=None) for every censo.divergencia.* path currently on record that the fresh set does not re-declare — the namespace-replace so a re-cotejo cannot leave a stale divergence standing;

  • the adopted certificate facts (each already carrying the artefact provenance token, so the registered-values suffix renders them as non-official evidence);

  • the fresh censo.divergencia.{n}.* rows for the deferred axes.

Then emits exactly one CENSO_APPLIED bucket event marking the apply-commit — never one per fact. Returns the updated WorkflowState; the caller persists it through the workflow repository like every other fact mutation.

The resulting sequence is judged by the same schema authority the registration and wizard doors use, because a certificate is authoritative about the TAXPAYER, not about this application’s fact vocabulary. AEAT certifies what the censal situation is; it does not certify that a value belongs at a path this schema declares, or that it arrives in the shape the schema types. Those are the profile’s own contract, and an official origin is not evidence about them — which is why the axis adopting certificate values must satisfy them exactly as an operator edit does. Provenance is carried separately and is not weakened by this: each adopted fact keeps its censo_artefact_g313 source token, a value the schema itself declares, so a reader can still tell a certified value from a typed one. Adopting unjudged is how a fact at an undeclared censo path was once written with no complaint.

require_complete follows the record’s own setup state rather than being asserted here. The cotejo runs DURING setup, so a profile that is still incomplete is legitimately missing the fields filing depends on, and demanding them would refuse the very reconciliation that helps supply them; a profile already past setup is held to the complete contract.

Return type:

TypeVar(StateT)

Parameters: