Aller au contenu

Valider le moteur sur le corpus actuariel

🎯 À retenir

Le corpus validation/ est le banc d'essai métier (distinct des tests unitaires) : des jeux de données, des sorties attendues explicites, un runner qui rejoue tout d'une commande. Trois types de scénario — green (bonne valeur), red (anomalie attendue), kill (oracle scellé délégué). On ajoute un scénario sans toucher au code.

Le corpus de validation (validation/) est le banc d'essai métier d'ActuaryLab : des jeux de données réels, des sorties attendues explicites, et un runner qui rejoue le tout d'une commande. Il est distinct des tests unitaires pytest (orientés développeur) : ici, on valide le comportement actuariel sur des données, de façon lisible et extensible par un actuaire — sans écrire de Python.

Décision fondatrice : ADR-0016.

Lancer le corpus

# tous les scénarios
backend/.venv/bin/python validation/runner.py

# un scénario par id
backend/.venv/bin/python validation/runner.py dbo-cima-h-population

Sortie : un tableau ✅/❌, code de retour 1 si un scénario échoue (CI ou main).

Les trois types de scénario

Type Question posée Mécanique
green Le moteur produit-il la bonne valeur ? calcule via le pipeline, compare à expected (tolérance)
red Le moteur signale-t-il ce qui cloche ? reconstruit, exige une anomalie attendue
kill L'oracle scellé tient-il ? délègue au test pytest (source de vérité unique)

Ajouter un scénario (sans toucher au code)

  1. Déposer le CSV dans validation/datasets/<famille>/ (colonnes matricule,nom,age,anciennete,salaire,sexe).
  2. Créer validation/scenarios/<id>.<type>.yaml.
  3. Citer la réglementation dans reference (CIMA art., IAS 19 §) — c'est ce qui rend le scénario auditable.
  4. Lancer le runner.

💡 Astuce — geler un golden-master

Pour un green dont tu ignores encore la valeur : mets une valeur bidon, lis la valeur obtenue dans le rapport, puis gèle-la.

Exemple — Green (oracle numérique)

id: dbo-cima-h-population
type: green
pipeline: dbo
reference: "IAS 19 §57-66 (PUC) ; table CIMA H 2012"
dataset: mono-entreprise/dbo-cima-h.csv
hypotheses:
  taux_actualisation: 0.05
  taux_revalorisation_salaire: 0.03
  age_retraite: 60
  table_mortalite: CIMA_H_2012
  date_evaluation: "2025-12-31"
  grille_ifc: [[0, 5, 0.0], [5, 15, 1.0], [15, 999, 2.0]]
expected:
  dbo_totale: { value: 32048233.724826552, tol: 1.0 }
  n_inclus: 3

Exemple — Red (anomalie attendue)

id: trajectoire-salaire-baisse
type: red
pipeline: trajectoires
reference: "Contrôle qualité  monotonicité salariale (ADR-0005 étage 1)"
dataset:
  - { file: mono-entreprise/photos-flavorB/photo-2023-12-31.csv, date: "2023-12-31" }
  - { file: mono-entreprise/photos-flavorB/photo-2024-12-31.csv, date: "2024-12-31" }
expected:
  matricule: BFEV-0004
  anomalies_attendues: ["salaire en baisse"]

Exemple — Kill (oracle scellé, délégué)

id: K1-oracle-dbo
type: kill
reference: "K1  DBO calculée à la main (2 751 205,02 FCFA)"
pytest: "tests/test_engagements.py::test_K1_oracle_dbo"

Pourquoi golden-master ET kill ?

Un green gelé sur la sortie du moteur protège de la régression (le moteur ne doit pas se mettre à produire autre chose) — mais ne prouve pas l'exactitude dans l'absolu. C'est le rôle des kill (calculés à la main). Les deux coexistent ; le corpus regroupe les kill par délégation à pytest, sans recopier l'oracle.

🔒 Oracle scellé

Les pipelines du runner appellent les mêmes fonctions que l'app (calculer_dbo_jeu, reconstruire). Aucune logique actuarielle n'est dupliquée.