PD-253 — Review Gate 3 v2¶
Auditeur : Claude (review Gate 3 indépendante) Date : 2026-03-12 Documents audités : PD-253-specification.md (v2), PD-253-tests.md (v2)
Scores¶
| Critère | Score |
|---|---|
| completeness | 8/10 |
| testability | 8/10 |
| clarity | 9/10 |
| traceability | 9/10 |
Score moyen : 8.5/10
Analyse par critère¶
Completeness (8/10)¶
La spec v2 couvre l'ensemble des invariants métier critiques (14 INV), la machine à états complète avec FAILED_TIMEOUT, les règles d'inclusion/exclusion, le modèle de données contractuel, les SLA temporels, les paramètres numériques et les codes d'erreur. La couverture est dense et cohérente.
Gaps résiduels identifiés :
- La transition
READY_FOR_DOWNLOAD → DOWNLOADEDest documentée en spec (§5.5 flux 3), mais le mécanisme de "confirmation de téléchargement réussi" qui en est le trigger n'est pas défini : HTTP 200 S3 ? callback client ? endpoint de confirmation ? L'implémentation est laissée libre, avec risque d'incohérence ou de blocage si la confirmation n'arrive pas. - La politique de purge post-téléchargement (PC-253-02) reste ouverte. Un package en état
DOWNLOADEDn'a pas de rétention contractuelle définie. SiDOWNLOADEDest terminal et que le package reste en staging indéfiniment, c'est une fuite de stockage. À trancher avant Gate 5. - La reprise après
FAILED_TIMEOUT(PC-253-05) n'est pas contractualisée : libération de quota non confirmée explicitement, mode de relance (manuel vs automatique) absent. La définition de "export actif" (§3) exclut implicitementFAILED_TIMEOUT, mais la libération explicite du quota n'est pas contractualisée. - Le schéma complet de
destruction-log.jsonn'est pas contractualisé. Seuldestruction_act_hashest défini en §5.1. Les autres champs (document_id, date, motif légal, référence PD-250) sont absents. Risque d'interopérabilité et de non-conformité NF Z42-013 §13.1. - Le champ
failure_reason(ex:PROOF_ENVELOPE_INCOMPLETE) est référencé dans §6 et dans TC-ERR-06 comme "observable dans les métadonnées de l'export", mais son format (enum ? string libre ?), son emplacement (colonne DB ? champ API GET ?) et ses valeurs contractualisées ne sont pas définis dans le modèle §5.1.
Testability (8/10)¶
Les tests v2 sont bien structurés dans l'ensemble : Given/When/Then déterministes, matrice de couverture exhaustive, tests négatifs et adversariaux pertinents (TC-NEG-01 à TC-NEG-08). L'explicitation de l'asynchronisme (TC-ERR-06, TC-NOM-10) est correcte. L'existence de TC-INV-11 et TC-INV-12 pour les invariants non fonctionnels est appréciable.
Gaps résiduels :
- Aucun test dédié ne couvre la transition
READY_FOR_DOWNLOAD → DOWNLOADED. TC-NOM-09 est générique ("un export dans chaque état, tentative de transitions autorisées puis interdites") mais ne documente pas le mécanisme de confirmation de téléchargement ni l'atteinte effective de l'étatDOWNLOADED. C'est un gap fonctionnel central compte tenu du flux 3 de §5.5. - TC-NOM-14 (annulation depuis
ASSEMBLING) prévoit deux branches (worker pas encore terminé vs déjà terminé), mais ne précise pas comment contrôler de manière déterministe dans quel état se trouve le worker au moment de l'appel DELETE. Sans hook de synchronisation ou chaos test déterministe, ce test risque d'être non-reproductible. - TC-INV-11 (chiffrement artefacts temporaires) mentionne "instrumentation sécurité activable" sans définir le mécanisme d'observation concret. Le test n'est pas reproductible par une équipe tierce sans définition de l'observable.
- TC-INV-12 couvre "crash simulé" générique mais ne modélise pas explicitement le crash OOM/kill-signal qui bypasse le
finallyblock — cas le plus critique pour INV-253-12. Gap de couverture sur le scénario précisément visé par le patternpurgeStale(). - CA-253-12 est marqué "Partielle" dans la matrice de couverture des tests (§2) avec "bloquant" dans §9, mais n'est pas annoté
[CONDITIONNEL]dans le tableau §7 de la spec. Incohérence de qualification entre les deux documents. - TC-NOM-13 accepte "200 ou 204" pour l'annulation réussie, sans que la spec contractualise un seul code HTTP de succès. La disjonction rend le test partiellement non-déterministe.
Clarity (9/10)¶
La machine à états v2 est complète : les 8 états sont explicités avec leurs transitions autorisées/interdites et leur caractère terminal. La note v2 sur FAILED_TIMEOUT vs FAILED est pertinente et justifiée. §5.5 documente l'annulation avec la règle d'idempotence du checkpoint worker. §5.6 clarifie l'atomicité multi-composant avec la table sync/async. §5.7 contractualise les contrôles d'accès pour les trois opérations (GET status, download URL, DELETE).
Seul gap résiduel :
- La relation entre l'état
DOWNLOADEDet la rétention package reste implicite. La spec §5.5 dit "Si non téléchargé avant TTL: EXPIRED" — confirmant que seulREADY_FOR_DOWNLOAD → EXPIREDest possible. Mais la purge du package aprèsDOWNLOADEDn'est pas tranchée. Mérite une note explicite pour éviter une implémentation divergente.
Traceability (9/10)¶
La matrice de couverture §2 des tests est complète et cohérente avec la spec : chaque INV pointe vers des CA et des TC. Les codes d'erreur sont cohérents entre §6 spec et §4 tests. La suppression du 422 est confirmée dans §8 observabilité des tests. Les IDs INV/CA/TC sont stables et traçables. Le lien entre 504 EXPORT_TIMEOUT (code HTTP, §6 spec) et l'état FAILED_TIMEOUT (async) est couvert par TC-ERR-09.
Seul gap résiduel :
- L'ambiguïté entre
504 EXPORT_TIMEOUTcomme code HTTP etFAILED_TIMEOUTcomme état asynchrone n'est pas explicitement résolue : un client qui fait un GET de statut sur un export enFAILED_TIMEOUTreçoit-il un504ou un200avecstatus: FAILED_TIMEOUTdans le body ? Les deux mécanismes sont différents et non précisés.
Écarts résiduels¶
-
ECT-01 [MAJEUR] : Transition
READY_FOR_DOWNLOAD → DOWNLOADEDnon testée explicitement. Aucun TC dédié ne couvre la confirmation de téléchargement et l'atteinte effective de l'étatDOWNLOADED. DIV-03 v1 partiellement résolu (flux documenté en spec §5.5), mais les tests ne couvrent pas ce point. À corriger avant soumission. -
ECT-02 [MAJEUR] : Schéma complet de
destruction-log.jsonnon contractualisé. Seuldestruction_act_hashest défini en §5.1. Les autres champs obligatoires pour la traçabilité NF Z42-013 §13.1 sont absents. TC-NOM-08 ne peut pas valider l'exhaustivité du schéma sans définition complète. -
ECT-03 [MAJEUR] : Champ
failure_reasonnon modélisé dans le modèle de données contractuel §5.1. Format (enum/string), emplacement (colonne DB/champ API) et valeurs contractuelles (PROOF_ENVELOPE_INCOMPLETE, autres ?) absents. TC-ERR-06 s'y réfère comme "observable" sans que l'observabilité soit garantie par contrat. -
ECT-04 [MINEUR] : Mécanisme de "confirmation de téléchargement réussi" non défini. Trigger de la transition
READY_FOR_DOWNLOAD → DOWNLOADEDnon contractualisé. Risque d'implémentation divergente ou de blocage. -
ECT-05 [MINEUR] : Politique de purge post-téléchargement (PC-253-02) non tranchée. Fuite de stockage staging possible sur packages
DOWNLOADED. À résoudre avant Gate 5. -
ECT-06 [MINEUR] : Reprise après
FAILED_TIMEOUT(PC-253-05) non contractualisée. Libération explicite du quota et mode de relance absents. À résoudre avant Gate 5. -
ECT-07 [MINEUR] : TC-NOM-14 potentiellement non-déterministe. Contrôle de l'état du worker au moment de l'appel DELETE nécessite un mécanisme d'injection déterministe non défini.
-
ECT-08 [MINEUR] : TC-INV-11 : observabilité concrète non définie ("instrumentation sécurité activable" sans précision du mécanisme). Test non reproductible par une équipe tierce.
-
ECT-09 [MINEUR] : TC-INV-12 ne modélise pas le crash OOM/kill-signal (bypass
finally). Sous-couverture du cas le plus critique pour INV-253-12. -
ECT-10 [MINEUR] : CA-253-12 non annoté
[CONDITIONNEL]dans §7 spec alors que les tests §9 le qualifient de "bloquant" si métriques absentes. -
ECT-11 [MINEUR] : TC-NOM-13 accepte "200 ou 204" sans que la spec contractualise un seul code HTTP de succès pour l'annulation. Test partiellement non-déterministe.
-
ECT-12 [MINEUR] : Ambiguïté
504 EXPORT_TIMEOUT: code HTTP synchrone (retourné sur quel endpoint ?) vs état asynchroneFAILED_TIMEOUT(visible via GET status). Le mécanisme d'émission du 504 n'est pas explicité.
Convergences v2¶
- Correction DIV-01 (
FAILED_TIMEOUTabsent de la machine à états) : vérifiée. L'étatFAILED_TIMEOUTest présent en §5.4, documenté avec note explicative distinguant timeout infrastructure vs échec fonctionnel, et couvert par TC-ERR-09. - Correction DIV-02 (422 sync/async ambigu) : vérifiée. Le
422est supprimé ; la détection de ProofEnvelope invalide est asynchrone avec étatFAILED+failure_reason: PROOF_ENVELOPE_INCOMPLETE. Confirmé dans TC-ERR-06 et §8 observabilité tests. - Correction DIV-03 (transition
DOWNLOADEDnon testée) : partiellement vérifiée. La spec documente le flux en §5.5 flux 3. Aucun TC dédié ne teste la transitionREADY_FOR_DOWNLOAD → DOWNLOADED(voir ECT-01 MAJEUR). - Correction DIV-04 (fallback export.sig strong→standard non contractualisé) : vérifiée. TC-NOM-06 couvre explicitement le fallback "le package reste au minimum
standardsi vérification strong indisponible". INV-253-06 et H-253-06 sont cohérents. - Correction DIV-05 (accès inter-utilisateur non contractualisé) : vérifiée. §5.7 contractualise les trois endpoints (GET status, download URL, DELETE) avec
403 FORBIDDEN_EXPORT_ACCESS. TC-SEC-01 couvre les trois opérations. - Correction ZO-08 (flux annulation non documenté) : vérifiée. §5.5 flux 4 documente l'annulation complète avec règles d'idempotence, transitions et traçage audit fail-closed. TC-NOM-13 et TC-NOM-14 couvrent les deux cas.
Verdict¶
RESERVE
La spec v2 et les tests v2 atteignent un niveau de maturité élevé. Les six corrections de la v1 sont toutes confirmées, dont cinq entièrement et une partiellement (DIV-03). Trois écarts MAJEURS résiduels (ECT-01, ECT-02, ECT-03) bloquent le GO.
Conditions pour passage GO (v3) :
- ECT-01 [MAJEUR] : Ajouter un TC dédié à la transition
READY_FOR_DOWNLOAD → DOWNLOADEDavec définition du mécanisme de confirmation de téléchargement. - ECT-02 [MAJEUR] : Contractualiser le schéma complet de
destruction-log.jsondans §5.1 (champs obligatoires pour traçabilité NF Z42-013). - ECT-03 [MAJEUR] : Modéliser
failure_reasondans §5.1 (format, emplacement API, valeurs enum contractualisées).
Les écarts MINEURS (ECT-04 à ECT-12) sont des améliorations souhaitables. ECT-05 et ECT-06 doivent être résolus avant Gate 5 (plan). Les autres peuvent être adressés en v3 de spec/tests ou lors de l'étape 4.