PD-282 — Rapport de confrontation (Étape 5)¶
Ce rapport est produit par l'orchestrateur Claude avant la gate PMO 5. Il confronte les documents produits pour identifier convergences, divergences et zones d'ombre.
1. Sources confrontées¶
| Document | Étape | Version |
|---|---|---|
| PD-282-specification.md | 1 | Post-Gate 3 (RESERVE 8.25/10 v3) |
| PD-282-tests.md | 2 | Post-Gate 3 |
| PD-282-plan.md | 4 | v1 (intègre adressage réserves Gate 3 + écarts Gate 5 v1) |
| Code contracts (YAML) | 4 | v1 (12 modules C1-C12) |
| Review ChatGPT v3 | Phase 1 Gate 5 | 8 écarts identifiés |
2. Convergences¶
-
CV-01 — Pattern INSERT-only : Les 4 documents convergent sur l'impossibilité d'un UPDATE (trigger PD-272) et le choix d'un INSERT atomique en état SEALED. Spec §5.4, tests TC-NOM-06, plan DA-02, contract entity : alignement total.
-
CV-02 — UNSEALED transitoire mémoire : Spec §5.4 (
UNSEALEDnon persisté), tests TC-NOM-06 (« aucune écriture DB en état UNSEALED »), plan DA-02, contract entity (forbidden: créer un état UNSEALED persisté) : convergence complète. -
CV-03 — Pipeline de scellement : L'ordre JCS → SHA3-384 → ECDSA P-384 HSM est identique dans spec §5.1, plan §4.2, contract seal-pipeline. Tests TC-NOM-01 vérifie le résultat bout-en-bout.
-
CV-04 — OCSP timeout → OCSP_UNAVAILABLE : Spec ERR-05, tests TC-ERR-05, plan §4.3 step 3, contract verification-material-assembly : même comportement (
ocspResponses=[],validationPolicy=OCSP_UNAVAILABLE). -
CV-05 — Immutabilité post-persistance : INV-282-08/09/10 tracés dans spec, tests (TC-NOM-05, TC-INV-09, TC-INV-10, TC-ERR-07), plan (réutilisation trigger PD-272), contracts (entity invariants).
-
CV-06 — Détection de secrets : INV-282-06 avec les 5 patterns interdits (
privateKey,secretKey,sessionToken,hmacSecret,dek) identiques dans spec, tests TC-INV-06/TC-NEG-08, contract secret-detection. -
CV-07 — Vérification historique post-rotation : INV-282-11 traçable dans spec, tests TC-NOM-07, plan §4.4 (kid + certificateChain embarquée), contract offline-verification.
-
CV-08 — Machine à états : Spec §5.4, tests TC-NOM-06/TC-INV-09/TC-INV-10, plan DA-02, contract entity : toutes les transitions autorisées/interdites sont alignées.
-
CV-09 — Atomicité multi-composant : Spec §5.5, tests TC-NOM-08 (crash pre/post-commit), plan §3 (stratégie injection de faute transactionnelle) : convergence sur les assertions.
-
CV-10 — Migration DDL : Spec §5.6 (
ADD COLUMN envelope_seal JSONB NULL), plan §4.1, contract entity : même colonne, même type, même contrainte nullable.
3. Divergences¶
⚠️ Les conflits ne doivent JAMAIS être lissés. Chaque divergence est rendue visible.
- DIV-01 :
signedAtnon couvert par le sceau — contradiction avec INV-282-03 - Spec INV-282-03 : « Tout octet modifié dans l'enveloppe scellée DOIT rendre la vérification invalide »
- Spec INV-282-02 : « Le calcul du sceau DOIT exclure strictement le champ
envelopeSeal» — orsignedAtest un sous-champ deenvelopeSeal - Plan §3 (Reserve DIV-01) : « Accepté par design. Mitigation existante : validationTimestamp dans le hash + token TSA PD-81 »
- Tests : Aucun test ne vérifie que modifier
signedAtinvalide la vérification (car par design ce n'est pas le cas) -
Impact : INV-282-03 tel que rédigé est faux pour les champs internes à
envelopeSeal. Soit l'invariant doit être amendé (« tout octet horsenvelopeSeal»), soit la mitigation plan doit être contractualisée dans la spec. En l'état, un auditeur lisant INV-282-03 attend une couverture intégrale. BLOQUANT tant que la spec n'est pas amendée. -
DIV-02 : OCSP
status=revoked— rejet non contractualisé dans la spec - Spec §5.1.2 :
ocspResponses[].statusenumgood|revoked|unknown, aucun comportement spécifique défini pourrevoked - Spec §6 ERR-05 : ne couvre que l'indisponibilité OCSP (timeout), pas le statut
revoked - Plan §3 (Reserve ECT-02) : « rejet finalisation si status=revoked » — ajout contractuel
- Contract verification-material-assembly : « Accepter un ocspResponse avec status=revoked sans lever d'exception » dans forbidden
- Tests : pas de test dédié pour OCSP revoked (TC-ERR-05 ne couvre que le timeout)
-
Impact : Le plan et le contract ajoutent un comportement non présent dans la spec. Ce n'est pas un écart mais une résolution de réserve Gate 3, cependant la spec n'a pas été amendée. MAJEUR — la spec doit être mise à jour pour contractualiser ce comportement (ajout ERR-XX + test dédié TC-ERR-XX).
-
DIV-03 : Validation format
verificationMaterial— couverture incomplète dans le contract format-validation - Spec §5.1.2 : définit les regex/bornes pour
tsaCertificateChain[],eidasCertificateChain[],ocspResponses[].response,ocspResponses[].producedAt - Contract format-validation (C7) : liste explicitement les regex pour
envelopeSealet quelques champsverificationMaterial(validationPolicy,ocspResponsescount,certSerialNumber), mais renvoie à « spec §5.1 » pour le reste sans listing exhaustif - Plan §4.2 : mentionne
EnvelopeFormatValidatorServicecomme responsable mais ne détaille pas la couverture champ par champ -
Impact : Risque que l'agent-seal implémente une validation partielle de
verificationMaterial. Les champstsaCertificateChain[],eidasCertificateChain[]element-level regex (taille 1..16384) etocspResponses[].response(1..32768) ne sont pas explicitement listés dans le contract. MAJEUR — compléter le contract C7 avec les regex de tous les champs §5.1.2. -
DIV-04 : Compatibilité pre-hash SHA3-384 (HSM) vs
crypto.createVerify('SHA3-384')(vérification) - Plan DA-03 : « Pre-hash SHA3-384 en software (js-sha3) puis signature ECDSA P-384 raw dans le HSM »
- Contract offline-verification (C12) : « Vérification ECDSA P-384 via crypto.createVerify('SHA3-384') de Node.js »
- Analyse :
crypto.createVerify('SHA3-384')effectue lui-même le hash SHA3-384 puis vérifie l'ECDSA. Le résultat estECDSA_verify(SHA3-384(data), sig, pubkey), ce qui est compatible avecECDSA_raw_sign(SHA3-384(data), privkey)si et seulement si l'encodage de signature (ieee-p1363) est identique entre HSM et Node.js crypto. - Aucun test ne vérifie explicitement cette compatibilité sign/verify cross-implementation.
-
Impact : Si l'encodage HSM (CKM_ECDSA raw output) diverge de ieee-p1363 attendu par Node.js, toutes les vérifications échouent. Le plan mentionne que le pattern est « déjà utilisé dans LegalAuditTrailService » mais avec SHA3-256, pas SHA3-384. MAJEUR — ajouter un test d'interopérabilité explicite sign(HSM) → verify(Node.js crypto) avec SHA3-384.
-
DIV-05 : Test Mode B nominal absent
- Spec §2 (Inclus) : « Vérification tierce en mode offline strict (air-gapped) et mode online public (sans service ProbatioVault) »
- Plan §3 (Mode B) : « La vérification en ligne est constitutive. DOIT requêter les serveurs OCSP/CRL publics »
- Tests : TC-NOM-04 couvre Mode A uniquement. TC-ERR-08 couvre l'échec cert chain en Mode A et B. Aucun test nominal pour Mode B réussi.
- Contract C12 : invariant « Mode B: verification en ligne CONSTITUTIVE » sans test associé
-
Impact : La réserve Gate 3 ECT-01 demandait exactement un test nominal Mode B. Le plan mentionne que l'agent-verifier l'ajoutera (« TC-NOM-xx-MODE-B »), mais ce test n'existe pas encore dans le document tests. MAJEUR — le test doit exister dans le document tests avant Gate 5.
-
DIV-06 : TC-NOM-04 — observabilité « zéro réseau PV » non instrumentée
- Tests TC-NOM-04 THEN : « Aucune dépendance réseau ProbatioVault n'est observée »
- Plan / Contract : aucun mécanisme d'observation (proxy, mock network, socket monitor) n'est spécifié pour asserter l'absence d'appels réseau
-
Impact : Le test est irréalisable tel que rédigé. Un test air-gapped nécessite soit un environnement réseau isolé, soit un mock de la couche réseau avec assertion « zero calls ». BLOQUANT — instrumenter le mécanisme d'assertion (ex: jest mock sur HttpService/fetch avec assertion
toHaveBeenCalledTimes(0)). -
DIV-07 : Séparation invariants normatifs / techniques incohérente entre contracts
- Contract seal-pipeline (C5-C9) : utilise
invariants_normatifs+invariants_techniques(séparation claire) - Contract offline-verification (C12) : utilise
invariants_normatifs+invariants_techniques(séparation claire) - Contracts entity (C1-C4), secret-detection (C6), format-validation (C7), hash-extension (C8), ocsp-client (C11) : utilisent
invariantssans distinction -
Impact : Risque de confusion lors de l'audit Gate 8 — un invariant technique non traçable à la spec pourrait être évalué comme un invariant normatif manquant. MINEUR — harmoniser la nomenclature dans tous les contracts.
-
DIV-08 :
Math.random()forbidden dans contract sans lien spec - Contract seal-pipeline forbidden : « Utiliser Math.random() pour quelque identifiant que ce soit (crypto.randomUUID() obligatoire) »
- Spec : aucune mention de
Math.random()ni decrypto.randomUUID() - Origine : convention projet (CLAUDE.md, REX PD-63, Sonar S2245)
- Impact : La règle est légitime (convention projet) mais référencée dans un contract lié à la spec PD-282 sans justification. Un agent pourrait croire que c'est un invariant de spec. MINEUR — ajouter un commentaire
# convention projet (Sonar S2245)pour clarifier l'origine.
4. Zones d'ombre¶
-
ZO-01 — Normalisation certSerialNumber : test absent : La spec §5.1.2 prescrit une normalisation uppercase à l'ingestion. Le contract la confirme. Mais aucun test ne vérifie explicitement que l'entrée
"a1b2c3"est normalisée en"A1B2C3"avant stockage/comparaison. -
ZO-02 — Environnement de référence P95 (Q-02) : Toujours non résolu depuis la spec. Le plan ne le résout pas. Les tests (TC-NR-05, §9 Règles non testables) le reconnaissent comme non objectivable. Aucun document ne propose de date ou critère de résolution.
-
ZO-03 — Compatibilité ESM/CJS de @peculiar/asn1-ocsp : Le plan DA-05 mentionne un risque avec un fallback (
await import()). Le contract ocsp-client ne mentionne pas cette contrainte. Aucun test ne couvre un scénario d'import CJS échoué. -
ZO-04 — Statuts exacts des dépendances inter-PD : Le plan §6 liste PD-272, PD-81, PD-280, PD-37 comme « Disponible ». Aucune indication de branche, commit, ou statut Jira (DONE / In Progress). Si une de ces dépendances est un stub, cela impacte la testabilité.
-
ZO-05 — Reconciliation handler post-crash : Le plan (note AMB-04) mentionne un « reconciliation handler existant dans le module legal-pre ». Ni la spec ni les tests ne documentent ce handler. TC-NOM-08 post-commit affirme « reconciliation asynchrone possible » sans le tester.
-
ZO-06 — ocspResponses vide vs absent — sémantique
status=unknown: La spec §5.1.2 dit « si absent: rejet; si vide: autorisé uniquement avec policy dégradée ». Le contract interditundefined. Mais la spec ne précise pas le comportement attendu quandocspResponses[].status = unknown. Le plan ne le couvre pas non plus. Est-ce queunknownest traité commegood(accepté), commerevoked(rejeté), ou déclenche une policy spécifique ? -
ZO-07 — Root CA dans certificateChain : Q-05 (spec §10.2) demande si l'inclusion du root CA est obligatoire ou optionnelle. Non résolu. Le contract offline-verification mentionne « certificateChain[0] (leaf cert) » mais pas si le root doit être présent.
5. Synthèse des écarts par gravité¶
| Gravité | Écarts | IDs |
|---|---|---|
| BLOQUANT | 2 | DIV-01 (signedAt/INV-282-03), DIV-06 (TC-NOM-04 observabilité) |
| MAJEUR | 4 | DIV-02 (OCSP revoked), DIV-03 (format validation incomplete), DIV-04 (SHA3-384 interop), DIV-05 (test Mode B absent) |
| MINEUR | 2 | DIV-07 (nomenclature contracts), DIV-08 (Math.random justification) |
| Zone d'ombre | 7 | ZO-01 à ZO-07 |
6. 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
Actions minimales avant soumission Gate 5 :
- DIV-01 : Amender INV-282-03 dans la spec pour exclure explicitement les champs internes à
envelopeSealdu périmètre d'intégrité, ou documenter la mitigation (validationTimestamp + TSA) comme acceptable. - DIV-06 : Instrumenter TC-NOM-04 avec un mécanisme d'assertion d'absence réseau (mock HttpService avec
expect(...).not.toHaveBeenCalled()). - DIV-02 : Ajouter dans la spec un ERR-XX pour OCSP revoked et un test dédié.
- DIV-03 : Compléter le contract C7 avec toutes les regex §5.1.2.
- DIV-04 : Ajouter un test d'interopérabilité sign/verify cross-implementation.
- DIV-05 : Ajouter TC-NOM-XX-MODE-B dans le document tests.