PD-101 — Plan d'implémentation : Revue¶
1. Références¶
- Spécification : PD-101-specification.md
- Tests contractuels : PD-101-tests.md
- Plan d'implémentation : PD-101-plan.md
- Code contracts : PD-101-code-contracts.yaml
- Date de revue : 2026-03-10
- Reviewer : Claude Opus 4.6 (mode factuel, temperature 0.1)
2. Constatations (écarts)¶
| # | Type | Référence (Spec/Test/Plan) | Description | Impact | Gravité |
|---|---|---|---|---|---|
| E-01 | Non-conformité Spec | Spec §3.2 vs Plan §1 CC-101-T1 | Seuil taille fichier incohérent : Spec §3.2 définit file_size_bytes max = 524 288 000 bytes (500 MiB, binaire). Plan déclare UPLOAD_SIZE_LIMIT = 500_000_000 bytes (500 MB, décimal SI). Écart de ~24 MB. La spec utilise explicitement "SI base 10" pour le seuil multipart (10 000 000) mais pas pour la taille max. Le plan applique implicitement la base 10 sans justification. | Un fichier de 510 MB serait accepté par le plan mais refusé par la spec. Ou inversement selon l'interprétation. Ambiguïté contractuelle. | MAJEUR |
| E-02 | Test irréalisable | TC-INV-08 / Plan §11 | TC-INV-08 hors scope exécutable : Le test exige "Accès lecture à la base de données backend" pour vérifier l'absence de secrets crypto en clair (INV-08). Le plan §11 déclare "Intégration avec backend réel (PD-63) : endpoints mockés, car dépendance cross-repo". Un test sur mocks ne peut pas vérifier ce que le backend stocke réellement en DB. Le test est mappé à T3+T4+T13 mais l'observable réel est côté backend. | INV-08 déclaré couvert mais non vérifiable dans le périmètre PD-101 mobile. Couverture illusoire. | MAJEUR |
| E-03 | Code Contract — Cohérence | CC-101-T9 / INV-04 | optimizedConsent optionnel sans garde : StartUploadParams déclare optimizedConsent?: OptimizedConsent (optionnel). Si optimized: true et optimizedConsent est undefined, l'orchestrateur procède sans preuve de consentement. Aucune garde dans les invariants de CC-101-T9 ne valide la cohérence optimized=true → optimizedConsent requis. | Violation potentielle de INV-04 (consentement explicite traçable). La preuve §3.4 pourrait ne pas être persistée. | MAJEUR |
| E-04 | Contrainte technique non documentée | Plan §8 / CC-101-T3 | Compatibilité ESM/CJS non adressée : @noble/ciphers (mentionné HT-03) est un package ESM-only. Le plan ne documente pas la configuration Jest requise (transformIgnorePatterns, moduleNameMapper, ou migration vers Vitest). React Native + Jest a des incompatibilités connues avec les packages ESM-only. | Tests T13 potentiellement non exécutables sans configuration spécifique. Blocage CI possible. | MAJEUR |
| E-05 | Risque sécu/conformité | CC-101-T11 / Learning anti-catch-absorb | Audit fire-and-forget sans garantie de livraison : CC-101-T11 déclare "Emission non bloquante (fire-and-forget via auditQueue existant)" et interdit de "Bloquer le flux upload en attendant la reponse audit". Si auditQueue échoue silencieusement (queue pleine, erreur sérialisation), les événements d'audit critiques (consentement optimisé §3.4, transitions d'état, purgeStale) sont perdus sans trace. Le contrat ne spécifie pas le comportement en cas d'échec de l'émission audit. | Perte de traçabilité (Art. III constitutionnel). Les preuves de consentement (INV-04) et transitions d'état (INV-09) pourraient ne pas être auditées. | MAJEUR |
| E-06 | Code Contract — Cohérence | CC-101-T12 dependencies / CC-101-T11 | Dépendance T12→T11 manquante : CC-101-T12 (UI) dépend de [T8, T9] mais pas de T11 (audit). Or T12 doit émettre des événements audit pour la confirmation EXIF (auditExifConfirmation), le choix transcodage (auditTranscodingChoice), et le consentement optimisé (auditOptimizedConsent). Ces événements surviennent dans le contexte UI, avant l'appel à l'orchestrateur. | Événements audit UI orphelins — aucun composant n'est contractuellement responsable de les émettre avant startUpload(). | MINEUR |
| E-07 | Hypothèse implicite | Plan §2.1 / Spec §5.1 étape 8 | Contrat API d'initialisation non spécifié : Le plan envoie tous les artefacts crypto (nonce, auth_tag, sha3_256, optimized, ios_transcoded) dans initUpload() au moment de l'initialisation backend. La spec §5.1 étape 8 dit "création enregistrement PENDING + URL pré-signée(s)" sans détailler le payload. Le plan fait une hypothèse implicite sur la répartition des données entre init et finalisation qui n'est pas contractualisée dans la spec. | Divergence possible avec le contrat backend PD-63 si celui-ci attend certaines données à la finalisation plutôt qu'à l'init. | MINEUR |
| E-08 | Code Contract — Complétude | CC-101-T9 invariants | Checkpoints UI absents de la séquence orchestrateur : L'invariant de séquence de CC-101-T9 est "purgeStale() → validate size → generate doc_id → hash → encrypt → verify → init → upload → finalize". Les étapes UI (disclaimer EXIF, avertissement transcodage) ne sont pas dans cette séquence car elles sont en amont (C12). Mais StartUploadParams ne contient ni exifConfirmed ni mécanisme de preuve que ces gates UI ont été franchies. | Un appel programmatique à startUpload() contournerait les gates EXIF et transcodage. Risque faible en pratique (UI seul appelant) mais non contractuellement garanti. | MINEUR |
| E-09 | Code Contract — Invariant | Validation section ca_coverage | CA-02 coverage incomplète : La section validation du code contracts mappe CA-02 à [T11, T12]. Le plan §4 mappe CA-02 à "C12, C11, C4" (incluant C4 pour la persistance metadata backend optimized=true). T4 est absent de ca_coverage pour CA-02. | Couverture contractuelle déclarée incomplète pour la persistance backend de la preuve de consentement. | MINEUR |
| E-10 | Contrainte technique non documentée | Plan §11 / CC-101-T13 | Framework de test implicite : CC-101-T13 mentionne "jest mock" et "fake timers" mais ne déclare pas explicitement Jest comme framework choisi. La convention projet exige "Jest ou Vitest explicitement choisi — pas de silence ambigu". | Ambiguïté de configuration CI, particulièrement critique combinée à E-04 (ESM/CJS). | MINEUR |
| E-11 | Hypothèse implicite | Plan §1 CC-101-T8 | Historique upload dans le store : CC-101-T8 introduit history: UploadRecord[] dans le store Zustand. La spec ne mentionne pas de conservation d'historique des uploads. C'est une fonctionnalité ajoutée non spécifiée. L'impact est faible (utile pour le flux retry §5.4) mais viole le principe "aucune règle ajoutée". | Donnée non spécifiée persistée dans le state. Pas de politique de rétention définie (croissance illimitée ?). | MINEUR |
3. Synthèse¶
Nombre d'écarts par gravité¶
| Gravité | Nombre |
|---|---|
| BLOQUANT | 0 |
| MAJEUR | 5 |
| MINEUR | 6 |
Points critiques¶
-
E-01 — Seuil taille : La spec a une incohérence interne (§3.2 utilise binaire 524 288 000, §5.5 et le reste utilisent "500 MB" conceptuel). Le plan doit expliciter quelle interprétation est retenue et pourquoi, ou la spec doit être corrigée.
-
E-03 — Guard
optimizedConsent: L'absence de validation dans l'orchestrateur crée un chemin d'exécution oùoptimized=truesans preuve de consentement est possible. La correction est simple (rendreoptimizedConsentrequis quandoptimized=true, ou ajouter une garde dansstartUpload()). -
E-04 — ESM/CJS :
@noble/ciphersESM-only est un blocage potentiel de CI. Ce point a déjà causé des échecs sur d'autres projets React Native avec Jest. À documenter avec la configuration requise. -
E-02 — TC-INV-08 : Le test doit être explicitement classé comme "cross-repo, délégué au backend" dans le plan plutôt que mappé à des composants mobiles. La couverture mobile se limite à vérifier que les secrets ne sont pas envoyés en clair via l'API (déjà couvert par TC-INV-01).
-
E-05 — Audit fire-and-forget : Le contrat doit documenter le comportement de
auditQueueen cas d'échec (retry local ? persistance disque ? drop silencieux ?). La perte d'événements audit sur le consentement optimisé (INV-04) est un risque de conformité.
Points positifs (hors scope revue mais notés)¶
- Couverture INV → mécanismes complète (10/10 invariants mappés).
- Découpage modulaire cohérent (13 composants, frontières claires).
- Mapping TC → composants exhaustif (46 tests mappés).
- Risques et dette technique documentés de manière transparente.
- Séquence stricte encrypt→upload bien contractualisée (INV-01, INV-02).
4. Verdict de la revue¶
- Statut : ⚠️ Accepté avec réserves
- Motif synthétique : Le plan est structurellement solide avec une couverture invariants/tests complète. Les 5 écarts MAJEUR sont corrigeables sans refonte architecturale : clarifier le seuil de taille (E-01), ajouter une garde
optimizedConsent(E-03), documenter la configuration ESM (E-04), reclasser TC-INV-08 comme cross-repo (E-02), et spécifier le comportement audit en cas d'échec (E-05). Aucun écart BLOQUANT identifié.