Aller au contenu

PD-280 — Retour d'experience (REX)

1. Resume executif

Metrique Valeur
Objectif initial Alignement canonique de l'etat PENDING pour la verification de preuve
Resultat obtenu Conforme — endpoint lecture seule, FSM 4 etats, SLA lazy, intercepteur coherence
Verdict final GO (Gate 8 v1 : 9.312/10)
Tests contractuels 25/30 TC implementes et passants (5 absents = CI/formel/documentaire hors scope backend)

2. Metriques de convergence

2.1 Temps et iterations

Etape Duree estimee Duree reelle Iterations Ecart
0 - Besoin 30 min 30 min 1 0%
1 - Specification 2h 3 min 1 -98%
2 - Tests 1h 2 min 1 -97%
3 - Gate spec 1h 3h42 min 3 +270%
4 - Plan 1h 9 min 1 -85%
5 - Gate plan 1h 41 min 3 -32%
6 - Implementation 4h 30 min 1 -88%
7 - Acceptabilite 2h 14 min 1 -88%
8 - Gate acceptabilite 1h 11 min 1 -82%
9 - REX 30 min ~30 min 1 0%
TOTAL ~14h ~6.1h 14 -56%

Note : Gate 3 inclut une pause utilisateur de ~3h entre v2 (12:06) et v3 (15:16). Temps actif estime : ~42 min. Le temps reel total actif est ~3h hors pause.

2.2 Scores de convergence par gate

Gate Score v1 Score v2 Score final Delta v1->final Iterations
Gate 3 4.688/10 8.25/10 9.25/10 +4.562 3
Gate 5 5.5/10 7.562/10 9.0/10 +3.5 3
Gate 8 9.312/10 9.312/10 0 1

2.3 Ecarts par categorie

Categorie d'ecart Gate 3 Gate 5 Gate 8 Total
ECT (completude/testabilite) 4 1 1 6
DIV (divergence spec/impl) 5 0 0 5
AMB (ambiguite) 4 3 0 7
SEC (securite) 1 0 0 1
PERF (performance) 0 0 0 0
TOTAL ecarts 14 4 1 19

3. Points fluides

  • Gate 8 GO en v1 (9.312/10) : score le plus eleve de l'historique legal-compliance backend. L'architecture read-only + intercepteur de coherence a produit un dossier propre.
  • Implementation rapide (~30 min) : la decomposition en 8 composants orthogonaux (C1-C8) a permis une implementation sequentielle sans backtracking.
  • Couverture tests elevee (95.03%) : les 49 tests unitaires couvrent exhaustivement les invariants. Le pattern mapper + intercepteur facilite le test isole.
  • Faux positifs LLM correctement identifies : la confrontation step 7 a reclasse 4 faux positifs (guards transversaux, RLS, CHECK constraints, tests CI/formel).
  • Convergence Gate 3 v2->v3 rapide : delta +1.0 avec corrections ciblees (verificationRequestId, mode lazy, idempotence concurrente).

4. Points difficiles

  • Gate 3 v1 NON_CONFORME (4.688/10) : score le plus bas de l'historique mesure pour une Gate 3. Les 4 criteres etaient sous 6.0. Cause : la spec v1 ChatGPT manquait de formalisme sur les frontiere interne/API, l'identifiant de verification, et les regles de concurrence.
  • Gate 5 v1 NON_CONFORME (5.5/10) : le plan v1 manquait de detail sur la faisabilite (lecture seule vs mutation DB pour SLA lazy) et la couverture des invariants. Le tension entre "reclassification lazy" (impliquant une mutation) et "endpoint lecture seule" (INV-280-09) a necessite 3 iterations pour etre resolue par le pattern "projection a la lecture".
  • Ambiguite reclassifie dans la spec : le verbe "reclassifie" dans le contexte SLA a ete interprete comme une mutation DB, alors que la spec + INV-280-09 imposent un endpoint lecture seule. Resolution : semantique de "projection a la lecture" documentee dans le plan §2.2.
  • Ecart MAJEUR E-01 residuel : l'intercepteur ne valide pas explicitement verificationStatus in {PENDING, DONE}. Accepte en Gate 8 car defense-in-depth (le mapper ne produit que ces 2 valeurs), mais dette technique a corriger.

