ADR-0016 — Corpus de validation actuarielle (Green / Red / Kill)¶
| Statut | ✅ Accepté — 2026-06-17 |
| Portée | Process de validation métier (actuariel) ; structure des jeux de données et des sorties attendues ; runner |
| Décision | Un répertoire validation/ regroupe jeux de données versionnés + manifestes de scénarios (green / red / kill) + un runner qui rejoue tout ; les oracles hand-computed restent en pytest |
| Réf. | Vision — Trajectoires/émergence (garde-fou 3) ; ADR-0005 ; ADR-0015 |
🎯 À retenir
Un répertoire validation/ regroupe des jeux de données versionnés + des manifestes
de scénarios (green / red / kill) + un runner mince qui rejoue tout. Le runner
appelle les mêmes fonctions que l'app (source de vérité unique) ; les oracles
hand-computed restent en pytest, le corpus les délègue, jamais ne les recopie. Un
actuaire étend le corpus sans coder.
Contexte¶
L'objectif déclaré est une campagne de validation sur de vrais jeux de données, pour éprouver le côté actuariel. Trois constats rendent le moment juste :
- Les jeux de test (
photos-flavorB/) vivaient hors du dépôt git (à la racineBFEV-Projects/) — non versionnés, perdables, invisibles à la CI. - Les suites
pytest(114 lib + 152 backend) sont orientées développeur : excellentes pour le moteur, mais ni lisibles ni extensibles par un actuaire qui veut ajouter un scénario réglementaire sans écrire de Python. - Le futur jeu multi-entités de l'étage 2 (mobilité groupe) allait naître comme un énième CSV perdu, faute de structure d'accueil.
Il manque une couche métier, data-driven, auditable : jeux de données + sorties attendues explicites + traçabilité réglementaire, rejouables d'une commande.
Options considérées¶
- A — Corpus data-driven séparé (
validation/, manifestes YAML, runner mince) : l'actuaire écrit des données + un attendu ; le code reste la source de vérité du moteur. - B — Tout en pytest : ajouter chaque scénario comme test Python.
- C — Ad hoc : des scripts/CSV au cas par cas, comme aujourd'hui.
| Critère | A — corpus | B — pytest | C — ad hoc |
|---|---|---|---|
| Authorable par un actuaire (sans Python) | ✅ YAML + CSV | ❌ | ⚠️ |
| Source de vérité moteur unique | ✅ (réutilise les fns app) | ✅ | ⚠️ dérive |
| Rapport lisible métier (Green/Red) | ✅ | ❌ (sortie pytest) | ❌ |
| Oracles hand-computed scellés | ✅ délégation kill |
✅ natif | ⚠️ |
| Traçabilité réglementaire | ✅ champ reference |
⚠️ commentaires | ❌ |
| Coût | faible (runner mince) | faible | nul mais dette |
Décision¶
Option A, avec ces partis pris :
- D-CORPUS-1 — Trois types de scénario.
green(golden-master / oracle numérique tolérancé — ce qui doit marcher),red(negative testing — une anomalie de reconstruction DOIT remonter, ce qui doit être refusé),kill(oracle scellé — délégué au node pytest qui le porte). - D-CORPUS-2 — Source de vérité unique. Les pipelines du runner appellent les
mêmes fonctions que l'app (
calculer_dbo_jeu,reconstruire). Aucune logique actuarielle n'est recopiée. Les oracles hand-computed (K1, K-WATERFALL-B…) restent en pytest ; le corpus les regroupe par délégation, jamais par copie. - D-CORPUS-3 — Jeux de données versionnés dans le dépôt (
validation/datasets/), par famille (mono-entreprise/,multi-entites/). Fin des CSV hors-git. Cohérent avec le garde-fou 3 (« ne jamais jeter »). - D-CORPUS-4 — Traçabilité réglementaire obligatoire. Chaque manifeste porte un
champ
reference(CIMA art., IAS 19 §, ou contrôle interne nommé). Un scénario sans base citée n'est pas auditable. - D-CORPUS-5 — Pas de DSL. YAML + runner mince ; le champ
pipelinepointe un petit registre de mécanismes connus (dbo,trajectoires, … étendus au besoin). - D-CORPUS-6 — Runner standalone, sous le venv backend, à code de sortie 1 si un
scénario échoue. L'intégration à la CI (un test qui rejoue Green+Red) viendra
quand le corpus grossira ; le
killreste en pytest natif (pas de récursion).
Conséquences¶
- Le jeu multi-entités de l'étage 2 naît dans le corpus (premier citoyen de
multi-entites/), avec ses Green (bouclage par entité) et Red (mutation ré-initialisant l'ancienneté alors que la convention la dit portable). - Un actuaire étend le corpus sans coder : dépose un CSV, écrit un manifeste, cite la réglementation, lance le runner.
- Golden-master ≠ oracle : un
greengelé sur la sortie 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 deskill(hand-computed). Les deux coexistent, nommés franchement.
⚠️ Piège
Un green ne prouve pas l'exactitude : c'est un golden-master qui gèle la sortie
moteur et n'attrape que la régression. Seuls les kill (oracles hand-computed)
attestent la justesse dans l'absolu. Ne pas lire un corpus tout-vert comme une preuve
de correction actuarielle.
Déclencheur de réexamen (pré-enregistré)¶
Si le nombre de scénarios rend le runner standalone insuffisant (besoin de parallélisme, de fixtures partagées, de paramétrage massif), réexaminer pour intégrer le corpus à pytest (paramétrage sur les manifestes) — en gardant la lisibilité métier du rapport.