Aller au contenu

PD-47 — Retour d'experience (REX)

1. Resume executif

Metrique Valeur
Objectif initial Sauvegarde PostgreSQL chiffree avec PITR et tracabilite probatoire
Resultat obtenu Conforme — 11 services NestJS, 347 tests, coverage 90.39%
Verdict final GO (Gate 8 v1 : 8.5/10)
Tests contractuels 347/347 passes (11 suites)

Story cross-repo (backend + infra) couvrant 4 flux : sauvegarde logique quotidienne (F1), archivage WAL continu (F2), basebackup hebdomadaire (F3), restauration PITR staging (F4). 9 invariants, 9 criteres d'acceptation, 13 agents de generation.

2. Metriques de convergence

2.1 Temps et iterations

Etape Duree estimee Duree reelle Iterations Ecart
0 - Besoin 30 min 160 min 1 +433%
1 - Specification 2h 3 min 1 -97%
2 - Tests 1h 3 min 1 -95%
3 - Gate spec 1h 34 min 2 -43%
4 - Plan 1h 16 min 1 -73%
5 - Gate plan 1h 71 min 2 +18%
6 - Implementation 4h 6h49 1 +71%
7 - Acceptabilite 2h 41 min 1 -66%
8 - Gate acceptabilite 1h 35 min 1 -42%
9 - REX 30 min 30 min 1 0%
TOTAL ~14h ~13.4h 12 -4%

2.2 Scores de convergence par gate

Gate Score v1 Score final Delta Iterations
Gate 3 6.0/10 9.06/10 +3.06 2
Gate 5 5.5/10 8.19/10 +2.69 2
Gate 8 8.5/10 8.5/10 0 1

Double NON_CONFORME Gate 3 + Gate 5 v1. Convergence forte (+3.06 et +2.69 respectivement). Gate 8 GO en v1.

2.3 Ecarts par categorie

Categorie d'ecart Gate 3 Gate 5 Gate 8 Total
ECT (completude/testabilite) 13 10 1 24
DIV (divergence spec/impl) 0 3 1 4
AMB (ambiguite) 4 1 0 5
SEC (securite) 1 2 2 5
PERF (performance) 0 0 0 0
TOTAL ecarts 18 16 4 38

Dominance ECT (63%) : la specification initiale manquait de nombreux details de format, de bornes et de testabilite. Les corrections E-01 a E-18 ont couvert les lacunes de completude.

3. Points fluides

  • Gate 8 GO en v1 : malgre la complexite (13 agents, 11 services), l'implementation a converge directement sans iteration supplementaire a la gate de cloture.
  • Coverage 90.39% : bien au-dessus du seuil de 80%, refletant la qualite des tests generes par les agents.
  • Quality gates toutes vertes : ESLint 0 erreurs, TypeScript 0 erreurs, Prettier conforme, 347/347 tests.
  • Architecture modulaire propre : 11 services avec separation nette des responsabilites (orchestration, chiffrement, journal, watchdog, reconciliation).
  • Etapes 1-2 tres rapides : specification et tests generes par ChatGPT en < 3 min chacun, qualite suffisante pour une correction limitee en Gate 3.

4. Points difficiles

  • Etape 0 disproportionnee (2h40 vs 30 min estime) : la definition du besoin pour une story infra/storage complexe a necessite de nombreux aller-retours avec le PO sur le perimetre exact (WAL, PITR, chiffrement double couche, watchdog independant).
  • Double NON_CONFORME v1 : Gate 3 (6.0/10) et Gate 5 (5.5/10) toutes deux NON_CONFORME en premiere iteration. 18 corrections spec + 16 corrections plan avant convergence.
  • Pause overnight entre Gate 5 v1 et v2 : la correction du plan a necessite une session de 3 min de travail actif le soir (v1) puis 47 min le lendemain matin (correction + v2). Pas de perte de convergence.
  • Step 6 le plus long (6h49) : 13 agents de generation + synthese + correction de 6 erreurs TypeScript + corrections tests pour obtenir 347/347.
  • Sonar CE task FAILED : Elasticsearch indexing du serveur Sonar en erreur, masquant le Quality Gate reel. 0 issues backup module mais le QG global est en ERROR (pre-existant, autres modules).

5. Hypotheses revelees tardivement

  • H-TECH-01 (pg_receivewal sur OVH) : identifiee des l'etape 4 (plan) mais non levee. Le flux F2 WAL continu depend de la disponibilite d'un slot de replication sur le PostgreSQL OVH Cloud Database. Tests E2E WAL conditionnes (SKIP si non leve). Impact : RPO < 5 min non garanti sans cette hypothese.
  • H-TECH-05 (Vault Transit aes256-gcm96) : confirmee comme critique — pas de fallback si Vault indisponible (fail-closed). Decouverte a l'etape 5 que le fallback HKDF local initial violait INV-47-03 et INV-47-09 → supprime.
  • H-TECH-06 (coexistence BullMQ scheduler) : potentiel conflit de scheduling entre le cron backup et les queues BullMQ metier existantes. Non confirme mais documente comme risque.

