Aller au contenu

PD-278 — Specification Review

Auditeur : Claude (agent factuel) Date : 2026-03-01 Documents analysés : PD-278-specification.md, PD-278-tests.md Domaine : legal-compliance (NF Z42-013 / OAIS lifecycle)


Synthèse

17 écarts identifiés : 3 Bloquants, 8 Majeurs, 6 Mineurs


Écarts détaillés

ECR-01 — Contradiction : code HTTP pour event_type invalide (400 vs 422)

Type        : Contradiction
Référence   : Spec §5.1 (table formats) vs §6 (E-400-ID-FORMAT) vs Tests TC-ERR-02
Description : §5.1 prescrit un rejet `422` pour un `event_type` hors enum contractuelle.
              §6 regroupe les identifiants invalides (UUID/timestamp/enum) sous `E-400-ID-FORMAT`
              avec code `400`. TC-ERR-02 tranche pour `422`. Trois sources, deux codes HTTP
              différents pour le même cas.
Impact      : Une équipe tierce ne sait pas quel code implémenter. Le test TC-ERR-02 valide
              un comportement qui contredit §6.
Gravité     : Majeur

ECR-02 — Ambiguïté : rôles autorisés pour la transition DIP → SEALED

Type        : Ambiguïté
Référence   : Spec INV-278-02 vs §5.4, Tests TC-NOM-03
Description : INV-278-02 liste explicitement les rôles autorisés pour SEALED → DIP :
              `{PA, SA, auditor}`. Pour DIP → SEALED, §5.4 mentionne uniquement
              « acteur autorisé » sans lister les rôles. TC-NOM-03 présuppose
              « acteur authentifié avec rôle autorisé » sans spécifier lequel.
Impact      : Impossible de vérifier contractuellement si un rôle donné est autorisé
              ou non pour le retour DIP → SEALED. Aucun test négatif ne couvre un
              rôle non autorisé pour cette transition.
Gravité     : Bloquant

ECR-03 — Contradiction : audit synchrone vs asynchrone

Type        : Contradiction
Référence   : Spec §5.8 vs §6 (E-500-AUDIT) vs INV-278-04
Description : §5.8 définit l'écriture audit comme « synchrone si même transaction,
              sinon async post-commit idempotent » avec « aucune perte d'événement tolérée ».
              §6 (E-500-AUDIT) conditionne l'échec de transition à « si audit synchrone
              obligatoire » (le mot « si » introduit un doute). INV-278-04 exige un événement
              audit à chaque transition sans trancher sync/async.
              Le contrat ne permet pas de déterminer si une panne d'audit DOIT bloquer
              la transition ou peut être rattrapée en asynchrone.
Impact      : Deux implémentations contradictoires sont conformes à la spec.
              Le comportement en cas de panne audit est non déterministe.
Gravité     : Majeur

ECR-04 — Hypothèse dangereuse : absence de gestion de la concurrence

Type        : Hypothèse dangereuse
Référence   : Spec §5.3, §5.4, §5.8 (atomicité)
Description : Aucune mention de verrouillage ou de contrôle de concurrence pour les
              transitions d'état. Scénarios non couverts :
              - Deux acteurs demandent SEALED → DIP simultanément sur le même document.
              - Un acteur demande SEALED → DIP tandis qu'un autre demande SEALED → EXPIRED.
              - Package multi-documents : un document est en cours de transition par un autre
                acteur pendant l'assemblage du package.
              §5.8 mentionne l'atomicité ACID par transaction mais pas le contrôle d'accès
              concurrent inter-requêtes.
Impact      : Risque de double attestation, état incohérent, ou race condition sur
              la machine à états.
Gravité     : Majeur

ECR-05 — Incohérence Spec↔Tests : motif_communication non testé en flux nominal

