PD-177 — Confrontation Gate 5 (Plan d'implementation)¶
Date : 2026-02-23 Reviewer P1 (Phase 1) : ChatGPT (via OpenCode) Confrontant P2 (Phase 2) : Claude
Synthese de la review P1¶
ChatGPT a identifie 10 ecarts : - 1 BLOQUANT (TC-SEC-02 irrealisable) - 8 MAJEUR (passthrough tezos, env vars, signer_address nullable, concurrence wallet, atomicite, WORM DB, code contracts relations, PostgreSQL reel) - 1 MINEUR (cardinalite modules 13 vs 14)
Analyse ecart par ecart¶
E-01 — Passthrough tezos (MAJEUR → MINEUR)¶
Review P1 : Le plan ne decrit pas de mecanisme operationnel explicite pour blockchain=tezos. Confrontation : Le plan INV-177-04 dit "Le service ignore les requetes tezos (passthrough)". Le code contract anchor-proof-validation interdit "Accepter blockchain='tezos' comme valide pour PD-177". Le mecanisme est implicite : pas de traitement = pas d'action. La spec dit "ignoree ou passee en passthrough". Un composant dedie pour ne rien faire est sur-ingenierie. Verdict : MINEUR — Le plan couvre le cas via exclusion (no-op). Manque un detail sur le point d'implementation exact (quel service filtre).
E-02 — Variables d'environnement en runtime (MAJEUR → REJETE)¶
Review P1 : L'interdiction d'export vers variables d'environnement en runtime n'est pas mappee. Confrontation : En mode S2 KMS, la cle privee n'existe jamais dans le processus applicatif. Elle reside dans AWS KMS (non exportable). Les env vars ne contiennent que l'ARN KMS (kmsKeyId), pas le secret. L'INV-177-10 du plan dit : "Le code applicatif ne detient que le kmsKeyId (ARN)". Les env vars sont un canal d'entree (lecture config), pas un canal de sortie. Aucune operation du plan n'ecrit de cle privee dans une env var. Verdict : FAUX POSITIF — L'architecture S2 rend cet ecart non applicable.
E-03 — signer_address nullable (MAJEUR → MINEUR)¶
Review P1 : La nullabilite ne garantit pas la presence pour les nouveaux enregistrements. Confrontation : Le plan est explicite : "AnchorBatchService.submitBatch() ecrit signer_address". La nullabilite est pour les batches PD-55 existants (backward compat). Le TC-177-06 verifie que le champ est present pour les nouveaux ancrages. La contrainte est applicative (le service ecrit toujours). Un NOT NULL au niveau DB casserait les batches existants. Verdict : MINEUR — Le plan couvre la presence via le service. Pourrait preciser "garantie applicative de non-nullite pour les nouveaux enregistrements".
E-04 — TC-SEC-02 irrealisable (BLOQUANT → MAJEUR)¶
Review P1 : Pas d'observabilite prouvant l'absence d'ecriture prealable sur tous les canaux. Confrontation : Le test est realisable : 1. Injecter un pattern secret dans la reponse d'un service blockchain 2. L'interceptor NestJS (RxJS pipe) detecte le pattern dans la reponse 3. Throw BlockchainError(SECRET_LEAK_DETECTED) avant que NestJS ne serialise la reponse HTTP 4. Verifier : (a) erreur emise, (b) incident securite cree, © la reponse HTTP ne contient pas le secret, (d) les logs ne contiennent pas le secret Cependant, le plan manque de precision sur le point d'interception exact dans le pipeline NestJS (response interceptor RxJS tap vs request interceptor). Le plan dit "intercepte l'Observable avant next.handle()" ce qui est techniquement incorrect — c'est apres next.handle() dans le pipe RxJS. Le test est realisable mais le mecanisme est mal decrit. Verdict : MAJEUR — Le TC-SEC-02 est realisable, mais le plan doit preciser le point d'interception (pipe RxJS post-handler, pas pre-handler).
E-05 — Concurrence multi-instance unicite wallet (MAJEUR → MINEUR)¶
Review P1 : Pas de mecanisme de coherence inter-processus. Confrontation : En S2 KMS, l'adresse wallet est deterministe — derivee de la cle KMS secp256k1. Toutes les instances utilisent le meme kmsKeyId (config partagee). La derivation est mathematiquement deterministe : meme cle KMS = meme adresse Ethereum. Il n'y a pas de risque de divergence car il n'y a pas d'etat local (contrairement a S1 ou S3 qui pourraient avoir des cles locales). Verdict : MINEUR — Risque negligeable en S2. L'hypothese est implicitement couverte par l'architecture KMS.
E-06 — Atomicite et idempotence (MAJEUR → MINEUR)¶
Review P1 : Hypotheses d'atomicite non explicitees pour le lien tx→append-only. Confrontation : Le processor BullMQ BlockchainAnchorProcessor a concurrency=1. Le flow est sequentiel. PD-55 fournit deja les mecanismes d'atomicite (advisory lock PostgreSQL, transaction englobante). Le plan section 6 (dependances) documente PD-55 comme fondation. Les learnings contextuels confirment ce pattern. PD-177 enrichit le modele sans modifier le flux transactionnel. Verdict : MINEUR — Les mecanismes existent dans PD-55. Le plan devrait mentionner explicitement cette dependance d'atomicite.
E-07 — Protection append-only applicative vs WORM DB (MAJEUR → REJETE)¶
Review P1 : Fragilite probatoire sans garantie DB-level. Confrontation : La spec elle-meme dit (section 3 Definitions) : "La protection WORM au niveau base est hors perimetre PD-177". Le verdict Gate 3 v2 NE-04 (MINEUR) a identifie et accepte cette difference semantique. Le plan documente cette decision dans HI-04. Demander plus que ce que la spec exige depasse le perimetre de la review de conformite. Verdict : FAUX POSITIF — Hors perimetre de la spec. Le reviewer demande une garantie explicitement exclue par la specification contractuelle.
E-08 — Cardinalite modules 13 vs 14 (MINEUR → CONFIRME MINEUR)¶
Review P1 : Incoherence documentaire entre le nombre annonce et l'enumeration. Confrontation : Le resume du plan annonce "13 modules" mais le YAML contient 14 entries - module: (incluant tests-pd177 comme 14e). Ecart documentaire reel mais sans impact fonctionnel — tous les composants ont un owner et des frontieres definies. Verdict : MINEUR CONFIRME.
E-09 — Code contracts immutabilite relations (MAJEUR → MINEUR)¶
Review P1 : Les relations d'entites et atomicite rollback ne sont pas dans les frontieres contractuelles. Confrontation : Le code contract anchor-service-enrichment couvre INV-177-14 et interdit les entrees orphelines. L'atomicite est heritee de PD-55 (advisory lock + transaction englobante). Le plan section 6.1 documente PD-55 comme dependance. Les code contracts ne repetent pas les proprietes heritees des stories fondation. Verdict : MINEUR — L'information existe dans le plan. Le code contract pourrait expliciter la dependance PD-55 pour l'atomicite.
E-10 — Dependance PostgreSQL reel pour migrations (MAJEUR → MINEUR)¶
Review P1 : La dependance a un PostgreSQL reel n'est pas explicitement contractualisee. Confrontation : Le plan section 6.4 dit "npm run migration:validate + npm run migration:run sur PostgreSQL local". La checklist pre-merge (section 9.4) repete ces commandes. Le TC-177-18 teste la validation locale. La commande migration:run implique necessairement une base PostgreSQL. La precondition est implicite dans l'outil utilise. Verdict : MINEUR — Implicitement couvert. Pourrait etre plus explicite dans la section "Contraintes techniques" comme prerequis.
Synthese de la confrontation¶
| Ecart | P1 (ChatGPT) | P2 (Claude) | Verdict final propose |
|---|---|---|---|
| E-01 Passthrough tezos | MAJEUR | MINEUR | MINEUR |
| E-02 Env vars runtime | MAJEUR | REJETE | REJETE (FAUX POSITIF) |
| E-03 signer_address nullable | MAJEUR | MINEUR | MINEUR |
| E-04 TC-SEC-02 fail-closed | BLOQUANT | MAJEUR | MAJEUR |
| E-05 Concurrence multi-instance | MAJEUR | MINEUR | MINEUR |
| E-06 Atomicite idempotence | MAJEUR | MINEUR | MINEUR |
| E-07 WORM DB hors perimetre | MAJEUR | REJETE | REJETE (FAUX POSITIF) |
| E-08 Cardinalite 13 vs 14 | MINEUR | MINEUR | MINEUR |
| E-09 Code contracts relations | MAJEUR | MINEUR | MINEUR |
| E-10 PostgreSQL reel | MAJEUR | MINEUR | MINEUR |
Bilan confrontation : 0 BLOQUANT, 1 MAJEUR, 7 MINEUR, 2 REJETES (FAUX POSITIFS).
Score P1 (ChatGPT) : 6.5/10 (trop severe — 2 faux positifs, 6 ecarts surclasses) Score P2 (Claude) : 8.0/10 (plan solide mais le mecanisme fail-closed de N-02 est mal decrit)