Skip to content

ccnl_engine.catalog

What the engine covers before any run: the bundled contracts and their discovery, ruleset identity and readiness, the capability catalog. See Find a CCNL and its level.

Contracts and rulesets

Before any run, engine.list_contracts() returns one ContractSummary (ccnl_id, name, cnel_code, readiness, validity) per bundled CCNL and engine.inspect_ruleset(ccnl_id) returns the RulesetAssurance of one CCNL, by slug or CNEL code: the same value the run reports in result.rulesets.

engine = PayrollEngine.bundled(mode="operational")
ruleset = engine.inspect_ruleset("commercio-confcommercio")
if not ruleset.is_production:
    print(ruleset.readiness, ruleset.confidence)  # the run of this CCNL is blocked
RulesetAssurance field Meaning
identity RulesetIdentity: id, version, validity, source and source_hash
kind RulesetKind: ccnl, tax, inps or surtax, set by the loader
readiness RulesetReadiness for a CCNL; None when the kind tracks no tier
confidence VerificationStatus: the CCNL verification.confidence, or the identity verification_status
confidence_contradicts_readiness True when a reviewed or production tier lacks a verified confidence
is_production production and a confidence that agrees

ContractSummary.validity is the ValidityWindow (first_day, last_day, both included, last_day None when open-ended) on which every rule of the CCNL has a value in the bundle: pay tables, parameters and work rules. A run whose month it covers never raises MissingRuleError; a run outside it raises that error when it reads a rule not in force on its date. Four CCNLs have 2026 pay tables that start after January (anas on 1 March, igiene-ambientale-utilitalia on 1 February, lavanderie-industriali-assosistema on 1 May, metalmeccanico-confimi-pmi on 1 June): a competence or tax year of theirs from January is partial (see Results).

(anas,) = (c for c in engine.list_contracts() if c.ccnl_id == "anas")
anas.validity.first_day  # → datetime.date(2026, 3, 1)

ccnl_engine.catalog.CapabilityCatalog dataclass

Capability registry of one fiscal year.

Raises:

Type Description
ValueError

When two entries share a feature.

by_feature(feature)

Return the entry for feature, or None when absent.

Returns:

Type Description
CapabilityEntry | None

The matching :class:CapabilityEntry, or None.

implemented()

Return the entries the engine computes, in declaration order.

Returns:

Type Description
tuple[CapabilityEntry, ...]

Every entry that is not unsupported.

ccnl_engine.catalog.CapabilityEntry dataclass

One capability of the registry.

Attributes:

Name Type Description
feature str

Stable capability name, as traced and reported.

layer CapabilityLayer

Payslip layer the capability belongs to.

implementation CapabilityImplementation

How the engine implements it.

applies_when CapabilityApplicability

Predicate that says whether it applies to a run.

handler CapabilityHandler | None

Kind of code that decides and traces it; None exactly when the capability is unsupported.

evidence EvidenceStatus

Weakest provenance its rules may have for a payable run.

description str

Human-readable description.

variants tuple[str, ...]

Variants the engine supports, for a partial capability the only ones it computes.

required_facts tuple[str, ...]

Request facts the capability reads; for an outside_input capability, the fact the request lacks.

applicability_facts tuple[str, ...]

Those of :attr:required_facts that decide whether a decided capability applies. The capability is then required in every run: left to its default, each of them blocks a run that did not rule the capability out (see :mod:~ccnl_engine.capability.requirement.rules).

Raises:

Type Description
ValueError

When the handler disagrees with the implementation or with the applicability predicate, or an applicability fact is not a required fact of a decided capability.

ccnl_engine.catalog.CapabilityImplementation

Bases: StrEnum

How the engine implements a capability, from the best to the worst.

Attributes:

Name Type Description
NATIVE

Computed from bundled rules and the facts of the request.

CALLER_SUPPLIED

Computed from a rate or amount the caller supplies in place of a rule.

PARTIAL

Computed for the listed variants only; a run that executes it is partially covered.

UNSUPPORTED

Not computed; a run it applies to is not covered.

worst(implementations) classmethod

Return the worst of implementations.

Returns:

Type Description
CapabilityImplementation

The worst implementation, or :attr:NATIVE when empty.

ccnl_engine.catalog.CcnlId = NewType('CcnlId', str) module-attribute

ccnl_engine.catalog.ContractSummary dataclass

Summary of one bundled CCNL: who it is and how far it is cleared.

Attributes:

Name Type Description
ccnl_id CcnlId

Human-readable slug (e.g. "metalmeccanico-federmeccanica").

name str

Full display name (e.g. "CCNL Metalmeccanico Federmeccanica").

cnel_code str

Official CNEL classification code (e.g. "E042").

readiness RulesetReadiness

Readiness tier of the CCNL ruleset; only production is payable in operational mode.

validity ValidityWindow | None

Dates on which every rule of the CCNL has a value in the bundle (pay tables, parameters, work rules), both ends included. A run inside it never raises :class:~ccnl_engine.errors.MissingRuleError; a run outside it raises that error when it reads a rule not in force on its date, and a competence year skips the runs before the base salary of the level starts. None when no date covers every rule.

ccnl_engine.catalog.LevelSummary dataclass

One level of a bundled CCNL, as Employment.level_code names it.

Attributes:

Name Type Description
code str

The level code (e.g. "C3").

description str

Label of the level in the CCNL data.

category WorkerCategory | None

Worker category the level is restricted to, None when the level admits any.

ccnl_engine.catalog.RulesetAssurance dataclass

Identity, readiness and confidence of one ruleset.

Attributes:

Name Type Description
identity RulesetIdentity

Id, version, validity, source and integrity hash.

kind RulesetKind

Part of the bundle the ruleset belongs to.

