Aller au contenu

PD-52 — Confrontation Gate 3

Story : PD-52 — Setup connexion Ethereum L2 (Polygon/Arbitrum) Contre-auditeur : Claude Opus 4.6 (mode contre-audit, indépendant de la review initiale) Date : 2026-02-12 Documents confrontés : PD-52-specification-review.md (16 écarts), PD-52-specification.md, PD-52-tests.md, PD-52-besoin.md


ECT-52-01 — Seuil de confirmations absent

Review initiale : Ambiguïté / Bloquant Décision : CONFIRMER Justification : L'écart est factuellement exact. La spec §3 définit "Finalité opérationnelle : état valide interne atteint après seuil de confirmations contractuel" et INV-52-09 impose "pas finalisée tant que le seuil n'est pas atteint" — mais aucune valeur n'est donnée. La spec §10 point #1 le reconnaît elle-même comme "point à clarifier". L'argument sur la différence de finalité Polygon PoS vs Arbitrum Rollup est techniquement pertinent : les modèles sont fondamentalement différents (checkpoint L1 vs challenge period). Le délai de 30s de CA-52-06 est potentiellement incompatible avec tout seuil de confirmations raisonnable. H-52-04 confirme que le seuil est "définissable par configuration" mais la valeur par défaut n'est pas contractualisée. Gravité finale : Bloquant


ECT-52-02 — Transaction type d'ancrage non définie

Review initiale : Ambiguïté / Bloquant Décision : RÉTROGRADER Justification : L'écart est réel — la définition §3 est effectivement circulaire ("transaction minimale représentative de l'écriture d'un engagement sans spécification de contrat"). Cependant, la review surestime l'impact. PD-52 est explicitement le setup de connexion : le smart contract d'ancrage est renvoyé à PD-53, et la spec §2 "Exclu" le confirme. Dans ce contexte, une "transaction type d'ancrage" est nécessairement un eth_sendTransaction avec un champ data contenant un hash (puisque INV-52-08 impose "limitées à hash et métadonnées techniques"). Le payload exact sera défini par PD-53. Pour PD-52, il suffit de fixer un payload de test reproductible (ex: un hash SHA-256 fixe en data field d'un envoi à une adresse nulle ou au sender). L'absence de spécification canonique rend les tests non reproductibles entre exécutions (point valide) mais ne bloque pas l'implémentation de PD-52 elle-même. Gravité finale : Majeur


ECT-52-03 — Politique gas indéterminée

Review initiale : Ambiguïté / Majeur Décision : CONFIRMER Justification : La spec ERR-52-07 dit "mise en attente ou rejetée selon politique de file" — c'est un OR non résolu. TC-ERR-07 ne peut effectivement pas discriminer entre les deux comportements. Le test trace la politique appliquée mais ne peut valider laquelle est correcte. C'est bien un placeholder. La spec §10 point #3 le reconnaît comme "politique exacte non tranchée". L'écart est factuel, la gravité Majeur est proportionnée — ce n'est pas bloquant car l'implémenteur peut choisir l'un ou l'autre, mais l'absence de décision rend le test non falsifiable. Gravité finale : Majeur


ECT-52-04 — Code d'erreur CUSTODY_MODE_AMBIGUOUS non spécifié

Review initiale : Non testable / Majeur Décision : RÉTROGRADER Justification : L'écart est factuellement exact — CUSTODY_MODE_AMBIGUOUS n'apparaît pas dans §6. Cependant, INV-52-04 dit "un et un seul custody mode doit être sélectionné explicitement". Le cas de deux modes configurés simultanément est une violation directe de cet invariant. Le système doit rejeter cette situation — c'est la conséquence logique nécessaire de l'invariant. Le code d'erreur spécifique est un détail d'implémentation, mais le comportement (rejet) est implicitement requis par INV-52-04. Le test TC-INV-04 est donc correct dans son intention mais devrait accepter tout code d'erreur indiquant une ambiguïté, pas uniquement CUSTODY_MODE_AMBIGUOUS. Gravité finale : Mineur