5. Hypotheses revelees tardivement

  • HT-03 (DB accepte deja 'PENDING' comme string) : decouverte a l'etape 6 — le champ chain_blockchain dans IntegrityCheckAttempt avait deja default: 'PENDING' en DB, confirmant que PostgreSQL accepte la string sans ALTER TYPE formel. A valider en environnement DEV.
  • Tension lecture seule vs persistance UUID : decouverte a l'etape 5 (v2) — le verificationRequestId doit etre stable entre PENDING et DONE mais l'endpoint est lecture seule. Resolution : UUID genere a la creation du job (processus externe), lu par l'endpoint GET.
  • Projection vs mutation pour SLA lazy : decouverte a l'etape 5 (v1->v2) — la spec dit "reclassifie" mais l'endpoint est lecture seule. Le plan a clarifie : projection a la lecture (pas de mutation en base).

6. Invariants complexes

  • INV-280-02 (status-coherence) : biconditionnelle PENDING ssi au moins un null. Necessite un mapper derive + un intercepteur de verification en sortie. — TC-NOM-01, TC-NOM-02, TC-ERR-03
  • INV-280-06 (job-transitions) : DONE terminal avec idempotence sur rappel. La resolution de l'ambiguite "meme verification" par l'introduction du verificationRequestId a coute 2 iterations de Gate 3. — TC-INV-06
  • INV-280-09 (concurrent-idempotence) : endpoint lecture seule sans lock applicatif. Impose que la resolution des maillons soit realisee par des processus externes. — TC-NOM-10

7. Dette technique

  • E-01 : validation explicite verificationStatus dans intercepteur — impact: moyen. ~5 lignes + 1 test. Non bloquant mais defense-in-depth incomplete.
  • E-02 : requestId manquant dans logs intercepteur — impact: faible. Correlation forensique incomplete, proofId seul present.
  • E-03 : fallback null silencieux dans mapLinkValue — impact: faible. Masquage potentiel de corruption, intercepteur couvre en defense-in-depth.
  • E-04 : guardFinalization partiel — impact: faible. Ne detecte que CheckResult.PENDING explicitement, pas les strings corrompues.
  • E-05 : migration DB sans ALTER TYPE — impact: faible. DB accepte deja 'PENDING' comme string (HT-03), mais delta contractuel a documenter.
  • E-06 : DTO pendingReason type string au lieu d'enum — impact: faible. Validation runtime assure par intercepteur.

8. Risques residuels

Risque Type Probabilite Impact Mitigation
Maillon PENDING indefini sans worker SLA ops moyen moyen Mode lazy couvre les appels API ; worker a planifier (STUB PD-???)
HT-03 non valide en DEV tech faible moyen Tester ALTER TYPE ADD VALUE sur environnement DEV avant deploiement
Clients legacy ignorant null dans linkResults metier faible moyen Documentation API + politique versionnement a definir
E-01 (verificationStatus non valide) tech faible faible Ajouter check explicite dans l'intercepteur (dette mineure)

8bis. Matrice de delegation inter-PD

Story Direction Statut Nature de la dependance Probleme rencontre
PD-251 <- depend de DONE Enum CheckResult partage, patterns verification integrite RAS — enum etendu sans casse
PD-281 -> bloque TODO Zlint anchor enum — detection PENDING_FINALITY A surveiller si PD-281 modifie validateurs d'ancrage
PD-??? -> bloque TODO Worker SLA background (reevaluation active) Story non creee, mode lazy suffisant pour l'instant

8ter. Bugs de tests

Aucun bug de test rencontre. Les 49 tests ont passe au premier cycle d'implementation.

8quater. Corrections post-Gate 8

Aucune correction post-Gate 8 necessaire. Gate 8 GO en v1.

9. Patterns recurrents detectes

