Aller au contenu

PD-56 — Specification Review

Écarts identifiés


Écart 1 — Contradiction CORRUPTED self-loop

Type : Contradiction Référence : Spec §5.4 (table transitions) vs §5bis (diagramme d'état Mermaid) Description : La table §5.4 déclare CORRUPTED comme état terminal avec transitions sortantes = "aucune" et CORRUPTED->* INTERDITE. Le diagramme d'état Mermaid montre explicitement CORRUPTED --> CORRUPTED : relecture même anomalie (self-loop). Ces deux déclarations sont mutuellement exclusives. Impact : L'implémenteur ne peut pas déterminer si un appel getMerkleProof sur un événement en état CORRUPTED doit (a) retourner ERR-56-04 sans transition, ou (b) effectuer une self-loop tracée. Les tests TC-ERR-10 et TC-INV-06 ne couvrent pas cette ambiguïté. Gravité : Bloquant


Écart 2 — Relation entre ERR-56-04 et transition vers CORRUPTED non spécifiée

Type : Ambiguïté Référence : Spec §6 (ERR-56-04), §5.4 (transitions PENDING→CORRUPTED, AVAILABLE→CORRUPTED), §5bis (diagramme de séquence) Description : Quand computedRoot != merkleRoot, le diagramme de séquence retourne ERR-56-04 au caller. La machine d'état §5.4 prévoit des transitions PENDING→CORRUPTED et AVAILABLE→CORRUPTED pour "incohérence détectée". Mais aucune section ne spécifie si la détection d'un mismatch (a) déclenche une transition d'état ET retourne ERR-56-04, ou (b) retourne seulement ERR-56-04 sans modifier l'état, ou © persiste l'état CORRUPTED pour les appels suivants. Impact : Un appel ultérieur sur le même eventId pourrait retourner available (si l'état n'est pas persisté comme CORRUPTED) alors que la corruption a déjà été détectée. Contredit INV-56-06. Gravité : Bloquant


Écart 3 — État CORRUPTED absent du contrat de sortie MerkleProofResult

Type : Ambiguïté Référence : Spec §5.1 (champ status), §5.4 (machine d'état), §3 (définitions) Description : Le champ status est défini en §5.1 avec regex ^(available|pending)$ — deux valeurs seulement. L'état CORRUPTED existe dans la machine d'état §5.4 et dans les définitions §3, mais aucune valeur corrupted n'est contractualisée en sortie. La spec ne précise pas comment l'état CORRUPTED est communiqué au caller (ERR-56-03 ? ERR-56-04 ? exception ? nouveau status ?). Impact : L'appelant ProofEnvelopeService ne peut pas distinguer programmatiquement un état CORRUPTED d'une erreur transitoire. Gravité : Majeur


Écart 4 — Terme inclusion_proof non défini dans le modèle de données

Type : Ambiguïté (terminologique) Référence : Spec §6 (ERR-56-03 : "inclusion_proof absent/vide"), Tests TC-ERR-04 ("inclusion_proof vide") Description : Le terme inclusion_proof apparaît dans la condition d'erreur ERR-56-03 et dans TC-ERR-04, mais n'est défini nulle part dans §5.1 ni §3. Le modèle de données utilise merklePath comme champ de preuve d'inclusion. Il y a confusion terminologique entre le nom du champ stocké en base (inclusion_proof ?) et le champ contractuel de sortie (merklePath). Impact : L'implémenteur ne sait pas quel champ vérifier en entrée. Si inclusion_proof est un champ de la couche de persistance (hors périmètre PD-56), la condition ERR-56-03 référence un détail d'implémentation dans un contrat fonctionnel. Gravité : Majeur


Écart 5 — Algorithme de hash-pair (sorted) spécifié uniquement dans le diagramme

Type : Ambiguïté Référence : Spec §5bis (diagramme de séquence : fold(hashPair(sorted(a,b)))), §5.5 F-03 (fold(eventHash, merklePath)) Description : Le diagramme de séquence spécifie sorted(a,b) pour l'appariement des hashes lors du calcul de la racine. Cette information critique pour la vérification off-chain (CA-56-02, CA-56-03) n'apparaît pas dans le texte de la spécification. §5.5 F-03 dit seulement fold(eventHash, merklePath) sans préciser l'ordre de concaténation des paires. Impact : Un vérificateur tiers implémentant F-03 sans consulter le diagramme utilisera potentiellement un ordre de concaténation non-sorted, produisant une racine différente. L'interopérabilité off-chain (raison d'être de PD-56) est compromise. Gravité : Majeur


Écart 6 — ERR-56-02 sémantique contradictoire

Type : Contradiction Référence : Spec §6 (ERR-56-02 = "événement non prouvable à l'instant T → pending"), §5.1 (ERR-56-02 = "pending sans ETA conforme = non conforme") Description : En §6, ERR-56-02 est la condition de flux normal "pending" (retour avec ETA). En §5.1, ERR-56-02 est le code d'erreur quand estimatedAvailableAt est absente ou non conforme. Le même code désigne à la fois un flux nominal et une erreur de conformité. Impact : Confusion implémentation et tests. TC-ERR-03 teste "pending sans ETA → ERR-56-02" (erreur conformité), tandis que §6 utilise ERR-56-02 pour le flux nominal pending. Gravité : Majeur


Écart 7 — Transition PENDING→AVAILABLE : critère de finality absent de la machine d'état

Type : Incohérence Spec↔Diagramme Référence : Spec §5.4 (transition PENDING→AVAILABLE : "preuve trouvée + auto-verification OK"), §5bis (diagramme de séquence : check finality FINALIZED requis) Description : Le diagramme de séquence montre qu'après auto-vérification réussie, un check de finality est requis. Si non-finalisé, le retour est pending même avec preuve vérifiée. La machine d'état §5.4 ne mentionne pas la finality comme condition de transition PENDING→AVAILABLE. La condition textuelle est "preuve trouvée + auto-verification OK" sans mention de finality. Impact : L'implémentation basée uniquement sur §5.4 pourrait retourner available pour une preuve vérifiée mais non finalisée, violant le flux du diagramme de séquence. Gravité : Majeur


Écart 8 — Transition AVAILABLE→CORRUPTED : pas de scénario de test

Type : Incohérence Spec↔Tests Référence : Spec §5.4 (AVAILABLE→CORRUPTED : "incohérence détectée ultérieurement"), Tests §3-4 Description : La machine d'état autorise AVAILABLE→CORRUPTED mais aucun scénario de test ne couvre cette transition. TC-INV-06 liste les transitions autorisées incluant AVAILABLE→CORRUPTED mais ne décrit pas le GIVEN/WHEN/THEN pour forcer cette condition. Comment un événement précédemment available devient-il corrupted ultérieurement ? (Données modifiées en base ? Recalcul périodique ?) Impact : Transition autorisée mais non testable faute de conditions de déclenchement spécifiées. Gravité : Majeur


Écart 9 — Absence d'obligation d'alerte/audit sur détection de corruption

Type : Risque sécu/conformité Référence : Spec §6 (ERR-56-04), §5.4 (CORRUPTED), Tests §8 (observabilité) Description : La détection d'une incohérence cryptographique (computedRoot != merkleRoot) est un événement de sécurité critique signalant une possible altération de données probatoires. La spec ne contractualise aucune obligation d'alerte, notification ou audit spécifique au-delà du rejet. §8 des tests mentionne un "journal d'audit" mais de façon générique, sans exigence spécifique pour les cas de corruption. Impact : Une corruption détectée pourrait passer inaperçue opérationnellement (pas de monitoring, pas d'alerte), retardant la réponse à un incident de sécurité sur des données probatoires. Gravité : Majeur


Écart 10 — Snapshot consistency non borné pour INV-56-02

Type : Hypothèse dangereuse Référence : Spec INV-56-02 ("même snapshot de données"), Tests TC-NOM-03 Description : INV-56-02 exige le déterminisme pour "le même snapshot de données" mais aucune section ne définit ce qu'est un snapshot ni comment garantir sa stabilité entre deux appels. Des écritures concurrentes en base (finalisation d'un batch entre deux appels) pourraient changer le résultat. TC-NOM-03 utilise un "snapshot immuable" sans définir le mécanisme d'immutabilité (transaction serializable ? mock ?). Impact : L'invariant est trivialement vrai si on définit "même snapshot" comme "aucune écriture entre les appels", mais non vérifiable en conditions réelles sans isolation transactionnelle contractualisée. Gravité : Mineur


Écart 11 — Diagramme de séquence : format d'entrée/sortie Event Source non spécifié

Type : Incohérence diagramme (§5bis) Référence : Spec §5bis (diagramme de séquence, appel ES: lookup(eventId)) Description : L'appel MPS→ES: lookup(eventId) retourne eventHash = sha256(canonical_event). Le diagramme implique que Event Source calcule ou retourne le hash, mais ne spécifie pas si eventHash est pré-calculé et stocké ou calculé à la volée. La spec §5.5 F-01 dit "Résolution eventId → eventHash" sans préciser le mécanisme, ce qui est cohérent avec le hors-périmètre, mais le diagramme ajoute sha256(canonical_event) qui est un détail d'implémentation non contractualisé. Impact : Le diagramme ajoute une information (sha256(canonical_event)) qui n'est pas dans la spec textuelle et pourrait induire un choix d'implémentation non validé. Gravité : Mineur


Écart 12 — TC-NEG-09 teste un champ de sortie comme entrée

Type : Incohérence Spec↔Tests Référence : Tests TC-NEG-09 ("estimatedAvailableAt non-UTC +02:00"), Spec §5.1 Description : estimatedAvailableAt est un champ produit par le service (sortie), pas un champ d'entrée. TC-NEG-09 le traite comme un vecteur d'injection adversariale, ce qui n'a pas de sens : le service génère ce champ lui-même. Le test devrait vérifier que le service ne produit jamais une ETA non-UTC, pas qu'il rejette une entrée non-UTC. Impact : Le scénario tel que rédigé n'est pas exécutable en conditions réelles (on ne peut pas "injecter" une ETA non-conforme dans un champ de sortie). Gravité : Mineur


Écart 13 — Diagramme d'état : transition AVAILABLE→PENDING montrée comme flèche

Type : Incohérence diagramme (§5bis) Référence : Spec §5bis (diagramme d'état Mermaid) Description : Le diagramme montre AVAILABLE --> PENDING : INTERDITE (retour arrière) comme une flèche de transition avec label. Bien que l'intention est documentaire, certains outils de rendu Mermaid l'interpréteront comme une transition valide, ce qui contredit §5.4. Impact : Risque de mauvaise interprétation par un outil de validation automatique de machine d'état. Gravité : Mineur


Synthèse

Gravité Nombre
Bloquant 2
Majeur 7
Mineur 4
Total 13

Bloquants à lever avant Gate 3 GO : 1. Contradiction CORRUPTED self-loop (§5.4 vs diagramme) 2. Relation ERR-56-04 ↔ transition CORRUPTED non spécifiée