Aller au contenu

PD-287 — Retour d'expérience (REX)

1. Résumé exécutif

Métrique Valeur
Objectif initial Partage de preuve sans compte par lien PRE, OTP et traçabilité probatoire (backend NestJS)
Résultat obtenu Partiel — architecture et entités livrées, 5 bloquants code et 2 critiques sécurité actionnables, tests CI absents, Sonar skipped
Verdict final RESERVE (Gate 3 RESERVE, Gate 5 RESERVE, Gate 8 RESERVE) — continuation validée humainement
Tests contractuels 0/~70 exécutés (aucun test CI n'a été produit dans le périmètre multi-agents)

2. Métriques de convergence

2.1 Temps et itérations

Étape Durée estimée Durée réelle Itérations Écart
0 - Besoin 30 min 101 min 1 +237%
1 - Spécification 2h 11 min 1 -91%
2 - Tests 1h 10 min 1 -83%
3 - Gate spec 1h 37 min 2 -38%
4 - Plan 1h 10 min 1 -83%
5 - Gate plan 1h 18 min 2 -70%
6 - Implémentation 4h 92 min 1 -62%
7 - Acceptabilité 2h 10 min 1 -92%
8 - Gate acceptabilité 1h 20 min 2 -67%
9 - REX 30 min ~15 min 1 -50%
TOTAL ~14h ~5h 40min 12 -60%

2.2 Scores de convergence par gate

Gate Score v1 Score final Delta Itérations
Gate 3 6.00/10 7.25/10 +1.25 2
Gate 5 6.625/10 7.25/10 +0.625 2
Gate 8 5.25/10 7.25/10 +2.00 2

2.3 Écarts par catégorie

Catégorie d'écart Gate 3 Gate 5 Gate 8 Total
ECT (complétude/testabilité) 3 2 4 9
DIV (divergence spec/impl) - 3 14 17
AMB (ambiguïté) 2 2 10 14
SEC (sécurité) - - 5 5
PERF (performance) - - 1 1
TOTAL écarts 5 7 34 46

3. Points fluides

  • Spec enrichie v2 fortement améliorée : delta +1.25 entre v1 et v2 de Gate 3 grâce à l'ajout complet des bornes numériques §5.2, de la FSM explicite §5.5 et des contraintes techniques §10.1.
  • Plan détaillé : 14 composants identifiés, 4 waves de parallélisation, 28 points de vigilance tracés — base robuste pour la décomposition multi-agents.
  • Gate 8 delta +2.0 : la v2 (après corrections) a rattrapé 2 points complets, ce qui démontre la valeur de la boucle de correction.
  • Temps LLM bref : les étapes LLM pures (spec, tests, plan) ont convergé en ~10 min chacune grâce au prompt caching et à l'injection unifiée (PD-295).
  • Traçabilité intégrale : tous les verdicts, reviews et confrontations sont sauvegardés dans le dossier epic.

4. Points difficiles

  • Gate 8 v1 NON_CONFORME sévère (5.25/10) : le code livré par les agents step 6 présente 5 bloquants code + 3 critiques sécurité — le verdict v1 reflète un écart majeur entre plan et implémentation.
  • Tests CI absents : aucun test unitaire/intégration n'a été produit par les agents step 6. agent-tests (C14 du plan) n'a pas été exécuté ou n'a produit aucun livrable testable.
  • Sonar skipped : Docker indisponible et sonar-scanner non installé → Phase 1.5 d'acceptabilité entièrement sautée (violation de la procédure .claude/rules/procedures.md Étape 7).
  • Crypto PRE en mode STUB : la primitive centrale de la story (proxy re-encryption) a été livrée en STUB documenté — ce que la spec/plan interdisaient (INV-287-02 + INV-287-18 + lint CI no-plaintext-key).
  • Session non liée au share_link_id (critique sécurité CVSS 9.1) : violation directe de INV-287-05 (compartimentation) non détectée en cours d'implémentation.
  • Transactions atomiques non appliquées : plusieurs services (createSession, purgeLink, expireOrphanLinks) ont l'audit append hors transaction, violant INV-287-21 (fail-closed).

5. Hypothèses révélées tardivement

  • H-plan-06 (scope ack DRM = compte serveur) découverte à l'étape 4 via ADR-287-02 ; non documentée dans la spec v2.
  • H-plan-08 (idempotence canonique JCS RFC 8785) découverte à l'étape 4 ; impose une contrainte client non documentée dans la spec.
  • Extension enum audit_event_type (LINK_OTP_BLOCKED, LINK_REAUTH_REQUESTED, LINK_REAUTH_CONFIRMED) introduite en step 4 comme « correction spec proposée » — extension non ratifiée par Gate 3.
  • Endpoints /reauth/* présents dans le diagramme de séquence spec mais absents du §5.4 contractuel — formalisés unilatéralement en plan §2.3.
  • OTP_CODE_TTL_SECONDS=300s ajouté par le plan sans décision PO (H-plan-03).
  • max_inline_document_bytes=50 MB introduit par ADR-287-01, absent du §5.2 spec.

6. Invariants complexes

  • INV-287-01 (zero-knowledge) — TC-INV-11 : protocole de grep mémoire non déterministe ; script scripts/security/memory-scan.sh défini en plan §9 point 11 mais non exécuté en acceptabilité.
  • INV-287-13 (hash-chain + ancrage Merkle) — DIV-05 : hash-chain lecture sans verrou → fork en concurrence. ADR-287-03 (worker mono-instance + pg_advisory_lock) non appliqué dans l'implémentation.
  • INV-287-08 (révocation P95 ≤ 2s) — ZO-06 : aucune mesure perf (k6 N≥200) exécutée ; SLO non vérifié.
  • INV-287-12 (anti-enumeration 404 homogène) — DIV-04 : ShareProofGuard relance les NotFoundException avec messages différents, brisant l'enveloppe unique.
  • INV-287-17 (trust-store obligatoire) — DIV-02 + DIV-10 : verifyCertificateChain() pas appelée dans reEncrypt(), TRUST_STORE_CONFIG provider non visible.
  • INV-287-21 (atomicité DB + audit synchrone) — DIV-05 + DIV-08 : multiples services audit hors transaction métier.
  • INV-287-02/18 (PRE obligatoire + roundtrip) — DIV-16 : PRE en STUB, test roundtrip absent.

7. Dette technique

  • Crypto PRE en STUB — impact : élevé. À remplacer par une lib réelle (Umbral PRE ou équivalent) avant tout déploiement.
  • Aucun test CI — impact : élevé. 70+ TC contractuels non couverts. Story de rattrapage obligatoire (suite tests C14).
  • Sonar non scanné — impact : moyen. À exécuter post-merge sur pipeline GitLab ou localement après installation sonar-scanner.
  • Session non scopée share_link_id — impact : élevé. Fix obligatoire avant merge (CVSS 9.1).
  • Extensions plan non ratifiées par spec (enum audit, endpoints reauth, OTP TTL) — impact : moyen. Propagation à la spec ou rollback requis pour cohérence.
  • Worker Merkle mono-instance non garanti — impact : moyen. pg_advisory_lock à implémenter.
  • Mesure P95 révocation absente — impact : moyen. Scénario k6 à produire (PD-287-PERF).
  • 1 TODO tracé (PD-287 Merkle worker stub) — impact : faible.

8. Risques résiduels

Risque Type Probabilité Impact Mitigation
Bypass FSM via réutilisation session inter-liens tech élevée élevé Fix DIV-01 : scoper recipient_session_id à share_link_id avant merge
Crypto PRE stub en pré-prod tech élevée élevé Intégration lib PRE réelle (story dédiée PD-287-CRYPTO)
Fuite bearer via recipient_session_id dans audit events ops moyenne élevé Masquer/hasher la session_id dans les payloads audit (DIV-14)
Race hash-chain divergent → journal non opposable tech moyenne élevé pg_advisory_lock + séquenceur BIGSERIAL strict (ADR-287-03)
Absence test CI → régression silencieuse tech élevée moyen Story C14 de rattrapage tests (backlog post-merge)
Fail-open maybeExpireLink() → TTL contournable tech moyenne élevé Fail-closed strict + retry bornée
Dépassement max_consultations_per_link en concurrence tech faible moyen Verrou optimistique ou feature désactivée jusqu'à correction

8bis. Matrice de délégation inter-PD

Story Direction Statut Nature de la dépendance Problème rencontré
PD-287-CRYPTO → bloque TODO Intégration PRE réelle (Umbral ou équivalent) — stub actuel viole INV-287-02/18 Crypto PRE livrée en STUB
PD-287-TESTS → bloque TODO Suite tests CI (TC-NOM/TC-ERR/TC-INV/TC-NR/TC-NEG) 0 test CI produit par agents
PD-287-PERF → bloque TODO Scénario k6 mesure P95 révocation (INV-287-08) Aucune mesure SLO
PD-287-SONAR → bloque TODO Scan Sonar + rapport QG Docker indisponible
PD-287-FRONT → bloque TODO Page activation destinataire + bandeau RGPD + warning DRM Stubbé dans backend
PD-287-EXT-1 → bloque BACKLOG Seuil intermédiaire non-terminal anti-DoS OTP Dette acceptée MVP
PD-287-EXT-2 → bloque BACKLOG DELETE /owner/shares/:id/recipient-data on-demand Hors périmètre MVP
PD-287-EXT-3 → bloque BACKLOG Transfert ownership pendant vie du lien Hors périmètre MVP
PD-XXX Proofs ← dépend de DONE ProofsService.assertOwner + getEncryptedDocument Hypothèse H-plan-01 assumée ; assertion ownership absente à la création (DIV-03)
PD-XXX HSM ← dépend de DONE/STUB Wrapper HSM pour PRE H-plan-02 assumée ; PRE réelle non fournie par HSM existant

8ter. Bugs de tests

Aucun bug de test rencontré : aucun test n'a été exécuté (0 TC produit).

8quater. Corrections post-Gate 8

Correction Fichier Nature Pipeline
(à venir) Fix session scoping share_link_id recipient-session/recipient-session.service.ts Fix sécurité CVSS 9.1 à planifier
(à venir) Appel verifyCertificateChain dans reEncrypt crypto/pre-crypto.service.ts Fix sécurité CVSS 9.0 à planifier
(à venir) Transactions atomiques audit+métier audit/audit-journal.service.ts, recipient-session/, retention/, reconciliation/ Fix INV-287-21 à planifier
(à venir) pg_advisory_lock worker Merkle audit/merkle-anchor.worker.ts Fix INV-287-13 à planifier
(à venir) Anti-enum uniforme ShareProofGuard sharing.controller.ts / guard Fix INV-287-12 à planifier
(à venir) Installation sonar-scanner + scan - Outillage CI à planifier

9. Patterns récurrents détectés

9.1 Patterns confirmés (déjà vus dans d'autres stories)

  • Génération massive de code sans couverture test proportionnelle — aussi dans PD-80, PG-03, PG-04. Ici amplifié à 52 fichiers TS / 3717 lignes sans aucun test.
  • Validation format ≠ validation fonctionnelle — learning universel 2026-03-09 (PD-283, PD-282, PD-265). Ici : verifyCertificateChain absent dans reEncrypt alors que isReady() seul est appelé.
  • Anti-enumeration messages 404 distincts — aussi dans PD-85. Ici DIV-04 : guard relance NotFoundException avec messages différents.
  • Audit fail-closed absorbé dans catch / hors transaction — aussi dans PD-85, PD-63, PD-250, PD-262, PD-265. Ici DIV-08 : createSession/purgeLink/expireOrphanLinks hors transaction audit.
  • STUB crypto sans story de destination précise — pattern PD-250/PD-251. Ici STUB PD-287 sans date cible de retrait ni story dédiée.
  • Contraintes/extensions plan↔spec non ratifiées — aussi dans PD-254, PD-262. Ici DIV-17 à DIV-22 (6 extensions non ratifiées par Gate 3).

9.2 Nouveaux patterns identifiés

  • Agents isolés sans intégration cross-module — 52 fichiers produits en 4 waves mais session non liée au share_link_id (DIV-01), guard non homogène (DIV-04), trust-store provider non visible (DIV-10) : les agents n'ont pas vu le contrat commun appliqué bout-en-bout.
  • Acceptabilité minimale sans tests ni Sonar — prérequis « Tests CI : pas de tests … (code agents) » coché comme normal, sans escalade : pattern à flagger systématiquement (violation procédure Étape 7).
  • Delta Gate 8 de +2.0 en une seule itération v1→v2 — la correction post-v1 a majoritairement été une mise à jour doctrinale (plan + acceptabilité rediscutés) plutôt qu'un vrai fix code ; à surveiller si le pattern se répète (risque de gate « cosmétique »).
  • Step 0 très long (101 min) — 3× la cible de 30 min. Exploration du domaine sharing + 4 clarifications PO + vérification de cohérence + injection unifiée. À normaliser si répété.

10. Améliorations du workflow

10.1 Améliorations des prompts/templates

Fichier Amélioration suggérée Priorité
templates/prompts/6b-agent-task.md Exiger livraison test unitaire minimal par agent (au moins 1 test par service public) — aucun agent ne doit livrer du code sans test associé haute
templates/prompts/6a-decomposition.md Ajouter section obligatoire « Contrat partagé inter-agents » (ex : scope session, format erreur guard, provider config) que chaque agent doit lire en préambule haute
templates/prompts/7a-review-code.md Ajouter item « Transactions audit+métier atomiques » dans la checklist review (récurrent PD-85/63/250/262/265/287) haute
templates/prompts/7c-review-security.md Ajouter item « Scope session vs scope ressource (compartimentation) » — récurrent ici CVSS 9.1 haute
templates/prompts/3-specification-review.md Exiger bornes numériques complètes §5.2 dès v1 (toutes les bornes + SLA temporels) moyenne
templates/outputs/PD-XX-acceptability.md Bloquer l'étape 7 si « Tests CI » coché « pas de tests » → escalade obligatoire ou job spécifique haute

10.2 Améliorations des agents

Agent Amélioration suggérée Justification
agent-tests (C14 du plan PD-287) Wave dédiée OBLIGATOIRE avec matrice TC-* à produire et exécuter ; bloquer synthèse 6c si suite test absente 0 test CI alors que plan exigeait 80% coverage
agent-sharing-api (ou équivalent orchestrateur step 6b) Vérifier cohérence inter-composants avant synthèse 6c (ex : session liée à ressource, guard homogène) 5 bloquants code issus de désalignement cross-module
agent-crypto-pre Refuser livraison STUB pour primitive obligatoire d'invariant — escalade systématique si la lib/HSM n'est pas disponible INV-287-02/18 violé par STUB accepté tacitement
agent-retention-worker + agent-reconciliation-worker Inclure systématiquement la transaction audit+métier dans le template DIV-08 pattern récurrent

10.3 Améliorations du processus

  • Gate 7 Phase 1.5 (Sonar) non contournable : installer sonar-scanner automatiquement si absent (cf. .claude/rules/procedures.md déjà prescrit) et escalader si Docker indisponible. Ici le workflow a continué malgré le skip.
  • Check pré-Gate 8 « tests exécutés ? » : ajouter une gate déterministe simple (test count > 0) avant de lancer le verdict Gate 8 v1. Évite qu'un verdict soit rendu sur un code non testé.
  • Check post-step-4 « extensions plan vs spec » (/gov-check-plan Phase 4) : détecter automatiquement les champs/events/endpoints introduits par le plan et absents de la spec ; forcer escalade PO ou retour Gate 3.
  • Formal-check integration : le formal-check GO 99.7 step 0 a validé la cohérence du besoin, mais aucun formal-check n'a été lancé post-step-4 ou post-step-6 pour cette story → vérifier que tous les hooks Art. VIII se sont bien exécutés.

11. Enseignements clés

  1. Aucun test, aucune gouvernance — Le plan a prévu agent-tests en wave 4 et exigé 80% coverage. Les agents step 6 ont livré 52 fichiers TS sans aucun test. L'acceptabilité a coché « N/A » sans escalade. Résultat : Gate 8 RESERVE sur un code non testé. Règle à graver : aucun verdict Gate 8 possible si 0 test CI exécuté.
  2. La compartimentation session/ressource se perd en multi-agents — Chaque agent produit son composant conforme à son prompt, mais le contrat transverse (ici : session liée à share_link_id) n'est porté par aucun. Ajouter un contrat partagé inter-agents explicite en step 6a.
  3. Un STUB d'invariant obligatoire est un NON_CONFORME déguisé — Le stub PRE a été accepté comme « attendu, documenté STUB: PD-287 » alors que INV-287-02 et INV-287-18 l'interdisent explicitement. Dérogation jamais tracée formellement par le PO. Règle : un STUB sur une primitive d'invariant obligatoire doit déclencher escalade PO avant Gate 8.
  4. Les extensions plan→spec doivent être ratifiées — 6 extensions (enum audit, endpoints reauth, OTP TTL, inline 50 MB, chiffrement PG, scope ack compte) introduites en plan sans retour vers Gate 3. À terme : soit la spec doit être amendée, soit le plan doit rollback. Le workflow actuel ne force aucune décision.
  5. Transactions atomiques audit+métier : pattern récurrent à coder par défaut — 6e story consécutive (PD-85, PD-63, PD-250, PD-262, PD-265, PD-287) où le pattern est violé. Mûr pour un learning-as-invariant injecté automatiquement dans les prompts agents via .claude/rules/learnings-universal.md (déjà présent mais visiblement non internalisé par les agents step 6).

12. Métriques cumulatives (auto-calculées)

Métrique Cette story Moyenne projet Tendance
Temps total 5.7h 5.9h
Itérations gates 6 (2+2+2) 5.3
Écarts totaux 46 15.4 ↑↑
Score convergence moyen 7.25/10 8.45/10

Cette story cumule plus d'écarts que la moyenne (46 vs 15.4) et un score final sous la moyenne projet (7.25 vs 8.45). Cause principale : 0 test CI livré et crypto PRE en STUB. Story à suivre avec ses 8 dépendances sortantes (CRYPTO, TESTS, PERF, SONAR, FRONT, EXT-½/3).