PD-253 — Rapport de confrontation (Gate 8 — CLOSURE)¶
Ce rapport est produit par l'orchestrateur Claude avant la gate PMO 8. Il confronte les documents produits pour identifier convergences, divergences et zones d'ombre.
1. Sources confrontées¶
- Specification : PD-253-specification.md (v2) — étape 1
- Tests : PD-253-tests.md (v2) — étape 2
- Plan : PD-253-plan.md (v1.0) — étape 4
- Acceptability : PD-253-acceptability.md — étape 7
2. Convergences¶
-
C-01 — Machine à états (INV-253-13) : Les 8 états (
REQUESTED,ASSEMBLING,READY_FOR_DOWNLOAD,DOWNLOADED,EXPIRED,FAILED,FAILED_TIMEOUT,CANCELLED), les transitions autorisées/interdites, et le caractère terminal de 5 états sont cohérents entre spec §5.4, tests TC-NOM-09/TC-NOM-13/TC-NOM-14, plan CC-253-04, et acceptabilité (corrections appliquées).FAILED_TIMEOUTdistinct deFAILEDdans tous les documents. -
C-02 — 14 invariants : Les 14 invariants (INV-253-01 à INV-253-14) sont identiques dans la spec, couverts par la matrice de tests (§2), mappés aux tâches dans le plan (§8), et vérifiés dans l'acceptabilité (corrections E-01 à E-05, T-01 à T-03, S-01 à S-07).
-
C-03 — Dual manifest (INV-253-04) : Noms
manifest-sha256.txtetmanifest-sha3.txtalignés entre spec, tests TC-NOM-04, plan CC-253-09. Correction E-03 dans l'acceptabilité confirme le renommage effectif demanifest-sha3-256.txt→manifest-sha3.txt. Convergence confirmée après correction. -
C-04 — Audit fail-closed (INV-253-10) : Pattern anti-catch-absorb contractualisé dans spec, testé (TC-ERR-07), formalisé dans plan CC-253-05 (pattern fail-closed explicite), et corrigé dans acceptabilité (E-01 : injection
AuditLogService, T-02 : +2 tests audit). Convergence confirmée après correction. -
C-05 — Quota 1 actif/user (INV-253-07) : 3 statuts actifs (
REQUESTED,ASSEMBLING,READY_FOR_DOWNLOAD) — cohérent entre spec, tests TC-ERR-04, plan CC-253-04/CC-253-07 (COUNT WHERE status IN 3 statuts), et acceptabilité (correction T-01/S-01 ajoutantREADY_FOR_DOWNLOADàACTIVE_BULK_EXPORT_STATUSES). Convergence confirmée après correction. -
C-06 — Soft-deleted / destroyed (INV-253-09) : Inclusion soft-deleted avec marquage, exclusion détruits avec traçage
destruction-log.json— cohérent entre spec, tests TC-NOM-08, plan CC-253-07/CC-253-10, et acceptabilité (correction E-02 :withDeleted: true). Convergence confirmée après correction. -
C-07 — Pending anchor (INV-253-08) : Conservation du statut
pendingsans upgrade implicite — aligné entre spec §5.4/INV-253-08, tests TC-NOM-07/TC-NEG-07, plan CC-253-06/CC-253-08, acceptabilité sans déviation. -
C-08 — Dual-hash et Merkle (INV-253-03) :
plaintext_hash+ciphertext_hashSHA3-256, chaîne Merkle référenceciphertext_hash— aligné dans les 4 documents. -
C-09 — Atomicité sync/async (INV-253-14) : DB ACID synchrone + BullMQ post-commit — cohérent entre spec §5.6, tests TC-NOM-10 (chaos test), plan CC-253-05.
-
C-10 — No-residuals (INV-253-12) :
purgeStale()au démarrage +finally— aligné entre spec, tests TC-INV-12, plan CC-253-06/CC-253-11. -
C-11 — Annulation : Flux
DELETE /exports/{export_id}avec idempotence si package déjà produit — aligné entre spec §5.5 flux 4, tests TC-NOM-13/TC-NOM-14, plan CC-253-05. -
C-12 — Sécurité inter-utilisateur :
403 FORBIDDEN_EXPORT_ACCESSuniforme sur GET/download/DELETE — cohérent entre spec §5.7, tests TC-SEC-01, plan CC-253-12. -
C-13 — Résolution ECTs Gate 3 : Les 6 écarts techniques (ECT-01 à ECT-06) identifiés en Gate 3 (verdict step3-v2) sont tous adressés dans le plan §2 avec décisions techniques justifiées.
-
C-14 — BagIt RFC 8493 : Structure package, chemins relatifs sans
.., séparateur/, encodage UTF-8 sans BOM — cohérent entre spec §5.5, tests TC-NOM-04, plan CC-253-08. -
C-15 — Learnings appliqués : Le plan intègre PD-283 (purgeStale), PD-85 (anti-catch-absorb), PD-63 (randomUUID), PD-55 (BullMQ v5, pas de subquery index), PD-282 (ALTER TYPE ADD VALUE évité via VARCHAR+CHECK), PD-250 (stubs inter-PD). Cohérent avec les règles learnings de gouvernance.
3. Divergences¶
⚠️ Les conflits ne doivent JAMAIS être lissés. Chaque divergence est rendue visible.
- DIV-01 : INV-253-11 (chiffrement artefacts temporaires) — invariant non satisfait, reporté
- Spec : INV-253-11 stipule « Tout artefact cryptographique temporaire [...] est chiffré au repos ; aucun secret en clair persistant. »
- Plan (H-253-10) : Hypothèse que les fichiers temp
/tmp/bulk-export-{exportId}/ne contiennent « aucun secret cryptographique » (Zero-Knowledge :content.encdéjà chiffré + hashes non-réversibles). S'appuie sur le chiffrement disque hôte. - Tests (TC-INV-11) : Vérifie qu'aucun secret n'est stocké en clair.
- Acceptabilité (E-04) : Identifié MAJEUR → reporté PD-253b.
-
Impact : L'invariant INV-253-11 est formellement non satisfait au niveau applicatif. La mitigation (chiffrement disque hôte) est une hypothèse infrastructure non vérifiée par le code.
-
DIV-02 : Code HTTP 504 — spec/tests vs plan
- Spec §6 : liste
504 EXPORT_TIMEOUTcomme code d'erreur. - Plan §ZA-02 : supprime le code 504 de la couche HTTP synchrone. Un client interrogeant GET sur un export
FAILED_TIMEOUTreçoit200 OKavec{ status: "FAILED_TIMEOUT" }. - Tests TC-ERR-09 : attend « Code
504 EXPORT_TIMEOUT». -
Impact : Incohérence triple entre spec (504), tests (504) et implémentation (200). TC-ERR-09 teste un comportement qui n'existe pas dans l'implémentation.
-
DIV-03 : Test TC-NOM-15 — absent du document de tests
- Plan ECT-01 : « TC-NOM-15 (à ajouter en Gate 5) — Given export READY_FOR_DOWNLOAD, When POST /confirm-download, Then état DOWNLOADED, audit émis ».
- Tests : TC-NOM-15 absent du document contractuel de tests.
- Acceptabilité : Le endpoint est fonctionnel, testé dans les 126 tests bulk-export mais sans test contractuel nommé TC-NOM-15.
-
Impact : Lacune de couverture test formelle pour le mécanisme
confirm-download. -
DIV-04 :
ExportExpiryScheduler— bypass FSM vs plan - Plan CC-253-11 : Prescrit que le scheduler appelle
expireExport()viaExportStateMachineService(passage par la FSM). - Acceptabilité E-05/S-05 : «
ExportExpirySchedulerbypass la FSM (setstatusdirect) » — MAJEUR reclassé mineur, reporté PD-253b. -
Impact : Violation de INV-253-13 (transitions explicites via FSM). Le scheduler fait un UPDATE direct sans passer par
ExportStateMachineService. Risque de régression si un nouvel état est ajouté. -
DIV-05 :
create()— absence de transaction DB - Plan CC-253-05 : Prescrit un pattern
queryRunnertransactionnel (quota + audit + INSERT atomiques). - Acceptabilité S-06 : «
create()sans transaction — export orphelin si queue.add() échoue » — MINEUR reporté PD-253b. -
Impact : Violation de INV-253-14 (atomicité sync/async). Sans transaction, un crash entre INSERT et
queue.add()laisse un exportREQUESTEDorphelin sans job BullMQ. -
DIV-06 :
confirmDownload— non idempotent - Plan CC-253-05/ECT-01 : « Idempotent — si déjà DOWNLOADED, retourne 200 sans re-audit ».
- Acceptabilité S-07 : «
confirmDownloadnon idempotent (ECT-01) » — MINEUR reporté PD-253b. -
Impact : L'implémentation ne respecte pas le contrat de code CC-253-05.
-
DIV-07 : Préfixe URL API —
/exportsvs/bulk-exports - Spec §5.5 :
DELETE /exports/{export_id}(préfixe/exports). - Plan CC-253-12 :
DELETE /bulk-exports/:id(préfixe/bulk-exports). - Impact : Incohérence de nommage. Le plan justifie
/bulk-exportspour éviter le conflit avec PD-85 (/exports). La spec n'a pas été mise à jour. Impact faible — le plan est postérieur et la décision est justifiée.
4. Zones d'ombre¶
-
ZO-01 : Périmètre exact signé par
export.sig(PC-253-01). Spec, tests et plan mentionnent « signature du digest SHA3-256 du package final » comme option provisoire. Confirmation sécurité/crypto non obtenue. TC-NOM-06 en couverture « Partielle ». Tests §9 : point marqué « Majeur » dans les règles non testables. -
ZO-02 : Multipart upload pour packages > 5GB. Plan H-253-11 :
S3Service.uploadFile()est un stub nécessitant extension pour multipart (packages > 5GB, jusqu'à 100GB). Acceptabilité silencieuse sur ce point. Question : l'upload multipart est-il implémenté ? Si non, les exports > 5GB échouent avecEntityTooLarge. -
ZO-03 : Performance P95 (CA-253-12). Tests : couverture « Partielle ». Tests §9 : « Bloquant » sans environnement instrumenté (H-253-04). Acceptabilité : aucun résultat de test de performance mentionné. Le critère CA-253-12 n'est pas vérifié.
-
ZO-04 :
BulkExportProcessor— 0% couverture unitaire (T-03). 610 lignes de code critique sans tests unitaires, exclu par conception (nécessite env S3/HSM). Les tests d'intégration (TC-NOM-01, TC-NOM-10, TC-INV-11, TC-INV-12) sont listés mais leur exécutabilité effective en CI n'est pas confirmée par l'acceptabilité. -
ZO-05 : Validation
scopeParams(S-03). Plan CC-253-03 spécifie des sous-validations (@IsUUID(),@IsISO8601(),@ArrayMinSize(1)). Acceptabilité S-03 : seul@IsObject()est implémenté. Les sous-DTOs ne sont pas validés côté controller. -
ZO-06 :
ParseUUIDPipesur@Param('id')(S-04). Absent selon l'acceptabilité. Unidnon-UUID traverse le controller jusqu'au repository sans rejet 400. -
ZO-07 : Canal de notification hors polling (PC-253-03). Contrat minimal = polling GET. Plan ajoute un stub
// STUB: PC-253-03. Aucun scénario de notification dans les tests. Mécanisme entièrement non spécifié et non implémenté. -
ZO-08 : Purge S3 post-
DOWNLOADED. Plan ECT-05 : rétention indépendante du téléchargement. Plan correction E-02 :DOWNLOADEDreste terminal, seulREADY_FOR_DOWNLOADtransite versEXPIRED. Question : que se passe-t-il physiquement pour l'objet S3 d'un exportDOWNLOADEDquand le TTL expire ? L'objet est-il purgé par le scheduler ? Si oui, le scheduler doit aussi scanner lesDOWNLOADEDavecexpires_atdépassé — maisDOWNLOADEDest terminal donc pas de transition d'état.
5. Recommandation¶
- Procéder — convergence confirmée, aucun conflit bloquant
- Rework nécessaire — divergences à résoudre avant de continuer
- Escalade — décision humaine requise sur un point structurant
Justification :
Les convergences sont solides sur la majorité des invariants (C-01 à C-15). Les corrections BLOQUANT (E-01 audit fail-closed, E-03 nom manifest) et MAJEUR critiques (E-02 soft-deleted, T-01/S-01 quota, S-02 audit) sont appliquées et vérifiées.
Les divergences se classent en :
-
Invariant non satisfait : DIV-01 (INV-253-11 chiffrement temp → reporté PD-253b). Le PMO doit statuer si un invariant explicitement non satisfait est acceptable en RESERVE.
-
Contrats de code non respectés (3 items) : DIV-04 (scheduler bypass FSM), DIV-05 (create sans transaction), DIV-06 (confirmDownload non idempotent) — tous reportés PD-253b. Le volume d'écarts reportés (6 items PD-253b total) mérite évaluation PMO.
-
Incohérence spec/tests/plan : DIV-02 (code 504 vs 200) — le test TC-ERR-09 attend un code HTTP qui n'est jamais émis.
-
Lacunes documentaires : DIV-03 (TC-NOM-15 absent), DIV-07 (préfixe URL non mis à jour dans la spec).
Les zones d'ombre ZO-02 (multipart > 5GB) et ZO-03 (P95 non vérifié) sont des limitations opérationnelles à documenter. ZO-04 (processor 0% couverture) est un risque technique accepté par conception.