Aller au contenu

PD-278 - NF Z42-013 : ajout contractuel de l'etat DIP (Dissemination Information Package)

1. Objectif

Specifier de maniere contractuelle l'extension du cycle de vie documentaire pour integrer l'etat OAIS DIP, supprimer l'ecart formel DocStates ⊆ RealStates, permettre la communication probatoire (mono et multi-documents), et preserver tracabilite, securite et conformite NF Z42-013:2020.

Objectifs mesurables : - Introduire l'etat DIP dans le modele metier des statuts documentaires. - Encadrer strictement les transitions SEALED -> DIP et DIP -> SEALED. - Garantir attestation + journalisation a chaque transition DIP. - Auditer aussi les tentatives refusees liees a l'authentification, autorisation, RLS, rate-limit et blocage retention. - Maintenir invariants WORM, RLS et conformite formelle (TLA+/tests contractuels). - Eliminer les ambiguities contractuelles (roles, atomicite package, audit, retention, observabilite).

2. Perimetre / Hors perimetre

Inclus

  • Ajout de DIP dans les statuts documentaires metiers.
  • Transition SEALED -> DIP (communication AIP).
  • Transition DIP -> SEALED (retour explicite, sans timeout implicite silencieux).
  • Support DIP package multi-documents (cardinalite 1..N_MAX, avec N_MAX=100 pour PD-278).
  • Ajout et gestion des champs :
  • disseminated_at
  • disseminated_by
  • dissemination_returned_at
  • dissemination_package_id
  • motif_communication (optionnel, persiste et tracable)
  • Generation d'attestation de restitution a chaque passage en DIP.
  • Journalisation audit des transitions DIP et des refus securite associes.
  • Controle de concurrence et atomicite de traitement package.
  • Protection anti-contournement retention via etat DIP.
  • Alignement formel avec TLA+ (DIP dans le mapping reel).

Exclu

  • Refactoring des autres etats existants (PENDING, SEALED, EXPIRED) hors ajustements strictement necessaires au nouvel etat.
  • Bordereau de destruction (GAP-NF-008).
  • Changement de mecanisme de diffusion externe deja existant.
  • Normalisation de format de package (SEDA/METS) : hors perimetre.
  • Interpretation juridique de la norme au-dela des regles testables : hors perimetre.

3. Definitions

  • SIP : Submission Information Package (represente par PENDING cote code).
  • AIP : Archival Information Package (represente par SEALED).
  • DIP : Dissemination Information Package (nouvel etat explicite).
  • ELIMINATED : etat OAIS de fin de conservation (represente par EXPIRED).
  • Attestation de restitution : preuve horodatee de communication d'un AIP vers DIP.
  • Package DIP : regroupement de 1 a N documents dans une unite de communication.
  • PA/SA/auditor/retention_service : roles/comptes autorises pour les transitions DIP.
  • RLS : Row-Level Security existante applicable sans regression.
  • WORM : propriete d'immutabilite du contenu archive, non levee en DIP.
  • Outbox audit : enregistrement transactionnel synchrone garantissant la non-perte avant publication asynchrone.
  • retention_due : booleen stocke sur le document, calcule par le module retention selon la politique legale active ; non editable par client API.
  • copies : nombre de copies durables sur domaines de panne distincts (fault domains distincts), fourni par la couche stockage et expose en metadonnees document.

4. Invariants (non negociables)