readiness RulesetReadiness | None

Readiness tier set by a reviewer; None when the kind tracks no tier (every kind but :attr:RulesetKind.CCNL).

confidence VerificationStatus

Editorial confidence in the values: the CCNL verification.confidence, or the identity verification_status for the other kinds.

id property

Stable id of the ruleset, e.g. ccnl/metalmeccanico-federmeccanica.

source_hash property

sha256 of the data file the ruleset was read from.

readiness_tracked property

Whether the ruleset carries a readiness tier at all.

confidence_contradicts_readiness property

Whether the tier claims a review the confidence does not record.

A reviewed or production ruleset must record confidence = verified (see the promotion criteria in the readiness documentation); one that does not is inconsistent.

is_production property

Whether the ruleset is production and its confidence agrees.

without_tier(identity, kind) classmethod

Report a ruleset whose kind tracks no readiness tier.

Returns:

Type Description
RulesetAssurance

The assurance, with no readiness and the confidence of the

RulesetAssurance

identity.

ccnl_engine.catalog.RulesetIdentity

Bases: BaseModel

Identity and provenance metadata for a single ruleset.

Attributes:

Name Type Description
id str

Stable identifier for the ruleset (e.g. "ccnl/metalmeccanico-federmeccanica" or "tax/2026/industria").

version str

Dataset version this ruleset ships in (e.g. "2026.1" — the knowledge base __version__).

effective_from date

First date the ruleset is applicable.

effective_until date | None

Last date the ruleset is applicable. None when the ruleset is still open-ended.

published_at date

Date the data file was published/recorded. Falls back to the current date when unknown (backfilled "as of today").

source str

Primary source reference (URL or identifier). "unavailable" when no source is recorded.

source_type SourceType

Origin classification of the underlying data.

source_hash str

sha256 hex digest of the underlying data file, used by the loaders for fail-hard integrity verification.

verification_status VerificationStatus

Confidence level in the recorded data.

verified_by str | None

Identifier of the person who verified this ruleset; required when verification_status is "verified".

verified_at date | None

Date the ruleset was verified; required when verification_status is "verified".

provisional bool

The sources of the year are not published yet: the values are carried over from the year before, pending them. A run that reads a provisional tax or INPS ruleset traverses the open engine limitation provisional_ruleset.

ccnl_engine.catalog.RulesetKind

Bases: StrEnum

Which part of the bundle a ruleset belongs to.

The kind is set by the loader that read the ruleset, never inferred from its id.

Attributes:

Name Type Description
CCNL

A collective agreement: salary tables, allowances, work rules.

TAX

A tax year file: IRPEF, deductions, variable pay, family deductions.

INPS

An INPS contribution year file.

SURTAX

A regional or municipal surtax table.

ccnl_engine.catalog.RulesetReadiness

Bases: StrEnum

Production readiness of a CCNL ruleset.

Separate from :class:VerificationStatus (which measures data confidence at the value level). Readiness classifies whether the ruleset as a whole is cleared for a given use context.

Values

exploratory: Extracted and traced; no human review of key values. Safe for demos, research, and prototyping. reviewed: Key salary table values and primary sources verified by a person. Suitable for product simulations with an explicit disclaimer and ruleset-level scope. production: Full review, at least one reference case from an independent source, a named owner, and a tracked update policy. Suitable for operational flows where figures are shown to end users or used in decisions.

Promotion criteria

exploratory → reviewed: a human has cross-checked at least L1 values (base salary, seniority table, additional months) against the primary CCNL source, and the source URL is recorded. reviewed → production: all L1+L2 values verified, at least one reference case from an official source or real payslip (anonymised), a named owner assigned, and an update-policy entry.

ccnl_engine.catalog.ValidityWindow dataclass

A span of dates, both ends included.

Attributes:

Name Type Description
first_day date

First date of the span.

last_day date | None

Last date of the span; None when it is open-ended.

covers(day)

Return whether day falls within the span.

Returns:

Type Description
bool

True from :attr:first_day to :attr:last_day included.

intersect(other)

Return the dates both spans cover.

Returns:

Type Description
ValidityWindow | None

The common span, None when the spans do not overlap.

ccnl_engine.catalog.VerificationStatus

Bases: StrEnum

How confident we are in the data behind a ruleset.

Attributes:

Name Type Description
VERIFIED

A named reviewer, a person or an AI model, checked the key values against the sources and recorded it.

UNVERIFIED

No review is recorded.

NEEDS_REVIEW

A review found values to correct or to re-check.

ccnl_engine.catalog.get_ccnl(ccnl_id)

Resolve a CCNL by slug or CNEL code.

Parameters:

Name Type Description Default
ccnl_id str

A slug (e.g. "metalmeccanico-federmeccanica", with or without .json) or CNEL code (e.g. "E042").

required

Returns:

Type Description
ContractSummary

The matching :class:ContractSummary.

Raises:

Type Description
UnknownCcnlError

When no CCNL matches ccnl_id, with up to five similar identifiers attached as suggestions, or when ccnl_id is a CNEL code shared by several bundled CCNLs, with their slugs as suggestions: a shared code does not name one contract.

ccnl_engine.catalog.search_ccnls(query)

Return all CCNLs whose name or slug contains query.

The comparison is case-insensitive.

Parameters:

Name Type Description Default
query str

Substring to match against :attr:ContractSummary.ccnl_id and :attr:ContractSummary.name.

required

Returns:

Type Description
tuple[ContractSummary, ...]

A tuple of matching :class:ContractSummary, in slug order.

ccnl_engine.catalog.supported_tax_years() cached

Return the tax years whose tax and INPS tables the bundle ships.

Returns:

Type Description
int

The years, ascending, that have both a sector tax file and a sector

...

INPS file.