PD-280 — Rapport de confrontation (Gate 5 — Review plan)¶
Ce rapport est produit par l'orchestrateur Claude avant la gate PMO 5. Il confronte les documents produits pour identifier convergences, divergences et zones d'ombre.
1. Sources confrontees¶
| Document | Etape d'origine | Version |
|---|---|---|
Specification (PD-280-specification.md) | Etape 1 | v3 corrigee |
Tests (PD-280-tests.md) | Etape 2 | v3 corriges |
Plan d'implementation (PD-280-plan.md) | Etape 4 | v1 |
Code contracts (PD-280-code-contracts.yaml) | Etape 4 | v1 |
2. Convergences¶
2.1 — Modele de domaine unanime Les 4 documents convergent sur CheckResult = {OK, KO, INDETERMINATE, PENDING} et VerificationStatus = {PENDING, DONE}. L'enum est etendu sur place (pas de nouvel enum). Aucune ambiguite residuelle. - Spec §3-4 | Tests §2 matrice INV-280-01 | Plan §1 C1 | Contracts module proof-verification-domain
2.2 — 8 invariants (INV-280-01 a 09, sans 08) alignes Les 8 invariants sont cites avec la meme formulation et les memes identifiants dans les 4 documents. Chaque invariant est mappe a au moins un mecanisme (plan §3), au moins un test (tests §5), et au moins un module de code contracts.
2.3 — 12 criteres d'acceptation couverts Les 12 CAs (CA-01 a CA-12) sont references de maniere coherente entre spec §7, tests §2 (matrice), plan §4 (mapping CA -> mecanismes), et code contracts (invariants par module).
2.4 — Mode SLA lazy sans worker background Les 4 documents excluent explicitement le worker/cron de reevaluation SLA. La reevaluation est declenchee uniquement sur appel API. - Spec §2 hors perimetre + §5.2 | Tests TC-NEG-11 | Plan §9.3 + §10 | Contracts proof-verification-service forbidden
2.5 — Endpoint lecture seule, idempotent, sans lock applicatif Convergence complete sur INV-280-09 (concurrence idempotente) et INV-280-06 (DONE terminal avec rappel identique). - Spec §4-5.3 | Tests TC-NOM-10, TC-INV-06 | Plan §2.3 | Contracts proof-verification-service invariants
2.6 — Mapping interne/API : PENDING -> null Les 4 documents specifient que CheckResult.PENDING interne est expose comme null dans linkResults[*] API, et que la string "PENDING" est interdite en API. - Spec §5.7 | Tests TC-NEG-04 | Plan C2 mapper | Contracts proof-verification-domain forbidden
2.7 — Codes d'erreur HTTP et metier Les 6 cas d'erreur (ERR-280-01 a ERR-280-07) sont specifies avec les memes codes HTTP et codes metier dans spec §6, tests §4-7, plan §6, et contracts C3/C4.
2.8 — Perimetre et exclusions Les 8 elements hors perimetre (BullMQ, worker, creation de preuve, finalisation, invariants constitutionnels, versionnement API, clients legacy, down migration production) sont listes de maniere coherente dans spec §2, tests §9, plan §10.
2.9 — Epic parent aligne PD-217 — LEGAL & COMPLIANCE est reference dans les 4 documents (correction DIV-05 appliquee en v3).
2.10 — verificationRequestId comme identifiant technique UUID v4 genere cote serveur, present sur toute reponse 200, stable en rappel idempotent DONE. - Spec §3 + §5.1 | Tests TC-NOM-09 | Plan C1 interfaces | Contracts proof-verification-domain CA-11
3. Divergences¶
Les conflits ne sont JAMAIS lisses. Chaque divergence est rendue visible.
DIV-S5-01 — Scenario SCN-280-04 (indeterminate durable) sans test dedie¶
- Source A (Spec §8 SCN-280-04) : Scenario explicite — "Given blockchain inaccessible, When verification echoue sans perspective de resolution courte, Then resultat maillon = INDETERMINATE".
- Source B (Tests §3) : La numerotation saute de TC-NOM-03 a TC-NOM-05. Aucun TC-NOM-04 n'existe. La matrice de couverture §2 ne reference pas de test dedie pour le cas "determination immediate INDETERMINATE par inaccessibilite blockchain" (distinct de la reclassification SLA lazy couverte par TC-NOM-05).
- Source C (Plan §5) : Le mapping TC-* -> mecanismes ne contient pas de ligne pour SCN-280-04.
- Impact : Chemin metier non couvert par les tests. La distinction entre "INDETERMINATE par inaccessibilite immediate" et "INDETERMINATE par expiration SLA" represente deux chemins de code differents dans le service (evaluation directe vs reclassification lazy). L'absence de test dedie laisse un trou de couverture sur CA-03 (partiellement — le cas PENDING est couvert, pas le cas INDETERMINATE direct).
DIV-S5-02 — Strategie DDL resolue par le plan sans engagement de la spec¶
- Source A (Spec §5.4) : Presente deux options — "Colonne check_result : soit varchar (inchangee), soit enum PostgreSQL 3 valeurs -> enum PostgreSQL 4 valeurs (ajout PENDING)".
- Source B (Plan §1 C5) : Tranche pour
ALTER TYPE ... ADD VALUE 'PENDING'(extension enum PostgreSQL). La decision est presentee comme definitive sans qualifier explicitement l'alternative varchar ecartee. - Source C (Code contracts
proof-verification-migration) : Invariant "Enum PostgreSQL check_result contient 4 valeurs apres migration" — presuppose l'option enum. - Impact : Si l'enum PostgreSQL n'est pas le mecanisme reel en base (varchar), la migration est incorrecte. La spec ouvrait la porte aux deux options ; le plan a tranche sans marquer explicitement cette decision architecturale. L'hypothese HT-03 du plan ("le champ chain_blockchain a deja default: 'PENDING' en DB") suggere que PENDING pourrait deja exister comme string meme sans enum — renforce la necessite de verifier le type reel avant implementation.
DIV-S5-03 — Stockage du verificationRequestId non specifie¶
- Source A (Spec §3, §5.1) : Definit
verificationRequestIdcomme "UUID v4 technique, porte par la reponse, identifiant la verification materialisee cote serveur". Implique une materialisation persistante. - Source B (Plan HT-05) : Hypothese non resolue — "genere par le serveur via crypto.randomUUID() et stocke en association avec le proofId (table de cache ou colonne additionnelle)". Aucun schema de persistance defini.
- Source C (Plan §1 C5 migration) : Mentionne "ajout eventuel de colonnes" — le "eventuel" contredit l'obligation de materialiser le
verificationRequestIdpour l'idempotence (INV-280-06 : "retourne la reponse DONE existante a l'identique, y compris verificationRequestId"). - Source D (Code contracts
proof-verification-migration) : Aucune mention deverificationRequestIddans les invariants ou les fichiers du module migration. - Impact : L'idempotence INV-280-06 exige que le meme
verificationRequestIdsoit retourne sur rappel. Sans mecanisme de stockage defini, l'implementeur doit improviser. SiverificationRequestIdest regenere a chaque appel, INV-280-06 est viole. C'est un manque structurant dans le plan.
DIV-S5-04 — Validation runtime de pendingReason hors enum non couverte par l'intercepteur¶
- Source A (Spec §5.1) :
pendingReason— "Rejet 500 (si present hors contrat ou valeur hors enum)". - Source B (Code contracts
proof-verification-guards) : Les invariants de l'intercepteur couvrent INV-280-02 (DONE + null), INV-280-03 (DONE + pending*), ERR-280-03, ERR-280-07 (PENDING en linkResults). Aucun invariant ne mentionne la validation quependingReasonest dans l'enum autorisee. - Source C (Plan §1 C4) : L'intercepteur verifie "INV-280-02, INV-280-03, valeur PENDING interdite en API" — pas de mention de validation de la valeur de
pendingReason. - Impact : Si un processus interne produit un
pendingReasonhors enum (ex: une nouvelle raison ajoutee en DB sans mise a jour du code), l'intercepteur ne le detecterait pas selon les contracts actuels. Le DTO TypeScript assure une protection a la compilation, mais pas au runtime si la valeur vient de la base de donnees.
4. Zones d'ombre¶
ZO-S5-01 — Disponibilite du timestamp pending_since par maillon (HT-06)¶
Le plan HT-06 pose comme hypothese que "les timestamps pending_since par maillon sont disponibles ou derivables depuis les donnees existantes". Si faux, une colonne pending_since doit etre ajoutee a la migration. La migration C5 ne mentionne pas cette colonne. Le mecanisme SLA lazy (TC-NOM-05, ERR-280-05) depend directement de ce timestamp. Aucun document ne confirme l'existence de cette donnee.
ZO-S5-02 — Entite LegalCompositeProof comme point d'entree (HT-01)¶
Le plan presuppose que LegalCompositeProof (schema vault_secure) expose un champ proofId UUID v4 utilisable comme cle d'entree. La spec ne mentionne pas cette entite par nom. Si l'entite n'existe pas ou utilise un identifiant different, le controller et le service doivent etre repenses.
ZO-S5-03 — Comportement hors bornes de pendingResolutionTtl non tranche¶
Spec §8 SCN-280-09 dit "rejet/normalisation hors bornes selon mecanisme de config". Tests TC-NEG-09 dit "Rejet de configuration ou normalisation selon mecanisme contractuel de config". Plan C1 et code contracts ne specifient pas si c'est un rejet (erreur au demarrage) ou une normalisation (clamp silencieux). Le mecanisme n'est pas decide.
ZO-S5-04 — Application de PENDING dans PD-251 non gardee¶
Plan §9.4 affirme que "PD-251 ne doit jamais produire PENDING dans ses resultats finaux". Code contracts et tests ne contiennent aucun mecanisme ou test verifiant cette contrainte. TC-NR-01 verifie que la suite PD-251 existante reste verte, mais ne verifie pas que PD-251 ne produit pas PENDING.
ZO-S5-05 — Schema anchor_batches et detection PENDING_FINALITY (HT-04)¶
Le plan presuppose que la table anchor_batches (schema vault_blockchain) contient un champ status avec la valeur PENDING_FINALITY. C'est une hypothese non verifiee. Si le champ ou la valeur n'existent pas, le mecanisme de detection du maillon blockchain en attente (CA-03, TC-NOM-03) ne peut pas etre implemente.
ZO-S5-06 — Down migration avec donnees PENDING actives¶
Reconnu comme non tranche par spec §10.2, plan §10, et code contracts (forbidden "sans plan explicite"). Aucune decision n'est attendue dans ce perimetre, mais le risque est documente. Pas bloquant pour Gate 5.
ZO-S5-07 — Tests documentaires et formels non automatisables dans le perimetre¶
TC-NR-03 (verification textuelle RFC), TC-NEG-11 (absence de worker), TC-NOM-07 et TC-ERR-06 (pipeline TLA+) dependent de CI ou de verification manuelle. Le plan les classe comme "Documentaire" ou "CI/Formel" mais ne specifie pas comment ils sont integres dans la suite de tests automatisee de l'etape 7 (acceptabilite). Le risque est un oubli en phase d'acceptabilite.
5. Recommandation¶
- Proceder — convergence confirmee, aucun conflit bloquant
- Rework necessaire — divergences a resoudre avant de continuer
- Escalade — decision humaine requise sur un point structurant
Justification : L'alignement global entre les 4 documents est solide (modele, invariants, CAs, perimetre). Cependant, 3 divergences necessitent correction avant soumission a la Gate 5 :
- DIV-S5-01 (bloquant) : Ajouter un test TC-NOM-04 couvrant SCN-280-04 (INDETERMINATE durable par inaccessibilite blockchain) dans le document de tests.
- DIV-S5-03 (bloquant) : Specifier le mecanisme de stockage du
verificationRequestIddans le plan (colonne, table, ou derivation deterministe) — requis pour satisfaire INV-280-06. - DIV-S5-02 (mineur) : Qualifier explicitement dans le plan la decision "enum PostgreSQL" vs "varchar" comme decision architecturale documentee.
- DIV-S5-04 (mineur) : Ajouter un invariant de validation
pendingReasondans les contracts du moduleproof-verification-guardsou documenter que la protection TypeScript est suffisante.