Aller au contenu

Campagne de validation actuarielle

🎯 À retenir

Temps 4 — « éprouver ». Le corpus validation/ confronte le moteur DBO à la surface réglementaire (CIMA, OHADA, IAS 19) en appelant les mêmes fonctions que l'application — aucune logique actuarielle recopiée. État : vagues A, B, C vertes (25 scénarios) ; vague D (données réelles) échafaudée, en attente d'un jeu client.

Les temps 1-3 (formaliser → résoudre → construire) ont produit un moteur et son corpus (ADR-0016). Cette campagne le confronte à la surface réglementaire de façon systématique et lisible métier, jusqu'à pouvoir l'éprouver sur données réelles.

Principe

UNE source de vérité : le corpus validation/ (ADR-0016). Les pipelines y appellent les mêmes fonctions que l'application (calculer_dbo_jeu, calculer_waterfall_jeu, calculer_waterfall_reel_jeu, calculer_ohada_jeu, reconstruire, attribuer_par_entreprise, oracles pytest) — aucune logique actuarielle n'y est recopiée. La campagne n'invente pas de nouvelle vérité : elle rend visible et rejouable d'un coup ce qui était dispersé dans 114 tests unitaires de actuariat_lib, puis comble les trous.

Trois types de scénarios (ADR-0016) :

  • Green — golden-master : reproduit une valeur numérique gelée (non-régression).
  • Red — negative testing : un jeu de données DOIT déclencher une anomalie.
  • Kill — oracle scellé : délègue au test pytest hand-computed (vérité unique).

Surface scellée (oracles hand-computed)

Le socle déjà prouvé au niveau unitaire dans actuariat_lib (références dans les notes de formalisation) — ce que la campagne doit surfacer dans le corpus :

Oracle (pytest) Régime / volet Référence
test_K1_oracle_dbo DBO déterministe (PUC, maintien) CIMA H 2012 ; v2 §5-6
test_K1bis_oracle_dbo DBO + rotation (décrément combiné) éq. (1), k1bis_oracle
test_K5_oracle_kmulti Multi-décréments (décès + départ payants) multidecrements_v1
test_KWATERFALL_oracle_charges_exercice Roll-forward attendu (P&L, flavor A) IAS 19 ; d-attrib §5-6
test_KWATERFALLB_oracle_reevaluation_experience Réévaluation expérience (OCI, flavor B) IAS 19 ; d-attrib §6-8
test_KWATERFALLB_oracle_reevaluation_hypotheses Réévaluation hypothèses (OCI) IAS 19 ; d-attrib §7-8
test_KWATERFALLMULTI_oracle_roulé Roll-forward multi-décréments note multi, annexe
test_KOHADA_provision_employe_reference Provision déterministe OHADA OHADA
test_KOHADA_pont_exact_employe_reference Pont OHADA (bouclage exact) OHADA
test_table_embarquee_reproduit_K1 Table CIMA embarquée alimente K1 CIMA art. 338

Plan par vagues

  • Vague A — surfacer les oracles scellés (kill).Faite. Chaque oracle du tableau ci-dessus est un scénario kill du corpus → un tableau de conformité unique (une ligne ✅/❌ par garantie réglementaire), au lieu d'un seul K1 noyé dans 114 tests.
  • Vague B — golden-masters au niveau population (green).Faite (complète). Les oracles unitaires couvrent la maille employé ; ils n'éprouvent pas l'orchestration (partition par sexe, agrégation, routage multi, bouclage des ponts). Gelés :
    • DBO : population CIMA F ; population mixte H/F (genre : partition + ré-agrégation, additivité dbo_genre[H]+dbo_genre[F]=total) ; population multi-décréments (additivité des composantes, et la composante retraite reproduit le Green retraite-seul = dégénérescence exacte).
    • Waterfall flavor A (P&L, waterfall-pl-population) : roll-forward attendu d'une population mixte ; ré-agrégation additive des postes (CSR, IC') et bouclage du pont au FCFA près (pont_residu ≈ 0). Le dbo_ouverture reproduit exactement la DBO du Green dbo-mixte-hf-population — cohérence inter-scénarios.
    • Waterfall flavor B (OCI, waterfall-oci-population) : rapprochement à deux photos (BFEV 2023→2024, périmètre ouvert : 16 restants, 2 sortants, 2 entrants) ; split réévaluation expérience vs hypothèses (taux 5 %→4,5 %), bouclage fermé du split à deux pas (oci_residu ≈ 0), frontières sortants/ entrants hors bouclage (perimetre_ferme = false).
    • OHADA (ohada-provision-population) : provision déterministe d'une population (régime de constatation, autre chemin moteur), additivité exacte provision[H]+provision[F]=provision_totale (indépendante du sexe et de l'âge),
    • pont vers la DBO PUC du même jeu (ratio).
  • Vague C — bords réglementaires & qualité de données (red).Faite. Deux couches défensives éprouvées : (1) reconstruction — ancienneté non monotone, avance d'âge / d'ancienneté incohérente avec l'écart de dates (sur les photos réelles BFEV 2024→2025) ; (2) garde-fou d'ingestion (valider, nouveau pipe_ingestion) — âge hors plage [16 ; 80], ancienneté négative, salaire nul, ancienneté > âge − 16, matricule dupliqué → statut « a_corriger ». Constat rassurant : aucun trou — toutes les anomalies sondées étaient déjà détectées.
  • Vague D — confrontation aux données réelles. 🟡 Échafaudage prêt ; en attente d'un jeu réel. Le protocole, la convention de répertoire gitignoré (validation/datasets/reel/) et un gabarit travaillé (reel-exemple-attestation, exemple synthétique qui passe) sont en place. Insight : comparer à une attestation = un scénario green (valeur attendue = valeur attestée, tol = écart méthodologique). Procédure : anonymiser → transcrire les hypothèses → comparer le passif moteur à l'attestation → conforme (✅) ou écart à investiguer. Voir le guide Éprouver le moteur sur données réelles. Bloqué sur la donnée client (que seul le métier a).

Exécuter

# Tout le corpus (golden + negative + oracles scellés) :
backend/.venv/bin/python validation/runner.py
# Un sous-ensemble par id :
backend/.venv/bin/python validation/runner.py k1-oracle-dbo kmulti-oracle-dbo

⚠️ Piège — quel Python ?

Le runner tourne sous le venv backend (backend/.venv/bin/python, il importe app.*) et délègue les scénarios kill à uv run pytest (env racine, où vit actuariat_lib). Le lancer avec uv run échoue (pas de sqlmodel à la racine).

Code de sortie non nul si un scénario échoue → utilisable en CI. Voir le guide pratique Valider le corpus actuariel pour la rédaction de nouveaux scénarios.