6. Invariants complexes

  • INV-47-01 (cleartext TTL 300s) — TC-INV-01 : timer strict non configurable. Risque de declenchement premature si pg_dump est lent sur base > 10 GB. Mitigation : timer commence APRES fin d'export.
  • INV-47-05 (journal append-only + dedup) — TC-INV-05 : combinaison INSERT-only (RLS bloque UPDATE/DELETE) + UPSERT ON CONFLICT DO NOTHING pour deduplication par backup_id. Garantie try/finally pour ecriture meme en echec precoce.
  • INV-47-06 (watchdog independant) — TC-INV-06 : decouplage complet via queue BullMQ backup-relaunch. Le watchdog ne depend pas du process orchestrateur. Complexite : si le process NestJS entier crash, le watchdog NestJS crash aussi → fallback Ansible cron documente.
  • INV-47-09 (envelope encryption) — TC-INV-09 : DEK ephemere en memoire, wrappee par K_backup via Vault Transit, zeroisee explicitement post-usage. Source de verite : DB (champ wrappedDek), copie redondante en metadata S3.

7. Dette technique

  • Coherence donnees post-restauration (Q-47-03) — impact: moyen. Le jeu contractuel de tables/compteurs pour valider la coherence apres PITR n'est pas defini. Implementation minimale (count tables + derniere transaction).
  • Granularite journal WAL (Q-47-02) — impact: faible. Implementation 1 evenement par segment WAL. Lotissement ulterieur possible si performance insuffisante.
  • Politique lifecycle versions S3 (Q-47-04) — impact: faible. Ambiguite sur suppression des versions non courantes vs conservation legale. A clarifier hors scope code.
  • backup-relaunch.consumer.ts non teste unitairement — impact: faible. Consumer BullMQ minimal, couvert par tests d'integration. Coverage 0% sur ce fichier.
  • backup-encryption.service.ts a 67% coverage — impact: faible. Methodes Vault init (AppRole, verifyTransitKey) non testees unitairement, testees en integration.

8. Risques residuels

Risque Type Probabilite Impact Mitigation
H-TECH-01 non levee (pg_receivewal OVH) tech elevee eleve Tests E2E WAL SKIP, fallback OVH backup natif non auditable
Sonar CE task infra FAILED ops moyenne moyen 0 issues module backup, QG global pre-existant ERROR
Crash complet process NestJS → watchdog down ops faible eleve Fallback Ansible cron independant documente
Vault Transit indisponible ops faible eleve Fail-closed (pas de fallback), incident operationnel infra
Base > 50 GB → SLA backup depasse metier faible moyen Chiffrement streaming documente comme evolution

8bis. Matrice de delegation inter-PD

Story Direction Statut Nature de la dependance Probleme rencontre
PD-5 ← depend de DONE Storage Vault Lock, Deep Archive, S3 bucket policies RAS — learnings injectes a l'etape 0
PD-264 ← depend de DONE Atomicite multi-composant (DB sync + async BullMQ) RAS — pattern reutilise pour §5.6 crash scenarios
PD-8 ← depend de DONE Vault PostgreSQL backend, AppRole cross-role RAS — pattern auth Vault reutilise pour K_backup

Aucune dependance sortante identifiee. Story autonome.

8ter. Bugs de tests

Pattern incorrect Pattern correct Cause Cout
6 erreurs TypeScript post-generation agents Fix synthese phase 6c Types incompatibles entre services generes par agents differents ~30 min
tests=ko apres synthese Corrections tests + relance Mocks incomplets pour services backup interconnectes ~100 min

8quater. Corrections post-Gate 8

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

9. Patterns recurrents detectes

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

  • Machine a etats explicite avec transitions autorisees/interdites — PD-47 BackupStateService (INV-47-07), 16eme occurrence (PD-82, PD-250, PD-264, PD-251, PD-277, PD-276, PD-275, PD-279, PD-280, PD-278, PD-282, PD-265, PG-02, PG-03, PG-04, PD-47)
  • Guard de securite fail-closed obligatoire — PD-47 Vault Transit indisponible = backup echoue (pas de fallback). 13eme occurrence.
  • Atomicite multi-composant : transaction ACID synchrone + post-commit async — PD-47 §5.6 crash pre/post-commit + reconciliation. 10eme occurrence.
  • Format non contractualise dans spec v1 bloque en Gate 3 — 18 corrections E-01 a E-18, majorite ECT. 17eme occurrence.
  • Stubs inter-PD acceptes en Gate 8 si documentes avec story destination — backup-relaunch.consumer.ts STUB documente PD-47 scope. 13eme occurrence.
  • Faux positifs LLM systematiques en reviews — Reviews code/tests/securite ont produit des ecarts non applicables (auth/authz sur module sans endpoint HTTP). 14eme occurrence.
  • Double NON_CONFORME Gate 3+5 v1 = indicateur complexite conceptuelle elevee — PD-47 confirme le pattern. 4eme occurrence (PD-280, PD-278, PD-282, PD-47).

