Aller au contenu

ADR-0001 — Où vivent les tables de mortalité réglementaires (CIMA q_x)

Statut Accepté — 2026-06-08
Portée actuariat_lib (couche de calcul DBO), module ActuaryLab
Décision Embarquer les tables CIMA H/F 2012 dans la lib (src/actuariat_lib/tables/data/)
Contexte méthode Temps 3 « construire » de la méthode à 4 temps — packaging de la donnée canonique

🎯 À retenir

Les deux tables CIMA H/F 2012 sont embarquées dans actuariat_lib (src/actuariat_lib/tables/data/), source unique de vérité co-localisée avec le code. C'est une exception assumée à la politique « données réglementaires non versionnées ». Migration vers un package séparé (quantis-actuarial-data) uniquement quand un 2ᵉ module Quantis consommera les mêmes tables.

Contexte

Le moteur DBO (dbo_population_puc, dbo_individuelle_puc) a besoin des probabilités annuelles de décès q_x des tables réglementaires CIMA H (décès) et CIMA F (vie), pour les calculs clients réels. Jusqu'ici la lib est une couche pure : charger_table_mortalite prend des tableaux lx/qx en entrée, et la lib ne livre aucune donnée. Les CSV extraits du Code CIMA 2019 (art. 338) vivent dans references/cima-tables/ et y sont gitignorés (politique « données réglementaires non versionnées »).

Question à trancher : où réside la copie canonique des q_x, pour que tout appelant calcule sur la même table sans ré-extraire un PDF de 21 Mo ?

Deux contraintes transverses pèsent :

  1. Règle d'or — la lib reste pure (aucune dépendance framework). Une donnée n'est pas une dépendance framework : embarquer un CSV ne viole pas la règle.
  2. Politique gitignore — les CSV réglementaires sont aujourd'hui non versionnés (references/.gitignore). Embarquer dans la lib suppose une exception explicite.

Options considérées

  • A — Embarquées dans la lib : src/actuariat_lib/tables/data/cima_*_2012.csv + loader charger_table_reglementaire("CIMA_H_2012"). La lib est livrée avec sa donnée canonique.
  • B — Fournies à l'exécution : la lib reste sans donnée ; l'appelant (backend, DB admin-éditable, dossier de config) injecte les q_x au runtime via charger_table_mortalite.
  • C — Package de données séparé : un quantis-actuarial-data versionné à part (dépendance optionnelle, checksums/provenance), consommable par plusieurs modules Quantis.

Comparatif pour / contre

Critère A — Embarquées dans la lib B — Fournies à l'exécution C — Package séparé
Source unique de vérité ✅ co-localisée avec le code ❌ chaque appelant a sa copie → divergence ✅ une seule, gouvernée
Reproductibilité / offline ✅ totale, aucun fetch ⚠️ dépend de l'appelant ✅ par version épinglée
API d'appel charger_table_reglementaire("CIMA_H") ❌ l'appelant lit PDF/CSV lui-même ✅ import + loader
Testabilité de la lib ✅ tests réels, sans fixture externe ❌ fixture quand même nécessaire ✅ via dép de test
Mise à jour d'une table ❌ nécessite une release de lib ✅ change côté data, lib intacte ✅ bump du package data seul
Respect règle d'or (pureté) ✅ (donnée ≠ dép framework) ✅✅ lib 100 % calcul ✅ lib pure + dép data optionnelle
Politique gitignore réglementaire contredit (exception à décider) ✅ inchangée ⚠️ déplacée dans l'autre repo
Gouvernance / redistribution ⚠️ la lib redistribue un extrait réglementaire ✅ aucune donnée dans la lib ✅ périmètre légal isolé
Réutilisation multi-modules ⚠️ couplée à actuariat_lib ⚠️ chacun se débrouille ✅✅ conçue pour ça
Coût / infra aujourd'hui ✅ quasi nul (2 petits CSV) ✅ nul ❌ 2e repo, publication, coordination
Couplage des cadences ❌ code et donnée bumpent ensemble ✅ découplés ✅ découplés

Décision

Option A — embarquer les tables dans la lib, et assumer l'exception à la politique gitignore pour ces deux fichiers.

Justification. Il y a 2 tables, ce sont des constantes réglementaires stables (les tables CIMA 2012 sont en vigueur depuis des années, art. 338) : la co-localisation maximise reproductibilité, simplicité d'API et testabilité réelle, à coût d'infra quasi nul. B ne répond pas à la question — il la déplace dans le backend et invite la divergence de copies. C est la bonne réponse à l'échelle plateforme (≥ 2 modules consommant la donnée), mais relève aujourd'hui du YAGNI et de la cérémonie cross-repo.

Conséquences

  • Fichiers versionnés : src/actuariat_lib/tables/data/cima_h_2012.csv, cima_f_2012.csv, CHECKSUMS.txt, PROVENANCE.md. Exception inscrite dans le .gitignore racine (négation de garde) ; le PDF source (21 Mo) reste gitignoré dans references/.
  • Garde-fous d'audit : charger_table_reglementaire(...) vérifie le SHA-256 de chaque CSV au chargement (toute altération silencieuse échoue). La provenance (Code CIMA 2019, art. 338, p. 225/226) et la procédure de régénération sont dans data/PROVENANCE.md.
  • API & packaging : nouvelle fonction publique charger_table_reglementaire (lib 1.1.0), package-data déclaré dans pyproject.toml pour livrer les CSV à l'install.
  • Tests : tests/test_tables_reglementaires.py (contenu, checksum, et bout-en-bout : la table embarquée reproduit l'oracle K1 = 2 751 205,018849 FCFA).

Déclencheur de réexamen (pré-enregistré)

Dès qu'un 2ᵉ module Quantis a besoin des mêmes tables CIMA, migrer A → C : extraire actuariat_lib/tables/data/ vers un package quantis-actuarial-data. La migration est mécanique (déplacer le dossier + publier + dépendance optionnelle), donc choisir A maintenant ne ferme pas la porte C.