Aller au contenu

PD-177 — Rapport de Confrontation Gate 8 v2

Story : PD-177 — Configurer wallet Ethereum et gestion cles privees Gate : 8 (CLOSURE) — Iteration v2 Orchestrateur : Claude (Opus 4.6) Date : 2026-02-23 Documents confrontes : - A : Specification (PD-177-specification.md) - B : Tests contractuels (PD-177-tests.md) - C : Acceptabilite v2 (PD-177-acceptability.md) - D : Review Gate 8 v2 (P1 ChatGPT) - E : Code source (secret-leak.interceptor.ts) - F : Tests unitaires (secret-leak.interceptor.spec.ts) - Verification codebase : lecture directe des fichiers source


1. Convergences

1.1 Resolution des 4 ecarts MAJEUR v1

Les documents C, D, E et F convergent factuellement sur la resolution des 4 ecarts :

Ecart Evidence code (E/F) Evidence doc (C/D) Statut
SEC-08-01 (cycles) WeakSet + seen.add(value) avant recursion (E:75-78) C et D confirment RESOLU Convergent
SEC-08-02 (profondeur) MAX_SCAN_DEPTH=10 + garde depth >= MAX_SCAN_DEPTH (E:71) C et D confirment RESOLU Convergent
ECT-08-02 (limites) 7 tests boundary presents (F:165-222) : base64 42/43, padding, mnemonic 24/25, uppercase, digits C et D confirment RESOLU Convergent
ECT-08-03 (anti-leak logs) 3 tests spy Logger (F:256-310) : hex, mnemonic, contexte erreur C et D confirment RESOLU Convergent

Verification codebase : les 28 it() sont presents dans le fichier spec (compte confirme par grep).

1.2 Invariants securite INV-177-08 / INV-177-09

  • La specification (A) exige fail-closed avec incident securite (INV-177-09).
  • Le code (E) implemente handleSecretDetected() qui log un SECURITY_INCIDENT puis throw BlockchainError(SECRET_LEAK_DETECTED) — conforme au fail-closed.
  • Les tests (F) verifient que le secret ne fuit jamais dans les logs ni dans le message d'erreur (F:257-310).
  • La review P1 (D) valide cette conformite.

Convergence confirmee sur INV-177-08 et INV-177-09.

1.3 Architecture SecretLeakInterceptor

  • Extraction scanArray/scanObject mentionnee en C (correction Sonar S3776) : presente dans le code (E:87-100).
  • MAX_SCAN_DEPTH=10 exporte comme constante module-level (E:19) : coherent avec C et D.
  • Pattern de detection par regex + fonction isMnemonicPattern (E:22-35) : coherent avec les tests boundary (F).

Convergence confirmee.

1.4 Couverture de la matrice INV/CA

  • B declare 21/21 INV et 17/17 CA couverts par au moins un TC.
  • C declare coverage 100% sur ⅚ composants PD-177 et 28% sur wallet-operational.service.ts.
  • D attribue test_coverage=8.9.
  • Verification codebase : les 6 suites de tests existent avec les fichiers spec correspondants.

Convergence confirmee sur la couverture declaree.

1.5 Politique de confirmations reseau

  • A specifie chainId=137 -> 12 confirmations, timeout=900s et chainId=42161 -> 30 confirmations, timeout=900s.
  • B reprend ces valeurs dans TC-177-05 et le cadre de validation (B:11).
  • Verification codebase : network-confirmation-policy.ts implemente exactement ces valeurs (Polygon: 12/900s, Arbitrum: 30/900s).

Convergence confirmee.

1.6 Nombre de tests et suites

  • C declare 6 suites, 65 tests PD-177.
  • D confirme 28/28 pour SecretLeakInterceptor.
  • F contient exactement 28 it() (verifie par grep).
  • C detaille : network-confirmation-policy(6), custody-mode.guard(4), secret-leak.interceptor(28), wallet-recovery.service(9), anchor-exclusivity.guard(5), anchor-proof.validator(13) = 65 total.

Convergence confirmee.


2. Divergences

2.1 DIV-01 — Nomenclature code erreur ERR-177-08 : SECRET_EXPOSURE_DETECTED vs SECRET_LEAK_DETECTED

Gravite : MINEUR (nomenclature documentaire)

  • Source A (specification, section 6) : ERR-177-08 reference BlockchainErrorCode: SECRET_EXPOSURE_DETECTED.
  • Source B (tests, TC-ERR-08) : reference BlockchainErrorCode=SECRET_EXPOSURE_DETECTED.
  • Source E (code) : l'enum BlockchainErrorCode dans error-codes.ts:29 definit SECRET_LEAK_DETECTED, pas SECRET_EXPOSURE_DETECTED.
  • Source F (tests unitaires) : BlockchainErrorCode.SECRET_LEAK_DETECTED (F:151).
  • Verification codebase : SECRET_EXPOSURE_DETECTED n'existe dans aucun fichier .ts du projet. Il apparait uniquement dans les documents de specification et de test contractuel (6 fichiers .md).

