PD-251 — 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¶
| Ref | Document | Étape |
|---|---|---|
| S1 | PD-251-specification.md (spec canonique contractuelle) | 1 |
| S2 | PD-251-tests.md (tests & validation, v2) | 2 |
| S3 | PD-251-plan.md (plan d'implémentation) | 4 |
| S4 | PD-251-acceptability.md (acceptabilité) | 7 |
| S5 | Review Gate 8 P1 ChatGPT (scores + écarts) | 8 |
2. Convergences¶
CON-01 — Chaîne de preuve 4 maillons¶
Les 4 documents s'accordent sur la vérification des 4 maillons (document SHA3, Merkle, TSA, blockchain) avec résultat explicite OK/KO/INDETERMINE par maillon. S1 §3.1 définit l'exigence, S2 TC-251-02 et TC-251-17 la testent, S3 TASK-3 l'implémente (colonnes chain_* en migration §4.1), S4 confirme INV-251-02 couvert. S5 ne signale aucun écart sur ce point.
CON-02 — Machine à états contractuelle¶
Les 6 états, les transitions autorisées/interdites et les 2 états terminaux (CORRUPTED_CONFIRMED, CORRUPTED_ARCHIVED) sont identiques entre S1 §5.3, S2 TC-251-11/TC-251-20, S3 TASK-2 et §6, S4 INV-251-10 couvert. Aucune incohérence dans la matrice de transitions.
CON-03 — Double vérification avant gel¶
Le mécanisme de confirmation indépendante (reconnect S3 + endpoint alternatif) avec tentatives bornées [2,3] est cohérent entre S1 §3.2, S2 TC-251-03/TC-251-04, S3 TASK-3, S4 INV-251-03 couvert (avec timingSafeEqual post-correction). Les paramètres numériques (verificationAttemptsMax, attemptTimeout, attemptInterval) sont identiques dans tous les documents.
CON-04 — Journal append-only signé¶
Le journal avec trigger PostgreSQL BEFORE UPDATE/DELETE, signature HSM, et canonicalisation RFC 8785 est convergent entre S1 §7 INV-251-05, S2 TC-251-06, S3 §4.1 (DDL trigger), S4 correction v2 "journal append-only AVANT transition d'état". Le séquencement journal-avant-transition est un acquis des corrections v2.
CON-05 — SLA temporels contractuels¶
Les SLA de détection (haute criticité <= 60 min, basse criticité <= 24 h) et de restauration (restoreSla défaut 4h, restoreRetryMax 3, restoreRetryBackoff 15 min) sont identiques entre S1 §3.4, S2 TC-251-14/TC-251-15, S3 §6 mapping INV-251-13, S4 INV-251-13 couvert.
CON-06 — Corrections de sécurité critiques (16 fixes)¶
S4 documente 16 corrections (10 v1 + 6 v2) : IDOR (ownership check S-01), timing-safe (timingSafeEqual REV-03/SEC-02), fail-closed (ServiceUnavailableException REV-02/SEC-03), SQL paramétré (SEC-03), journal préalable (S-05), Lua compare-and-delete (REV-06), @UseGuards (SEC-05), @Roles (S-02). S5 confirme la prise en compte. S3 §3.2 anticipe le guard SEC-01.
CON-07 — Snapshot HSM obligatoire avant restauration¶
La précondition snapshot.signature_status = 'SIGNED' avant SUSPECT -> RESTORE_PENDING est cohérente entre S1 INV-251-07, S2 TC-251-08, S3 §3.3 (code du guard), S4 INV-251-07 couvert.
CON-08 — Rapport de run systématique¶
L'exigence de rapport même sans anomalie est convergente entre S1 §3.7/INV-251-14, S2 TC-251-01, S3 §6 (report_json toujours non-null), S4 INV-251-14 couvert.
CON-09 — Non-suppression des archives corrompues¶
L'interdiction de suppression des archives en état terminal est convergente entre S1 INV-251-09, S2 TC-251-21, S3 §6 (ERR_INTEG_DELETE_FORBIDDEN), S4 INV-251-09 couvert.
CON-10 — Priorisation multi-critères¶
La formule linéaire pondérée (legalScore 0.40, ageScore 0.25, criticalityScore 0.35) est définie dans S3 §3.1 (résolution AMB-02 de Gate 3). S2 TC-251-18 valide l'ordre de traitement. S4 INV-251-11 couvert. S1 §3.5 pose le cadre générique, le plan résout l'ambiguïté. Bornes des poids validées (S4 correction SEC-04).
CON-11 — Notification propriétaire conditionnelle¶
Les conditions de notification (uniquement CORRUPTED_CONFIRMED ou dépassement restoreSla) sont identiques entre S1 §3.8/INV-251-11, S2 TC-251-12, S3 §6 mapping INV-251-11, S4 INV-251-11 couvert. L'absence de notification en SUSPECT/RESTORE_PENDING/RESTORED est explicitement testée (S2 CA-251-11).
CON-12 — Atomicité multi-composant¶
Le tableau d'atomicité (synchrone ACID pour DB, async post-commit idempotent pour journal/Merkle, réconciliation obligatoire) est cohérent entre S1 §3.9, S2 TC-251-16, S3 §8.1 (algorithme réconciliation), S4 INV-251-15 couvert.
3. Divergences¶
Les conflits ne doivent JAMAIS être lissés. Chaque divergence est rendue visible.
DIV-01 — INV-251-06 : gel effectif — guard implémenté mais branchement cross-module indéterminé¶
- Source S1 (spec §7 INV-251-06) : "état
SUSPECTimplique blocage lecture publique et export" — exigence inconditionnelle. - Source S3 (plan §2.2.1) :
ArchiveAccessGuardimplémenté avec jointure cross-schéma, 4 routesdocumentsidentifiées (download, export, content, preview), déclaré commeAPP_GUARDdansDocumentsModule. - Source S4 (acceptabilité) : INV-251-06 marqué ⚠️ — "Guard implémenté, branchement endpoints documents = hors scope".
- Source S5 (review) : DIV/MAJEUR (stubs inter-PD).
- Impact : Si le guard existe dans le module
integritymais n'est pas branché sur les routes du moduledocuments, une archiveSUSPECTreste accessible en lecture publique. Violation directe de INV-251-06.
DIV-02 — INV-251-12 : rapport incident PDF non signé cryptographiquement¶
- Source S1 (spec §3.3 Phase 4 + §9.1) : "PDF signé" et "Toute preuve incidente DOIT être signée via HSM".
- Source S4 (acceptabilité) : INV-251-12 marqué ⚠️ — "Rapport JSON signé, PDF stub (scope PD-37)".
- Source S4 (écart R-04) : "Signature PDF non cryptographique. PDF signing = scope PD-37."
- Source S5 (review) : SEC/MAJEUR (PDF signing PD-37).
- Impact : Le JSON canonicalisé RFC 8785 est signé HSM (conforme), mais le PDF n'est pas signé cryptographiquement. En contexte NF Z42-013, un PDF non signé a une valeur probante réduite.
DIV-03 — INV-251-17 : versionnement probatoire — ancrage blockchain non implémenté¶
- Source S1 (spec §7 INV-251-17) : "restauration réussie crée nouvelle version et chaîne cryptographique vers version corrompue archivée".
- Source S3 (plan §6) : "restoration.service crée ArchiveVersionLink + nouvelle archive + ancre blockchain".
- Source S4 (acceptabilité) : INV-251-17 marqué ⚠️ — "Lien version créé, ancrage blockchain = scope PD-55".
- Source S4 (écart R-05) : "Chaîne probatoire complète = scope PD-55 + PD-63. Stub avec TODO tracé."
- Impact :
ArchiveVersionLinkest créé aveclink_hash(conforme), mais l'ancrage blockchain de ce lien est délégué à PD-55. La chaîne de filiation est vérifiable en base mais pas sur la chaîne externe.
DIV-04 — Rate limiting absent (spec exige, implémentation reporte)¶
- Source S1 (spec §9.6) : "Rate limiting obligatoire.
opsRateLimit: défaut 60 op/min [10, 300]". - Source S3 (plan §10.1) : ThrottlerGuard NestJS prévu sur 3 endpoints.
- Source S4 (écart S-03/R-07) : "ThrottlerGuard absent. ThrottlerModule non importé dans le projet. Rate limiting sera ajouté en PD-265."
- Source S5 (review) : SEC/MAJEUR (rate limiting PD-265).
- Impact : Les endpoints de run/restore/réconciliation manuels ne sont pas protégés contre les rafales d'appels. Le lock Redis (
integrity:run:lock) empêche la concurrence d'exécution (un seul run actif) mais pas la saturation API.
DIV-05 — Tests d'intégration non exécutés en local¶
- Source S2 (tests §2) : TC-251-16 (atomicité crash), TC-251-01 (scheduler BullMQ) nécessitent PostgreSQL/Redis réels.
- Source S4 (écarts T-02 à T-05) : "Tests d'intégration PostgreSQL = périmètre pipeline CI".
- Source S4 : "231/231 tests passing (local Jest, 2.3s)" — tests unitaires uniquement.
- Source S5 (review) : DIV/MAJEUR (TC intégration non exécutés).
- Impact : Les garanties d'atomicité multi-composant (INV-251-15) et de scheduler réel (INV-251-01) restent vérifiées uniquement en mock. La validation intégration dépend du pipeline CI.
DIV-06 — Mapping CA-251-06 incohérent dans la matrice tests¶
- Source S1 (spec §8) : CA-251-06 = "restauration réussie produit
RESTORED+ ancienne versionCORRUPTED_ARCHIVED+ lien cryptographique". - Source S2 (matrice §1.2) : CA-251-06 est mappé à "Gel effectif lecture/export" avec TC-251-07.
- Impact : Le cahier de tests associe CA-251-06 au gel effectif (qui correspond à INV-251-06 / CA-251-04), pas au scénario de restauration réussie. TC-251-09 couvre bien le scénario de restauration, mais la traçabilité formelle CA → TC est incorrecte pour CA-251-06.
DIV-07 — Migration DDL : triggers append-only non déployés¶
- Source S3 (plan §4.1) : Trigger
prevent_modify_journal()défini dans le DDL de migration. - Source S4 (écart R-03/S-04) : "Migration DDL vide (triggers append-only). Migration skeleton — DDL réelle en PD-252. Le code applicatif interdit UPDATE/DELETE."
- Impact : La protection append-only du journal repose uniquement sur le code NestJS. Un accès direct à la base (DBA, compromission) pourrait modifier le journal. En contexte NF Z42-013 §11.1, la protection applicative seule est insuffisante pour un audit formel.
4. Zones d'ombre¶
ZO-01 — Exposition des données de preuve dans les DTOs incidents¶
- S4 (écart S-06) : "Filtrage par rôle sur DTO = amélioration future. L'ownership check (S-01 fix) limite déjà l'accès."
- S1 §6.1 endpoint 4 (
GET /archives/{archiveId}/integrity/incidents) ne spécifie pas de filtrage de champs par rôle. - Question : un propriétaire d'archive accédant à ses incidents voit-il les mêmes données qu'un
INTEGRITY_INVESTIGATOR? Les hashes observés/attendus exposés au propriétaire pourraient constituer une fuite d'information technique. - Sévérité : mineure — l'ownership check limite le périmètre d'accès.
ZO-02 — Sonar Quality Gate non exécuté¶
- S4 Phase 1 : "Quality Gate : N/A (sonar-scanner non disponible en local — pipeline GitLab vérifiera)".
- Le CLAUDE.md stipule : "Phase 1.5 (Sonar local) est BLOQUANTE. Si Sonar QG ERROR → STOP avant reviews LLM." Et : "La dérogation ESLint+tsc comme substitution n'est PLUS acceptée."
- S4 applique la substitution ESLint+tsc que le CLAUDE.md déclare obsolète.
- Sévérité : écart de processus — le pipeline CI sera le filet de sécurité, mais l'écart au processus de gouvernance est factuel.
ZO-03 — Comportement concret du guard sur module documents¶
- S3 §2.2.1 détaille le mécanisme (jointure cross-schéma,
APP_GUARDdansDocumentsModule). - S4 ne confirme pas explicitement si la modification de
documents.module.tsa été appliquée. - Aucun test d'intégration cross-module n'est mentionné dans S2 ou S4.
- Question : le guard est-il enregistré dans
DocumentsModuleou uniquement dansIntegrityModule? L'absence de confirmation rend DIV-01 non résoluble par les documents seuls.
ZO-04 — Réconciliation Merkle : couverture effective post-crash¶
- S3 §8.1 décrit l'algorithme de réconciliation (scan orphelins, rattrapage, vérification proof, checkpoint).
- S4 mentionne INV-251-15 couvert ("Réconciliation Merkle").
- S2 TC-251-16 teste l'atomicité crash pré/post-commit.
- Mais S4 écarts T-05 : "Test atomicité crash pre/post-commit nécessite infrastructure test PostgreSQL réelle (pipeline CI)."
- Question : la réconciliation a-t-elle été testée avec injection de crash simulé (mock), ou uniquement en logique unitaire ?
- Sévérité : couverte par DIV-05 (tests intégration CI).
5. Synthèse quantitative¶
| Catégorie | Nombre | Bloquants |
|---|---|---|
| Convergences | 12 | — |
| Divergences | 7 | 0 bloquant strict (tous documentés avec stubs/dépendances tracées) |
| Zones d'ombre | 4 | 0 bloquant (ZO-02 est un écart de processus) |
Divergences par sévérité et type¶
| ID | Sévérité | Type | Dépendance externe |
|---|---|---|---|
| DIV-01 | MAJEUR | Intégration cross-module | Possiblement interne PD-251 |
| DIV-02 | MAJEUR | Stub inter-PD | PD-37 (HSM audit signature) |
| DIV-03 | MAJEUR | Stub inter-PD | PD-55 (blockchain anchoring) |
| DIV-04 | MAJEUR | Fonctionnalité absente | PD-265 (cross-cutting rate limiting) |
| DIV-05 | MAJEUR | Couverture test | Pipeline CI (infra) |
| DIV-06 | MINEUR | Mapping documentaire | Cahier de tests (matrice CA/TC) |
| DIV-07 | MAJEUR | Stub infra | PD-252 (infra DB triggers) |
Alignement avec la review Gate 8 (S5)¶
| Écart S5 | Divergence correspondante |
|---|---|
| DIV/MAJEUR (stubs inter-PD) | DIV-01, DIV-02, DIV-03 |
| DIV/MAJEUR (TC intégration) | DIV-05 |
| SEC/MAJEUR (rate limiting) | DIV-04 |
| SEC/MAJEUR (PDF signing) | DIV-02 |
| AMB/MAJEUR (mapping CA/TC) | DIV-06 |
| DIV/MINEUR, AMB/MINEUR | Convergences maintainability confirmées |
6. Recommandation¶
- Procéder — convergence confirmée sur le coeur fonctionnel, divergences documentées avec dépendances tracées
- Rework nécessaire
- Escalade
Justification : Les 12 convergences couvrent les invariants fondamentaux (chaîne 4 maillons, machine à états, double vérification, journal append-only, SLA, non-suppression, rapport systématique, snapshot HSM, notification conditionnelle, atomicité). Les 7 divergences sont toutes des stubs inter-PD documentés (PD-37, PD-55, PD-252, PD-265) ou des écarts d'intégration/test qui ne compromettent pas la logique métier implémentée. Les 16 corrections de sécurité démontrent une boucle d'amélioration effective. Les 231 tests unitaires couvrent la logique contractuelle.
Points d'attention pour le PMO : 1. DIV-01 (guard non branché sur documents) est le seul écart potentiellement interne à PD-251 — clarifier si le branchement dans DocumentsModule est fait ou reporté (ZO-03). 2. DIV-07 (triggers DDL) est critique pour l'audit NF Z42-013 — PD-252 doit être priorisée. 3. ZO-02 (Sonar non exécuté) constitue un écart factuel au processus de gouvernance — à noter dans le verdict. 4. DIV-06 (mapping CA-251-06) est une erreur formelle de traçabilité, pas un manque de couverture réelle.