PD-46 — Review du Plan d'implémentation (Gate 5)¶
Date : 2026-02-11 Reviewer : Claude Opus 4.5 (orchestrateur, mode factuel) Type : AMBIGUITY
1. Conformité stricte à la spécification¶
Analyse¶
Le plan couvre l'ensemble des éléments de la spécification :
| Élément Spec | Présent dans le plan | Conforme |
|---|---|---|
| Endpoint GET /documents/:id/download | download-controller | ✅ |
| Vérification owner | document-access-guard | ✅ |
| Vérification partage actif | document-access-guard + share-repository | ✅ |
| Vérification B2B (OIDC tenant/role) | document-access-guard | ✅ |
| Pre-signed URL S3 (TTL 5min) | s3-presign-service | ✅ |
| Journalisation DOWNLOAD_SUCCESS/DENIED | audit-download-service | ✅ |
| Codes d'erreur HTTP 401/403/404/410/500 | download.errors | ✅ |
Verdict : Aucune règle ajoutée, aucune règle affaiblie. Conforme.
2. Couverture des invariants¶
| Invariant | Mécanisme dans le plan | Composant(s) | Couvert |
|---|---|---|---|
| INV-46-01 (TTL + droits) | TTL=300s + Guard avant génération | s3-presign-service, document-access-guard | ✅ |
| INV-46-02 (Révocation bloque) | Guard vérifie revoked_at IS NULL | document-access-guard | ✅ |
| INV-46-03 (Download non interrompu) | Pre-signed URL indépendante | Architecture (accepté) | ✅ |
| INV-46-04 (Journalisation append-only) | S3 Events → AuditService | audit-download-service | ✅ |
| INV-46-05 (Attribution acteur+PM) | userId + tenant_id dans event | audit-download-service | ✅ |
| INV-46-06 (Zero-Knowledge) | getSignedUrl() sans GetObject | s3-presign-service | ✅ |
Verdict : 6/6 invariants couverts. Aucun contournement possible par le design.
3. Cohérence Plan ↔ Tests¶
| Test ID | Mécanisme requis | Présent dans le plan | Observable | Réalisable |
|---|---|---|---|---|
| TC-NOM-01 | Guard + presign | ✅ | HTTP 200, URL format | ✅ |
| TC-NOM-02 | Guard + ShareRepo | ✅ | HTTP 200, share check | ✅ |
| TC-NOM-03 | Guard + OIDC claims | ✅ | HTTP 200, tenant_id log | ✅ |
| TC-ERR-01 | JwtAuthGuard | ✅ | HTTP 401 | ✅ |
| TC-ERR-02 | Guard ownership | ✅ | HTTP 403 | ✅ |
| TC-ERR-03 | Guard share.revoked_at | ✅ | HTTP 403 SHARE_REVOKED | ✅ |
| TC-ERR-04 | Guard tenant mismatch | ✅ | HTTP 403 TENANT_MISMATCH | ✅ |
| TC-ERR-05 | Guard role check | ✅ | HTTP 403 INSUFFICIENT_ROLE | ✅ |
| TC-ERR-06 | Document not found | ✅ | HTTP 404 | ✅ |
| TC-ERR-07 | S3 URL expiration | ✅ | S3 AccessDenied | ✅ (E2E) |
| TC-INV-01 | Guard timing | ✅ | Rejet après révocation | ✅ |
| TC-INV-02 | Guard share check | ✅ | Rejet immédiat | ✅ |
| TC-INV-03 | URL independance | ✅ | Download continue | ✅ (E2E) |
| TC-INV-04 | AuditService | ✅ | Event dans registre | ✅ |
| TC-INV-05 | AuditService fields | ✅ | user_id + tenant_id | ✅ |
| TC-ZK-01 | presign sans GetObject | ✅ | CloudTrail analysis | ✅ (E2E/Sec) |
Verdict : Tous les tests sont réalisables avec les mécanismes décrits.
4. Hypothèses implicites identifiées¶
Hypothèses listées dans le plan (explicites) :¶
| ID | Hypothèse | Statut |
|---|---|---|
| H-IMPL-01 | OVH supporte getSignedUrl avec TTL | Documentée ✅ |
| H-IMPL-02 | S3 Events disponibles sur OVH | Documentée ✅ |
| H-IMPL-03 | Table documents existe | Documentée ✅ |
| H-IMPL-04 | Table shares existe | Documentée ✅ |
| H-IMPL-05 | AuditService existant | Documentée ✅ |
| H-IMPL-06 | Keycloak expose tenant_id/roles | Documentée ✅ |
Hypothèses implicites détectées :¶
Aucune hypothèse implicite majeure détectée.
Le plan liste explicitement toutes les dépendances environnementales et techniques.
5. Risques sécurité / conformité¶
| Risque | Traitement dans le plan | Statut |
|---|---|---|
| URL partagée publiquement | TTL 5 min limite l'exposition | ✅ Mitigé |
| Révocation non immédiate | Documenté et accepté (INV-46-03) | ✅ Accepté |
| Contournement Zero-Knowledge | getSignedUrl sans GetObject | ✅ Mitigé |
| Token OIDC falsifié | Validation signature Keycloak | ✅ Mitigé |
| Escalade privilèges B2B | Vérification tenant_id strict | ✅ Mitigé |
| RGPD | Pas de log du contenu | ✅ Conforme |
| NF Z42-013 | Journalisation append-only | ✅ Conforme |
Verdict : Aucun risque sécurité ou conformité non traité.
6. Code Contracts¶
Complétude¶
| Composant du plan | Code contract | Présent |
|---|---|---|
| download-controller | download-controller | ✅ |
| download-service | download-service | ✅ |
| document-access-guard | document-access-guard | ✅ |
| s3-presign-service | s3-presign-service | ✅ |
| audit-download-service | audit-download-service | ✅ |
| share-repository | share-repository | ✅ |
| download.dto | download-dto | ✅ |
| download.errors | download-errors | ✅ |
| download.tests | download-tests | ✅ |
Verdict : 9/9 composants ont un code contract.
Cohérence interfaces¶
Les interfaces déclarées dans les code contracts sont cohérentes avec le plan : - Les dépendances sont correctement déclarées - Les exports correspondent aux classes décrites - Les paths de fichiers ne se chevauchent pas
Couverture invariants/critères¶
| Invariant | Code contracts qui le couvrent | Couverture |
|---|---|---|
| INV-46-01 | download-controller, download-service, s3-presign-service, document-access-guard | ✅ Multi-couche |
| INV-46-02 | document-access-guard, share-repository | ✅ |
| INV-46-03 | s3-presign-service (architecture) | ✅ |
| INV-46-04 | audit-download-service | ✅ |
| INV-46-05 | audit-download-service | ✅ |
| INV-46-06 | s3-presign-service, download-controller | ✅ |
Verdict : Code contracts complets et cohérents.
7. Écarts identifiés¶
ECT-05-01 : Question Q-46-01 non résolue dans le plan¶
Type : Hypothèse implicite
Référence : Q-46-01, Section 8 du plan
Description : La question "Comment le backend détecte-t-il qu'un téléchargement S3 a effectivement eu lieu ?" (Lambda, S3 Events, CloudTrail) n'est pas explicitement résolue dans le plan. Le plan mentionne "S3 Events → Lambda → AuditService" mais ne précise pas le mécanisme exact (Lambda, SNS, polling CloudTrail).
Impact : L'implémentation pourrait diverger selon l'interprétation
Gravité : MINEUR
ECT-05-02 : Question Q-46-02 non résolue dans le plan¶
Type : Hypothèse implicite
Référence : Q-46-02, Section 8 du plan
Description : La question "Le TTL de 5 minutes est-il configurable par environnement ?" n'est pas traitée. Le plan hardcode TTL=300 sans mention de configurabilité.
Impact : Moins de flexibilité pour les tests (doit attendre 5 min réelles)
Gravité : MINEUR
8. Synthèse¶
| Axe d'analyse | Verdict |
|---|---|
| Conformité spec | ✅ Conforme |
| Couverture invariants | ✅ 6/6 couverts |
| Cohérence Plan↔Tests | ✅ Tous tests réalisables |
| Hypothèses implicites | ⚠️ 2 mineures (Q-46-01, Q-46-02) |
| Risques sécurité | ✅ Tous mitigés |
| Code Contracts | ✅ Complets et cohérents |
Écarts totaux : - BLOQUANTS : 0 - MAJEURS : 0 - MINEURS : 2
Recommandation : Le plan est globalement conforme. Les 2 écarts mineurs (questions non résolues) peuvent être acceptés car : - Q-46-01 : Le mécanisme exact de notification S3 est une décision d'implémentation - Q-46-02 : Le TTL peut être rendu configurable sans changer l'architecture
Généré par : Claude Opus 4.5 (orchestrateur) Date : 2026-02-11