Fait : le code implemente SECRET_LEAK_DETECTED ; la specification et les tests contractuels referencent SECRET_EXPOSURE_DETECTED. Ce sont deux noms differents. Le comportement fonctionnel est identique (fail-closed + incident securite), mais le mapping ERR-177-08 -> code enum reel diverge.

2.2 DIV-02 — AnchorExclusivityGuard reutilise INVALID_CUSTODY_MODE au lieu d'un code dedie

Gravite : MINEUR (semantique des codes erreur)

  • Source A (specification) : l'invariant INV-177-03 (exclusivite ancrage) est distinct de INV-177-07 (mode custody S2). La specification ne definit pas de code d'erreur explicite pour les violations d'exclusivite.
  • Source E (code) : AnchorExclusivityGuard (anchor-exclusivity.guard.ts:26) throw BlockchainError(BlockchainErrorCode.INVALID_CUSTODY_MODE) pour un acces non autorise au wallet.
  • Fait : le meme code erreur INVALID_CUSTODY_MODE est utilise pour deux invariants distincts (mode S2 incorrect ET appelant non autorise). Cela pourrait compliquer le diagnostic en production. Aucun document ne releve ce point.

2.3 DIV-03 — Verdict acceptabilite vs verdict P1

Gravite : INFORMATION (pas de contradiction, ecart de perspective)

  • Source C (acceptabilite) : verdict global = RESERVES (7.0-7.8 reviews securite et tests).
  • Source D (P1 review) : verdict = GO (8.60/10, tous scores >= 8).
  • Fait : C integre les 3 reviews LLM (code, tests, securite) dont 2 sont RESERVES. D est la review P1 qui produit un verdict GO. Les deux documents sont coherents dans leur perimetre respectif — C rapporte les avis des reviewers incluant des reserves, D est le scoring CLOSURE du P1 qui a pris ces reserves en compte pour son scoring. Il n'y a pas de contradiction, mais le lecteur pourrait interpreter une incoherence entre "RESERVES" et "GO".

3. Zones d'ombre

3.1 ZO-01 — Coverage wallet-operational.service.ts a 28%

  • Source C : coverage 28% Stmts sur wallet-operational.service.ts, qualifie de "facade d'orchestration".
  • Source D : n'evoque pas ce point, attribue test_coverage=8.9.
  • Fait : aucun test unitaire dedie a wallet-operational.service.ts n'est present dans les 6 suites PD-177 listees en C. Le service est le point d'entree principal du wallet (initialisation, getOfficialAddress, isOperational). La justification "facade d'orchestration couverte par tests integration PD-52" est mentionnee en C mais aucun test d'integration specifique PD-177 n'est reference.
  • Question : le scoring test_coverage=8.9 de P1 est-il coherent avec un composant central a 28% de couverture ?

3.2 ZO-02 — Sonar Quality Gate non disponible

  • Source C : "NON DISPONIBLE (Docker daemon arrete)" avec mitigation par pipeline GitLab CI/CD.
  • Source D : ne mentionne pas l'absence de Sonar.
  • Fait : la gate CLOSURE s'appuie sur un scan Sonar non execute. Le risque est qualifie "Faible" en C mais cette evaluation n'est pas factuelle — c'est une estimation. Les corrections v2 visent Sonar S3776 mais sans validation Sonar effective.

3.3 ZO-03 — Ecarts RESERVE S-01 et S-02 non resolus

  • Source C : 2 ecarts RESERVE acceptes :
  • S-01 : bypass par profondeur > 10 (secret au-dela de MAX_SCAN_DEPTH non detecte).
  • S-02 : bypass sur objets Error avec proprietes non-enumerables.
  • Source D : ecarts_ouverts: [] dans le YAML.
  • Source E : le code arrete le scan a depth >= 10 (E:71), confirmant que S-01 est un fait technique.
  • Fait : D declare zero ecarts ouverts, mais C identifie 2 ecarts RESERVE. Ce ne sont pas des ecarts MAJEUR, mais le YAML de D pourrait laisser croire qu'il n'y a aucun ecart residuel d'aucune gravite.

3.4 ZO-04 — Tests contractuels (B) vs tests unitaires (F) : perimetre different

  • Source B : definit 19 TC nominaux + 8 TC erreur + 3 TC securite = 30 scenarios contractuels couvrant les 21 invariants.
  • Source F : 28 tests unitaires focusses sur le SecretLeakInterceptor seul.
  • Source C : 65 tests unitaires sur 6 suites.
  • Fait : les 65 tests unitaires implementes couvrent un sous-ensemble technique des 30 scenarios contractuels. Certains TC de B (TC-177-04 emission nominale, TC-177-05 confirmation reseau, TC-177-11 liaison deterministe, TC-177-12 reconstruction tierce, TC-SEC-03 compromission serveur) ne sont pas couvrables par des tests unitaires isoles — ils requierent des tests d'integration ou e2e non presents dans le perimetre PD-177. Aucun document ne distingue explicitement quel TC est couvert par test unitaire vs a couvrir par test integration.