9.1 Patterns confirmes (deja vus dans d'autres stories)

  • Machine a etats avec transitions interdites : FSM 4 etats avec transitions monotones (PENDING -> {OK,KO,INDETERMINATE}). Pattern stabilise, 9e occurrence. — aussi dans PD-82, PD-250, PD-264, PD-251, PD-277, PD-276, PD-275, PD-279
  • Guard de securite fail-closed : intercepteur de coherence rejette 500 au lieu d'envoyer une reponse incoherente. 9e occurrence. — aussi dans PD-238, PD-240, PD-250, PD-251, PD-277, PD-276, PD-275, PD-279
  • Stubs inter-PD documentes avec story destination : 2 STUBs (PD-281, PD-??? Worker SLA). Pattern accepte en Gate 8. 9e occurrence.
  • Format non contractualise en spec v1 : frontiere interne/API, verificationRequestId, regles de concurrence absents en v1 -> Gate 3 NON_CONFORME. 10e occurrence.
  • Faux positifs LLM en reviews : guards transversaux, RLS, CHECK constraints signales comme CRITIQUE/MAJEUR par ChatGPT mais hors perimetre PD-280. 7e occurrence.
  • Sonar Phase 1.5 indisponible : QG ERROR cross-project, 0 issues dans probatiovault-backend. 6e occurrence.

9.2 Nouveaux patterns identifies

  • Projection a la lecture vs mutation pour logique lazy : la reevaluation SLA est une projection (pas de mutation DB) pour respecter la lecture seule de l'endpoint. Pattern a generaliser pour tout endpoint GET qui doit "evaluer" un etat derive. — a surveiller dans les prochaines stories.
  • Intercepteur de coherence DTO en sortie : VerificationContractInterceptor verifie les invariants de coherence APRES construction de la reponse, AVANT envoi au client. Pattern NestJS sous-utilise mais puissant pour defense-in-depth contractuelle. — a surveiller.
  • Double NON_CONFORME Gate 3+5 v1 sur story complexe : premiere occurrence de double NON_CONFORME en v1 pour les deux premieres gates. Indicateur de complexite conceptuelle elevee (frontiere interne/API + lecture seule + idempotence concurrente).

10. Ameliorations du workflow

10.1 Ameliorations des prompts/templates

Fichier Amelioration suggeree Priorite
templates/prompts/1 Specification.md Exiger une section "Mapping interne/API" explicite quand l'API expose une transformation non triviale (ex: PENDING interne -> null API) haute
templates/prompts/1 Specification.md Exiger un identifiant technique UUID serveur pour toute ressource stateful (evite ambiguite "meme verification") moyenne
templates/prompts/4 Plan d'implementation.md Clarifier la semantique lecture seule vs mutation quand la spec utilise des verbes ambigus ("reclassifie", "met a jour") haute
templates/prompts/7a Review Code.md Injecter la liste des intercepteurs/guards transversaux pour reduire les faux positifs sur les checks de securite hors perimetre moyenne

10.2 Ameliorations des agents

Agent Amelioration suggeree Justification
config/agents step 1 Pour stories avec frontiere interne/API, injecter les conventions de mapping (null = en cours, enum = terminal) Eviterait ambiguite AMB-01 recurrente
config/agents step 5 Ajouter check explicite : si spec dit "reclassifie/modifie" et plan dit "lecture seule", forcer la resolution avant v2 Eviterait double NON_CONFORME Gate 3+5

10.3 Ameliorations du processus

  • Resoudre la tension lecture/ecriture en spec (etape 1) : quand la spec utilise des verbes impliquant une mutation ("reclassifie", "met a jour") mais que le perimetre impose la lecture seule, la spec DOIT expliciter "projection a la lecture" des l'etape 1. Cela aurait evite 2 iterations de Gate 5.
  • Pre-check Gate 3 sur la frontiere interne/API : ajouter une checklist "Si API expose une transformation non triviale, la spec documente-t-elle le mapping ?" avant de soumettre a Gate 3.

11. Enseignements cles

  1. Projection vs mutation dans les endpoints lecture seule — quand la spec exige une "reevaluation" ou "reclassification" mais l'endpoint est GET (lecture seule), modeliser la logique comme une projection a la lecture. Documenter explicitement cette semantique dans le plan pour eviter les allers-retours Gate 5.

  2. Intercepteur de coherence en sortie (defense-in-depth) — un intercepteur NestJS verifiant les invariants de coherence DTO APRES construction de la reponse et AVANT envoi au client est un pattern puissant pour les contrats d'API complexes. Cout : ~50 lignes de code + tests dedies. ROI : Gate 8 GO en v1.

  3. Double NON_CONFORME v1 = indicateur de complexite conceptuelle — un double NON_CONFORME en Gate 3 v1 + Gate 5 v1 signale une story avec ambiguite conceptuelle elevee. Investir plus de temps a l'etape 0 pour clarifier les frontieres et semantiques avant la spec ChatGPT.

  4. verificationRequestId comme desambiguisateur — l'introduction d'un identifiant technique UUID serveur elimine l'ambiguite "meme verification" et simplifie la modelisation de l'idempotence. Pattern a generaliser pour toute ressource stateful avec etats transitoires.

  5. SLA lazy sans worker = dette planifiee — le mode lazy (projection a la lecture) est suffisant pour un MVP mais necessite un worker pour la couverture operationnelle complete. Documenter le STUB avec story destination des l'etape 4.

12. Metriques cumulatives (auto-calculees)

Metrique Cette story Moyenne projet Tendance
Temps total 6.1h 4.8h (7 dernieres)
Iterations gates 7 5.0
Ecarts totaux 19 22.0
Score convergence moyen 9.19/10 8.56/10