ECT-52-05 — Timeout d'abandon après reorg non spécifié

Review initiale : Incohérence Spec↔Tests / Majeur Décision : CONFIRMER Justification : L'analyse est rigoureuse. ERR-52-08 spécifie "suivi continue jusqu'à nouvelle finalité ou échec" — mais ne définit ni le timeout d'abandon ni le concept d'état "échouée" pour une transaction non réapparue. 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 sont deux concepts absents de la spec : (1) un timeout et (2) un état terminal "échouée". Le test est effectivement plus prescriptif que la spec. Sans timeout, le suivi pourrait durer indéfiniment — ce qui est un bug potentiel mais qui devrait être spécifié, pas inventé par les tests. Gravité finale : Majeur


ECT-52-06 — Couche de validation de payload non spécifiée

Review initiale : Incohérence Spec↔Tests / Majeur Décision : RÉTROGRADER Justification : L'écart est techniquement correct — INV-52-08 est une contrainte de résultat ("données émises limitées à hash"), pas de mécanisme. Cependant, la review ignore que TC-NEG-03 est un test adversarial — par nature, les tests adversariaux explorent les frontières non spécifiées. La question n'est pas "la spec exige-t-elle une couche de validation" mais "que se passe-t-il si quelqu'un injecte des données personnelles dans le payload ?". L'invariant INV-52-08 impose le résultat : aucune donnée identifiante on-chain. Le mécanisme (validation entrante, transformation, ou architecture rendant l'injection impossible) est effectivement un choix d'implémentation. L'écart est valide mais sa gravité est disproportionnée : c'est un enrichissement légitime du test adversarial, pas une incohérence bloquante. Gravité finale : Mineur


ECT-52-07 — Codes d'erreur non catalogués

Review initiale : Incohérence Spec↔Tests / Majeur Décision : CONFIRMER Justification : L'analyse est solide. INV-52-11 exige des "codes d'erreur déterministes et journalisables" mais la spec §6 ne fournit que 9 codes d'erreur (RPC_UNAVAILABLE, CUSTODY_MODE_MISSING, CUSTODY_MODE_INVALID, SIGNATURE_VERIFICATION_FAILED, INSUFFICIENT_FUNDS, GAS_PRICE_CEILING_EXCEEDED). Les tests négatifs introduisent au moins 3 codes supplémentaires non spécifiés : CUSTODY_MODE_UNKNOWN, RPC_INVALID_ENDPOINT, MAINNET_FORBIDDEN. L'absence de catalogue exhaustif crée un risque réel de divergence spec↔implémentation. L'implémenteur pourrait utiliser des codes génériques ou une nomenclature différente. La gravité Majeur est justifiée car cela affecte la testabilité de manière systémique. Gravité finale : Majeur


ECT-52-08 — SLA failover sans paramètres de détection

Review initiale : Hypothèse dangereuse / Majeur Décision : CONFIRMER Justification : L'analyse technique est correcte. Le SLA de 5s (CA-52-07) inclut implicitement le temps de détection d'échec + le temps de bascule. Si le timeout de détection du provider primaire est configuré à 5s (valeur par défaut de nombreux clients HTTP), le SLA est déjà consommé avant la bascule. TC-NEG-09 (timeout 30s) illustre bien le problème. La spec devrait spécifier au minimum : (1) timeout de détection, (2) nombre de retries, (3) budget temporel total. Sans ces paramètres, le SLA est une déclaration d'intention, pas un engagement testable. Gravité finale : Majeur


ECT-52-09 — Concurrence wallet non spécifiée

