Skip to main content

ccnl-engine

PyPI version Python CI Coverage License: MIT

A Python library for modeling Italian collective labor agreements (CCNL) as structured, versioned data and computing gross-to-net salary and employer cost from first principles.

Why

Italian payroll is governed by collective agreements (CCNL) that define base salaries, seniority increments, and allowances as time-series values — they change at negotiated renewal dates. Existing tools either lock this data inside proprietary systems or require a full HRMS. This library treats each CCNL as a validated JSON file and the computation as a pure function:

compute(ccnl, rules, ComputeRequest(...)) → ComputationResult

Quickstart

from datetime import date
from ccnl_engine.contracts.loaders import load_ccnl
from ccnl_engine.tax.loaders import load_year_rules
from ccnl_engine.engine.compute import ComputeRequest, compute
from ccnl_engine.models.ccnl import TaxSector
from ccnl_engine.models.employment import Permanent

ccnl = load_ccnl("commercio-confcommercio.json")
rules = load_year_rules(2026, TaxSector.TERZIARIO, num_employees=50)
result = compute(
    ccnl,
    rules,
    ComputeRequest(level_code="4", as_of=date(2026, 9, 1), employment=Permanent()),
)

print(result.net_annual)  # → Decimal('...')
print(result.employer_cost_annual)  # → Decimal('...')

CCNL coverage

Layers legend

Layer Meaning
Layer 1 base salary, seniority increments (scatti di anzianità), fixed allowances, additional months.
Layer 2 part-time, fixed-term (NASpI addizionale), apprenticeship (percentage or under-classification).

Status legend

Symbol Meaning
✅ Fully modelled; all salary tables and rules for this layer are in scope
⚠️ Partially modelled; known gaps or simplifications apply — see coverage.notes in the contract's JSON data file
🤖 Extraction: extracted automatically via Claude Code — no manual human review
🧑 Extraction: verified manually against the official source

CCNL Matrix

