Aller au contenu

PD-52 — Specification Review (Audit indépendant)

Story : PD-52 — Setup connexion Ethereum L2 (Polygon/Arbitrum) Epic : PD-187 — BLOCKCHAIN Date : 2026-02-12 Auditeur : Claude Opus 4.6 (mode factuel, température 0.1) Documents audités : PD-52-specification.md, PD-52-tests.md, PD-52-besoin.md Learnings appliqués : PD-7, PD-36, PD-37, PD-19, PD-239


Synthèse de l'audit

Gravité Nombre
Bloquant 3
Majeur 8
Mineur 5
Total 16

Écarts identifiés

ECT-52-01

Type : Ambiguïté Référence : Spec §5 FN-52-05, CA-52-06, INV-52-09 Description : Le seuil de confirmations nécessaire pour déclarer la finalité opérationnelle n'est pas défini. CA-52-06 fixe un délai de 30 secondes pour la confirmation, mais le seuil de confirmations (nombre de blocs) est absent. Or, la finalité sur Polygon PoS et Arbitrum Rollup est fondamentalement différente : Polygon atteint la finalité en ~2 minutes (checkpoints), Arbitrum en ~7 jours (challenge period L1) ou quasi-immédiat en soft-confirmation. Sans valeur contractuelle par réseau, INV-52-09 ("pas finalisée tant que le seuil n'est pas atteint") est inapplicable. Impact : TC-NOM-08 et TC-ERR-08 ne sont pas exécutables avec un critère de succès déterministe. Le délai de 30s de CA-52-06 pourrait être incompatible avec le seuil de confirmations choisi. Gravité : Bloquant


ECT-52-02

Type : Ambiguïté Référence : Spec §3 (Définitions), §5 FN-52-04, FN-52-05, CA-52-05 Description : La "transaction type d'ancrage" est définie comme "transaction minimale représentative de l'écriture d'un engagement (sans spécification de contrat)". Cette définition est circulaire : elle décrit l'intention sans spécifier le contenu. S'agit-il d'un eth_sendTransaction avec un champ data contenant un hash ? D'un transfert ETH de 0 avec données annexes ? D'un appel à une adresse spécifique ? Sans payload normatif, l'estimation de gas (CA-52-05, écart < 50%), la confirmation (CA-52-06), et l'inspection de payload (CA-52-10) sont non reproductibles d'un test à l'autre. Impact : Trois critères d'acceptation (CA-52-05, CA-52-06, CA-52-10) dépendent d'un artefact dont la structure n'est pas contractualisée. Résultats de test non comparables entre exécutions. Gravité : Bloquant


ECT-52-03

Type : Ambiguïté Référence : Spec §6 ERR-52-07, Tests TC-ERR-07 Description : La politique en cas de dépassement du plafond gas est indéterminée. La spec mentionne "transaction mise en attente ou rejetée selon politique de file". Le test TC-ERR-07 vérifie que "la politique appliquée (rejet strict / mise en queue) est tracée" sans pouvoir valider laquelle est correcte. Cela rend le test non falsifiable : tout comportement est acceptable. Impact : ERR-52-07 n'est pas un cas d'erreur vérifiable — c'est un placeholder. L'implémentation ne pourra pas être auditée sur ce point. Gravité : Majeur


ECT-52-04

