cadrumo.domain.calculations.registry.binding_temporal module

Relative temporal, applicability, and authorship members for binding declarations.

Three closed unions live here, each replacing a set of loosely coupled optional fields whose legal combinations were previously enforced by mutual-exclusion validators rather than by the type.

BindingTemporalSelector is the provider-agnostic lift of the previous-filing period grammar: the six field combinations that grammar actually admitted become six named members, so a combination it refused is now unspellable rather than merely rejected. Every member is relative to the target filing context. No member carries an absolute year or a revision identifier, which is the point: a declaration states timeless intent, and the concrete source coordinate is derived at resolve time from the target context.

BindingApplicability states which revision contexts a binding applies to, including the explicit non-calculation disposition that keeps an export-only binding from reading as an unreferenced declaration.

BindingAuthorship distinguishes a hand-authored row from a generated one and, for the generated case, requires the generator identity and run digest that make the row reproducible.

class BindingTemporalKind(*values)[source]

Bases: StrEnum

Discriminator tokens for the closed temporal-selector union.

SAME_TARGET_CONTEXT
SAME_FILING_YEAR_PERIODS
FILING_YEAR_OFFSET
FILING_YEAR_OFFSET_BY_TARGET_PERIOD
TARGET_PERIOD_OFFSET
PRIOR_QUARTER_EXPANDING_SPAN
FILED_CURRENT_PERIOD
class SameTargetContext(**data)[source]

Bases: RegistryModel

The source shares the target’s filing year and period exactly.

The default for providers with no cross-period coordinate at all: ledger aggregations, profile fields, operator input, and design constants.

Parameters:

kind (Literal[BindingTemporalKind.SAME_TARGET_CONTEXT])

kind: Literal[BindingTemporalKind.SAME_TARGET_CONTEXT]
class SameFilingYearPeriods(**data)[source]

Bases: RegistryModel

Named periods of the target’s own filing year.

Parameters:

data (Any)

kind: Literal[BindingTemporalKind.SAME_FILING_YEAR_PERIODS]
source_periods: _SourcePeriods
class FilingYearOffset(**data)[source]

Bases: RegistryModel

Named periods of a filing year a fixed, non-zero number of years away.

max_years bounds how far the resolver may reach when the offset is applied repeatedly (the bounded carry-forward case); it is an absolute bound, so it is never negative.

Parameters:

data (Any)

kind: Literal[BindingTemporalKind.FILING_YEAR_OFFSET]
years: int
source_periods: _SourcePeriods
max_years: int | None
class FilingYearOffsetByTargetPeriod(**data)[source]

Bases: RegistryModel

Named periods of a filing year whose distance depends on the target period.

The uniform FilingYearOffset states one distance for every target period. Some instalment regimes cannot: modelo 202’s modalidad 40.2 bases each pago fraccionado on the last período impositivo whose declaration deadline has already elapsed, and that is two filing years back for the April instalment and one year back for the October and December ones, because the source modelo 200’s July deadline falls between them.

The distance is therefore declared per target period rather than once. offsets is total over the target periods this member covers: a target period the mapping does not name produces NO anchor at all, which is a scope-out, not a fallback onto a neighbouring year. An offset chain that reached for an adjacent year whenever the declared one was absent would silently substitute a filing whose deadline had not elapsed, which is precisely the condition the law keys on.

Parameters:

data (Any)

kind: Literal[BindingTemporalKind.FILING_YEAR_OFFSET_BY_TARGET_PERIOD]
offsets: Annotated[Mapping[RegistrySelectorPeriodCode, int], FROZEN_MAPPING]
source_periods: _SourcePeriods
class TargetPeriodOffset(**data)[source]

Bases: RegistryModel

The period a fixed, non-zero number of periods from the target period.

within_filing_year confines the offset to the target’s own filing year: the modelo 130/131 carry-forward pattern offsets one period back but must not reach across the year boundary, so a 1T target resolves to no source anchor at all. That emptiness is a scope-out, not a missing observation, and it is declared here rather than inferred, because an offset that silently crossed into the prior year would carry a foreign year’s quota forward.

Parameters:

data (Any)

kind: Literal[BindingTemporalKind.TARGET_PERIOD_OFFSET]
periods: int
within_filing_year: bool
class PriorQuarterExpandingSpan(**data)[source]

Bases: RegistryModel

Every quarter of the target’s filing year preceding the target quarter.

The span expands with the target quarter rather than naming a fixed period set, which is why it carries no period fields and is mutually exclusive with every axis that does.

Parameters:

data (Any)

kind: Literal[BindingTemporalKind.PRIOR_QUARTER_EXPANDING_SPAN]
class FiledCurrentPeriod(**data)[source]

Bases: RegistryModel

One literal already-filed period of the target’s own filing year.

Parameters:
  • kind (Literal[BindingTemporalKind.FILED_CURRENT_PERIOD])

  • source_period (Annotated[str, BeforeValidator(func=~cadrumo.core.period._validate_registry_selector_period, json_schema_input_type=PydanticUndefined)])

