PD-278 - Scenarios de tests contractuels
1. References
- Specification :
PD-278-specification.md - Epic :
EPIC-XX - Version cible : correction finale v3
2. Matrice de couverture
| ID Invariant / Critere | ID Test | Couverture | Commentaire |
| INV-278-01-state-set / CA-01 | TC-INV-01 | Oui | Verifie les 4 statuts exacts exposes. |
| INV-278-02-sealed-to-dip-guard / CA-02 | TC-NOM-01, TC-ERR-03, TC-ERR-04, TC-ERR-05, TC-ERR-07, TC-ERR-13, TC-ERR-14, TC-INV-02 | Oui | Gardes exhaustives incluant retention_due=false. |
| INV-278-03-dip-to-sealed-explicit / CA-03 | TC-NOM-03, TC-NOM-04, TC-ERR-12, TC-INV-03 | Oui | Retour explicite uniquement + roles autorises F2. |
| INV-278-04-auditability / CA-06 | TC-NOM-01, TC-NOM-03, TC-NOM-05, TC-ERR-10, TC-ERR-03, TC-ERR-04, TC-ERR-05, TC-ERR-13, TC-ERR-14, TC-INV-04 | Oui | Audit transitions + refus securite. |
| INV-278-05-attestation / CA-07 | TC-NOM-01, TC-NOM-02, TC-INV-05, TC-ERR-09 | Oui | 1 attestation par requete mono/multi. |
| INV-278-06-worm-preserved / CA-09 | TC-NR-01, TC-INV-06, TC-NOM-06 | Oui | Immutabilite contenu + motif. |
| INV-278-07-rls-preserved | TC-ERR-05, TC-NR-02, TC-INV-07 | Oui | RLS inchangee sur chemins DIP. |
| INV-278-08-terminal-state | TC-INV-08, TC-ERR-06 | Oui | EXPIRED terminal strict. |
| INV-278-09-transition-matrix | TC-INV-09, TC-ERR-06, TC-NEG-04 | Oui | Toute transition hors matrice rejetee. |
| INV-278-10-envelope-encryption / CA-15 | TC-INV-10, TC-NEG-05 | Oui | Chiffrement repos + absence secret en clair. |
| INV-278-11-package-atomicity / CA-13 | TC-NOM-02, TC-ERR-11, TC-INV-11 | Oui | Aucun effet partiel. |
| INV-278-12-concurrency-control / CA-14 | TC-INV-12, TC-NEG-06 | Oui | Conflits concurrents renvoient 409 sans etat partiel. |
| INV-278-13-temporal-order / CA-05 | TC-NOM-03, TC-NEG-07, TC-INV-13 | Oui | returned_at >= disseminated_at garanti meme en clock skew. |
| INV-278-14-retention-non-bypass | TC-INV-13, TC-ERR-14 | Oui | Blocage entree SEALED->DIP + cloture explicite retention. |
| CA-04 | TC-NOM-01, TC-NEG-02 | Oui | disseminated_at + disseminated_by serveurs conformes format. |
| CA-08 | TC-ERR-08A, TC-ERR-08B | Oui | Bornes 1..100 contractuelles. |
| CA-10 | TC-FML-01 | Oui | TLC sans violation DocStates ⊆ RealStates. |
| CA-11 | TC-FML-02 | Oui | Invariants contractuels valides. |
| CA-12 | TC-NOM-06, TC-NEG-03 | Oui | Cycle de vie motif_communication valide. |
3. Scenarios de test - Flux nominaux
TEST-ID: TC-NOM-01
Reference spec: INV-278-02, INV-278-04, INV-278-05, CA-02, CA-04, CA-06, CA-07
GIVEN
- Document status=SEALED
- copies=MIN_COPIES
- retention_due=false
- Acteur authentifie role=PA
- RLS accordee
WHEN
- Demande SEALED -> DIP
THEN
- status devient DIP
- disseminated_at present (RFC3339 UTC ms)
- disseminated_by present (UUID valide)
- dissemination_package_id=NULL (mono-document)
AND
- Une attestation unique est creee et liee document+acteur(+motif si fourni)
- Audit DOCUMENT_DISSEMINATED persiste en transaction
TEST-ID: TC-NOM-02
Reference spec: INV-278-05, INV-278-11, CA-07, CA-08, CA-13
GIVEN
- N_MAX=100
- Acteur autorise, RLS accordee, tous documents en SEALED, retention_due=false
- Requete package taille documents[]=1 puis documents[]=100
WHEN
- Communication DIP package demandee
THEN
- Les deux requetes sont acceptees
- Tous les documents concernes passent en DIP
AND
- Cas multi: dissemination_package_id non NULL (UUID v4 serveur)
- 1 seule attestation par requete, reliee a l'ensemble des documents
TEST-ID: TC-NOM-03
Reference spec: INV-278-03, INV-278-04, INV-278-13, CA-03, CA-05, CA-06
GIVEN
- Document status=DIP avec disseminated_at present
- Acteur authentifie role=SA
WHEN
- Action explicite DIP -> SEALED
THEN
- status devient SEALED
- dissemination_returned_at present (RFC3339 UTC ms)
- dissemination_returned_at >= disseminated_at
AND
- Audit DOCUMENT_RETURNED persiste avec metadonnees de correlation
TEST-ID: TC-NOM-04
Reference spec: INV-278-03, CA-03, §5.5
GIVEN
- Document en DIP
- Aucune action utilisateur/API de retour
WHEN
- Duree observation > SLA max contractuel
THEN
- status reste DIP
AND
- Aucun DOCUMENT_RETURNED sans commande explicite
TEST-ID: TC-NOM-05
Reference spec: §5.5 SLA latence, INV-278-04
GIVEN
- Fenetre de mesure stable
- Echantillon statistique de transitions valides
WHEN
- Executer SEALED -> DIP et DIP -> SEALED
THEN
- P95 <= seuil cible configure pour chaque transition
AND
- Tout depassement de cible est marque performance_flag=SLOW_OPERATION
- Timeout hard (>max) provoque echec atomique
TEST-ID: TC-NOM-06
Reference spec: §5.1 motif_communication, CA-12, INV-278-06
GIVEN
- Requete SEALED -> DIP avec motif_communication valide (<=1024)
WHEN
- Transition executee
THEN
- motif_communication est persiste
AND
- motif_communication est present dans attestation et audit associe
- Tentative UPDATE ulterieure du motif est rejetee (immutabilite)
TEST-ID: TC-NOM-07
Reference spec: §5.1 dissemination_package_id (serveur)
GIVEN
- Cas A: requete mono-document
- Cas B: requete multi-documents
WHEN
- SEALED -> DIP execute
THEN
- Cas A: dissemination_package_id=NULL
- Cas B: dissemination_package_id non NULL genere serveur
AND
- Correlation audit coherent dans les deux cas
4. Scenarios de test - Cas d'erreur
TEST-ID: TC-ERR-01
Reference spec: E-400-ID-FORMAT
GIVEN
- Requete avec document_id invalide (non UUID)
WHEN
- Requete DIP soumise
THEN
- Rejet HTTP 400
- Aucun changement de status
- Aucune attestation creee
TEST-ID: TC-ERR-02
Reference spec: E-400-READONLY-FIELD
GIVEN
- Requete contenant un champ serveur interdit (ex: dissemination_package_id)
WHEN
- Demande SEALED -> DIP soumise
THEN
- Rejet 400
- Aucun document ne passe en DIP
- Aucun audit de succes, aucune attestation
TEST-ID: TC-ERR-03
Reference spec: E-401-AUTH, INV-278-02, INV-278-04
GIVEN
- Acteur non authentifie
- Document SEALED avec copies suffisantes et retention_due=false
WHEN
- Demande SEALED -> DIP
THEN
- Rejet 401
- Status inchange (SEALED)
AND
- Audit securite DOCUMENT_DISSEMINATION_DENIED persiste
TEST-ID: TC-ERR-04
Reference spec: E-403-ROLE, INV-278-02, INV-278-04
GIVEN
- Acteur authentifie role non autorise pour SEALED -> DIP
- Document SEALED, copies suffisantes, RLS accordee, retention_due=false
WHEN
- Demande SEALED -> DIP
THEN
- Rejet 403
- Status inchange
AND
- Audit securite DOCUMENT_DISSEMINATION_DENIED persiste
TEST-ID: TC-ERR-05
Reference spec: E-403-RLS, INV-278-07, INV-278-04
GIVEN
- Acteur authentifie role autorise
- RLS refuse acces document cible
WHEN
- Demande communication DIP
THEN
- Rejet 403
- Status inchange
AND
- Audit securite DOCUMENT_DISSEMINATION_DENIED persiste
TEST-ID: TC-ERR-06
Reference spec: E-409-STATE, INV-278-08, INV-278-09
GIVEN
- Transition interdite demandee (ex: PENDING -> DIP, PENDING -> EXPIRED, DIP -> EXPIRED, EXPIRED -> SEALED)
WHEN
- Requete soumise
THEN
- Rejet 409
- Motif explicite de transition interdite
- Aucun etat partiel
TEST-ID: TC-ERR-07
Reference spec: E-422-GUARD-COPIES, INV-278-02
GIVEN
- Document SEALED avec copies=MIN_COPIES-1
- Acteur autorise, RLS accordee, retention_due=false
WHEN
- Demande SEALED -> DIP
THEN
- Rejet 422
- Status reste SEALED
- Aucune attestation, aucun audit de succes
TEST-ID: TC-ERR-08A
Reference spec: E-422-PACKAGE-SIZE, CA-08
GIVEN
- Requete package avec documents[] vide
WHEN
- Soumission demande DIP
THEN
- Rejet 422
- Aucun traitement partiel
TEST-ID: TC-ERR-08B
Reference spec: E-422-PACKAGE-SIZE, CA-08
GIVEN
- Requete package avec documents[] taille 101
WHEN
- Soumission demande DIP
THEN
- Rejet 422
- Aucun document ne passe en DIP
TEST-ID: TC-ERR-09
Reference spec: E-500-ATTESTATION, INV-278-05
GIVEN
- Conditions SEALED -> DIP valides
- Defaillance injectee sur generation attestation
WHEN
- Transition demandee
THEN
- Echec 500
- Status final reste SEALED
- Aucun artefact incoherent persistant
TEST-ID: TC-ERR-10
Reference spec: E-500-AUDIT, INV-278-04, §5.8
GIVEN
- Conditions transition valides
- Defaillance injectee sur persistance audit/outbox synchrone
WHEN
- Transition DIP demandee
THEN
- Echec atomique 500
- Status inchange
- Aucune perte silencieuse d'evenement
TEST-ID: TC-ERR-11
Reference spec: INV-278-11, CA-13
GIVEN
- Requete package multi-documents
- Au moins un document ne satisfait pas une garde (etat/copies/RLS/retention_due)
WHEN
- Demande SEALED -> DIP
THEN
- Rejet global
- Aucun document du package ne passe en DIP
- Aucune attestation de succes, aucun audit de succes
TEST-ID: TC-ERR-12
Reference spec: E-403-ROLE, INV-278-03
GIVEN
- Document status=DIP
- Acteur authentifie role non autorise pour DIP -> SEALED
WHEN
- Demande retour DIP -> SEALED
THEN
- Rejet 403
- Status reste DIP
- Aucun DOCUMENT_RETURNED de succes
TEST-ID: TC-ERR-13
Reference spec: E-429-RATE-LIMIT, INV-278-02, INV-278-04
GIVEN
- Acteur autorise depassant quota/debit de SEALED -> DIP
WHEN
- Nouvelle demande de communication DIP
THEN
- Rejet 429
- Aucun changement de status
AND
- Audit securite DOCUMENT_DISSEMINATION_DENIED persiste
TEST-ID: TC-ERR-14
Reference spec: E-409-RETENTION-DUE, INV-278-02, INV-278-14
GIVEN
- Document status=SEALED
- retention_due=true
- Acteur autorise, copies suffisantes, RLS accordee
WHEN
- Demande SEALED -> DIP
THEN
- Rejet 409 avec code E-409-RETENTION-DUE
- Status reste SEALED
AND
- Audit securite DOCUMENT_DISSEMINATION_DENIED persiste avec motif retention_due
5. Tests d'invariants (non negociables) - scenarios explicites Given/When/Then
TEST-ID: TC-INV-01
Invariant: INV-278-01-state-set
GIVEN
- Contrat API des statuts et enum persistee en base
WHEN
- Lecture des valeurs exposees
THEN
- Ensemble exact = {PENDING, SEALED, DIP, EXPIRED}
- Aucune valeur manquante ou additionnelle
TEST-ID: TC-INV-02
Invariant: INV-278-02-sealed-to-dip-guard
GIVEN
- Batterie de cas couvrant copies, retention_due, auth, role, RLS, rate-limit
WHEN
- Tentatives SEALED -> DIP executees
THEN
- Acceptation uniquement quand toutes gardes sont satisfaites
- Rejet sinon avec code erreur specifique
TEST-ID: TC-INV-03
Invariant: INV-278-03-dip-to-sealed-explicit
GIVEN
- Document en DIP
WHEN
- Observation sans commande explicite puis avec commande role autorise
THEN
- Aucun retour automatique
- Retour possible uniquement sur action explicite autorisee
TEST-ID: TC-INV-04
Invariant: INV-278-04-auditability
GIVEN
- Cas de transitions reussies et cas refuses (401/403/429/409-retention_due)
WHEN
- Execution des cas
THEN
- Chaque transition reussie cree audit transactionnel complet
- Chaque refus cree audit securite avec motif/code
TEST-ID: TC-INV-05
Invariant: INV-278-05-attestation
GIVEN
- Requetes SEALED -> DIP mono et multi-documents
WHEN
- Execution des transitions
THEN
- Exactement 1 attestation par requete
- Attestation reliee au bon ensemble de document_ids et a l'acteur
TEST-ID: TC-INV-06
Invariant: INV-278-06-worm-preserved
GIVEN
- Document en DIP
WHEN
- Tentative mutation contenu archive et motif_communication
THEN
- Mutation refusee
- Integrite WORM preservee
TEST-ID: TC-INV-07
Invariant: INV-278-07-rls-preserved
GIVEN
- Acteur sans droit RLS sur document DIP
WHEN
- Tentative lecture/export/transition
THEN
- Refus maintenu selon politique RLS existante
TEST-ID: TC-INV-08
Invariant: INV-278-08-terminal-state
GIVEN
- Document status=EXPIRED
WHEN
- Tentative de transition sortante
THEN
- Rejet systematique 409
- Aucun changement d'etat
TEST-ID: TC-INV-09
Invariant: INV-278-09-transition-matrix
GIVEN
- Ensemble des transitions possibles sur 4 etats
WHEN
- Fuzz de transitions non autorisees
THEN
- Toute transition hors matrice est rejetee avec motif explicite
TEST-ID: TC-INV-10
Invariant: INV-278-10-envelope-encryption
GIVEN
- Artefacts temporaires crypto produits par flux DIP
WHEN
- Verification stockage et scans base
THEN
- Chiffrement au repos actif
- Aucun secret en clair detecte
TEST-ID: TC-INV-11
Invariant: INV-278-11-package-atomicity
GIVEN
- Package multi-documents avec un element invalide
WHEN
- Tentative SEALED -> DIP
THEN
- Rejet global
- Aucun effet partiel statut/attestation/audit de succes
TEST-ID: TC-INV-12
Invariant: INV-278-12-concurrency-control
GIVEN
- Deux requetes concurrentes sur meme document cible
WHEN
- Lancement simultane
THEN
- Une seule requete reussit
- L'autre recoit E-409-CONFLICT
TEST-ID: TC-INV-13
Invariant: INV-278-13 et INV-278-14 (ordre temporel + retention)
GIVEN
- Cas A: document DIP puis retour explicite
- Cas B: document DIP avec retention_due=true puis action retention_service
WHEN
- Execution des retours
THEN
- Cas A: dissemination_returned_at >= disseminated_at
- Cas B: DIP -> SEALED explicite audite, puis retention existante applicable
6. Tests de non-regression
| Test ID | Objet | Observable | Commentaire |
| TC-NR-01 | WORM avant/apres DIP | Mutation contenu rejetee en SEALED et DIP | Pas de regression immutabilite. |
| TC-NR-02 | RLS avant/apres DIP | Meme acteur non autorise reste refuse | Pas de regression securite d'acces. |
| TC-NR-03 | Flux PENDING -> SEALED | Comportement historique inchange | Story n'altere pas ce flux. |
| TC-NR-04 | Transition SEALED -> EXPIRED | Comportement existant preserve | Contrat historique maintenu. |
| TC-NR-05 | Compatibilite consommateurs enum | Tous composants acceptent DIP | Requis migration §5.7. |
| TC-NR-06 | Migration descendante | Rollback interdit si DIP actif | Verifie garde de down migration. |
7. Tests negatifs et adversariaux
| Test ID | Entree invalide / abus | Resultat attendu | Observable |
| TC-NEG-01 | UUID uppercase/mixte mais valide | Accepte puis normalise lowercase | Persistance normalisee. |
| TC-NEG-02 | Client fournit timestamp metier | Rejet 400 E-400-READONLY-FIELD | Timestamps strictement serveur. |
| TC-NEG-03 | motif_communication longueur 1025 | Rejet 422 | Aucun effet secondaire. |
| TC-NEG-04 | Fuzz transitions interdites | Rejet 409 avec motif | Couverture exhaustive matrice. |
| TC-NEG-05 | Tentative lecture secret crypto en clair | Aucune donnee sensible en clair | Preuve chiffrement repos. |
| TC-NEG-06 | Rejeu apres echec atomique | Pas d'etat partiel ni duplication invalide | Coherence transactionnelle. |
| TC-NEG-07 | Injection de clock skew inter-noeuds via test harness | Pas de violation ordre temporel grace max(now, disseminated_at) | returned_at >= disseminated_at toujours vrai. |
8. Observabilite requise pour les tests
- Etat systeme :
status, disseminated_at, disseminated_by, dissemination_returned_at, dissemination_package_id, motif_communication, retention_due. - Reponse API : code HTTP, payload erreur normalise, code erreur contractuel.
- Journal audit transition :
DOCUMENT_DISSEMINATED / DOCUMENT_RETURNED avec document_id, actor_id, timestamp, package_id, motif_communication, performance_flag. - Journal audit refus securite :
DOCUMENT_DISSEMINATION_DENIED avec actor_id (si connu), document_id (si resolu), reason_code, http_status, timestamp. - Attestation :
attestation_id, request_id, document_ids, actor_id, issued_at, motif_communication, hash_evidence, signature_ref. - Observabilite perf : metriques latence +
performance_flag=SLOW_OPERATION. - Observabilite securite :
- preuve chiffrement au repos des artefacts temporaires crypto,
- preuve absence secret en clair en base,
- trace de configuration crypto active.
- Observabilite concurrence : traces lock/version conflict pour valider
E-409-CONFLICT.
9. Regles non testables
Aucune reserve bloquante restante sur ce perimetre. Les points Q-01..Q-05 sont tranches dans la specification corrigee.
10. Verdict QA
- ✅ Testable completement (sans reserve bloquante)
Motif : les deux bloquants (CONTR-01, INC-02) sont couverts explicitement, les 13 TC-INV disposent de scenarios Given/When/Then, et les ecarts majeurs de coherence/ambiguite/hypothese sont contractualises de maniere deterministe.