Aller au contenu

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

1. Résumé exécutif

Métrique Valeur
Objectif initial UI propriétaire (création, liste, détail, révocation, journal) des liens de partage sans compte PD-287, côté React Native / Expo
Résultat obtenu Livraison 10/10 agents, 25 fichiers TS (2 333 lignes) — conforme au plan en surface, partiel sur 4 invariants matérialisés
Verdict final RESERVE (Gate 8 v1, moyenne 7.5)
Tests contractuels 0/45 preuve d'exécution PASS fournie (aucun test Jest dans src/sharing/**)

2. Métriques de convergence

2.1 Temps et itérations

Temps calculés à partir des timestamps artefacts (dir créé 08:56, verdict step 8 15:44).

Étape Durée estimée Durée réelle Itérations Écart
0 - Besoin + clarifications 30 min 96 min 1 +220%
1 - Spécification 2h 12 min 1 -90%
2 - Tests 1h 7 min 1 -88%
3 - Gate spec 1h 14 min 1 -77%
4 - Plan + code-contracts 1h 8 min 1 -87%
5 - Gate plan 1h 15 min 1 -75%
6 - Décomposition + implémentation 4h 282 min 1 (10 agents) +17%
7 - Acceptabilité 2h 18 min 1 -85%
8 - Gate acceptabilité 1h 12 min 1 -80%
9 - REX 30 min 30 min 1 ±0%
TOTAL ~14h 7h44 10 -45%

Commits implémentation : 14:59:30 (agent 1) → 15:14:20 (agent 10) — 15 min de commits sur 4h42 d'étape 6, soit ≈4h de recherche/décomposition/textes ARB/contrats avant les commits.

2.2 Scores de convergence par gate

Gate Score v1 Score final Delta Itérations
Gate 3 8.0/10 8.0/10 +0.0 1
Gate 5 7.875/10 7.875/10 +0.0 1
Gate 8 7.5/10 7.5/10 +0.0 1

Toutes les gates en RESERVE v1 avec moyenne ≥ 7.0 mais au moins un critère < 8.0. Aucune correction de cycle (pas de v2) — l'orchestrateur a laissé les réserves ouvertes à l'appréciation humaine plutôt que de relancer une itération.

2.3 Écarts par catégorie

Extraits des confrontations (step 3, step 5, step 8) + acceptability.

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

Acceptabilité : 4 majeurs confirmés (ACC-01..04) + 2 mineurs (ACC-05, ACC-06) ; 3 faux positifs écartés (E-07, E-09, E-10).

3. Points fluides

  • Décomposition 6a exceptionnellement productive : les 3 textes normatifs manquants (ARB-7, ARB-8, RGPD rétention) ont été résolus lors de la décomposition en négociant des textes par défaut alignés PD-287, sans escalade PO — ce qui a permis d'éviter un blocage v1 des gates ⅗.
  • Waves séquentielles 10 agents en 15 min : de 14:59 à 15:14, chaque agent a produit son module en ~1-2 min (cache-first très efficace). Aucun retry, 0 erreur TS bloquante.
  • Réutilisation PD-287 comme accélérateur documentaire : la story frontend PD-298 a consommé directement les artefacts PD-287 backend (5 états FSM, endpoints, enum eventType) sans redécouverte.
  • Formal-check : aucun blocage formel sur toute la chaîne (domaine sharing-UI non instrumenté, SKIP attendu).
  • Convergence v1 sur toutes les gates : aucune relance, délais inter-gates courts (<30 min chacun).