# CCNL Sector Lavoratori (~)1 Layer 1 Layer 2 Extraction2
1 Commercio — Confcommercio Terziario ~800k ✅ ✅ 🤖
2 Metalmeccanico — Federmeccanica/Assistal Industria ~1,7M ✅ ✅ 🤖
3 Metalmeccanico PMI — Unionmeccanica-Confapi Industria ~350k ✅ ✅ 🤖
4 Chimica-Farmaceutica — Federchimica/Farmindustria/Assistal Industria ~210k ✅ ✅ 🤖
5 Turismo — Confcommercio Terziario ~300k ✅ ✅ 🤖
6 Edilizia — ANCE Edilizia ~550k ✅ ✅ 🤖
7 Cooperative Sociali — Confcooperative/Legacoop/AGCI Terziario ~380k ✅ ✅ 🤖
8 Logistica, Trasporto Merci e Spedizione — Confetra Industria ~430k ✅ ✅ 🤖
9 Servizi di Pulizia e Multiservizi — ANIP-Confindustria Terziario ~580k ✅ ✅ 🤖
10 Studi e Attività Professionali — Confprofessioni Terziario ~350k ✅ ✅ 🤖
11 Credito — ABI Credito ~270k ✅ ✅ 🤖
12 Tessile Abbigliamento Moda — SMI Industria ~160k ✅ ✅ 🤖
13 Alimentari Industria — Federalimentare Industria ~145k ✅ ✅ 🤖
14 Distribuzione Moderna Organizzata — Federdistribuzione Terziario ~460k ✅ ✅ 🤖
15 Metalmeccanica e Installazione Impianti — Artigianato Artigianato ~350k ✅ ✅ 🤖
16 Gomma e Plastica Industria — Federazione Gomma Plastica Industria ~90k ✅ ✅ 🤖
17 Grafica e Editoria — AIEG-Acigraf Industria ~70k ✅ ✅ 🤖
18 Carta e Cartone — Assocarta Industria ~35k ✅ ✅ 🤖
19 Telecomunicazioni — Asstel Industria ~110k ✅ ✅ 🤖
20 Vigilanza Privata — ASSIV/ANIVP/UNIV (GPG) Terziario ~85k ✅ ✅ 🤖
21 Legno e Arredamento — Federlegno-Arredo Industria ~90k ✅ ✅ 🤖
22 Edilizia e Affini — CNA/Confartigianato/Casartigiani Artigianato ~350k ✅ ✅ 🤖
23 Gas e Acqua — Utilitalia/Proxigas/Anfida/Assogas Industria ~65k ✅ ✅ 🤖
24 Istituzioni Socio-Assistenziali — UNEBA Terziario ~130k ✅ ✅ 🤖
25 Acconciatura ed Estetica — Confartigianato/CNA Artigianato ~95k ✅ ✅ 🤖
26 Area Alimentazione e Panificazione — Artigianato (Confartigianato/CNA) Artigianato ~90k ✅ ✅ 🤖
27 Autoferrotranvieri e Internavigatori (Mobilita/TPL) — AGENS/ASSTRA/ANAV Terziario ~120k ✅ ✅ 🤖
28 Credito Cooperativo (BCC/CRA) — Federcasse Credito ~33k ✅ ✅ 🤖
29 Elettrico (produzione/distribuzione energia) — Elettricita Futura Industria ~60k ✅ ✅ 🤖
30 Calzaturiero (industria delle calzature) — Assocalzaturifici Industria ~75k ✅ ✅ 🤖
31 Area Tessile-Moda e Chimica-Ceramica — Artigianato (Confartigianato/CNA) Artigianato ~120k ✅ ✅ 🤖
32 Area Legno-Lapidei — Artigianato (Confartigianato/CNA) Artigianato ~95k ✅ ✅ 🤖
33 Area Comunicazione — Artigianato (Confartigianato/CNA) Artigianato ~60k ✅ ✅ 🤖
34 Ceramica Industria — Confindustria Ceramica (Assopiastrelle) Industria ~23k ✅ ✅ 🤖
35 Orafi e Argentieri — Federorafi Industria ~18k ✅ ✅ 🤖
36 Pelli e Cuoio Industria — Assopellettieri Industria ~17k ✅ ✅ 🤖
37 Pubblici Esercizi, Ristorazione Collettiva e Turismo — FIPE/ANGEM Terziario ~350k ✅ ✅ 🤖
38 Agenzie di Viaggio e Turismo — Fiavet/Confcommercio Terziario ~25k ✅ ✅ 🤖
39 Terziario Distribuzione e Servizi — Confesercenti Terziario ~230k ✅ ✅ 🤖
40 Turismo — Federalberghi/Faita Terziario ~220k ✅ ✅ 🤖
41 Funzioni Centrali 2022-2024 — ARAN (Ministeri, Agenzie, INPS, INAIL) Pubblica Amministrazione ~250k ✅ ✅ 🤖
42 Funzioni Locali 2022-2024 — ARAN (Comuni, Province, Regioni, Camere di Commercio) Pubblica Amministrazione ~400k ✅ ✅ 🤖
43 Comparto Sanità 2022-2024 — ARAN (SSN non-dirigenza) Pubblica Amministrazione ~580k ✅ ✅ 🤖
44 Area Sanità 2022-2024 — ARAN (Dirigenti Medici e Veterinari SSN) Pubblica Amministrazione ~100k ✅ ✅ 🤖
45 Area Sanità 2022-2024 — ARAN (Dirigenti Sanitari: psicologi, farmacisti, biologi) Pubblica Amministrazione ~37k ✅ ✅ 🤖
46 Area Dirigenza Funzioni Locali 2022-2024 — ARAN (Dirigenti enti locali, Segretari comunali) Pubblica Amministrazione ~13k ✅ ✅ 🤖
47 Area Dirigenza Funzioni Centrali 2022-2024 — ARAN (Dirigenti ministeri, agenzie fiscali, INPS, INAIL) Pubblica Amministrazione ~30k ✅ ✅ 🤖
48 Area Dirigenza Istruzione e Ricerca 2022-2024 — ARAN (Dirigenti scolastici, universitari, ricerca) Pubblica Amministrazione ~8k ✅ ✅ 🤖
49 Comparto Istruzione e Ricerca 2022-2024 — ARAN (Docenti e ATA scuola, università, ricerca) Pubblica Amministrazione ~1,2M ✅ ✅ 🤖
50 Case di Cura Private - Personale Non Medico (AIOP/ARIS) Sanità privata ~150k ✅ ✅ 🤖
51 Lavoro Domestico — DOMINA/FIDALDO/ASSINDATCOLF (conviventi) Lavoro Domestico ~900k ✅ ✅ 🤖
52 Lavoro Domestico — DOMINA/FIDALDO/ASSINDATCOLF (non conviventi) Lavoro Domestico ~900k ✅ ✅ 🤖
53 Operai Agricoli e Florovivaisti — Coldiretti/Confagricoltura/CIA Agricoltura ~600k ✅ ✅ 🤖
54 Chimica e Affini PMI — Unionchimica Confapi Chimica ~56k ✅ ✅ 🤖
55 Panificazione e Settori Affini Industria — Assipan/Fiesa/Federpanificatori Alimentare ~20k ✅ ✅ 🤖
56 Attività Ferroviarie — AGENS Trasporto ~75k ✅ ✅ 🤖
57 Trasporto Aereo — Gestori Aeroportuali (Assaeroporti) Trasporto ~40k ✅ ✅ 🤖
58 Igiene Ambientale — Servizi Ambientali e di Igiene Urbana (Utilitalia/FISE) Industria ~65k ✅ ✅ 🤖
59 Impiegati e Tecnici Agricoli — Confagricoltura/CIA/Coldiretti Agricoltura ~80k ✅ ✅ 🤖