Review initiale : Hypothèse dangereuse / Majeur Décision : RÉTROGRADER Justification : L'écart est factuellement correct — TC-NEG-10 teste un cas non spécifié. Cependant, la review surestime la gravité pour PD-52. La spec §4 "Contraintes opérationnelles" du besoin mentionne "< 100 tx/jour" — ce volume n'implique pas de multi-instance. La concurrence wallet avec gestion de nonce est un problème architectural complexe qui relève de PD-55 (worker d'ancrage périodique) ou d'un ADR d'architecture dédié, pas de PD-52 (setup de connexion). Le test adversarial couvre un risque réel mais hors périmètre contractuel de PD-52. Le risque de double-spend mentionné est pertinent pour production mais PD-52 est testnet-only (INV-52-02). Gravité finale : Mineur


ECT-52-10 — Seuil gas 50% peu discriminant

Review initiale : Ambiguïté / Mineur Décision : CONFIRMER Justification : Le constat technique est correct — 50% d'écart est très permissif. Sur L2, l'estimation de gas est généralement plus fiable que sur L1 (pas de mempool compétitive). Un seuil de 20-25% serait plus discriminant. Cependant, comme le note la review, le coût réel sera visible en monitoring et ce seuil est un garde-fou minimal. La gravité Mineur est appropriée. Gravité finale : Mineur


ECT-52-11 — Historique git hors scope INV-03

Review initiale : Risque sécu/conformité / Mineur Décision : RÉVOQUER Justification : TC-INV-03a couvre "tous les fichiers du repository (y compris historique git)". La review qualifie cela de "plus exigeant que la spec" et d'incohérence. En réalité, c'est une bonne pratique de sécurité standard — gitleaks et trufflehog scannent l'historique par défaut. INV-52-03 dit "la clé privée ne doit jamais être présente en clair dans code, variables d'environnement, logs ou traces". L'historique git est du code versionné. Un secret commité puis supprimé reste accessible via git log. L'interprétation du test est correcte et alignée avec l'intention de l'invariant. Il n'y a pas d'incohérence — le test est fidèle à l'esprit de INV-52-03. Gravité finale : Révoqué


ECT-52-12 — Preuve S3 chiffré au repos non spécifiée

Review initiale : Non testable / Bloquant Décision : RÉTROGRADER Justification : L'écart est techniquement exact — la méthode de preuve "chiffré au repos" n'est pas spécifiée. Cependant, la classification Bloquant est excessive. Le mode S3 est l'une des trois options de custody (avec S1 et S2). INV-52-04 exige "un et un seul mode sélectionné". Si S3 n'est pas pleinement testable, S1 et S2 restent pleinement testables. La spec §10 point #4 prévoit un "choix explicite du custody mode initial pour l'acceptation v1". Il est fort probable que S1 ou S2 soit choisi en v1, rendant la preuve S3 non bloquante pour l'acceptation. De plus, l'observable existe pour Vault : l'API sys/seal-status et les audit logs de Vault prouvent le chiffrement au repos. Le problème est que la spec ne nomme pas ces observables, pas qu'ils n'existent pas. Gravité finale : Majeur


ECT-52-13 — Format observabilité indéfini

Review initiale : Ambiguïté / Mineur Décision : CONFIRMER Justification : Le format (JSON vs Prometheus vs OpenMetrics) et l'endpoint ne sont pas spécifiés. Le besoin mentionne un "endpoint /health dédié" (CS-6) non repris dans la spec. TC-NOM-10 accepte "JSON ou Prometheus" — décision d'implémentation absente de la spec. Écart valide, gravité Mineur appropriée car le contenu (4 métriques) est bien défini même si le format ne l'est pas. Gravité finale : Mineur


ECT-52-14 — Connectivité ponctuelle vs fiabilité

Review initiale : Hypothèse dangereuse / Mineur Décision : CONFIRMER Justification : 10 appels consécutifs prouvent la connectivité instantanée, pas la fiabilité opérationnelle. L'hypothèse H-52-01 reconnaît ce risque. TC-NR-01 (reconnexion après interruption) compense partiellement mais n'est pas un critère d'acceptation. Pour PD-52 (setup de connexion testnet), cette limitation est acceptable — la fiabilité long terme relève de l'opérationnel. Gravité Mineur correcte. Gravité finale : Mineur


ECT-52-15 — Duplication de couverture

Review initiale : Incohérence Spec↔Tests / Mineur Décision : RÉVOQUER Justification : TC-ERR-01 vérifie le failover (ERR-52-01) ET ajoute une clause de non-fuite de secrets dans les logs. La review qualifie cela de "duplication" avec INV-52-11. En réalité, c'est de la défense en profondeur — vérifier l'absence de fuite de secrets dans un contexte de failover est un cas spécifique pertinent (les logs d'erreur de failover pourraient contenir des tokens API du provider). Ce n'est pas une incohérence mais un renforcement de couverture. Le diagnostic en cas d'échec est simple : si le test échoue sur la clause de non-fuite, c'est une violation d'INV-52-11 détectée via TC-ERR-01. Aucune ambiguïté réelle. Gravité finale : Révoqué


ECT-52-16 — Format de signature EIP-191/712 non spécifié

Review initiale : Incohérence Spec↔Tests / Majeur Décision : CONFIRMER Justification : FN-52-03 dit "une signature Ethereum" et "vérification comme correspondante à l'adresse attendue". TC-NOM-06 exige "conforme au format EIP-191 ou EIP-712". La spec ne mentionne ni l'un ni l'autre. Ce sont effectivement des standards très différents : EIP-191 préfixe le message avec \x19Ethereum Signed Message:\n, EIP-712 structure des types. Un raw ECDSA sign(keccak256(message)) satisferait la spec mais pas le test. Le test est plus prescriptif que la spec. Cependant, dans la pratique Ethereum, toute signature vérifiable par ecrecover est nécessairement encodée selon un standard (EIP-191 étant le minimum pour personal_sign). Le test restreint inutilement — la spec devrait nommer explicitement le standard attendu. Gravité Majeur confirmée. Gravité finale : Majeur


Synthèse de la confrontation

Écart Gravité initiale Décision Gravité finale
ECT-52-01 Bloquant CONFIRMER Bloquant
ECT-52-02 Bloquant RÉTROGRADER Majeur
ECT-52-03 Majeur CONFIRMER Majeur
ECT-52-04 Majeur RÉTROGRADER Mineur
ECT-52-05 Majeur CONFIRMER Majeur
ECT-52-06 Majeur RÉTROGRADER Mineur
ECT-52-07 Majeur CONFIRMER Majeur
ECT-52-08 Majeur CONFIRMER Majeur
ECT-52-09 Majeur RÉTROGRADER Mineur
ECT-52-10 Mineur CONFIRMER Mineur
ECT-52-11 Mineur RÉVOQUER Révoqué
ECT-52-12 Bloquant RÉTROGRADER Majeur
ECT-52-13 Mineur CONFIRMER Mineur
ECT-52-14 Mineur CONFIRMER Mineur
ECT-52-15 Mineur RÉVOQUER Révoqué
ECT-52-16 Majeur CONFIRMER Majeur

Bilan après confrontation

Gravité Avant Après Delta
Bloquant 3 1 -2
Majeur 8 6 -2
Mineur 5 5 0
Révoqué 0 2 +2
Total actif 16 12 -4

Verdict du contre-auditeur

1 écart bloquant résiduel (ECT-52-01 : seuil de confirmations) empêche la contractualisation complète. Les 2 autres bloquants initiaux ont été rétrogradés : - ECT-52-02 → Majeur (PD-52 est un setup, pas la définition du contrat d'ancrage) - ECT-52-12 → Majeur (S3 est une option parmi trois, les observables Vault existent)

Pattern systémique confirmé : les tests sont systématiquement plus prescriptifs que la spec (6 écarts sur 12 actifs sont des incohérences Spec↔Tests). Ce n'est pas un défaut des tests — c'est un défaut de la spec qui ne contractualise pas assez de décisions, forçant les tests à les anticiper.

Recommandation : résoudre ECT-52-01 (fixer un seuil de confirmations par réseau) et définir un catalogue de codes d'erreur (ECT-52-07) avant passage au plan d'implémentation.