Type : Non testable Référence : Spec §4 INV-52-04, Tests TC-INV-04 Description : TC-INV-04 teste la détection de configuration avec deux modes simultanés et attend CUSTODY_MODE_AMBIGUOUS. Cependant, la spec (INV-52-04) dit seulement "un et un seul custody mode doit être sélectionné explicitement". L'erreur CUSTODY_MODE_AMBIGUOUS n'apparaît pas dans la section §6 (Cas d'erreur). Le test introduit un comportement (refus de démarrage) et un code d'erreur (CUSTODY_MODE_AMBIGUOUS) non spécifiés. Impact : Le test suppose un comportement non contractualisé. Si l'implémentation choisit une autre stratégie (sélection du premier mode, erreur générique), le test échoue sans que la spec soit violée. Gravité : Majeur


ECT-52-05

Type : Incohérence Spec↔Tests Référence : Spec §6 ERR-52-08, Tests TC-ERR-08 Description : La spec stipule pour ERR-52-08 : "État transaction repasse à non finalisée, suivi continue jusqu'à nouvelle finalité ou échec". Le test TC-ERR-08 ajoute : "Si la transaction ne réapparaît pas après un délai configurable, elle est marquée 'échouée'". Ce délai configurable et l'état "échouée" ne sont pas définis dans la spec. Le test introduit un concept (timeout d'abandon après reorg) absent du contrat fonctionnel. Impact : Le test est plus prescriptif que la spec. Un implémenteur suivant uniquement la spec ne prévoirait pas ce timeout, et le test échouerait légitimement. Gravité : Majeur


ECT-52-06

Type : Incohérence Spec↔Tests Référence : Tests TC-NEG-03 Description : TC-NEG-03 teste l'injection de données personnelles dans le payload et attend "la couche de validation rejette le payload non conforme ou le transforme en hash". La spec (INV-52-08) dit que les données émises doivent être limitées à des hash — mais ne mentionne aucune couche de validation de payload entrante ni de mécanisme de transformation. Le test présuppose l'existence d'un composant de validation/sanitisation non spécifié. Impact : Ce test adversarial ne peut être implémenté car aucune exigence de validation entrante n'est spécifiée. L'invariant INV-52-08 est une contrainte de résultat, pas de mécanisme. Gravité : Majeur


ECT-52-07

Type : Incohérence Spec↔Tests Référence : Tests TC-NEG-01, TC-NEG-02, TC-NEG-04, TC-NEG-07 Description : Plusieurs tests négatifs introduisent des codes d'erreur non définis dans la spec : CUSTODY_MODE_UNKNOWN (TC-NEG-01), RPC_INVALID_ENDPOINT (TC-NEG-02), MAINNET_FORBIDDEN (TC-NEG-04). INV-52-11 exige des "codes d'erreur déterministes" mais la spec ne fournit aucun catalogue exhaustif de codes. Les tests inventent librement des codes sans base contractuelle. Impact : L'implémenteur n'a pas de référentiel de codes d'erreur. Tout code est acceptable au regard de la spec, mais les tests attendent des codes spécifiques. Divergence spec↔tests inévitable. Gravité : Majeur


ECT-52-08

Type : Hypothèse dangereuse Référence : Spec §5 FN-52-06, CA-52-07 Description : Le SLA de bascule RPC est fixé à "moins de 5 secondes" (CA-52-07). Ce délai suppose un mécanisme de détection d'échec rapide. Or, la spec ne définit pas : - Le timeout de détection d'échec sur le provider primaire (1s ? 3s ? configurable ?) - Le nombre de retries avant bascule (0 ? 1 ?) - Le comportement si le secondaire aussi a une latence élevée (3s response time + 3s timeout = 6s > 5s SLA) Le test TC-NEG-09 (timeout extrême > 30s) illustre bien le problème : "failover déclenché dans le délai contractuel (< 5s)" mais aucun timeout de détection n'est spécifié. Impact : Le SLA de 5s est potentiellement non tenable sans spécifier les paramètres de détection. Risque de faux échecs en test si le timeout de détection est mal calibré. Gravité : Majeur


ECT-52-09

Type : Hypothèse dangereuse Référence : Tests TC-NEG-10, Spec (absent) Description : TC-NEG-10 teste le cas de deux instances du service utilisant le même wallet simultanément et attend "nonce géré correctement ou erreur explicite". Ce scénario de concurrence d'accès wallet n'est mentionné nulle part dans la spec — ni dans les invariants, ni dans les cas d'erreur, ni dans les flux nominaux. La gestion de nonce Ethereum en contexte multi-instance est un problème architectural majeur (race conditions, nonce gaps, transactions orphelines) qui nécessite une spécification dédiée. Impact : Le test couvre un risque réel mais non contractualisé. L'implémenteur pourrait légitimement ignorer ce cas, créant un risque de double-spend ou de blocage de nonce en production. Gravité : Majeur


