Aller au contenu

PD-284 — Rapport de confrontation (Gate 8 — Closure)

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

1. Sources confrontées

Document Étape
Spécification PD-284 (v3) Étape 1
Tests contractuels PD-284 (v3) Étape 2
Plan d'implémentation PD-284 Étape 4
Acceptabilité PD-284 (Étape 7) Étape 7
Agent seal-types (C1) Étape 6b
Agent seal-state-machine (C2) Étape 6b
Agent seal-sse-client (C3) Étape 6b
Agent seal-event-processor (C4) Étape 6b
Agent seal-store (C5) Étape 6b
Agent seal-api (C6) Étape 6b
Agent seal-orchestrator (C7) Étape 6b
Agent seal-secure-storage (C12) Étape 6b

2. Convergences

2.1 Machine d'états monotone

  • Spec §5.7, Plan §3, C2 (state-machine), C4 (event-processor), C5 (store) s'accordent sur :
  • 7 états exactement : RECEIVED, QUEUED_PRIORITY, TSA_PENDING, TSA_SEALED, ANCHOR_PENDING, SEALED, FAILED_TIMEOUT.
  • Modèle strictement monotone (aucune transition retour).
  • SEALED et FAILED_TIMEOUT sont terminaux (tableau de transitions vide).
  • FAILED_TIMEOUT accessible depuis tout état non terminal.

2.2 Branded types et sécurité de type

  • Plan §3 INV mapping, C1 (seal-types), C6 (api-client), C12 (secure-storage) convergent sur l'utilisation de branded types SealId et DocumentId pour empêcher les inversions UUID à la compilation.

2.3 Séquence POST → GET → SSE

  • Spec §5.1, Plan §2.1, C7 (orchestrator), C6 (api-client), Tests TC-NOM-04 s'accordent sur la séquence stricte et non contournable.

2.4 Backoff exponentiel et failover

  • Spec §5.2, Plan §2.2, C3 (sse-client), Tests TC-NOM-08/09 convergent sur : backoff 1s/2s/4s, failover polling 5s, tentative SSE parallèle à chaque cycle polling, plafond cumulé 30s.

2.5 Déduplication et réordonnancement

  • Spec §5.2, Plan §2.3, C4 (event-processor), Tests TC-NOM-16/17 convergent sur : cache FIFO ring buffer N=100, fenêtre de grâce 200ms, resync GET sur gap persistant.

2.6 Artefacts sensibles vs publics

  • Spec §5.11, Plan §7, C12 (secure-storage), C5 (store), Tests TC-INV-09/11 convergent sur : tsa_token_ref en SecureStore uniquement, hash_document/merkle_root/blockchain_tx_hash en mémoire Zustand. Purge proactive au démarrage (learning PD-283/PD-262).

2.7 INV-284-05 : pas de calcul local de dégradation

  • Spec INV-284-05, Plan §3, C5 (store), Tests TC-NOM-10 convergent : le store consomme degradation_flag brut du serveur, aucun timer ni seuil local. Flag inconnu traité comme none + telemetry silencieuse.

2.8 Badge Hors ligne vs échec SSE

  • Spec INV-284-09, Plan §3, C3 (sse-client), C9 (progress-card via hook NetInfo), Tests TC-NOM-08/14 convergent : badge uniquement en perte réseau réelle, pas sur échec SSE.
  • Spec §5.5, Plan §4, C11 (notifications), C15 (navigation), Tests TC-NOM-06/07 convergent sur les notifications succès/échec avec deep-link vers détail.

2.10 Validation Zod systématique

  • Plan §¾, C6 (api-client), C4 (event-processor) convergent : toute donnée entrante (réponse API, événement SSE) passe par safeParse Zod avant application. Aucun chemin de succès sans validation.

3. Divergences

DIV-01 : Contradiction coverage UrgentSealButton vs review QA

  • Acceptabilité Phase 1 (coverage) : « UrgentSealButton.tsx : 100% (via RNTL) »
  • Acceptabilité Phase 2b (review QA, T-01) : « MAJEUR — Aucun test composant UrgentSealButton (C8) — TC-NOM-01/02/03/15 non couverts »
  • Impact : Contradiction factuelle. Si C8 a 100% de coverage via RNTL, les tests existent et les TC correspondants sont vraisemblablement couverts. Le reviewer QA (claude -p) n'a probablement pas eu C8 dans son contexte d'audit (même artefact d'injection que E-01/E-02 en code review). La réserve T-01 MAJEUR pourrait être un faux positif d'audit. Alternativement, la coverage 100% pourrait provenir d'un rendu indirect (enfant d'un autre composant testé) sans vérification des TC contractuels.
  • Conclusion : Ambiguïté non résolue. Le verdict d'acceptabilité liste 4 réserves MAJEUR dont potentiellement 1 à 2 sont des artefacts d'injection. Le dossier gate doit statuer sur la fiabilité des findings T-01 à T-05.

