Now I have full context. Let me produce the specification review.
PD-84-specification-review.md¶
Metadata¶
- Story ID: PD-84
- Epic: PD-185 — B2C-MINEURS
- Type de revue: Audit technique indépendant — Gate 3 (CONFORMITY_CHECK)
- Documents audités:
PD-84-specification.md(v1.2.0)PD-84-tests.md(v1.2.0)- Date: 2026-02-24
Learnings contextuels injectés¶
Stories précédentes du domaine B2C-Mineurs : PD-79
Patterns à surveiller : - [PD-79] Extension PD-60 via catégorie documentaire — faux positifs LLM fréquents sur défense en profondeur - [PD-106] Contradictions INV vs exigences fonctionnelles sur pré-requis d'authentification - [PD-19] Critères d'acceptation non mesurables → rejet Gate 3 systématique - [PD-31] Audit log avec contexte partiel génère des faux positifs en review ChatGPT
Écarts récurrents : - ECT : SLA non chiffrés, critères subjectifs non testables - AMB : Termes non définis, seuils absents
Points identifiés¶
Point 1¶
Type : Ambiguïté Référence : Spec 3.2.3 / 7.1 (PUT /account/plan) — ECT-v2-05 Description : Le garde-fou production stipule que PUT /account/plan est protégé par ENABLE_PLAN_STUB=true (désactivé par défaut). Cependant, la spécification ne définit pas le comportement exact lorsque cet endpoint est appelé en production avec la variable désactivée : réponse 404 ? 403 ? 501 ? Absence silencieuse de la route ? Le code erreur métier n'est pas documenté. Impact : Une équipe tierce pourrait implémenter un 500 Internal Server Error ou un comportement indéfini en production. Gravité : Mineur
Point 2¶
Type : Hypothèse dangereuse Référence : Spec 3.2.2 (SLA propagation) / TC-SLA-01 Description : Le SLA p95 < 5s et la borne absolue <= 30s supposent un mécanisme de mesure du temps de propagation. Or la spécification ne précise pas le point de départ de la mesure : est-ce l'instant de l'appel PUT /account/plan ? L'instant de la réponse HTTP 200 ? L'instant de l'événement interne ? Et le point d'arrivée : premier appel GET /capabilities retournant true ? Ou moment effectif dans le système ? TC-SLA-01 implique un polling sur GET /capabilities, mais la fréquence de polling impacte directement la mesure p95. Impact : Deux implémentations valides pourraient mesurer des p95 radicalement différents. Le test TC-SLA-01 ne spécifie pas la fréquence de polling ni le N (nombre de répétitions) nécessaire pour un calcul p95 significatif. Gravité : Majeur
Point 3¶
Type : Incohérence Spec↔Tests Référence : Spec 3.2.3 (PREMIUM -> FREE non spécifié) / TC-18 (action 4) Description : TC-18 teste la transition PREMIUM -> FREE via PUT /account/plan (action 4 : {"plan_type": "FREE"}). Or, la spécification ne mentionne jamais la transition inverse PREMIUM -> FREE. La section 3.2.3 ne documente que FREE -> PREMIUM. Le payload { "plan_type": "FREE" } n'est pas contractuellement autorisé. Le test suppose un comportement (downgrade) qui n'est pas spécifié. Impact : TC-18 teste un flux non couvert par la spécification. Soit le test est hors périmètre, soit la spec manque un cas d'usage. La question du downgrade (re-verrouillage des exports, que devient un dossier avec >3 actifs en PREMIUM revenu en FREE ?) est entièrement absente. Gravité : Majeur
Point 4¶
Type : Ambiguïté Référence : Spec 7.1 (POST /folders/{folderId}/documents) / CA-84-04 Description : L'endpoint d'ajout de document vérifie le quota <= 100 en plan FREE. La spécification ne précise pas si cette limite s'applique aussi en plan PREMIUM. La section 3.3 indique "aucune borne supérieure de cardinalité n'est appliquée par PD-84" en PREMIUM, mais la règle de l'endpoint (section 7.1) dit "refuse au-delà de 100 en FREE" — ce qui laisse entendre implicitement que PREMIUM n'a pas de limite. Cependant, aucun CA ne valide explicitement qu'un utilisateur PREMIUM puisse ajouter un 101e document. Impact : L'absence de test explicite du comportement PREMIUM pour les documents > 100 laisse un trou de couverture. Un implémenteur pourrait appliquer la limite 100 globalement par erreur. Gravité : Mineur
Point 5¶
Type : Non testable Référence : Spec 8 (SEC-84-03) — Indisponibilité PD-31 Description : SEC-84-03 spécifie qu'en cas d'indisponibilité du service PD-31, les opérations métier ne doivent pas être bloquées et les événements d'audit doivent être mis en file d'attente. Aucun test ne couvre ce scénario de dégradation (PD-31 indisponible). TC-13 et TC-SEC-04 supposent un canal audit toujours disponible. Impact : Le comportement de file d'attente (retry asynchrone) et la non-interruption des opérations métier ne sont vérifiés par aucun scénario. Un implémenteur pourrait ne pas prévoir ce mode dégradé. Gravité : Majeur
Point 6¶
Type : Ambiguïté Référence : Spec 7.2 (codes de réponse) / Endpoints multiples Description : Le mapping entre codes erreur métier et codes HTTP n'est pas entièrement explicite. QUOTA_FOLDER_LIMIT_REACHED retourne-t-il 422 ou 409 ? FOLDER_CLOSED_READ_ONLY retourne-t-il 409 (conflit d'état) ou 422 (violation règle métier) ? La section 7.2 liste les codes HTTP et les codes métier séparément sans mapping direct, sauf pour FOLDER_ALREADY_CLOSED -> 409. Impact : Deux implémentations conformes pourraient retourner des codes HTTP différents pour la même erreur métier. Les tests n'assertent pas systématiquement le code HTTP exact. Gravité : Mineur
Point 7¶
Type : Hypothèse dangereuse Référence : Spec 3.4 (contrôle de concurrence) / TC-LIM-01, TC-LIM-02 Description : Les tests de concurrence utilisent une "barrière de synchronisation" pour 2 requêtes parallèles, répétées 30 fois. Le résultat attendu est "exactement 1 succès et 1 refus à chaque itération". Cette assertion suppose que les deux requêtes arrivent systématiquement en concurrence réelle (même fenêtre temporelle de transaction). En pratique, une barrière côté client ne garantit pas la concurrence côté serveur — les requêtes peuvent être sérialisées par le framework HTTP, le pool de connexions ou le load balancer. Impact : Le test pourrait passer trivialement (les 2 requêtes sérialisées = toujours 1 succès + 1 refus) sans prouver la robustesse sous concurrence réelle. Le scénario est correct en intention mais l'assertion "déterministe inter-runs" est une hypothèse forte non garantie par l'architecture de test décrite. Gravité : Mineur
Point 8¶
Type : Incohérence Spec↔Tests Référence : Spec 4 (F-84-04, F-84-05) / TC-03, TC-04 — Quota documents en plan PREMIUM Description : F-84-04 dit "Chaque dossier actif DOIT accepter au maximum 100 documents scellés" et F-84-05 dit "Le 101e document DOIT être refusé". Ces règles ne sont pas qualifiées par le plan (FREE seulement). Lues littéralement, elles s'appliquent à tous les plans. Or la section 3.3 et la clarification 2.3 indiquent qu'en PREMIUM les quotas sont levés. F-84-04 et F-84-05 sont en contradiction avec la section 3.3 pour le cas PREMIUM. Impact : Un auditeur tiers pourrait considérer que les quotas de 100 documents s'appliquent même en PREMIUM (lecture littérale des F-84-04/F-84-05). La spec devrait qualifier explicitement "en plan FREE" dans F-84-04 et F-84-05. Gravité : Majeur
Point 9¶
Type : Risque sécu/conformité Référence : Spec 3.2.3 / 7.1 (PUT /account/plan) — ECT-v2-05 Description : L'endpoint PUT /account/plan est un stub de test protégé par variable d'environnement. La spécification ne mentionne aucune authentification renforcée pour cet endpoint en environnement test/development. Un attaquant avec accès au réseau dev/test pourrait changer le plan de n'importe quel compte. De plus, la spec ne précise pas si l'endpoint nécessite un token d'identité (qui peut changer son propre plan ? un admin ? n'importe quel utilisateur authentifié ?). Impact : En environnement de développement ou test partagé, une transition de plan non autorisée pourrait fausser les résultats de test d'autres développeurs. Le risque en production est mitigé par la variable d'environnement. Gravité : Mineur
Point 10¶
Type : Ambiguïté Référence : Spec 3.1 (SealedDocument document_type) / Section 7.1 Description : L'entité SealedDocument définit document_type avec les valeurs IMAGE, AUDIO, VIDEO, PDF, OTHER_SUPPORTED. La spec ne fournit pas la liste exhaustive des types acceptés dans OTHER_SUPPORTED, ni le comportement de rejet si un type inconnu est soumis. Aucun test ne couvre le cas d'un document_type invalide (contrairement à la catégorie de dossier qui a TC-16). Impact : Un implémenteur pourrait accepter tout type MIME ou refuser arbitrairement certains types. Pas de code erreur défini pour type de document invalide. Gravité : Mineur
Point 11¶
Type : Contradiction Référence : Spec 6 (CA-84-08) vs Spec 3.2.1 (états ProbatoryFolder) Description : CA-84-08 (révisé) mentionne "ajout de document est refusé au-delà du quota" pour un dossier CLOSED_READ_ONLY. Or, un dossier CLOSED_READ_ONLY refuse tout ajout de document (pas seulement "au-delà du quota") — c'est le sens de la clôture (section 3.2.1 : "Blocage de toute modification"). La formulation "au-delà du quota" dans CA-84-08 est trompeuse car elle suggère qu'un ajout pourrait être accepté si le quota n'est pas atteint, ce qui contredit l'état CLOSED_READ_ONLY. Impact : Lecture ambiguë du CA-84-08 : un testeur pourrait penser qu'un dossier clôturé avec 50 docs accepte encore des ajouts jusqu'à 100. TC-08 teste correctement le refus systématique, mais le CA est mal formulé. Gravité : Majeur
Point 12¶
Type : Hypothèse dangereuse Référence : Spec 3.1 (entité AuditLogEvent) / SEC-84-03 Description : La spécification déclare une dépendance sur PD-31 pour l'audit log, et SEC-84-03 introduit une contrainte de résilience (file d'attente en cas d'indisponibilité PD-31). L'entité AuditLogEvent est définie dans PD-84 mais appartient fonctionnellement à PD-31. Il n'est pas spécifié si PD-84 crée sa propre file d'attente locale ou si PD-31 fournit déjà un mécanisme de buffer. L'hypothèse implicite est que PD-31 est "fire-and-forget" avec garantie de livraison éventuelle, mais ce contrat n'est pas formalisé dans PD-84. Impact : L'implémentation du retry asynchrone pourrait être dupliquée (PD-84 et PD-31 chacun ayant leur buffer), ou absente (chacun supposant que l'autre gère). Gravité : Mineur
Point 13¶
Type : Non testable Référence : Spec 9.1 — "SLA paramétrable runtime" Description : La section 9.1 mentionne explicitement : "Le besoin ne précise pas si ce SLA est paramétrable runtime." Cette information manquante est signalée mais non résolue (contrairement aux autres items de 9.1 qui portent la mention "Résolu"). Impact : Si le SLA est hardcodé, un changement de configuration nécessitera un redéploiement. Si paramétrable, la surface de configuration doit être documentée. La décision reste en suspens. Gravité : Mineur
Point 14¶
Type : Incohérence Spec↔Tests Référence : Spec 4 (F-84-19) / TC-16 Description : TC-16 indique dans sa colonne "Couvre" : INV-84-04. Or INV-84-04 porte sur "Le nombre de dossiers actifs (3) et de documents par dossier (100) est exact, déterministe et traçable". Le rejet d'une catégorie invalide (TC-16) ne couvre pas cet invariant — c'est un test de validation d'entrée, pas de quota. Le mapping TC-16 → INV-84-04 est incorrect. Impact : L'invariant réellement couvert serait un invariant d'intégrité des données (validation des entrées), qui n'existe pas dans la liste actuelle. Ce faux mapping gonfle artificiellement la couverture d'INV-84-04. Gravité : Mineur
Point 15¶
Type : Ambiguïté Référence : Spec 7.1 (POST /folders) / F-84-03 Description : F-84-03 indique "Chaque dossier DOIT pouvoir être nommé par l'utilisateur et associé à la catégorie probatoire applicable." L'endpoint POST /folders accepte display_name et category comme entrée minimale. Cependant, la spec ne définit pas de contraintes de validation sur display_name : longueur min/max, caractères interdits, unicité, valeur vide. Aucun test ne vérifie le comportement avec un display_name vide ou excessivement long. Impact : Un implémenteur pourrait accepter un dossier sans nom ou avec un nom de 10 000 caractères. Gravité : Mineur
Synthèse¶
| Gravité | Nombre |
|---|---|
| Bloquant | 0 |
| Majeur | 4 |
| Mineur | 11 |
Points majeurs à traiter en priorité :¶
- Point 2 — SLA : point de départ/arrivée de mesure non défini, fréquence de polling et N de TC-SLA-01 non spécifiés
- Point 3 — TC-18 teste un downgrade
PREMIUM -> FREEnon spécifié - Point 5 — Aucun test pour le mode dégradé PD-31 indisponible (SEC-84-03)
- Point 8 — F-84-04 et F-84-05 non qualifiées "en plan FREE", contradiction avec section 3.3
- Point 11 — CA-84-08 formulation "au-delà du quota" trompeuse pour dossier clôturé
Voilà la review complète. 4 points majeurs identifiés :
- SLA-84-01 sous-spécifié — les bornes temporelles existent mais les conditions de mesure (point de départ, fréquence polling, taille d'échantillon) manquent dans TC-SLA-01
- Downgrade PREMIUM→FREE testé mais non spécifié — TC-18 teste une transition inverse jamais documentée
- Mode dégradé PD-31 non testé — SEC-84-03 exige la résilience audit mais aucun scénario ne la vérifie
- Contradiction F-84-04/F-84-05 vs section 3.3 — les règles fonctionnelles de quota ne sont pas qualifiées par plan, alors que la section 3.3 les lève en PREMIUM
Aucun point bloquant. La spécification est globalement bien structurée et la couverture de test est élevée. Les 11 points mineurs portent principalement sur des imprécisions de mapping codes HTTP↔erreurs métier, des validations d'entrée manquantes et des incohérences mineures de traçabilité.