Type        : Incohérence Spec↔Tests
Référence   : Spec §5.1 (motif_communication) vs Tests (aucun TC nominal)
Description : Le champ `motif_communication` est défini dans le modèle de données
              contractuel (§5.1, 0..1024 chars UTF-8) mais :
              - Aucun flux nominal (§5.3, §5.4) ne le mentionne dans les effets testables.
              - Aucun test nominal ne vérifie son stockage, sa persistance ou sa restitution.
              - Seul TC-NEG-03 teste le rejet pour longueur > 1024.
              - Aucune mention dans les champs d'audit (INV-278-04) ni dans l'attestation.
Impact      : Le champ est spécifié mais son cycle de vie (stockage, lecture, présence
              en audit/attestation) n'est pas contractualisé. Non implémentable de
              manière déterministe.
Gravité     : Majeur

ECR-06 — Hypothèse dangereuse : contournement de la politique de rétention via DIP

Type        : Risque sécu/conformité
Référence   : Spec §5.2 (DIP → EXPIRED INTERDITE) + INV-278-03 (pas de timeout auto)
Description : Un document en DIP ne peut ni expirer directement (DIP → EXPIRED interdit)
              ni revenir automatiquement en SEALED (INV-278-03). Si un document reste
              indéfiniment en DIP, la politique de rétention (SEALED → EXPIRED) ne peut
              jamais s'appliquer. Aucun mécanisme de forçage n'est spécifié.