ID Regle Justification
INV-278-01-state-set Le set des statuts implemente inclut exactement PENDING, SEALED, DIP, EXPIRED. Conformite OAIS/NF et correction FAIL TLA+.
INV-278-02-sealed-to-dip-guard SEALED -> DIP autorisee uniquement si, pour chaque document, copies >= MIN_COPIES, retention_due=false, acteur authentifie, role ∈ {PA, SA, auditor}, RLS valide, limites de debit/quota respectees. Conformite securite + anti-exfiltration + anti-contournement retention.
INV-278-03-dip-to-sealed-explicit DIP -> SEALED est uniquement une action explicite initiee par acteur authentifie role ∈ {PA, SA, auditor, retention_service} ; aucun timeout implicite ne change l'etat sans commande explicite. Eviter ambiguite probatoire + permettre cloture de conformite retention.
INV-278-04-auditability Chaque transition DIP reussie persiste en transaction un enregistrement audit/outbox ; et chaque tentative refusee pour 401/403/429/409-retention_due persiste un evenement audit securite (sans changer l'etat). NF Z42-013 §10.1 tracabilite et evenements de securite.
INV-278-05-attestation Chaque SEALED -> DIP genere exactement une attestation par requete de communication (mono=1 doc, multi=1 attestation reliee a N docs), reliee au(x) document(s) source(s) et a l'acteur. NF Z42-013 §4.6.4.2 + cardinalite deterministe.
INV-278-06-worm-preserved Le contenu documentaire reste WORM en DIP ; seuls statut et metadonnees de diffusion changent. Non-regression probatoire.
INV-278-07-rls-preserved Les controles RLS existants restent applicables aux lectures/exports DIP. Non-regression securite.
INV-278-08-terminal-state EXPIRED est terminal strict au niveau applicatif : EXPIRED -> * interdite sans exception API/metier. Machine a etats explicite, non ambiguie.
INV-278-09-transition-matrix Toute transition non listee comme autorisee est explicitement interdite avec motif. Eliminer ambiguities de gates.
INV-278-10-envelope-encryption Tout artefact cryptographique temporaire lie a la communication DIP est chiffre au repos (AES-256-GCM ou HSM envelope), aucun secret en clair en base. Invariant crypto obligatoire.
INV-278-11-package-atomicity Pour un package multi-documents, toute garde est evaluee pour chaque document ; si un seul document echoue, rejet global sans effet partiel (statut, attestation, audit de succes). Integrite transactionnelle multi-documents.
INV-278-12-concurrency-control Les transitions DIP sont protegees par controle de concurrence (verrouillage row-level ou optimistic locking par version) pour eviter doubles transitions concurrentes. Eviter races et incoherences d'etat.
INV-278-13-temporal-order dissemination_returned_at >= disseminated_at pour un meme document ; timestamps serveur UTC RFC3339 ms ; en retour, returned_at = max(now_utc, disseminated_at). Coherence temporelle robuste au clock skew.
INV-278-14-retention-non-bypass La retention legale ne peut pas etre contournee via maintien indefini en DIP : quand un document DIP est retention_due, une commande explicite DIP -> SEALED par retention_service est obligatoire et auditee, puis la retention existante s'applique. Conformite NF/RGPD.

5. Flux nominaux

5.1 Modele de donnees contractuel (formats et contraintes)

Definition unique des formats :

Donnee Format/encodage Taille Validation Source Comportement si invalide
document_id UUID RFC 4122 36 regex UUID canonique Client API Rejet 400
actor_id (disseminated_by) UUID RFC 4122 36 UUID valide Serveur (auth) N/A en entree
dissemination_package_id UUID RFC 4122 nullable 36 UUID valide Serveur uniquement Si fourni par client: 400 E-400-READONLY-FIELD
disseminated_at RFC3339 UTC ms - parse stricte ...Z Serveur uniquement Si fourni par client: 400 E-400-READONLY-FIELD
dissemination_returned_at RFC3339 UTC ms - parse stricte ...Z Serveur uniquement Si fourni par client: 400 E-400-READONLY-FIELD
event_type audit enum max 64 DOCUMENT_DISSEMINATED, DOCUMENT_RETURNED, DOCUMENT_DISSEMINATION_DENIED Serveur interne N/A
motif_communication UTF-8 texte 0..1024 chars longueur max Client API (optionnel) Rejet 422 si >1024
retention_due booleen 1 true/false Retention orchestrator Non editable API

Regles dissemination_package_id : - Requete mono-document (documents[].size = 1) : dissemination_package_id = NULL. - Requete multi-documents (documents[].size > 1) : dissemination_package_id genere serveur (UUID v4), non NULL. - Le client ne fournit jamais dissemination_package_id.

Regles motif_communication : - Champ optionnel en entree. - Si present et valide, il est persiste avec la transition SEALED -> DIP. - Il est copie dans la metadonnee d'attestation et dans l'audit associe. - Il reste immuable apres creation (enforcement contractuel : contrainte applicative + trigger DB de refus UPDATE sur ce champ).

Contraintes de cardinalite package : - documents[] : min 1, max N_MAX. - Pour PD-278 : N_MAX = 100. - Hors bornes : rejet 422 (aucun traitement partiel).

5.2 Machine a etats (transitions sortantes explicites, baseline canonique)

  • PENDING
  • PENDING -> SEALED : AUTORISEE.
  • PENDING -> DIP : INTERDITE.
  • PENDING -> EXPIRED : INTERDITE.

  • SEALED

  • SEALED -> DIP : AUTORISEE (gardes INV-278-02).
  • SEALED -> EXPIRED : AUTORISEE (politique retention existante).
  • SEALED -> PENDING : INTERDITE.

  • DIP

  • DIP -> SEALED : AUTORISEE, explicite uniquement, roles {PA, SA, auditor, retention_service}.
  • DIP -> EXPIRED : INTERDITE directe.
  • DIP -> PENDING : INTERDITE.

  • EXPIRED

  • EXPIRED -> * : INTERDITE au niveau applicatif/metier.

5.3 Flux nominal F1 - Communication AIP vers DIP (SEALED -> DIP)

Preconditions testables : - Tous les documents cibles sont en SEALED. - Pour chaque document, copies >= MIN_COPIES. - Pour chaque document, retention_due=false. - Acteur authentifie avec role autorise {PA, SA, auditor}. - Controles RLS satisfaits pour chaque document. - Rate limit et quota journalier non depasses. - Cardinalite package dans bornes (1..100). - Controle concurrence acquis.

Effets testables : - Transition atomique vers DIP pour tous les documents de la requete. - disseminated_at renseigne (serveur UTC RFC3339 ms). - disseminated_by renseigne (UUID acteur auth). - dissemination_package_id : - NULL en mono-document. - non NULL (UUID v4 serveur) en multi-documents. - motif_communication persiste si fourni. - Une attestation unique par requete est creee et liee aux documents + acteur + motif (si present). - Audit DOCUMENT_DISSEMINATED persiste en transaction.

5.4 Flux nominal F2 - Retour DIP vers SEALED (DIP -> SEALED)

Preconditions testables : - Document en DIP. - Action explicite d'un acteur authentifie role autorise {PA, SA, auditor, retention_service}. - Aucun timeout implicite de transition. - Controle concurrence acquis.

Effets testables : - Statut devient SEALED. - dissemination_returned_at renseigne (serveur UTC RFC3339 ms). - dissemination_returned_at = max(now_utc, disseminated_at) pour garantir ordre. - Audit DOCUMENT_RETURNED persiste en transaction. - Aucune alteration WORM du contenu.

5.5 SLA temporels (transitions d'etat)

  • Aucune transition d'etat automatique silencieuse.
  • Mesure de latence via horloge monotone.
  • Seuil SLOW_OPERATION = seuil cible P95 configure par transition :
  • SLA_TARGET_SEALED_TO_DIP_MS (defaut 2000)
  • SLA_TARGET_DIP_TO_SEALED_MS (defaut 1500)
Transition Cible defaut (P95) Min Max hard timeout Comportement hors bornes
SEALED -> DIP 2000 ms 200 ms 5000 ms si P95 > cible -> performance_flag=SLOW_OPERATION; si > max hard -> echec atomique
DIP -> SEALED 1500 ms 200 ms 5000 ms idem

5.6 Bornes numeriques obligatoires

Parametre Defaut Min Max Unite Comportement hors bornes
MIN_COPIES 2 2 10 copies Rejet 422
Taille package DIP (documents[]) 100 1 100 elements Rejet 422
motif_communication longueur 0 0 1024 caracteres UTF-8 Rejet 422
Rate limit SEALED -> DIP par acteur 60 1 1000 req/min Rejet 429 + audit securite
Quota journalier SEALED -> DIP par acteur 1000 1 100000 req/jour UTC (reset 00:00:00Z) Rejet 429 + audit securite

5.7 DDL / migration

Element Contrat
Type actuel et type cible status enum existant (PENDING,SEALED,EXPIRED) -> enum etendu avec DIP
Nouvelles colonnes disseminated_at, disseminated_by, dissemination_returned_at, dissemination_package_id, motif_communication, retention_due
Backfill Aucune conversion historique requise ; nouvelles colonnes nullable sauf retention_due default false
Enforcement WORM metadonnees Trigger DB bloque update de motif_communication apres insertion
Down migration Retrait de DIP uniquement si aucun enregistrement actif en DIP
Index recommande status, dissemination_package_id, retention_due, (actor_id, created_at) audit

5.8 Atomicite multi-composant

Scope Synchrone/Async Garantie
Mise a jour statut + colonnes DIP Synchrone (transaction DB) Atomicite ACID
Persistance audit/outbox de transition Synchrone meme transaction Aucune transition reussie sans trace persistante
Persistance audit refus securite Synchrone (transaction legere dediee) Aucune tentative refusée sans trace
Publication audit externe Async post-commit idempotent Retry-safe
Crash pre-commit - Rollback total
Crash post-commit - Etat DB valide + outbox present

5.9 Concurrence et isolation

Regles contractuelles : - Verrou exclusif logique sur chaque document_id cible (row lock ou version check). - En package, verrouillage ordonne deterministe global : tri lexicographique croissant de document_id. - Regle cross-module obligatoire : tout module qui verrouille ces documents (retention_service, export, audit enrichi) applique le meme ordre. - Conflit concurrent -> 409 E-409-CONFLICT, sans effet partiel. - Deux transitions concurrentes sur meme document ne peuvent pas toutes reussir.

5.10 Horloge et ordre temporel

  • Source temps murale : UTC synchronisee NTP (derive max configurable, defaut 100 ms).
  • Mesure SLA : horloge monotone.
  • Timestamps metier generes cote serveur.
  • Ordre temporel garanti applicativement : returned_at = max(now_utc, disseminated_at).
  • Si impossibilite technique de respecter l'ordre (defaillance interne), rejet 409 E-409-TEMPORAL-ORDER.

5.11 Contraintes inter-modules

Element Contrat
Modules impactes Audit, authz, export, retention orchestrator
Donnees cross-module document_id, identite acteur, roles, contexte acces, retention_due, retention_deadline_at
Source retention_due Retention orchestrator (evaluation policy + date echeance)
Frequence mise a jour retention_due Evementielle + reconciliation periodique max 5 min
Ordre de verrouillage Meme ordre global que §5.9 pour tous les modules
Exceptions d'acces Aucune exception additionnelle

5.12 Retention et anti-contournement DIP

  • DIP -> EXPIRED reste interdite.
  • Si un document en DIP atteint l'echeance retention (retention_due=true) :
  • commande explicite DIP -> SEALED par retention_service (auditee),
  • puis retention existante peut appliquer SEALED -> EXPIRED.
  • Tant que retention_due=true, toute tentative SEALED -> DIP est refusee 409 E-409-RETENTION-DUE.
  • Cette mecanique n'est pas un timeout implicite ; c'est une action explicite tracee.

5.13 Attestation de restitution (schema contractuel)

Format minimal (JSON persiste) : - attestation_id (UUID) - request_id (UUID de la requete de communication) - document_ids (liste non vide UUID) - actor_id (UUID) - issued_at (RFC3339 UTC ms) - motif_communication (nullable) - hash_evidence (empreinte integrite) - signature_ref (reference cle/KMS/HSM)

Contraintes : - Exactement 1 attestation par requete SEALED -> DIP. - Conservation minimale : 10 ans. - Stockage : base probatoire interne + replication lecture. - Non modifiable apres creation (append-only).

5.14 Contrat API (black-box)

  • POST /api/v1/documents/disseminations
  • Body: documents: UUID[], motif_communication?: string
  • Interdit: dissemination_package_id, disseminated_at, dissemination_returned_at
  • POST /api/v1/documents/{document_id}/dissemination-return
  • Body: {} (aucun timestamp client)
  • Les codes d'erreur suivent §6.

5bis. Diagrammes

5bis.1 Machine a etats — cycle de vie documentaire OAIS/NF Z42-013

stateDiagram-v2
    [*] --> PENDING : Soumission SIP

    PENDING --> SEALED : Archivage (AIP)\n[validation integrite]

    SEALED --> DIP : Communication (F1)\n[copies >= MIN_COPIES\nretention_due=false\nrole ∈ {PA,SA,auditor}\nRLS OK, rate-limit OK]\n→ attestation + audit
    SEALED --> EXPIRED : Retention echeance\n[politique retention existante]

    DIP --> SEALED : Retour explicite (F2)\n[role ∈ {PA,SA,auditor,retention_service}]\n→ audit DOCUMENT_RETURNED

    EXPIRED --> [*]

    note right of PENDING
        SIP — Submission Information Package
        Transitions interdites :
        PENDING → DIP
        PENDING → EXPIRED
    end note

    note right of DIP
        Dissemination Information Package
        WORM preserve (INV-278-06)
        RLS preserve (INV-278-07)
        Transitions interdites :
        DIP → EXPIRED (directe)
        DIP → PENDING
    end note

    note right of EXPIRED
        Etat terminal strict (INV-278-08)
        EXPIRED → * INTERDIT
        sans exception API/metier
    end note

    note left of SEALED
        AIP — Archival Information Package
        Transition interdite :
        SEALED → PENDING
    end note

Matrice de transitions (INV-278-09 — toute transition non listee est interdite) :

De Vers PENDING SEALED DIP EXPIRED
PENDING OK NON NON
SEALED NON OK (gardes INV-278-02) OK (retention)
DIP NON OK (explicite, INV-278-03) NON
EXPIRED NON NON NON

5bis.2 Flux F1 — Communication AIP vers DIP (SEALED -> DIP)

sequenceDiagram
    participant Client
    participant API as API Gateway
    participant AuthZ as AuthZ / RLS
    participant Retention as Retention Orchestrator
    participant Storage as Storage Layer
    participant DocSvc as Document Service
    participant Attestation as Attestation Service
    participant Audit as Audit Outbox
    participant DB as PostgreSQL

    Client->>API: POST /api/v1/documents/disseminations<br/>{documents: UUID[], motif_communication?}
    API->>API: Validation format (UUID, cardinalite 1..100,<br/>champs readonly absents, motif <= 1024)
    alt Validation echouee
        API-->>Client: 400 / 422
    end

    API->>AuthZ: Verification authentification + role ∈ {PA,SA,auditor}
    alt 401 / 403
        AuthZ-->>API: Refus
        API->>Audit: Audit DOCUMENT_DISSEMINATION_DENIED (sync)
        API-->>Client: 401 E-401-AUTH / 403 E-403-ROLE / 403 E-403-RLS
    end

    API->>API: Verification rate-limit + quota journalier
    alt 429
        API->>Audit: Audit DOCUMENT_DISSEMINATION_DENIED (sync)
        API-->>Client: 429 E-429-RATE-LIMIT
    end

    API->>DB: Acquisition verrous (tri lexicographique document_id)<br/>(INV-278-12)
    alt Conflit concurrence
        DB-->>API: Lock conflict
        API-->>Client: 409 E-409-CONFLICT
    end

    loop Pour chaque document
        API->>DocSvc: Verification etat == SEALED
        API->>Storage: Verification copies >= MIN_COPIES
        API->>Retention: Verification retention_due == false
    end
    alt Un document echoue une garde
        Note over API,DB: Rejet global atomique (INV-278-11)
        API-->>Client: 409 / 422 (selon garde)
    end

    rect rgb(230, 245, 230)
        Note over DocSvc,DB: Transaction ACID atomique
        DocSvc->>DB: UPDATE status = DIP,<br/>disseminated_at, disseminated_by,<br/>dissemination_package_id, motif_communication
        Attestation->>DB: INSERT attestation restitution<br/>(1 par requete, liee N docs + acteur + motif)
        Audit->>DB: INSERT audit DOCUMENT_DISSEMINATED<br/>(outbox transactionnel synchrone)
        DB-->>DocSvc: COMMIT
    end

    DocSvc-->>API: Succes
    API-->>Client: 200 {attestation_id, documents[]}

    Note over Audit: Publication async post-commit<br/>(idempotent, retry-safe)

5bis.3 Flux F2 — Retour DIP vers SEALED (DIP -> SEALED)

sequenceDiagram
    participant Client
    participant API as API Gateway
    participant AuthZ as AuthZ / RLS
    participant DocSvc as Document Service
    participant Audit as Audit Outbox
    participant DB as PostgreSQL

    Client->>API: POST /api/v1/documents/{id}/dissemination-return<br/>{}
    API->>AuthZ: Verification authentification + role ∈ {PA,SA,auditor,retention_service}
    alt 401 / 403
        AuthZ-->>API: Refus
        API->>Audit: Audit DOCUMENT_DISSEMINATION_DENIED (sync)
        API-->>Client: 401 / 403
    end

    API->>DB: Acquisition verrou sur document_id (INV-278-12)
    alt Conflit concurrence
        DB-->>API: Lock conflict
        API-->>Client: 409 E-409-CONFLICT
    end

    API->>DocSvc: Verification etat == DIP
    alt Etat != DIP
        DocSvc-->>API: Etat incompatible
        API-->>Client: 409 E-409-STATE
    end

    DocSvc->>DocSvc: Calcul returned_at = max(now_utc, disseminated_at)<br/>(INV-278-13)
    alt Ordre temporel impossible
        DocSvc-->>API: Erreur interne
        API-->>Client: 409 E-409-TEMPORAL-ORDER
    end

    rect rgb(230, 245, 230)
        Note over DocSvc,DB: Transaction ACID atomique
        DocSvc->>DB: UPDATE status = SEALED,<br/>dissemination_returned_at
        Audit->>DB: INSERT audit DOCUMENT_RETURNED<br/>(outbox transactionnel synchrone)
        DB-->>DocSvc: COMMIT
    end

    DocSvc-->>API: Succes
    API-->>Client: 200

    Note over Audit: Publication async post-commit

5bis.4 Flux retention anti-contournement DIP (INV-278-14)

sequenceDiagram
    participant RetSvc as Retention Orchestrator
    participant DocSvc as Document Service
    participant Audit as Audit Outbox
    participant DB as PostgreSQL

    Note over RetSvc: Reconciliation periodique (<= 5 min)<br/>ou evenementielle

    RetSvc->>DB: Detecte document DIP avec retention_due=true
    RetSvc->>DocSvc: Commande explicite DIP -> SEALED<br/>(role: retention_service)

    rect rgb(230, 245, 230)
        Note over DocSvc,DB: Transaction ACID atomique
        DocSvc->>DB: UPDATE status = SEALED,<br/>dissemination_returned_at
        Audit->>DB: INSERT audit DOCUMENT_RETURNED<br/>(acteur: retention_service)
        DB-->>DocSvc: COMMIT
    end

    Note over RetSvc: Retention existante peut ensuite<br/>appliquer SEALED -> EXPIRED

    RetSvc->>DocSvc: Transition SEALED -> EXPIRED<br/>(politique retention standard)

6. Cas d'erreur

  • E-400-ID-FORMAT : UUID invalide (document_id) -> 400.
  • E-400-READONLY-FIELD : champ serveur fourni par client (dissemination_package_id, disseminated_at, dissemination_returned_at) -> 400.
  • E-401-AUTH : acteur non authentifie -> 401.
  • E-403-ROLE : role non autorise -> 403.
  • E-403-RLS : refus RLS -> 403.
  • E-409-STATE : transition incompatible avec etat courant -> 409.
  • E-409-CONFLICT : conflit de concurrence -> 409.
  • E-409-TEMPORAL-ORDER : ordre temporel incoherent interne -> 409.
  • E-409-RETENTION-DUE : blocage retention (retention_due=true) -> 409.
  • E-422-GUARD-COPIES : copies < MIN_COPIES -> 422.
  • E-422-PACKAGE-SIZE : cardinalite package hors bornes -> 422.
  • E-422-MOTIF-LENGTH : motif_communication > 1024 -> 422.
  • E-429-RATE-LIMIT : depassement debit/quota -> 429.
  • E-500-ATTESTATION : echec generation attestation -> echec atomique.
  • E-500-AUDIT : echec persistance audit/outbox synchrone -> echec atomique.

7. Criteres d'acceptation (testables)

ID Critere Observable
CA-01 Le modele inclut DIP. Enum/API expose 4 valeurs attendues.
CA-02 SEALED -> DIP reussit uniquement si gardes satisfaites, y compris retention_due=false. Tests positifs/negatifs auth/role/RLS/copies/retention/rate-limit.
CA-03 DIP -> SEALED uniquement par action explicite role autorise. Aucun changement automatique ; rejets role non autorise.
CA-04 Chaque SEALED -> DIP renseigne disseminated_at + disseminated_by. Donnees persistees conformes §5.1.
CA-05 Chaque DIP -> SEALED renseigne dissemination_returned_at avec ordre garanti. returned_at >= disseminated_at.
CA-06 Chaque transition DIP journalise l'evenement attendu et chaque refus securite est audite. Audit transition + audit refus conforme.
CA-07 Attestation creee a chaque passage en DIP avec cardinalite deterministe. 1 attestation/requete, liee docs+acteur(+motif).
CA-08 Package DIP accepte 1..100 et rejette hors borne. Tests limites 0, 1, 100, 101.
CA-09 WORM non regresse en DIP. Tentatives mutation contenu/metadonnees protegees echouent.
CA-10 ASSUME TLA+ DocStates ⊆ RealStates ne viole plus. TLC sans violation.
CA-11 Invariants DIP contractuels passent en tests contractuels. Rapport contractuel vert.
CA-12 motif_communication optionnel est persiste et trace correctement. Cohesif entre DB/audit/attestation.
CA-13 Atomicite package multi-documents totale. Si 1 document echoue, aucun ne passe en DIP.
CA-14 Conflits de concurrence geres deterministement. 409 sans etat partiel.
CA-15 Invariant crypto INV-278-10 testable sans reserve. Preuves observabilite securite exploitables.

8. Scenarios de test (Given / When / Then)

  • ST-01 Given un document SEALED, copies=MIN_COPIES, retention_due=false, acteur PA When demande SEALED -> DIP Then statut DIP, attestation creee, audit DOCUMENT_DISSEMINATED, metadonnees conformes.

  • ST-02 Given un document SEALED, copies=MIN_COPIES-1 When demande SEALED -> DIP Then rejet 422, statut inchange.

  • ST-03 Given un document DIP When aucune action explicite pendant duree > SLA max Then statut reste DIP.

  • ST-04 Given un document DIP et acteur autorise When retour explicite DIP -> SEALED Then statut SEALED, dissemination_returned_at renseigne, audit DOCUMENT_RETURNED.

  • ST-05 Given documents=[] When demande package DIP Then rejet 422.

  • ST-06 Given documents taille 101 When demande package DIP Then rejet 422.

  • ST-07 Given package multi-documents dont 1 document non conforme When demande package DIP Then rejet global sans transition partielle.

  • ST-08 Given acteur non autorise pour DIP -> SEALED When demande retour Then rejet 403.

  • ST-09 Given deux transitions concurrentes sur meme document When execution simultanee Then une seule reussit, l'autre recoit 409.

  • ST-10 Given document DIP avec retention_due=true When commande explicite retention_service Then DIP -> SEALED auditee puis retention existante applicable.

  • ST-11 Given document SEALED avec retention_due=true When demande SEALED -> DIP Then rejet 409 E-409-RETENTION-DUE et audit refus securite.

9. Hypotheses explicites

ID Hypothese Impact si faux
H-01 Projet cible ProbatioVault-backend (NestJS + TypeORM + PostgreSQL). Contraintes techniques a reecrire si autre repo.
H-02 Roles IAM PA, SA, auditor, retention_service existent. Sans eux, CA-02/03/14 invalidables.
H-03 Audit supporte outbox transactionnelle + evenements refus securite. Sinon evolution schema audit necessaire.
H-04 MIN_COPIES par defaut = 2. Valeur differente modifie tests limites.
H-05 Horodatages metier sont strictement serveur. Si client autorise timestamps, contrat a reviser.

10. Points clarifies pour cette version

ID Decision contractuelle
Q-01 N_MAX fixe a 100 pour PD-278.
Q-02 Endpoints contractuels definis en §5.14.
Q-03 motif_communication reste optionnel ; validation longueur stricte.
Q-04 Rattrapage publication audit post-commit : objectif <= 15 min (SLO), alerte si depassement.
Q-05 Baseline transitions hors DIP figee en §5.2.

References

  • JIRA : PD-278
  • Repos concernes : ProbatioVault-backend, ProbatioVault-doc
  • Documents associes :
  • ProbatioVault-doc/docs/normes/nf-z42-013/formal/NF_Z42_013.tla
  • ProbatioVault-doc/docs/normes/nf-z42-013/formal/NF_Z42_013.als
  • ProbatioVault-doc/docs/normes/AUDIT-SYNTHESIS.md