4. Points difficiles

  • 0 test Jest livré pour les 10 modules (répétition exacte du pattern PD-287). Prérequis Acceptabilité Tests CI : N/A coché sans escalade, puis Gate 8 critère test_coverage: 7.0 — pattern « acceptabilité tacite » déjà identifié PD-287.
  • Sonar scanner local non exécutable (token auth) — dérogation « QG vérifié via API REST » conforme au pattern déjà documenté (12 occurrences récurrentes).
  • Guard owner-only partiellement câblé : src/sharing/guards/index.ts:34 existe mais n'est pas monté dans ProofDetailScreen.tsx → INV-298-12 non matériellement garanti (ACC-01).
  • useProofShares(undefined) dans ShareDetailScreen.tsx:46 : appel déterministe cassé, aucun test ne l'a capturé.
  • Étape 0 longue (96 min) : 3,2× la cible 30 min. Domaine sharing riche (17 invariants, 4 clarifications PO, injection de veille/learnings, formal-check) — répétition quasi-exacte de PD-287 step 0 (101 min).
  • Divergences plan→spec : le plan introduit GET /shares/:id, Idempotency-Key, timeout 30 s, re-check anti-race revoke — non spécifiés et non testés (DIV-01/02/03/04 Gate 5). Pattern « extensions plan→spec non ratifiées » récurrent PD-287.

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

  • HT-01 / D-287-03 (regex email) — découverte step 1 ; résolue step 6a via fallback class-validator @IsEmail() + trim/lowercase aligné backend.
  • HT-02 / texte RGPD — découverte step 3 ; résolue step 6a par template FR structuré (finalité/base/rétention 90j/destinataires/droits) — sans validation Legal.
  • HT-03 / ARB-7 + ARB-8 — découverte step 3 ; résolues step 6a par textes injectés dans les clarifications (cohérents PD-287). Aucun blocage PO requis.
  • HT-04 / mapping eventType — découverte step 3 ; acceptée comme UNKNOWN_EVENT fallback.
  • HT-05 / borne max maxViews — découverte step 3 ; non validée côté client, 400 backend propagée.
  • HT-06/07/08 / contrat PD-287 (offset/limit, ?state=, 204/409 revoke) — non levées avant Gate 5 (plan §8.1 prévoyait levée Wave 2, non documentée) — DIV-14 Gate 5.
  • Stub getAuthToken() — non mentionné ni plan ni spec, découvert en acceptabilité → DIV-08 Gate 8 (ERR-298-11 non vérifiable).

