Aller au contenu

PD-280 — Rapport de confrontation (Gate 5 — Plan d'implementation)

Ce rapport est produit par l'orchestrateur Claude avant la gate 5 PMO. Il confronte les documents produits pour identifier convergences, divergences et zones d'ombre.

1. Sources confrontees

Document Etape Version
PD-280-specification.md Etape 1 v3 corrigee
PD-280-tests.md Etape 2 v3 corriges
PD-280-plan.md Etape 4 v1
PD-280-code-contracts.yaml Etape 4 v1

2. Convergences

2.1 Modele de domaine

Les 4 documents convergent sur : - CheckResult = {OK, KO, INDETERMINATE, PENDING} (4 valeurs exactes) — Spec §4 INV-280-01, Tests TC-NOM-08, Plan C1, Contracts module proof-verification-domain. - verificationStatus = {PENDING, DONE} au niveau job — Spec §3, Tests TC-NOM-01/02, Plan C1, Contracts. - pendingReason = {ANCHOR_BATCH_NOT_FINALIZED, TX_NOT_ENOUGH_CONFIRMATIONS} dans ce perimetre — Spec §5.1, Plan C1, Contracts.

2.2 Invariants

Les 8 invariants (INV-280-01 a INV-280-09, sauf INV-280-08 retire) sont identiques entre Spec §4, Tests §5, Plan §3 et Contracts. Aucune difference de formulation substantielle.

2.3 Comportement API

  • Mapping CheckResult.PENDING interne -> null en API publique — Spec §5.7, Tests TC-NOM-01/03, Plan C2 mapper, Contracts proof-verification-service forbidden.
  • verificationRequestId UUID v4 obligatoire sur toute reponse 200 — Spec §5.1, Tests TC-NOM-09, Plan C3, Contracts CA-11.
  • Champs pendingReason et nextCheckAfterSeconds conditionnels (obligatoires si PENDING, interdits si DONE) — Spec INV-280-03, Tests TC-NOM-01/02 + TC-ERR-04, Plan C4 intercepteur, Contracts.
  • Clamp nextCheckAfterSeconds en [1, 86400] — Spec §5.1/§5.2, Tests TC-NEG-05, Plan C2.

2.4 Idempotence et lecture seule

  • Endpoint lecture seule (INV-280-09) — Spec §4, Tests TC-NOM-10, Plan §2.2/§2.3, Contracts forbidden "Muter l'etat metier".
  • Rappel DONE retourne reponse identique (INV-280-06) — Spec §4, Tests TC-INV-06, Plan §2.3, Contracts.
  • Concurrence idempotente (INV-280-09) — Spec §4, Tests TC-NOM-10, Plan §3, Contracts.

2.5 Reevaluation SLA lazy

  • Mode lazy uniquement, pas de worker/cron background — Spec §2/§5.2, Tests TC-NEG-11, Plan §2.2/§10, Contracts forbidden.
  • pendingResolutionTtl defaut 72h, bornes [1h, 30j] — Spec §5.2, Tests TC-NEG-09, Plan C1 config.

2.6 Erreurs

Les 7 cas d'erreur (ERR-280-01 a ERR-280-07) sont identiques entre Spec §6, Tests §4/§7, Plan §6, Contracts.

2.7 Perimetre et exclusions

Les 4 documents s'accordent sur les exclusions : pas de pattern asynchrone BullMQ, pas de worker SLA, pas de modification endpoint de creation, pas de modification de finalisation. References croisees coherentes a Spec §2.

2.8 Epic parent et references

Les 4 documents referent a PD-217 — LEGAL & COMPLIANCE (corrige par DIV-05 en v3).

2.9 Artefacts formels TLA+

Alignement RealStates = CheckResults a 4 valeurs, norm.yaml comme source de verite — Spec §4 INV-280-07, Tests TC-NOM-07/TC-ERR-06, Plan C6, Contracts module tla-alignment.

3. Divergences

DIV-01 : Semantique SLA lazy — "reclassification" vs "projection"

  • Specification (§5.2, ERR-280-05) : utilise le terme "reclassifie" (maillon reclassifie INDETERMINATE), impliquant un changement d'etat.
  • Tests (TC-NOM-05 THEN) : "Le maillon devient INDETERMINATE pendant le traitement de cet appel" — formulation ambigue entre mutation et projection.
  • Plan (§2.2) : tranche explicitement pour une projection sans mutation DB : "pas de mutation en base — l'etat DB reste PENDING". Le plan precise : "SEMANTIQUE : La spec dit 'reclassifie' — cela signifie que l'endpoint PRESENTE le maillon comme INDETERMINATE dans sa reponse (projection), pas qu'il ecrit en base."
  • Contracts (module proof-verification-service) : forbidden "Muter l'etat metier lors d'un appel de verification (endpoint lecture seule)" — coherent avec le plan.
  • Tension intra-spec : INV-280-09 dit "lecture seule" tandis que §5.2 dit "reclassifie". Le plan resout cette tension en faveur de INV-280-09.
  • Impact : Si la gate retient la lecture de la spec comme mutation, le plan est non conforme. Si la gate retient l'interpretation du plan (projection), les tests doivent preciser que l'observable est le payload API, pas l'etat DB.

DIV-02 : Scenario TC-NOM-04 absent du document de tests

  • Specification (§8 SCN-280-04) : definit le scenario "indeterminate durable" — blockchain inaccessible -> maillon = INDETERMINATE.
  • Plan (§5) : reference TC-NOM-04 deux fois, mappe vers SCN-280-04, CA-03, niveau unitaire.
  • Code contracts (module proof-verification-tests) : mentionne "30 scenarios TC-* (incluant TC-NOM-04)".
  • Tests : ne contient pas TC-NOM-04. Les scenarios nominaux passent de TC-NOM-03 a TC-NOM-05 directement. Le scenario SCN-280-04 de la spec n'a pas de test dedie.
  • Impact : Couverture incomplete. Le critere CA-03 n'est que partiellement couvert (le cas PENDING_FINALITY -> PENDING est teste par TC-NOM-03, mais le cas blockchain inaccessible -> INDETERMINATE ne l'est pas).