ECT-52-10

Type : Ambiguïté Référence : Spec §7 CA-52-05 Description : L'écart relatif entre gas estimé et gas consommé est borné à "< 50%". La formule dans le test TC-NOM-07 est |gas_estimé - gas_réel| / gas_réel < 50%. Cependant, la spec ne précise pas si c'est le gas limit ou le gas effectivement consommé (gas used) qui est comparé. Sur les L2, la structure de gas est différente du L1 (Arbitrum utilise ArbGas, Polygon a un EIP-1559 modifié). Un écart de 50% est très large et pourrait masquer un problème réel d'estimation. Impact : Le critère est testable mais son pouvoir discriminant est faible. Un seuil de 50% valide pratiquement toute estimation. Risque mineur car le coût réel sera visible en monitoring. Gravité : Mineur


ECT-52-11

Type : Risque sécu/conformité Référence : Spec §4 INV-52-03, Tests TC-INV-03a Description : TC-INV-03a mentionne que le scan de secrets doit couvrir "tous les fichiers du repository (y compris historique git)". L'historique git peut contenir des secrets commités puis supprimés. Cependant, la spec (INV-52-03) ne mentionne pas l'historique git — elle parle de "code, variables d'environnement, logs ou traces applicatives". Le test va au-delà de la spec sur ce point, ce qui est positif en termes de sécurité mais crée une incohérence contractuelle. Impact : Le test est plus exigeant que la spec. Un scan réussissant sur les fichiers actuels mais échouant sur l'historique git lèverait un finding non couvert par le contrat INV-52-03. Gravité : Mineur


ECT-52-12

Type : Non testable Référence : Spec §3 (Définition S3), §10 Point à clarifier #5 Description : La définition de S3 est "approche hybride avec matériel dérivé depuis HSM et secret secp256k1 stocké chiffré dans Vault". La méthode de preuve que le matériel reste chiffré au repos n'est pas définie. TC-NOM-05 attend "le secret reste chiffré au repos dans Vault (non extrait en clair)" mais aucun observable n'est défini pour prouver cette propriété (API Vault seal status ? Audit log Vault ? Inspection mémoire ?). Impact : CA-52-03 n'est pas pleinement démontrable pour le mode S3 tant que la méthode de preuve n'est pas définie. Le test existe mais est non exécutable sur le volet chiffrement. Gravité : Bloquant


ECT-52-13

Type : Ambiguïté Référence : Spec §5 FN-52-07, §7 CA-52-08 Description : Les métriques doivent être "exposables à la demande" (INV-52-10) via un "endpoint/rapport d'observabilité" (CA-52-08). Le format (JSON ? Prometheus ? OpenMetrics ?), l'endpoint (HTTP path ?), et le mécanisme d'accès ne sont pas définis. Le besoin mentionne un "dashboard ou endpoint /health dédié" (CS-6) mais la spec ne reprend pas cette précision. Le test TC-NOM-10 mentionne "JSON ou Prometheus" comme formats acceptables, ce qui est une décision d'implémentation absente de la spec. Impact : Le test est exécutable avec n'importe quel format, mais l'auditeur d'acceptation ne saura pas quel format vérifier. Point #6 des clarifications le reconnaît. Gravité : Mineur


ECT-52-14

Type : Hypothèse dangereuse Référence : Spec §5 FN-52-01, CA-52-01, CA-52-02, H-52-01 Description : La connectivité est validée par 10 appels consécutifs eth_blockNumber. Ce test vérifie la disponibilité instantanée, pas la fiabilité. Il est exécuté une seule fois en campagne de test, mais ne couvre pas : - La stabilité dans le temps (latence dégradée après N heures) - Les reconnexions après interruption (TC-NR-01 existe mais n'est pas un critère d'acceptation) - Les erreurs intermittentes (1 échec sur 100 appels) L'hypothèse H-52-01 reconnaît ce risque ("endpoints disponibles pendant les campagnes de test") mais n'est pas borné par un SLA de disponibilité testnet. Impact : CA-52-01/02 prouvent la connectivité à un instant T, pas la fiabilité opérationnelle. Le test de non-régression TC-NR-01 compense partiellement mais n'est pas un critère d'acceptation. Gravité : Mineur