kind: Literal[BindingTemporalKind.FILED_CURRENT_PERIOD]
source_period: RegistrySelectorPeriodCode
temporal_max_year_delta(temporal)[source]

Return the absolute bound on anchor year deltas the member declares.

None means unbounded. FilingYearOffset carries the bound explicitly; a period offset confined to the filing year is the bound 0. FilingYearOffsetByTargetPeriod is deliberately unbounded: its offsets ARE the declaration, and filtering them through a second bound would silently drop the farther of two authored distances.

Return type:

int | None

Parameters:

temporal (Annotated[SameTargetContext | SameFilingYearPeriods | FilingYearOffset | FilingYearOffsetByTargetPeriod | TargetPeriodOffset | PriorQuarterExpandingSpan | FiledCurrentPeriod, FieldInfo(annotation=NoneType, required=True, discriminator='kind')])

temporal_period_anchors(temporal, *, target_period)[source]

Return the (year_delta, source_period) anchors a member names for a target.

The single derivation every provider carrying a temporal member resolves through, so a member added to the union reaches the previous-filing and relation-prefill folds at once instead of being interpreted twice. The result is already bounded by temporal_max_year_delta(); an empty tuple means the member names no source window for this target period, which is a scope-out the caller must preserve rather than fill.

Parameters:
Return type:

tuple[tuple[int, str], ...]

Returns:

Anchors in declaration order, each a year delta relative to the target filing year paired with the source period token.

class BindingApplicabilityKind(*values)[source]

Bases: StrEnum

Discriminator tokens for the closed applicability union.

ALL_REVISION_CONTEXTS
TARGET_PERIODS
NON_CALCULATION
class AllRevisionContexts(**data)[source]

Bases: RegistryModel

The binding applies in every filing context its revision covers.

Parameters:

kind (Literal[BindingApplicabilityKind.ALL_REVISION_CONTEXTS])

kind: Literal[BindingApplicabilityKind.ALL_REVISION_CONTEXTS]
class TargetPeriods(**data)[source]

Bases: RegistryModel

The binding applies only when the target period is one of these.

Parameters:

data (Any)

kind: Literal[BindingApplicabilityKind.TARGET_PERIODS]
periods: _SourcePeriods
NonCalculationReason

The classes of declaration that legitimately have no typed calculation consumer.

Each member is a class the authored corpus actually contains, not a speculative slot:

informational_total

A total the official design reports for information only. Modelo 303’s criterio-de-caja entregas and adquisiciones totals are this: the printed casillas left the form, and the total is still declared and handed off.

profile_input

A taxpayer-profile fact declared as a binding for a downstream consumer rather than for a casilla of its own revision.

rate_band_reserved

A rate-band declaration kept for a band the revision’s form does not print, so the band stays declarable without claiming a box.

application_calculation_handoff

A value an application-layer calculation reads directly, rather than a formula or casilla of the revision.

alias of Literal[‘informational_total’, ‘profile_input’, ‘rate_band_reserved’, ‘application_calculation_handoff’]

class NonCalculation(**data)[source]

Bases: RegistryModel

The binding is not consumed by calculation, and that is declared intent.

An export-only binding has no typed calculation consumer, which is indistinguishable from an orphaned declaration unless the author says so. This member is that statement, so the compiler can refuse every other unreferenced binding instead of tolerating all of them.

The statement is not a bare flag: reason classes WHY the row has no calculation consumer, and consumed_by names WHAT does read it. A disposition that named neither would be indistinguishable from an author silencing an orphan, which is the failure this member exists to prevent – hence the refusal of a blank consumed_by. box_retired_in records the revision from which the printed casilla is absent, so a retired box is traceable to the edition that retired it rather than inferred from the casilla’s absence.

Parameters:

data (Any)

kind: Literal[BindingApplicabilityKind.NON_CALCULATION]
reason: NonCalculationReason
box_retired_in: RevisionId | None
consumed_by: Annotated[str, Field(min_length=1, max_length=300)]
binding_applies_to_period(applicability, period)[source]

Return whether a binding’s applicability admits one target period.

A non_calculation binding admits none: it is declared as having no typed calculation consumer, so admitting it into a calculation scan would reintroduce exactly the ambiguity the member exists to remove. period of None means “every context this revision covers”, which only the period-scoped member narrows.

Return type:

bool

Parameters:
class BindingAuthorshipKind(*values)[source]

Bases: StrEnum

Discriminator tokens for the closed authorship union.

AUTHORED
GENERATED
class AuthoredBinding(**data)[source]

Bases: RegistryModel

The row was written by hand and is owned by its author.

Parameters:

kind (Literal[BindingAuthorshipKind.AUTHORED])

kind: Literal[BindingAuthorshipKind.AUTHORED]
class GeneratedBinding(**data)[source]

Bases: RegistryModel

The row was emitted by a named generator run and is reproducible from it.

Parameters:

data (Any)

kind: Literal[BindingAuthorshipKind.GENERATED]
generator_id: _GeneratorToken
run_digest: _GeneratorToken