6. Invariants complexes

  • INV-298-07 (emails non loggés) / ACC-03metadata: Record<string, string|number|boolean> relaie encore n'importe quelle valeur. L'invariant exige un allowlist runtime strict, non implémenté.
  • INV-298-09 (IP masquée) / ACC-04 — fallback retourne IP brute/trimmée sur entrée invalide, contraire à l'intention du TC-NEG-07.
  • INV-298-12 (CTA owner-only) / ACC-01 — le guard est écrit mais pas câblé dans l'écran preuve — zone cross-module classique (pattern récurrent PD-251/279).
  • INV-298-17 (pas d'offline) / ACC-05 — aucune garde NetInfo dans les hooks/écrans.
  • INV-298-11 (actions selon état) / DIV-05 step 8useProofShares(undefined) dans ShareDetailScreen casse le contrat proofId non vide.

7. Dette technique

  • Suite tests Jest intégrée (45 TC contractuels) — impact : élevé (aucune garantie runtime, gouvernance partielle).
  • Câblage guard CTA ProofDetailScreen.tsx (cross-module) — impact : élevé (INV-298-12).
  • Allowlist PII telemetry (INV-298-07) — impact : moyen (risque RGPD fuite PII via metadata libre).
  • Fallback masquage IP robuste (INV-298-09) — impact : moyen (affichage IP brute possible sur entrée malformée).
  • Détection NetInfo offline (INV-298-17) — impact : moyen (UX incohérente offline).
  • Levée des placeholders ARB-7/ARB-8/RGPD par validation Legal/PO — impact : faible à moyen (textes corrects techniquement, non juridiquement validés).
  • Intégration auth existante : remplacer getAuthToken() stub — impact : élevé (ERR-298-11 non fonctionnel).

8. Risques résiduels

Risque Type Probabilité Impact Mitigation
Régression UX CTA partage visible sur preuve non possédée tech élevé élevé Story suivante : câbler ShareCta dans ProofDetailScreen.tsx + test intégration
Fuite PII email via metadata telemetry sec moyen élevé Typer metadata avec allowlist stricte (zod.object({...})) + test runtime Sentry
Écran détail cassé sur appel useProofShares(undefined) tech élevé moyen Refactor hook pour tolérer null OU retirer l'appel
400 backend sur maxViews > borne sans message i18n dédié ux faible faible Ajout mapping erreur backend spécifique quand borne fournie
Divergence normalisation email backend vs client tech faible moyen Test contractuel en backend-dev avant release
45 TC non exécutés — régression future non détectée tech élevé élevé Story dédiée test coverage sharing/**
Extensions plan→spec (GET /shares/:id, Idempotency-Key) non ratifiées process moyen faible Check PD-287 Swagger + rétro-ajout à la spec ou retrait du client

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

Story Direction Statut Nature de la dépendance Problème rencontré
PD-287 ← dépend de DONE (RESERVE) Endpoints API, FSM 5 états, enum events, textes ARB-7/ARB-8 implicites FSM backend non entièrement confirmée (HT-07), ?state= non documenté (HT-08), Idempotency-Key non tracé (DIV-03 Gate 5)
PD-298-TESTS → bloque TODO Suite Jest 45 TC (17 NOM + 12 ERR + 8 NR + 8 NEG) À créer
PD-298-GUARD → bloque TODO Câblage ShareCta dans ProofDetailScreen.tsx + guard navigation share/create/:proofId INV-298-12 non garanti sans cette story
PD-298-ACC-FIX → bloque TODO Correction ACC-02/03/04/05 (useProofShares, PII allowlist, maskIp fallback, NetInfo) À planifier sprint suivant
PD-298-PLACEHOLDERS → bloque TODO Validation Legal/PO des textes ARB-7, ARB-8, RGPD rétention 90j Textes fournis par PD-287 mais non Legal-validés
PD-99 (auth core) ← dépend de Existant getAuthToken() réel à substituer au stub Pas d'interface claire documentée dans la story

8ter. Bugs de tests

Pattern incorrect Pattern correct Cause Coût
(aucun test écrit → aucun bug de test observé)

Aucun bug de test capitalisable — il n'y a eu aucun test livré pour la story.

8quater. Corrections post-Gate 8

Aucune correction post-Gate 8 appliquée ; le verdict RESERVE reste ouvert pour décision humaine (stories filles PD-298-GUARD, PD-298-ACC-FIX, PD-298-TESTS à lancer).

9. Patterns récurrents détectés

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

  • 0 test CI livré sur story multi-agents — aussi dans PD-287, PG-03, PG-04, IM-01 — pattern structurel lorsque décomposition 6a ne mandate pas un test par module.
  • Faux positifs LLM en reviews — review code a signalé E-07 (code-contracts YAML vs implémentation adaptée), E-09 (SharingStack absent — faux), E-10 (markdownlint) — 3 faux positifs sur 12 écarts remontés (≈25%) — aligne la fréquence cross-stories.
  • Sonar Phase 1.5 indisponible — dérogation de fait — 13e occurrence (token auth local).
  • Extensions plan→spec non ratifiées (pattern PD-287) — DIV-01/02/03/04 Gate 5 (endpoint détail, anti-race, Idempotency-Key, timeout 30s).
  • Placeholders contractuels résolus en décomposition plutôt qu'escaladés — similaire PD-287 (ARB-7/ARB-8 fournis décomp) ; pattern fragile si Legal refuse les textes.
  • Guard cross-module avec câblage externe oublié — pattern PD-251/PD-279 (guard écrit mais non monté sur la route cible) ; ACC-01 reproduit.
  • Format non contractualisé dans spec v1 bloque en Gate 3 — 25e occurrence : regex D-287-03, textes ARB, copy RGPD, borne maxViews.
  • Machine à états explicite avec transitions autorisées/interdites — 24e occurrence : matrice ALLOWED_ACTIONS 5×5 correctement implémentée.
  • Stubs inter-PD acceptés en Gate 8 si documentés — 19e occurrence (getAuthToken() stub documenté).

9.2 Nouveaux patterns identifiés

  • Décomposition 6a comme point de résolution des placeholders normatifs — PD-287 et PD-298 ont utilisé la décomposition pour fournir des textes ARB/RGPD par défaut plutôt que d'escalader. ROI : -1 iteration par gate. Risque : textes non Legal-validés livrés en production si pas de story follow-up.
  • Réutilisation backend story (PD-287) comme accélérateur frontend (PD-298) — première paire backend→frontend livrée sur un même domaine en 3 jours (PD-287 DONE 2026-04-19, PD-298 DONE 2026-04-22). Temps story frontend -45% vs cible (-3h sur 7h estimées pour une UI 10 modules). À évaluer comme template « pair backend/frontend ».
  • Implémentation 10 agents multi-wave en 15 min chrono — du 1er commit au dernier (14:59→15:14). Plus rapide que PD-287 (10 fichiers en 1h30) grâce à cache prompt-first effectivement appliqué et décomposition 6a détaillée. Rendement décroissant non observé (10 agents = pas d'accélération additionnelle mesurable vs 5).
  • Idempotency-Key UUID v4 côté client sans ratification backend — introduit par le plan unilatéralement (DIV-03 Gate 5). À surveiller si pattern se répète pour valider un besoin cross-story « clés d'idempotence ».

10. Améliorations du workflow

10.1 Améliorations des prompts/templates

Fichier Amélioration suggérée Priorité
templates/prompts/6a-decomposition.md Ajouter un bloc obligatoire « Données résolues (pré-implémentation) » avec traçabilité PO/Legal des décisions — actuellement PD-298 a tranché ARB-7/ARB-8/RGPD sans validation humaine haute
templates/prompts/6a-decomposition.md Exiger livraison d'au moins 1 test unitaire par agent 6b (reprise recommandation PD-287, toujours non appliquée) haute
templates/prompts/9-rex.md Ajouter section « Résolution des placeholders » pour tracer la source des textes normatifs livrés moyenne
templates/prompts/4-plan-implementation.md Détecter automatiquement les extensions plan→spec (endpoints, headers, timeouts non spec'ifiés) et forcer ratification PO ou retour Gate 3 (reprise PD-287) haute
templates/prompts/7a-review-code.md Ajouter item déterministe « guard cross-module câblé au point d'entrée cible » (check grep point d'intégration) moyenne
templates/outputs/PD-XX-acceptability.md Bloquer l'étape 7 si Tests CI : N/A coché sans escalade explicite (reprise PD-287) haute
.claude/commands/gov-gate.md Gate 8 : check déterministe pré-verdict tests > 0 dans le module livré ; refuser si 0 test (reprise PD-287) haute
templates/prompts/6b-agent-task.md Rappeler que tout hook signant un contrat (proofId non vide) DOIT voir ses usages vérifiés en fin de phase 6c (synthèse) moyenne

10.2 Améliorations des agents

Agent Amélioration suggérée Justification
agents/agent-screens.md Ajouter en mission : « vérifier que les hooks consommés respectent leur contrat de type (proofId non undefined) » Bug useProofShares(undefined) non capturé step 6b (ACC-02)
agents/agent-guards.md Ajouter en mission : « câbler explicitement le guard dans le ou les écrans cibles identifiés par le plan §Mécanismes cross-module » ACC-01 : guard écrit mais non monté
agents/agent-telemetry.md Ajouter en mission : « typer strictement metadata avec allowlist Zod ; refuser clés non explicitement autorisées » ACC-03 : PII fuite potentielle via metadata libre
agents/agent-tests.md (à créer) Agent dédié test 6b.N+1 consommant la décomposition et produisant le squelette Jest Absence structurelle de tests — 6b ne livre pas de test, pas d'agent tests

10.3 Améliorations du processus

  • Forcer l'escalade PO sur les placeholders normatifs avant Gate 5 — décomposition 6a ne doit pas se substituer à Legal/PO pour des textes contractuels (ARB-7/ARB-8/RGPD). Rattaché au pattern structurel PD-287/PD-298.
  • Check « 0 test = 0 gate 8 » au niveau skill /gov-gate : refuser le verdict si find src/<module> -name "*.test.ts*" | wc -l == 0.
  • Pair backend/frontend template : documenter l'enchaînement PD-287 → PD-298 comme pattern pour toute feature cross-layer (API livrée puis UI consommatrice). ROI mesuré : -45% temps frontend vs cible.
  • Audit plan→spec automatique : script detect-plan-extensions.py comparant les endpoints/headers/timeouts du plan aux contrats spec, invoqué par /gov-check-plan.

11. Enseignements clés

  1. Tests-as-gate-prerequisite — Une story multi-agents qui livre 25 fichiers sans un seul test renvoie un signal de gouvernance faible même avec Gate 8 RESERVE. Rendre tests > 0 un prérequis déterministe pré-verdict Gate 8 (reprise PD-287). La « dette test » systématique creuse un écart structurel entre conformité formelle et garantie runtime.
  2. Décomposition 6a comme mini-arbitre normatif — Quand spec/plan portent des placeholders contractuels (ARB, RGPD), la décomposition est devenue de facto le point où les textes sont tranchés. Ce shift non documenté fait que des décisions PO/Legal sont prises par l'orchestrateur. À formaliser : soit interdire (escalade obligatoire avant 6a), soit tracer (§« Données résolues » avec source humaine).
  3. Guard cross-module : écrire ne suffit pas, câbler est l'invariant — ACC-01 reproduit un pattern déjà vu PD-251/PD-279. Le plan listait src/screens/proofs/ProofDetailScreen.tsx comme fichier à modifier, mais l'agent guards a uniquement écrit le composant ShareCta. Ajouter une phase 6c.bis « vérification cross-module » avec grep du point d'intégration.
  4. Pair backend→frontend accélérateur — La paire PD-287/PD-298 a tiré bénéfice de la FSM partagée, des endpoints réutilisés, et de 3 textes normatifs déjà tranchés côté backend. Temps frontend -45% vs cible. Réutiliser ce séquencement pour toute feature cross-layer.
  5. Extensions plan→spec récurrentes — PD-287 et PD-298 ont tous deux introduit 4+ extensions non ratifiées (endpoints, headers, timeouts, flux additionnels). Automatiser la détection dans /gov-check-plan phase 4 pour forcer soit la ratification soit le retour Gate 3.

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

Métrique Cette story Moyenne projet Tendance
Temps total 7.74h 6.27h (31 stories)
Itérations gates 3 5.4
Écarts totaux 29 21.2
Score convergence moyen 7.79/10 8.42/10
Temps step 6 (impl) 4.70h 1.33h ↑↑
Stories app mesurées (avec PD-298) 5 avg 9.16h ↓ (plus rapide)