DIV-02 : merkle_proof[] non stocké dans le store — mécanisme d'accès absent

  • Spec §5.4 : « merkle_proof[] : dès ANCHOR_PENDING » (affichage expert).
  • Spec §5.12 : merkle_proof[] est un champ obligatoire pour ANCHOR_PENDING et SEALED.
  • C5 (store), H-STORE-03 : « merkle_proof[] (array) is NOT stored in flat state. Components needing it (C10 ExpertPanel) will receive it via a separate mechanism (event cache or prop drilling from orchestrator). »
  • Impact : Le mécanisme alternatif n'est documenté dans aucun livrable agent. L'ExpertPanel (C10) n'a pas de livrable agent fourni. Comment C10 accède-t-il à merkle_proof[] ? Le plan ne détaille pas ce point. La spec exige que ce champ soit disponible en mode expert dès ANCHOR_PENDING.

DIV-03 : Mapping visuel ANCHOR_PENDING — incohérence plan vs types

  • Plan §2.1b : ANCHOR_PENDING → « Arbre Merkle / Blockchain » → étapes 3-4 actives (indexation 1-based).
  • C1 (seal-types), STATE_TO_VISUAL_STEP : ANCHOR_PENDING: { step: 'Blockchain', index: 3, completed: false }.
  • VISUAL_STEPS (0-based) : ['Capture'(0), 'Horodatage TSA'(1), 'Arbre Merkle'(2), 'Blockchain'(3), 'Scellé'(4)].
  • Impact : En indexation 0-based, ANCHOR_PENDING est mappé à l'index 3 (Blockchain) uniquement. L'étape « Arbre Merkle » (index 2) n'est jamais assignée à aucun état dans STATE_TO_VISUAL_STEP. Elle est invisible dans la carte de progression.

DIV-04 : resync() contourne la table de transitions — exception non documentée dans la spec

  • Spec INV-284-06 : « Toute transition d'état affichée doit correspondre à une transition autorisée PD-80 ; transition inconnue => erreur contrôlée. »
  • C2 (state-machine), resync() : « En resync, on accepte tout état qui est "en avant" dans la progression ou FAILED_TIMEOUT depuis n'importe quel état non terminal. »
  • Impact : La méthode resync() accepte des sauts d'état (ex: RECEIVED → TSA_SEALED directement) qui ne sont pas dans ALLOWED_TRANSITIONS. La spec ne prévoit pas d'exception pour le cas de resynchronisation serveur. Le plan documente cette décision (§2.3 du flux C4) mais la spec ne l'autorise pas explicitement.

DIV-05 : Regex UUID permissive — accepte 36 tirets

  • Spec §5.6 : ^[0-9a-fA-F-]{36}$ pour UUID v4.
  • C6 (api-client), C1 (types) : utilisent la même regex SEAL_VALIDATION_PATTERNS.UUID_V4.
  • Acceptabilité S-01 : MINEUR — « accepte 36 tirets — atténué par validation serveur. »
  • Impact : Mineur. La regex ne valide pas la structure UUID v4 (format 8-4-4-4-12). Un string de 36 tirets passerait la validation. Atténué par la validation serveur en amont.

DIV-06 : Store ne valide pas les transitions — confiance implicite en C4

  • Spec INV-284-06 : « Toute transition d'état affichée doit correspondre à une transition autorisée PD-80. »
  • C5 (store), H-STORE-01 : « The store itself does NOT re-validate transitions — it trusts C4's pre-validation. »
  • Impact : Si C4 contient un bug de validation, une transition invalide pourrait atteindre le store et l'UI. Il n'y a pas de défense en profondeur sur la validation des transitions. Le plan documente ce choix comme une hypothèse architecturale, pas un risque.