DIV-03 : Incoherence interne du plan sur la generation de verificationRequestId

  • Plan Decision DDL-02 (§1, C5) : "Le UUID est genere a la creation du job de verification (processus externe, hors perimetre PD-280), pas par l'endpoint GET" et "colonne verification_request_id UUID NOT NULL DEFAULT gen_random_uuid()".
  • Plan HT-05 resolu (§8) : "Genere via crypto.randomUUID() au premier appel DONE, persiste, retourne a l'identique en rappel".
  • Contradiction : DDL-02 dit generation a la creation du job (INSERT en base, donc disponible des le premier appel PENDING). HT-05 dit generation "au premier appel DONE" (donc indisponible pendant les appels PENDING). Le DEFAULT gen_random_uuid() de la migration confirme DDL-02 (generation a l'INSERT).
  • Specification (§5.1) : verificationRequestId obligatoire sur toute reponse 200, incluant les reponses PENDING. Compatible uniquement avec DDL-02.
  • Impact : Le texte de HT-05 est vestigiel et incorrect par rapport a DDL-02 qu'il est cense referencer. Pas de risque fonctionnel si l'implementation suit DDL-02, mais la confusion documentaire pourrait induire en erreur un agent d'implementation.

DIV-04 : Decompte des scenarios de test

  • Code contracts : "30 scenarios TC-* (incluant TC-NOM-04)".
  • Tests document : 29 scenarios definis (TC-NOM-04 manquant, cf. DIV-02).
  • Plan (§5) : 30 entrees dans la table de mapping (TC-NOM-04 inclus, et TC-NOM-04 apparait deux fois — doublon dans la table).
  • Impact : Incoherence numerique mineur mais consequence directe de DIV-02.

4. Zones d'ombre

ZO-01 : Etat DB vs etat API apres projection SLA

Consequence directe de DIV-01. Si l'endpoint projette INDETERMINATE sans muter la DB (choix du plan), et qu'aucun worker background n'est prevu dans ce perimetre : - L'etat en base reste PENDING indefiniment. - Tout consommateur qui lit directement la base (sans passer par l'API) voit PENDING alors que l'API retourne INDETERMINATE. - Le processus externe futur (worker SLA, story non creee) devra reconcilier cette divergence.

Aucun des 4 documents ne specifie le comportement attendu d'un consommateur direct de la DB face a un maillon PENDING dont le TTL est depasse.

ZO-02 : Existence du job de verification (prerequis a verificationRequestId)

La spec definit verificationRequestId comme un identifiant technique porte par la reponse. Le plan (DDL-02) dit qu'il est genere a la creation du job de verification par un processus externe hors perimetre PD-280.

Question non tranchee : Si le processus externe qui cree les jobs de verification n'existe pas encore (ou n'est pas deploye), l'endpoint GET retournera une erreur 500 ou 404 car aucun verificationRequestId ne sera present en base. Aucun document ne specifie : - Quel processus externe cree le job de verification. - Si le job est cree a la soumission de la preuve, au premier appel de verification, ou autrement. - Le comportement de l'endpoint si aucun job n'existe pour un proofId valide et existant.

ZO-03 : Mecanisme de test pour la concurrence (TC-NOM-10)

Le test TC-NOM-10 exige deux appels concurrents au meme proofId avec reponses identiques. Ni les tests ni le plan ne specifient : - Le mecanisme de concurrence en environnement de test (Promise.all, appels HTTP paralleles, injection de timing). - Le niveau d'isolation requis (meme instance NestJS, instances separees). - La tolerance sur "identiques" (corps JSON byte-identical, ou equivalence semantique).

ZO-04 : Cardinalite verificationRequestId par proofId

La spec INV-280-06 dit "Pour un verificationRequestId donne: DONE terminal". Le plan §2.3 dit "si DONE existant pour le proofId, retourne tel quel".

Question implicite : Peut-il exister plusieurs verificationRequestId pour un meme proofId (verifications successives) ? Le plan assume un seul job par preuve (le DDL-02 n'ajoute pas de table de jointure). Si une preuve peut etre re-verifiee (nouveau contexte), le schema actuel ne le supporte pas.

Aucun document ne tranche explicitement cette cardinalite.

ZO-05 : Comportement de la down migration avec donnees PENDING en production

Identifie comme "non tranche" par la Spec §10.2 et reconnu par le Plan §9.2 et §10. Aucune decision architecturale n'est prise. Le plan dit "Guard : verifier qu'aucune ligne PENDING n'existe en base avant down migration" mais ne specifie pas ce qui se passe si des lignes PENDING existent.

ZO-06 : Interaction SLA lazy avec la projection lors de rappels multiples

Si un maillon est projete INDETERMINATE par SLA lazy (TTL depasse, pas de mutation DB), et que le client rappelle : - Le plan dit que la meme projection sera appliquee a chaque appel (coherent). - Mais si entre deux appels, le processus externe resout le maillon (ex: la blockchain finalise), le maillon en DB passerait de PENDING a OK — est-ce que la projection SLA doit etre prioritaire sur la resolution externe ?

Le plan ne traite pas cette course condition entre projection SLA et resolution externe.

5. Recommandation

  • Proceder — convergence confirmee, aucun conflit bloquant
  • Rework necessaire — divergences a resoudre avant de continuer
  • Escalade — decision humaine requise sur un point structurant

Actions de rework recommandees :

  1. DIV-02 (bloquant) : Ajouter TC-NOM-04 dans le document de tests (scenario blockchain inaccessible -> INDETERMINATE, cf. SCN-280-04 de la spec).
  2. DIV-01 (clarifiant) : Aligner le vocabulaire entre spec, tests et plan. Soit la spec adopte "projete" au lieu de "reclassifie", soit le plan documente explicitement la decision de diverger de la lettre de la spec (avec justification par INV-280-09).
  3. DIV-03 (mineur) : Corriger le texte de HT-05 dans le plan pour refleter DDL-02 (generation a la creation du job, pas "au premier appel DONE").
  4. ZO-02 (clarifiant) : Preciser dans le plan le prerequis d'existence du job de verification — quel processus le cree, et quel comportement si absent.