9.2 Nouveaux patterns identifies

  • Module sans endpoint HTTP → faux positifs securite auth/authz — Le module backup n'expose aucun controleur HTTP (execution via Cron + BullMQ uniquement). La review securite a signale auth/authz comme MAJEUR alors que non applicable. A surveiller dans les prochaines stories infra/jobs.
  • Sonar CE task infra failure masquant le Quality Gate reel — Le serveur Sonar a un probleme d'indexation Elasticsearch qui fait echouer le CE task. Le QG ERROR est pre-existant (autres modules) mais masque l'evaluation reelle du module backup (0 issues). Pattern a surveiller si recurrence.
  • Story cross-repo (backend + infra) avec 13+ agents — Premiere story infra avec flux multi-agents complet. La decomposition a produit 13 taches (T1-T13) dont une relancee (T13-v2). Le cout d'implementation (6h49) est le plus eleve du projet pour une story medium.

10. Ameliorations du workflow

10.1 Ameliorations des prompts/templates

Fichier Amelioration suggeree Priorite
templates/prompts/1 Specification.md Ajouter checklist obligatoire pour stories infra/backup : RPO, RTO, chiffrement, journal append-only, watchdog haute
templates/prompts/7c Review Security.md Ajouter detection project_type (backend API vs cron/BullMQ) pour desactiver criteres auth/authz non pertinents haute
templates/prompts/1 Specification.md Exiger la specification du code de rejet vs etat machine (FAILED_FORMAT vs status enum) pour eviter confusion moyenne
templates/prompts/4 Plan d'implementation.md Ajouter section obligatoire "Hypotheses techniques a lever AVANT implementation" avec actions de levee moyenne

10.2 Ameliorations des agents

Agent Amelioration suggeree Justification
config/agents step 7c Injecter le type de module (HTTP controller / Cron / BullMQ worker) pour filtrer les criteres de securite Faux positifs auth/authz sur module sans endpoint HTTP
config/agents step 6 Pour stories avec 10+ composants, pre-generer les interfaces TypeScript partagees avant de lancer les agents en parallele 6 erreurs TS post-synthese dues a des types incompatibles entre agents

10.3 Ameliorations du processus

  • Lever les hypotheses techniques AVANT Gate 5 : H-TECH-01 (pg_receivewal OVH) aurait du etre testee entre l'etape 4 et l'etape 5. Le plan a ete valide avec un risque majeur non leve.
  • Detecter les stories cross-repo des l'etape 0 : PD-47 touche backend + infra mais l'epic est dans infra. La complexite de coordination inter-repo devrait etre signalee dans le besoin.
  • Corriger l'infrastructure Sonar : le CE task FAILED Elasticsearch rend la Phase 1.5 Sonar non fiable. Action infra necessaire.

11. Enseignements cles

  1. Envelope encryption Vault Transit fail-closed — Quand un service crypto externe (Vault Transit) est la seule source de cles, ne JAMAIS implementer de fallback local. Un fallback viole la separation des cles (INV-47-03) et l'envelope encryption (INV-47-09). L'indisponibilite de Vault est un incident infra, pas un contournement applicatif.

  2. Journal append-only avec garantie try/finally — Pour tout journal d'audit probatoire, wrapper l'execution complete dans un try/finally qui garantit l'ecriture d'au moins un evenement (status=FAILED avec code erreur), meme en echec precoce (avant upload, avant chiffrement). Sans cela, un crash pre-upload produit une execution sans trace.

  3. Watchdog independant via queue BullMQ — Le decouplage d'un watchdog de son orchestrateur par une queue de messages (pas d'injection directe) est le pattern correct. Le watchdog produit un job de relance dans la queue ; un consommateur separe injecte l'orchestrateur. Ainsi le watchdog reste reellement independant.

  4. Hash SHA3-256 sur le clair AVANT chiffrement — Pour une verification d'integrite de bout en bout, le hash doit etre calcule sur le clair compresse (pas sur le ciphertext, pas sur le clair non compresse). La verification post-upload necessite un GetObject + dechiffrement + recalcul SHA3-256 (pas de confiance sur l'ETag S3 qui est MD5).

  5. Double NON_CONFORME v1 = complexite conceptuelle — Quand Gate 3 ET Gate 5 sont NON_CONFORME en v1, c'est un indicateur fiable de complexite conceptuelle elevee. Les corrections sont massives (18 + 16 ecarts) mais la convergence est forte (+3.06 et +2.69). Le processus fonctionne : les gates detectent, les corrections convergent.

12. Metriques cumulatives (auto-calculees)

Metrique Cette story Moyenne projet Tendance
Temps total 13.4h 6.1h
Iterations gates 5 5.4
Ecarts totaux 38 21.9
Score convergence moyen 8.58/10 8.47/10