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
DIPdans 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, avecN_MAX=100pour PD-278). - Ajout et gestion des champs :
disseminated_atdisseminated_bydissemination_returned_atdissemination_package_idmotif_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+ (
DIPdans 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 parPENDINGcote code).AIP: Archival Information Package (represente parSEALED).DIP: Dissemination Information Package (nouvel etat explicite).ELIMINATED: etat OAIS de fin de conservation (represente parEXPIRED).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)¶
PENDINGPENDING -> 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 -> EXPIREDreste interdite.- Si un document en
DIPatteint l'echeance retention (retention_due=true) : - commande explicite
DIP -> SEALEDparretention_service(auditee), - puis retention existante peut appliquer
SEALED -> EXPIRED. - Tant que
retention_due=true, toute tentativeSEALED -> DIPest refusee409 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-01Given un documentSEALED,copies=MIN_COPIES,retention_due=false, acteurPAWhen demandeSEALED -> DIPThen statutDIP, attestation creee, auditDOCUMENT_DISSEMINATED, metadonnees conformes. -
ST-02Given un documentSEALED,copies=MIN_COPIES-1When demandeSEALED -> DIPThen rejet422, statut inchange. -
ST-03Given un documentDIPWhen aucune action explicite pendant duree > SLA max Then statut resteDIP. -
ST-04Given un documentDIPet acteur autorise When retour expliciteDIP -> SEALEDThen statutSEALED,dissemination_returned_atrenseigne, auditDOCUMENT_RETURNED. -
ST-05Givendocuments=[]When demande package DIP Then rejet422. -
ST-06Givendocumentstaille101When demande package DIP Then rejet422. -
ST-07Given package multi-documents dont 1 document non conforme When demande package DIP Then rejet global sans transition partielle. -
ST-08Given acteur non autorise pourDIP -> SEALEDWhen demande retour Then rejet403. -
ST-09Given deux transitions concurrentes sur meme document When execution simultanee Then une seule reussit, l'autre recoit409. -
ST-10Given document DIP avecretention_due=trueWhen commande expliciteretention_serviceThenDIP -> SEALEDauditee puis retention existante applicable. -
ST-11Given documentSEALEDavecretention_due=trueWhen demandeSEALED -> DIPThen rejet409 E-409-RETENTION-DUEet 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.tlaProbatioVault-doc/docs/normes/nf-z42-013/formal/NF_Z42_013.alsProbatioVault-doc/docs/normes/AUDIT-SYNTHESIS.md