ECT-52-15

Type : Incohérence Spec↔Tests Référence : Spec §6 ERR-52-01, Tests TC-ERR-01 Description : La spec ERR-52-01 dit : "erreur non bloquante si secondaire disponible". Le test TC-ERR-01 AND-clause ajoute : "le journal NE contient PAS de secret (token, clé API provider en clair)". Cette exigence de non-fuite de token API dans les logs de failover relève d'INV-52-11 (erreur sans fuite de secret), pas d'ERR-52-01 spécifiquement. La duplication est bénigne mais crée une ambiguïté : si le test échoue sur la fuite de token API, est-ce un échec d'ERR-52-01 ou d'INV-52-11 ? Impact : Duplication de couverture qui complexifie le diagnostic en cas d'échec de test. Non bloquant. Gravité : Mineur


ECT-52-16

Type : Incohérence Spec↔Tests Référence : Spec §5 FN-52-03, Tests TC-NOM-06 Description : TC-NOM-06 exige que la signature soit "conforme au format EIP-191 ou EIP-712". La spec FN-52-03 mentionne uniquement "une signature Ethereum" et "vérification comme correspondante à l'adresse attendue" sans mentionner EIP-191 ni EIP-712. Le test impose une contrainte de format non présente dans la spec. EIP-191 (personal_sign) et EIP-712 (typed data) sont des standards très différents avec des implications de sécurité distinctes. Impact : Le test est plus prescriptif que la spec. L'implémenteur pourrait utiliser un format de signature valide mais ni EIP-191 ni EIP-712 (ex: raw ECDSA), et le test échouerait alors que la spec serait respectée. Gravité : Majeur


Matrice de couverture des points à clarifier

Point à clarifier (Spec §10) Couvert par un écart ID écart
#1 — Seuil de confirmations Oui ECT-52-01
#2 — Transaction type d'ancrage Oui ECT-52-02
#3 — Politique GAS_PRICE_CEILING Oui ECT-52-03
#4 — Choix custody mode initial Non couvert — n'affecte pas la testabilité, décision opérationnelle
#5 — Preuve S3 chiffré au repos Oui ECT-52-12
#6 — Endpoint observabilité Oui ECT-52-13
#7 — Seuil solde critique Non couvert — uniquement alerting, pas de critère d'acceptation impacté
#8 — Indépendance vérification Non couvert — concerne l'organisation, pas la testabilité

Observations sur la cohérence learnings → spec

Learning Application dans PD-52 Verdict
PD-7 : tests en CI obligatoires INV-52-12, CA-52-12, TC-NOM-13, TC-INV-12 Correctement intégré
PD-36 : PKCS#11 / pool sessions HSM Mentionné via S1 mais sans exigence de pool de sessions Intégration partielle — le risque de saturation HSM n'est pas contractualisé
PD-37 : indépendance de vérification Point #8 des clarifications Identifié mais non résolu
PD-19 : critères mesurables Critères d'acceptation avec seuils explicites Correctement intégré
PD-239 : payload non spécifié Transaction type d'ancrage non définie (ECT-52-02) Pattern récurrent — même écart que PD-239

Verdict auditeur

3 écarts bloquants identifiés (ECT-52-01, ECT-52-02, ECT-52-12) empêchent la contractualisation complète de la spécification. Les points à clarifier §10 #1, #2 et #5 doivent être résolus avant passage en plan d'implémentation.

8 écarts majeurs identifiés, dont plusieurs incohérences Spec↔Tests où les tests sont plus prescriptifs que la spec. Ceci est un pattern systémique : les tests compensent les imprécisions de la spec en introduisant des décisions d'implémentation non contractualisées.

La spec est globalement bien structurée et les learnings des stories précédentes sont correctement intégrés. Le principal risque est l'absence de décision sur les paramètres opérationnels critiques (seuils, formats, politiques) qui laisse trop de latitude à l'implémenteur.