Aller au contenu

PD-32 — Confrontation Gate AMBIGUITY (Step 5)

1. Contexte

  • Story ID : PD-32
  • Gate : AMBIGUITY (Review Plan d'implementation)
  • Date : 2026-02-05
  • Reviewer initial : ChatGPT
  • Confrontation : Claude (Orchestrateur)

2. Documents confrontes

Document Version Hash/Date
PD-32-specification.md v2 2026-02-05
PD-32-tests.md v2 2026-02-05
PD-32-plan.md v1 2026-02-05
PD-32-code-contracts.yaml v1 2026-02-05
PD-32-plan-review.md v1 2026-02-05

3. Analyse des ecarts identifies

DIV-01 : Champ plan expose dans GET (BLOQUANT)

Source : Review ChatGPT - Ecart #1 Observation ChatGPT : Le flux GET planifie retourne { name, email, plan, avatar_url, preferences } alors que plan est un champ protege.

Analyse confrontation : - Plan §2.1 step 8 : "Response 200 → { name, email, plan, avatar_url, preferences }" - Spec §3 : "plan est liste dans Champs proteges" - Spec CA-32-04 : "GET ne contient aucun champ sensible/protege" - Code contract INV-32-08 : "GET DOIT retourner UserProfileResponseDto (name, email, avatar_url)"

Verdict confrontation : ✅ VALIDE - Incoherence triple : Plan vs Spec, Plan vs Code Contract, Definition "protege" vs champs retournes - Le champ plan NE DOIT PAS apparaitre dans la reponse GET selon la spec - Le plan doit etre corrige pour retourner uniquement { name, email, avatar_url, preferences }

Gravite confirmee : BLOQUANT


DIV-02 : Tests acces croise irrealisables (BLOQUANT)

Source : Review ChatGPT - Ecart #3 Observation ChatGPT : TC-ERR-03/04 exigent une cible U2 explicite mais l'endpoint ne permet pas de cibler un autre utilisateur.

Analyse confrontation : - Tests §8 prerequis : "Mecanisme explicite de simulation d'acces croise en environnement de test" - TC-ERR-03 GIVEN : "Le contexte de donnees cible U2" - Plan §5 mapping : "Point d'observation: Absence donnees U2" - Le plan ne decrit PAS comment etablir "un contexte ciblant U2"

Verdict confrontation : ✅ VALIDE - L'endpoint /user/profile n'expose aucun parametre de cible - Le seul moyen de tester est de manipuler le contexte RLS au niveau test - Le plan doit expliciter le mecanisme de test (ex: injection directe SET LOCAL app.current_user_id en test, verification SELECT sur table avec deux users)

Gravite confirmee : BLOQUANT


DIV-03 : Mapping code erreur ERR-32-* non contractualise (MAJEUR)

Source : Review ChatGPT - Ecart #2 Observation ChatGPT : Le mecanisme de production des codes ERR-32-* n'est pas garanti explicitement.

Analyse confrontation : - Plan §6.3 : "Si le filter global ne produit pas le format attendu, creer UserProfileExceptionFilter" - Cette formulation est conditionnelle, pas contractuelle - Spec §6 exige le format {"error":"ERR-32-XXX","message":"..."}

Verdict confrontation : ✅ VALIDE - Le plan devrait affirmer le mecanisme (ExceptionFilter dedie ou configuration globale verifiee) - La formulation "si ... alors" n'est pas un engagement

Gravite confirmee : MAJEUR


DIV-04 : Seuil rate limiting non documente (MAJEUR)

Source : Review ChatGPT - Ecart #4 Observation ChatGPT : Les parametres seuil/fenetre necessaires a TC-ERR-08 ne sont pas documentes.

Analyse confrontation : - Tests §8 prerequis : "Configuration explicite du rate limiting (seuil N requetes, fenetre T secondes)" - Plan §1.3 : "RateLimitGuard global" (reutilise, pas de parametres) - Plan HT-03 : "RateLimitGuard global applique sur routes /user/*"

Verdict confrontation : ✅ VALIDE - Le plan devrait referencer la configuration existante ou documenter les valeurs pour testabilite - Suggestion : ajouter une note sur la configuration globale existante avec reference au fichier de config

Gravite confirmee : MAJEUR


DIV-05 : Hypothese RLS sans verification (MAJEUR)

Source : Review ChatGPT - Ecart #5 Observation ChatGPT : Le plan suppose RLS actif sans mecanisme de verification explicite.

Analyse confrontation : - Plan §8 HT-02 : "RLS PostgreSQL actif en environnement cible" avec impact si faux - C'est une hypothese explicite, pas un ecart implicite - La verification RLS est une responsabilite infra/ops, hors scope PD-32

Verdict confrontation : ❌ NON VALIDE - L'hypothese est explicitement documentee avec son impact - La verification de RLS est hors perimetre PD-32 (cf. H-32-02 dans spec)

Gravite revue : NON RETENU


DIV-06 : Risque serialisation non contractualise (MAJEUR)

Source : Review ChatGPT - Ecart #6 Observation ChatGPT : La protection @Exclude() repose sur une discipline non explicitee.

Analyse confrontation : - Plan §9.1 : "Verifier que ClassSerializerInterceptor est bien applique globalement" - C'est identifie comme risque mais pas comme invariant - Spec HT-04 : "class-transformer @Exclude() fonctionne avec intercepteur global"

Verdict confrontation : ⚠️ PARTIELLEMENT VALIDE - Le risque est identifie mais pas contractualise - Suggestion : ajouter invariant dans code contract controller ou verifier HT-04 en test

Gravite revue : MINEUR (risque identifie, non bloquant)


DIV-07 : AppModule non couvert dans code contracts (MAJEUR)

Source : Review ChatGPT - Ecart #7 Observation ChatGPT : AppModule est modifie mais aucun code contract ne le couvre.

Analyse confrontation : - Plan §1.2 : "AppModule | Import UserModule | src/app.module.ts" - Code contracts : 6 modules listes, AppModule absent - La modification AppModule est triviale (ajout import)

Verdict confrontation : ⚠️ PARTIELLEMENT VALIDE - Formellement, tout composant modifie devrait avoir un contract - Pragmatiquement, l'import est trivial et verifiable par compilation - Suggestion : ajouter un contract minimal ou documenter explicitement l'exclusion

Gravite revue : MINEUR (modification triviale)


DIV-08 : Invariant supplementaire user-module (MAJEUR)

Source : Review ChatGPT - Ecart #8 Observation ChatGPT : L'invariant "export UserProfileService" n'est pas dans la spec.

Analyse confrontation : - Code contract user-module : "Le module DOIT exporter UserProfileService pour injection externe si necessaire" - Aucun invariant spec ne mentionne cet export - C'est une decision technique d'implementation

Verdict confrontation : ✅ VALIDE - Les code contracts devraient tracer les invariants spec, pas en inventer - Si l'export est une decision technique, documenter dans §9 (points de vigilance), pas comme invariant

Gravite confirmee : MAJEUR (incoherence contractuelle)


DIV-09 : Incoherence GET payload Plan vs Code contracts (MAJEUR)

Source : Review ChatGPT - Ecart #9 Observation ChatGPT : Le code contract controller exige name,email,avatar_url mais le plan retourne aussi plan et preferences.

Analyse confrontation : - Code contract INV-32-08 : "GET DOIT retourner UserProfileResponseDto (name, email, avatar_url)" - Plan §2.1 : retourne { name, email, plan, avatar_url, preferences } - Cette incoherence est liee a DIV-01

Verdict confrontation : ✅ VALIDE (mais lie a DIV-01) - La correction de DIV-01 resoudra cette incoherence - Le payload correct est { name, email, avatar_url, preferences } selon spec §5 F-32-01 step 4 - Note : le code contract INV-32-08 omet preferences qui est dans la spec

Gravite confirmee : MAJEUR (subsume par DIV-01)


DIV-10 : Composants reutilises non traces (MINEUR)

Source : Review ChatGPT - Ecart #10 Observation ChatGPT : Guards et middleware critiques non traces dans code contracts.

Analyse confrontation : - Plan §1.3 : "Composants reutilises (sans modification)" - Ces composants sont hors perimetre PD-32 - Leurs invariants sont geres par leurs stories respectives

Verdict confrontation : ❌ NON VALIDE - Les composants reutilises sans modification n'ont pas besoin de code contract PD-32 - La tracabilite est assuree par reference dans le plan

Gravite revue : NON RETENU


4. Synthese des ecarts retenus

ID Description Gravite Correction requise
DIV-01 Champ plan expose dans GET BLOQUANT Retirer plan du payload GET dans le plan §2.1
DIV-02 Mecanisme test acces croise non decrit BLOQUANT Ajouter description du mecanisme de test dans plan §5 ou §9
DIV-03 Mapping ERR-32-* non contractualise MAJEUR Affirmer le mecanisme dans plan §6.3
DIV-04 Seuil rate limiting non documente MAJEUR Ajouter reference config globale dans plan §1.3
DIV-08 Invariant supplementaire user-module MAJEUR Retirer invariant non-spec ou documenter comme decision technique
DIV-09 Code contract INV-32-08 incomplet MAJEUR Ajouter preferences au contrat de sortie
DIV-06 Serialisation non contractualisee MINEUR Renforcer HT-04 ou ajouter note §9.3
DIV-07 AppModule non contractualise MINEUR Ajouter contract minimal ou documenter exclusion

5. Bilan

  • Ecarts BLOQUANTS : 2
  • Ecarts MAJEURS : 4
  • Ecarts MINEURS : 2
  • Ecarts non retenus : 2

6. Verdict confrontation

Le plan d'implementation presente des incoherences significatives avec la specification et les code contracts. Les deux ecarts BLOQUANTS concernent : 1. L'exposition d'un champ protege (plan) dans la reponse GET 2. L'absence de description du mecanisme de test pour les scenarios d'acces croise

Le plan necessite des corrections avant passage a l'implementation.

Statut : ⛔ NON CONFORME (corrections requises)