3.5 ZO-05 — Faux positifs base64 (S-05 et doc C)

  • Source C (securite) : S-05 (MINEUR) identifie une surface de faux positifs sur la regex base64 ^[A-Za-z0-9+/]{43,}={0,2}$.
  • Source E (code) : le regex (E:24) matchera toute chaine >= 43 caracteres composee de [A-Za-z0-9+/] — ce qui inclut des identifiants, JWT segments, ou URLs encodees.
  • Fait : le risque de faux positifs est documente (C) mais non quantifie ni teste (aucun test dans F verifiant le passage de chaines non-secretes longues de 43+ caracteres en base64-like, par exemple des JWT). L'impact en production n'est pas evalue.

3.6 ZO-06 — Absence de test pour Error avec proprietes non-enumerables

  • Source C : S-02 identifie un bypass possible via objets Error dont certaines proprietes (comme message) ne sont pas enumerables par Object.entries().
  • Source E (code) : scanObject utilise Object.entries(obj) (E:94) qui ne retourne que les proprietes propres enumerables.
  • Source F : le test "should scan error objects too" (F:155-162) injecte un objet plain { mnemonic: 'leaked-in-error' } via throwError(), pas un veritable objet Error avec message comme propriete non-enumerable.
  • Fait : le test F:155 ne valide pas le scenario S-02 identifie en C. Un secret dans Error.message ne serait pas detecte par le scan Object.entries().

4. Analyse du scoring P1

4.1 Verification arithmetique

Critere Score P1
conformity 8.8
test_coverage 8.9
security 8.2
maintainability 8.5
Moyenne (8.8+8.9+8.2+8.5)/4 = 8.60

Calcul verifie : la moyenne arithmetique est correcte.

4.2 Coherence interne du scoring

  • conformity 8.8 : coherent avec 0 ecart MAJEUR ouvert et la divergence de nomenclature DIV-01 (mineure).
  • test_coverage 8.9 : score eleve. A nuancer avec ZO-01 (wallet-operational.service.ts a 28%) et ZO-04 (certains TC contractuels non couvrables par tests unitaires seuls). Le delta v1->v2 (+2.1) est justifie par les +14 tests SecretLeakInterceptor.
  • security 8.2 : coherent avec les 2 RESERVE (S-01, S-02) identifies en C. Le score reflete que le SecretLeakInterceptor est un mecanisme de defense-in-depth, pas la derniere ligne de defense.
  • maintainability 8.5 : coherent avec les corrections Sonar S3776 (extraction scanArray/scanObject). Non verifiable par Sonar (ZO-02).

4.3 Progression v1 -> v2

La progression declaree (+1.20 point moyen) est proportionnee aux corrections apportees : +14 tests, 4 ecarts MAJEUR resolus, hardening du composant le plus critique (SecretLeakInterceptor).


5. Recommandation pour le PMO

Faits etablis

  1. Les 4 ecarts MAJEUR v1 sont factuellement resolus dans le code (verification directe des fichiers source).
  2. Le scoring P1 est arithmetiquement correct et les justifications factuelles sont coherentes.
  3. La couverture declaree (21/21 INV, 17/17 CA) est supportee par la matrice de tests.
  4. Le code et les tests sont coherents entre eux.

Points d'attention factuels

  1. DIV-01 : la nomenclature SECRET_EXPOSURE_DETECTED (spec/tests contractuels) vs SECRET_LEAK_DETECTED (code reel) est un ecart documentaire a arbitrer — correction de la spec ou du code.
  2. ZO-01 : la couverture de wallet-operational.service.ts (28%) est un fait non conteste mais non reflecte dans le score test_coverage (8.9).
  3. ZO-02 : le scan Sonar n'est pas execute — la conformite Sonar est une assertion non verifiee a cette gate.
  4. ZO-03 : 2 ecarts RESERVE (S-01, S-02) existent mais le YAML P1 declare ecarts_ouverts: [], ce qui est techniquement exact (ce sont des RESERVE, pas des ecarts MAJEUR ouverts) mais potentiellement trompeur.
  5. ZO-04/ZO-06 : certains scenarios contractuels (TC-SEC-03, S-02) ne sont pas couvrables par les tests unitaires presents — cela necessite des tests d'integration non encore implementes.

Synthese

Le dossier PD-177 v2 est materiellement ameliore par rapport a v1. Les corrections sont verifiees dans le code source. Les divergences identifiees sont de gravite MINEUR ou INFORMATION. Les zones d'ombre relevent principalement de la couverture par tests d'integration (hors perimetre immediat) et de l'absence de validation Sonar.