1. Approximate estimates. Sources: CNEL, INPS, Ministero del Lavoro, CCNL renewal communications.

2. Salary tables were extracted from official CCNL documents using Claude Code (AI-assisted), without manual human review. Values should be verified against the official source before use in production payroll systems.

The 59 contracts above cover approximately 14.3 million workers (sum of per-CCNL estimates; some overlap is possible where sector boundaries are not mutually exclusive, so the unique-worker count is somewhat lower). Italy has roughly 16 million employees covered by some collective agreement (ISTAT/CNEL 2024, public and private sectors combined). This library therefore reaches an estimated ~85–90% of CCNL-covered workers on a gross-headcount basis.

What is not modelled

  • Addizionali regionali and addizionali comunali
  • Detrazioni per carichi di famiglia (Art. 12 TUIR)
  • IVS contributory ceiling split (Art. 1 L. 335/1995)
  • Second-level bargaining (territorial and company agreements)
  • Bilateral system contributions (EST, Fon.Te, …)
  • Overtime, night/holiday premiums, leave accruals, sick-pay integrations

Each limitation is documented in the relevant data file's coverage.notes field and marked with # SIMPLIFICATION: comments in the engine source.

Releasing a new version

Releases are fully automated via GitHub Actions. Steps:

  1. Bump version in pyproject.toml following SemVer.
  2. Commit the change: git commit -m "chore: bump version to X.Y.Z".
  3. Push a tag: git tag vX.Y.Z && git push origin vX.Y.Z.

The release workflow then: runs the full test suite, builds the wheel and sdist with uv build, verifies the tag matches the package version, publishes to PyPI via Trusted Publishing (no API token required), and creates a GitHub Release with auto-generated notes and the dist files attached.

Pre-requisite (one-time): configure a Trusted Publisher on PyPI for this repository under the pypi GitHub environment.

Development

This library was built with AI coding assistants — Claude Code, Codex, and Opencode. Generated code is covered by the test suite but has not been manually reviewed line by line.

Disclaimer

This library is not legal or tax advice. Figures are computed from publicly available CCNL tables and statutory rates as of the dates indicated in the data files. Always verify results against official sources or a qualified payroll professional.

Metadata

Release files for ccnl-engine 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ccnl-engine 0.1.0
File Size Uploaded
ccnl_engine-0.1.0.tar.gz 171.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ccnl-engine 0.1.0
File Interpreter ABI Platform
ccnl_engine-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 409.8 kB

Release files / ccnl_engine-0.1.0.tar.gz

Download URL ccnl_engine-0.1.0.tar.gz
Size 171.4 kB
Tags Source
SHA-256 checksum
How to use checksums
772486a01626e57caa9f182677bd97426119c3e6e2c2c8b9c01a207b5b0bfc9f
BLAKE2b-256 checksum
How to use checksums
874df37aeea4e519bc2ac9363bc975951c0ad6f5e4da2b5d9584527ec3bbca82
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / ccnl_engine-0.1.0-py3-none-any.whl

Download URL ccnl_engine-0.1.0-py3-none-any.whl
Size 238.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
84109fe877d2373d784f097e51225cb6450dce581a4ddec97dde4b1cac53e187
BLAKE2b-256 checksum
How to use checksums
c2d96344ce2333ffa97feeea64f16202047fce8e2769e6ac4f038ba1600d84e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release history Release notifications | RSS feed

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page