DIV-07 : 5 composants sans livrable agent (C8, C9, C10, C11, C14)

  • Plan §1 : 15 composants listés (C1-C15).
  • Livrables agents fournis : C1, C2, C3, C4, C5, C6, C7, C12 (8 sur 15).
  • Composants absents : C8 (UrgentSealButton), C9 (SealProgressCard), C10 (ExpertPanel), C11 (notifications), C13 (telemetry), C14 (SealDetailScreen), C15 (navigation).
  • Acceptabilité : Coverage montre que C8 (100%), C11 (86.8%), C15 (94.1%) existent et sont testés. C9, C10, C14 ont 0% coverage.
  • Impact : L'absence de livrables agents pour C9, C10, C14 empêche de vérifier la conformité de ces composants aux invariants. Les réserves MAJEUR T-01 à T-05 de l'acceptabilité sont possiblement liées à cette incomplétude du contexte d'audit.

4. Zones d'ombre

ZO-01 : Accès merkle_proof[] pour l'ExpertPanel (C10)

Le store ne stocke pas merkle_proof[]. Aucun mécanisme alternatif n'est documenté ni implémenté. L'ExpertPanel (C10) n'a pas de livrable agent. Comment les preuves Merkle sont-elles affichées en mode expert ?

ZO-02 : Politique iOS hors foreground (Q-284-04)

Toujours non résolu. La spec, les tests et le plan le signalent comme point ouvert. Le document tests §9 le classe « Majeur » dans les règles non testables. Impact : le comportement des notifications lorsque l'app est en arrière-plan n'est pas spécifié.

ZO-03 : Quotas max par plan (Q-284-05)

Les valeurs numériques de quota par segment (standard/premium/enterprise) ne sont pas fournies. Le bouton urgent vérifie urgent_quota_remaining > 0 mais les valeurs plafond ne sont pas contractualisées.

ZO-04 : Tests E2E performance sur device (TC-NOM-13)

Le plan et les tests documentent un test proxy CI (re-render count ≤ 2/event) mais le test réel P95 ≤ 100ms nécessite un iPhone 12+ physique. Aucun ticket de suivi n'est créé. Le critère CA-284-14 n'est pas vérifiable en CI.

ZO-05 : Comportement ExpertPanel avec données merkle_proof invalides

TC-ERR-07 couvre les champs expert invalides (hash, merkle_root, tx_hash) mais ne mentionne pas merkle_proof[] invalide (ex: tableau avec éléments non conformes regex). Le schema Zod dans C4 valide les éléments individuels, mais le comportement UI en cas de tableau partiellement invalide n'est pas spécifié.

ZO-06 : Implémentation du heartbeat SSE

La spec §5.9 définit un TTL heartbeat SSE de 30s (H-284-02). Le client SSE (C3) doit détecter l'absence de heartbeat et déclencher une reconnexion. Le livrable C3 mentionne que les lignes de commentaire (:) sont ignorées (heartbeats) mais ne documente pas le mécanisme de timeout heartbeat côté client.

ZO-07 : Purge SecureStore au logout/deleteAccount — intégration non vérifiée

C12 exporte purgeAllSealData() pour appel par le auth store existant (logout, deleteAccount). Le livrable C12 §8 signale les points d'intégration mais aucun livrable agent ne montre les modifications effectives dans useAuthStore.ts. L'intégration est déclarée mais non vérifiable.


5. Recommandation

  • Procéder — convergence confirmée, aucun conflit bloquant
  • Rework nécessaire — divergences à résoudre avant de continuer
  • Escalade — décision humaine requise sur un point structurant

Justification

Les convergences sont solides sur la majorité de l'architecture (machine d'états, séquence POST→GET→SSE, sécurité stockage, déduplication, backoff). Cependant :

  1. DIV-01 (contradiction coverage/review QA) nécessite une clarification factuelle pour déterminer si les 4 réserves MAJEUR sont réelles ou des artefacts d'injection. Ce point impacte directement le scoring gate 8.
  2. DIV-02 (merkle_proof[] inaccessible au store) est un gap fonctionnel : le mode expert ne peut pas afficher les preuves Merkle sans mécanisme documenté.
  3. DIV-03 (étape visuelle « Arbre Merkle » jamais assignée) est un écart d'implémentation vis-à-vis du plan.

Les autres divergences (DIV-04 à DIV-07) sont de criticité moindre (décisions architecturales documentées, regex permissive atténuée, composants fonctionnels mais non audités).