Impact      : Un acteur autorisé pourrait maintenir des documents en DIP pour contourner
              la rétention légale. Risque RGPD (droit à l'effacement) et conformité
              NF Z42-013 (durée de conservation).
Gravité     : Bloquant

ECR-07 — Ambiguïté : cardinalité attestation pour package multi-documents

Type        : Ambiguïté
Référence   : Spec INV-278-05, §5.3, Tests TC-INV-05
Description : INV-278-05 exige « une attestation unique reliée au(x) document(s) source(s)
              et à l'acteur ». Pour un package de N documents :
              - 1 attestation par package (reliée à N documents) ?
              - Ou N attestations (1 par document) ?
              Le terme « unique » peut signifier « une seule » ou « à identifiant unique ».
              TC-INV-05 ne clarifie pas (« attestation unique, liée source(s)+acteur »).
Impact      : Deux implémentations contradictoires satisfont la spec.
Gravité     : Majeur

ECR-08 — Ambiguïté : dissemination_package_id pour transition mono-document

Type        : Ambiguïté
Référence   : Spec §5.3 vs INV-278-04, Tests TC-NOM-01
Description : §5.3 dit « dissemination_package_id renseigné si package multi-documents ».
              INV-278-04 (audit) inclut « package_id (si présent) ». Mais aucune règle
              ne définit le comportement pour un mono-document :
              - Le champ est-il NULL ?
              - Un package_id est-il généré même pour un seul document ?
              TC-NOM-01 (mono-document) n'inclut pas de vérification de l'absence ou
              présence de package_id.
Impact      : Ambiguïté d'implémentation sur le champ nullable et sur la corrélation audit.
Gravité     : Mineur

ECR-09 — Ambiguïté : statut PENDING → EXPIRED — interdit ou inchangé ?

Type        : Ambiguïté
Référence   : Spec §5.2 (transitions PENDING)
Description : §5.2 dit « PENDING → EXPIRED : INTERDITE dans cette story (inchangé
              existant non modifié) ». Deux lectures possibles :
              1. La transition existe actuellement et n'est pas modifiée par PD-278.
              2. La transition est interdite.
              Le mot « INTERDITE » contredit « inchangé existant ». Si elle est
              actuellement autorisée, elle ne peut pas être à la fois INTERDITE et inchangée.
Impact      : Ambiguïté sur la matrice complète de transitions. INV-278-09 exige que
              « toute transition non listée comme autorisée est explicitement interdite »,
              mais le statut réel de PENDING → EXPIRED est ambigu.
Gravité     : Mineur

ECR-10 — Incohérence Spec↔Tests : atomicité package — échec partiel non spécifié

Type        : Incohérence Spec↔Tests
Référence   : Spec §5.1 (cardinalité), §5.3 (flux F1), Tests TC-NOM-02
Description : Pour un package multi-documents, §5.1 rejette en bloc si cardinalité
              hors bornes. Mais aucune règle ne couvre le cas où un document individuel
              du package échoue (ex: un document sur N n'a pas assez de copies, ou un
              document n'est pas SEALED). TC-NOM-02 suppose « tous documents en SEALED »
              mais ne teste pas le cas mixte.
              Aucun test ne vérifie : « si 1 document sur N échoue la garde, le package
              entier est rejeté (pas de traitement partiel) ».
Impact      : Risque d'état partiel en multi-documents. Le comportement atomique
              n'est contractualisé qu'au niveau cardinalité, pas au niveau des gardes
              individuelles.
Gravité     : Bloquant

ECR-11 — Incohérence Spec↔Tests : TC-ERR-02 teste un champ non exposé

Type        : Incohérence Spec↔Tests
Référence   : Spec §5.1 (event_type), Tests TC-ERR-02
Description : TC-ERR-02 teste une valeur `event_type` hors enum soumise « à validation
              contractuelle ». Or `event_type` est un champ d'audit interne
              (`DOCUMENT_DISSEMINATED`, `DOCUMENT_RETURNED`) produit par le système,
              pas un champ d'entrée utilisateur. La spec ne définit aucun endpoint
              permettant à un utilisateur de soumettre un `event_type`.
Impact      : Le test couvre un scénario qui ne peut pas se produire via l'API.
              Test hors périmètre ou spec incomplète sur un endpoint d'audit.
Gravité     : Mineur

ECR-12 — Hypothèse dangereuse : dépendance à l'horloge sans spécification

Type        : Hypothèse dangereuse
Référence   : Spec §5.1 (timestamps RFC3339 UTC), §5.5 (SLA latence)
Description : Les champs `disseminated_at` et `dissemination_returned_at` sont des
              timestamps UTC à la milliseconde. Le SLA mesure des latences en millisecondes.
              Aucune mention de :
              - Source d'horloge (horloge système, NTP, horloge monotone).
              - Tolérance au skew d'horloge entre composants.
              - Garantie d'ordre temporel (disseminated_at < dissemination_returned_at).
Impact      : En environnement distribué, un skew d'horloge peut produire des
              timestamps incohérents (retour avant communication). Aucun invariant
              ne protège l'ordre temporel.
Gravité     : Mineur

ECR-13 — Risque sécu/conformité : absence de rate limiting sur transitions DIP

Type        : Risque sécu/conformité
Référence   : Spec §5.3 (flux F1), INV-278-02
Description : Un acteur avec rôle PA/SA/auditor peut déclencher SEALED → DIP sur un
              nombre illimité de documents sans aucune limitation de débit spécifiée.
              Aucune mention de quota, rate limiting, ou alerte en cas de communication
              massive.
Impact      : Risque d'exfiltration massive par un acteur légitime compromis.
              Absent de la matrice de risques et des tests.
Gravité     : Mineur

ECR-14 — Ambiguïté : « résolution manuelle uniquement » pour état EXPIRED

Type        : Ambiguïté
Référence   : Spec INV-278-08, §5.2 (EXPIRED terminal)
Description : INV-278-08 et §5.2 déclarent EXPIRED terminal avec « résolution manuelle
              uniquement ». Ce mécanisme de résolution manuelle n'est défini nulle part :
              - Quel acteur est autorisé ?
              - Via quel canal (admin, DBA, procédure documentée) ?
              - Quelles transitions manuelles sont possibles ?
              TC-INV-08 vérifie que toute sortie est interdite, ce qui contredit
              l'existence même d'une « résolution manuelle ».
Impact      : Contradiction entre « terminal strict » (tests) et « résolution manuelle »
              (spec). Impossible de savoir si EXPIRED est réellement terminal ou non.
Gravité     : Majeur

ECR-15 — Incohérence Spec↔Tests : absence de test négatif rôle pour DIP → SEALED

Type        : Incohérence Spec↔Tests
Référence   : Tests (aucun TC-ERR pour rôle non autorisé sur DIP→SEALED)
Description : TC-ERR-04 teste le rejet 403 pour un rôle non autorisé sur SEALED → DIP.
              Aucun test équivalent n'existe pour DIP → SEALED. Couplé à ECR-02
              (rôles non définis pour DIP → SEALED), la vérification du contrôle d'accès
              sur le retour est entièrement absente.
Impact      : La transition DIP → SEALED n'est couverte en test que pour le cas nominal.
              Le contrôle d'accès du retour n'est ni spécifié ni testé.
Gravité     : Majeur

ECR-16 — Non testable : INV-278-10 couverture partielle assumée

Type        : Non testable
Référence   : Spec INV-278-10, Tests TC-INV-10 (matrice couverture « Partielle »)
Description : La matrice de couverture (§2 des tests) indique explicitement une
              couverture « Partielle » pour INV-278-10 (envelope encryption), dépendante
              de « l'accès observabilité sécurité ». Aucun prérequis d'observabilité
              n'est contractualisé pour garantir que ce test puisse être exécuté.
Impact      : Un invariant non négociable pourrait ne jamais être validé si
              l'observabilité sécurité n'est pas disponible.
Gravité     : Majeur

ECR-17 — Ambiguïté : SLOW_OPERATION non défini

Type        : Ambiguïté
Référence   : Spec §5.5 (SLA temporels), Tests TC-NOM-05
Description : §5.5 mentionne qu'un dépassement de SLA produit une opération marquée
              `SLOW_OPERATION` et « auditée ». TC-NOM-05 vérifie ce comportement.
              Mais `SLOW_OPERATION` n'est défini nulle part :
              - Ce n'est pas un `event_type` dans l'enum contractuelle (§5.1).
              - Pas de structure d'événement définie.
              - Pas de destination (même journal d'audit ? métriques ? logs ?).
Impact      : Non implémentable de manière déterministe. Le test TC-NOM-05 n'a pas
              d'observable précis pour vérifier le marquage.
Gravité     : Mineur

Tableau récapitulatif

ID Type Référence Gravité
ECR-01 Contradiction §5.1 vs §6 vs TC-ERR-02 — code HTTP event_type Majeur
ECR-02 Ambiguïté INV-278-02 vs §5.4 — rôles DIP→SEALED Bloquant
ECR-03 Contradiction §5.8 vs §6 — audit sync/async Majeur
ECR-04 Hypothèse dangereuse §5.3, §5.8 — concurrence Majeur
ECR-05 Incohérence Spec↔Tests §5.1 vs tests — motif_communication Majeur
ECR-06 Risque sécu/conformité §5.2 + INV-278-03 — rétention via DIP Bloquant
ECR-07 Ambiguïté INV-278-05 — attestation par package Majeur
ECR-08 Ambiguïté §5.3 vs INV-278-04 — package_id mono-doc Mineur
ECR-09 Ambiguïté §5.2 — PENDING→EXPIRED interdit ou inchangé Mineur
ECR-10 Incohérence Spec↔Tests §5.1, §5.3, TC-NOM-02 — atomicité package Bloquant
ECR-11 Incohérence Spec↔Tests TC-ERR-02 — event_type non exposé Mineur
ECR-12 Hypothèse dangereuse §5.1, §5.5 — horloge Mineur
ECR-13 Risque sécu/conformité §5.3, INV-278-02 — rate limiting Mineur
ECR-14 Ambiguïté INV-278-08, §5.2 — résolution manuelle EXPIRED Majeur
ECR-15 Incohérence Spec↔Tests Tests — pas de test rôle pour DIP→SEALED Majeur
ECR-16 Non testable INV-278-10 — observabilité non garantie Majeur
ECR-17 Ambiguïté §5.5 — SLOW_OPERATION non défini Mineur

Points à clarifier existants (Q-01 à Q-05)

Les 5 questions en suspens du §10.2 de la spécification sont confirmées comme légitimes. Q-01 (N_MAX) est effectivement bloquant et impacte CA-08, TC-ERR-08B, TC-ERR-08C. Les écarts ci-dessus s'ajoutent à ces questions et ne les remplacent pas.