Aller au contenu

PD-275 — Scenarios de tests contractuels

1. References

  • Specification : PD-275-specification.md
  • Epic : EPIC-XX

2. Matrice de couverture

ID Invariant ID Critere ID Test Couverture Commentaire
INV-275-01-fail-closed CA-02 TC-NOM-02 Oui Refus explicite de finalisation si preconditions non satisfaites.
INV-275-01-fail-closed CA-05 TC-NOM-06 Oui Refus explicite de soumission signer REVOKED.
INV-275-01-fail-closed CA-05 TC-NOM-07 Oui Refus explicite de soumission signer inconnu.
INV-275-01-fail-closed CA-04 TC-ERR-06 Oui Refus de revocation si audit trail non persistant.
INV-275-02-finality-guard CA-02 TC-NOM-02 Oui Garde bloquante confirmation_count < FINALITY_DEPTH.
INV-275-02-finality-guard CA-02b TC-NOM-03 Oui Chemin nominal autorise a seuil atteint.
INV-275-03-confirmation-persistence CA-01 TC-NOM-01 Oui Persistance et mise a jour du compteur.
INV-275-03-confirmation-persistence CA-01 TC-ERR-01 Oui Rejet des valeurs hors bornes contractuelles.
INV-275-04-signer-status-authority CA-03 TC-NOM-04 Oui Statut derive du registre pour transition de revocation.
INV-275-04-signer-status-authority CA-05 TC-NOM-06 Oui Registre fait foi pour refus signer REVOKED.
INV-275-04-signer-status-authority CA-05 TC-NOM-07 Oui Registre fait foi pour refus signer absent.
INV-275-05-revocation-atomic-audited CA-04 TC-NOM-04 Oui Transition atomique + revokedAt + revokedBy.
INV-275-05-revocation-atomic-audited CA-04 TC-NOM-05 Oui Double revocation refusee sans mutation d'etat.
INV-275-05-revocation-atomic-audited CA-04 TC-ERR-06 Oui Absence de trace audit bloque la transition.
INV-275-06-terminal-state-revoked CA-04 TC-INV-06 Oui Interdiction explicite de toute transition sortante depuis REVOKED.
INV-275-07-state-machine-complete CA-04 TC-INV-07A Oui Couverture des transitions signer autorisees/interdites.
INV-275-07-state-machine-complete CA-02 TC-INV-07B Oui Couverture des transitions batch autorisees/interdites.
INV-275-08-envelope-encryption CA-07 TC-INV-08 Oui Verification d'absence de secrets en clair sur artefacts temporaires eventuels.
INV-275-03-confirmation-persistence CA-08 TC-NOM-09 Oui Reversibilite up/down/up preserve contraintes attendues.
INV-275-02-finality-guard CA-06 TC-NOM-08 Oui Audit Prolog confirme checks 28-32 et score global 32/32.
INV-275-01-fail-closed CA-07 TC-NR-01 Oui Preuve de couverture des 5 nouveaux comportements en test report.
INV-275-09-revoke-authorization CA-04b TC-ERR-08 Oui Refus revokeSigner() sans role ADMIN/SIGNER_ADMIN.
INV-275-10-revokedBy-auth-derived CA-04c TC-ERR-09 Oui revokedBy derive JWT, injection refusee.
INV-275-11-signer-concurrency-serialization CA-05b TC-NOM-10 Oui SELECT FOR UPDATE serialise revoke/submit concurrents.
INV-275-12-single-revocation-audit-event CA-05b TC-NOM-11 Oui Double revoke concurrent : un seul succes.

3. Scenarios de test - Flux nominaux

TEST-ID: TC-NOM-01
Reference spec: INV-275-03-confirmation-persistence, CA-01, Flux F1

GIVEN
  - Une base de test avec un `anchor_batch` existant et `confirmation_count = 0`
  - Le batch est dans un etat non finalise
WHEN
  - Une mise a jour de confirmations valide est appliquee avec `n = 3`
THEN
  - La lecture persistante du batch retourne `confirmation_count = 3`
AND
  - Le type persiste est entier
  - Aucun changement d'etat du batch n'est observe
TEST-ID: TC-NOM-02
Reference spec: INV-275-01-fail-closed, INV-275-02-finality-guard, CA-02, Flux F2

GIVEN
  - `FINALITY_DEPTH = D` (D >= 1)
  - Un batch non finalise avec `confirmation_count = D-1`
WHEN
  - `finalizeBatch()` est invoque
THEN
  - La requete est refusee avec `ERR-FINALITY-INSUFFICIENT`
AND
  - L'etat du batch reste non finalise
  - Aucun marqueur de finalisation n'est persiste
TEST-ID: TC-NOM-03
Reference spec: INV-275-02-finality-guard, CA-02b, Flux F2

GIVEN
  - `FINALITY_DEPTH = D` (D >= 1)
  - Un batch non finalise avec `confirmation_count = D`
WHEN
  - `finalizeBatch()` est invoque
THEN
  - La requete est acceptee
AND
  - Le batch passe a `FINALIZED`
  - La transition inverse `FINALIZED -> *` n'est pas creee implicitement
TEST-ID: TC-NOM-04
Reference spec: INV-275-04-signer-status-authority, INV-275-05-revocation-atomic-audited, CA-03, CA-04, Flux F3

GIVEN
  - Une entree `signer_registry` existante avec `status = ACTIVE`
  - L'appelant est authentifie avec un JWT valide portant le role `ADMIN`
WHEN
  - `revokeSigner(address)` est invoque
THEN
  - Le statut devient `REVOKED`
AND
  - `revokedAt` est non nul et horodate
  - `revokedBy` est non nul et attribue
  - La transition est atomique (pas d'etat intermediaire observable)
TEST-ID: TC-NOM-05
Reference spec: INV-275-05-revocation-atomic-audited, CA-04, Cas d'erreur ERR-SIGNER-ALREADY-REVOKED

GIVEN
  - Une entree `signer_registry` avec `status = REVOKED`
  - `revokedAt` et `revokedBy` deja renseignes
WHEN
  - `revokeSigner(address)` est invoque une seconde fois
THEN
  - La requete est refusee avec `ERR-SIGNER-ALREADY-REVOKED`
AND
  - Les champs `status`, `revokedAt`, `revokedBy` restent inchanges
TEST-ID: TC-NOM-06
Reference spec: INV-275-01-fail-closed, INV-275-04-signer-status-authority, CA-05, Flux F4

GIVEN
  - Une entree `signer_registry` existante avec `status = REVOKED`
  - Une requete `submitBatch()` pour ce signer
WHEN
  - La soumission est evaluee
THEN
  - La requete est refusee avec `ERR-SIGNER-REVOKED`
AND
  - Aucun batch n'est cree
  - Aucun effet de bord de soumission n'est emis
TEST-ID: TC-NOM-07
Reference spec: INV-275-01-fail-closed, INV-275-04-signer-status-authority, CA-05, Flux F4

GIVEN
  - Aucune entree `signer_registry` pour l'adresse fournie
WHEN
  - `submitBatch()` est invoque
THEN
  - La requete est refusee avec `ERR-SIGNER-NOT-FOUND`
AND
  - Aucun batch n'est cree
  - Aucun effet de bord de soumission n'est emis
TEST-ID: TC-NOM-08
Reference spec: CA-06, Cas d'erreur ERR-COMPLIANCE-NOT-MET

GIVEN
  - Le code et les migrations PD-275 sont deployee(s) en environnement de verification
  - Les faits Prolog sont regeneres a partir de l'etat courant
WHEN
  - L'audit PV Anchor est execute
THEN
  - Le rapport affiche `32/32 OK`, `0 KO`, `0 WARN`
AND
  - Les checks 28, 29, 30, 31, 32 sont `OK`
  - Le rapport est archive comme preuve verifiable
TEST-ID: TC-NOM-09
Reference spec: CA-08, Flux F1/F3/F4 (schema), section 10.4

GIVEN
  - Un environnement de test avec donnees representatives
WHEN
  - La migration DDL est executee en sequence `up`, puis `down`, puis `up`
THEN
  - Les objets `anchor_batch.confirmation_count` et `signer_registry` sont presents apres re-`up`
AND
  - Les contraintes contractuelles (types, defauts, enum statuts, unicite attendue) sont restaurees
  - Aucune derive de schema non contractuelle n'est detectee
TEST-ID: TC-NOM-10
Reference spec: INV-275-11-signer-concurrency-serialization, CA-05b

GIVEN
  - Une entree `signer_registry` existante avec `status = ACTIVE`
  - Deux transactions concurrentes : `revokeSigner(address)` et `submitBatch()` pour le meme signer
WHEN
  - Les deux transactions sont executees simultanement
THEN
  - La serialisation via `SELECT ... FOR UPDATE` garantit un ordre deterministe
AND
  - Si `revokeSigner()` acquiert le verrou en premier : `submitBatch()` recoit `ERR-SIGNER-REVOKED`
  - Aucun batch n'est cree pour un signer revoque
  - Un seul evenement d'audit de revocation est emis
TEST-ID: TC-NOM-11
Reference spec: INV-275-12-single-revocation-audit-event, CA-05b

GIVEN
  - Une entree `signer_registry` existante avec `status = ACTIVE`
  - Deux transactions concurrentes : `revokeSigner(address)` emises simultanement
WHEN
  - Les deux transactions sont executees
THEN
  - Un seul appel reussit (transition `ACTIVE -> REVOKED` + audit trail)
AND
  - Le second appel recoit `ERR-SIGNER-ALREADY-REVOKED`
  - Un seul evenement d'audit de revocation est persiste
  - Les champs `revokedAt` et `revokedBy` refletent uniquement la premiere transaction

4. Scenarios de test - Cas d'erreur

TEST-ID: TC-ERR-01
Reference spec: ERR-CONFIRMATION-COUNT-INVALID, INV-275-03-confirmation-persistence

GIVEN
  - Un batch existant
WHEN
  - Une mise a jour de `confirmation_count` est demandee avec valeur hors bornes (`< 0` ou `> 2147483647`)
THEN
  - La mise a jour est rejetee avec `ERR-CONFIRMATION-COUNT-INVALID`
  - La valeur persistante precedente est conservee
TEST-ID: TC-ERR-02
Reference spec: ERR-FINALITY-INSUFFICIENT, INV-275-02-finality-guard

GIVEN
  - `FINALITY_DEPTH = D`
  - `confirmation_count = D-1`
WHEN
  - `finalizeBatch()` est invoque
THEN
  - Refus explicite `ERR-FINALITY-INSUFFICIENT`
  - Aucun passage a `FINALIZED`
TEST-ID: TC-ERR-03
Reference spec: ERR-SIGNER-NOT-FOUND, INV-275-01-fail-closed

GIVEN
  - Adresse signer absente du registre
WHEN
  - `revokeSigner(address)` est invoque
THEN
  - Refus explicite `ERR-SIGNER-NOT-FOUND`
  - Aucun enregistrement de revocation n'est cree
TEST-ID: TC-ERR-04
Reference spec: ERR-SIGNER-NOT-FOUND, INV-275-01-fail-closed

GIVEN
  - Adresse signer absente du registre
WHEN
  - `submitBatch()` est invoque
THEN
  - Refus explicite `ERR-SIGNER-NOT-FOUND`
  - Aucun effet secondaire de soumission
TEST-ID: TC-ERR-05
Reference spec: ERR-SIGNER-REVOKED, INV-275-04-signer-status-authority

GIVEN
  - Signer present avec `status = REVOKED`
WHEN
  - `submitBatch()` est invoque
THEN
  - Refus explicite `ERR-SIGNER-REVOKED`
  - Aucun effet secondaire de soumission
TEST-ID: TC-ERR-06
Reference spec: ERR-AUDIT-TRAIL-MISSING, INV-275-05-revocation-atomic-audited

GIVEN
  - Signer `ACTIVE` existant
  - Le contexte force l'echec de persistance de `revokedAt` ou `revokedBy`
WHEN
  - `revokeSigner(address)` est invoque
THEN
  - L'operation est invalidee avec `ERR-AUDIT-TRAIL-MISSING`
  - Le statut reste `ACTIVE`
  - Aucun etat partiellement revoque n'est persiste
TEST-ID: TC-ERR-07
Reference spec: ERR-COMPLIANCE-NOT-MET, CA-06

GIVEN
  - Un rapport d'audit Prolog dont le score est `< 32/32`
WHEN
  - Le gate de conformite est evalue pour la livraison
THEN
  - Verdict `ERR-COMPLIANCE-NOT-MET`
  - Livraison marquee non conforme
TEST-ID: TC-ERR-08
Reference spec: ERR-REVOKE-UNAUTHORIZED, INV-275-09-revoke-authorization, CA-04b

GIVEN
  - Un signer `ACTIVE` existant dans `signer_registry`
  - L'appelant est authentifie avec un JWT valide portant un role autre que `ADMIN` ou `SIGNER_ADMIN`
WHEN
  - `revokeSigner(address)` est invoque
THEN
  - La requete est refusee avec `ERR-REVOKE-UNAUTHORIZED`
  - Le statut du signer reste `ACTIVE`
  - Aucun evenement d'audit de revocation n'est emis
TEST-ID: TC-ERR-09
Reference spec: ERR-REVOKEDBY-SPOOFING, INV-275-10-revokedBy-auth-derived, CA-04c

GIVEN
  - Un signer `ACTIVE` existant dans `signer_registry`
  - L'appelant est authentifie avec un JWT valide portant le role `ADMIN`
  - Le payload de la requete contient un champ `revokedBy` explicite (tentative d'injection)
WHEN
  - `revokeSigner(address)` est invoque
THEN
  - La requete est refusee avec `ERR-REVOKEDBY-SPOOFING` ou le champ `revokedBy` est ignore
AND
  - Le `revokedBy` persiste est derive du JWT `sub` de l'appelant, jamais du payload
  - Si refus : aucune mutation d'etat ni evenement d'audit

5. Tests d'invariants (non negociables)

Invariant Test(s) dedies Observable Commentaire
INV-275-01-fail-closed TC-NOM-02, TC-NOM-06, TC-NOM-07, TC-ERR-03, TC-ERR-04 Refus explicite + absence d'effets secondaires Le deny-by-default est verifie sur les 3 decisions de securite.
INV-275-02-finality-guard TC-NOM-02, TC-NOM-03, TC-ERR-02 Etat batch avant/apres + code erreur Couvre refus sous seuil et acceptation au seuil.
INV-275-03-confirmation-persistence TC-NOM-01, TC-ERR-01 Valeur persistante, type entier, bornes Couvre defaut, mise a jour, rejection hors bornes.
INV-275-04-signer-status-authority TC-NOM-04, TC-NOM-06, TC-NOM-07, TC-ERR-05 Source de statut = signer_registry Valide autorite unique pour decision de soumission/revocation.
INV-275-05-revocation-atomic-audited TC-NOM-04, TC-NOM-05, TC-ERR-06 status, revokedAt, revokedBy, atomicite Verifie audit trail obligatoire et idempotence metier stricte.
INV-275-06-terminal-state-revoked TC-INV-06 Rejet de toute transition sortante depuis REVOKED Test dedie sur terminalite explicite.
INV-275-07-state-machine-complete TC-INV-07A, TC-INV-07B Presence de transitions autorisees/interdites pour chaque etat identifie Verifie exhaustivite du modele declare.
INV-275-08-envelope-encryption TC-INV-08 Absence de secret crypto en clair dans artefacts temporaires eventuels Test de non-divulgation sur perimetre PD-275.
INV-275-09-revoke-authorization TC-ERR-08 Refus avec ERR-REVOKE-UNAUTHORIZED Moindre privilege sur revocation — seuls ADMIN/SIGNER_ADMIN autorises.
INV-275-10-revokedBy-auth-derived TC-ERR-09 revokedBy = JWT sub, pas input Anti-usurpation audit trail.
INV-275-11-signer-concurrency-serialization TC-NOM-10 Serialisation prouvee par resultat deterministe Elimine race condition revoke/submit et revoke/revoke.
INV-275-12-single-revocation-audit-event TC-NOM-11 Un seul audit event pour double tentative concurrente Unicite transition + audit.
TEST-ID: TC-INV-06
Reference spec: INV-275-06-terminal-state-revoked

GIVEN
  - Un signer en etat `REVOKED`
WHEN
  - Toute action de changement de statut est demandee (dont retour `REVOKED -> ACTIVE`)
THEN
  - La transition est refusee
AND
  - L'etat `REVOKED` reste inchange
TEST-ID: TC-INV-07A
Reference spec: INV-275-07-state-machine-complete (signer)

GIVEN
  - Le modele d'etats signer contractuel
WHEN
  - Les transitions sortantes de `ACTIVE` et `REVOKED` sont verifiees
THEN
  - `ACTIVE -> REVOKED` est autorisee
  - `REVOKED -> ACTIVE` et `REVOKED -> *` sont explicitement interdites
TEST-ID: TC-INV-07B
Reference spec: INV-275-07-state-machine-complete (batch)

GIVEN
  - Le modele d'etats batch contractuel partiel
WHEN
  - Les transitions sortantes de `NON_FINALIZED` et `FINALIZED` sont verifiees
THEN
  - `NON_FINALIZED -> FINALIZED` est autorisee uniquement sous garde de finalite
  - `FINALIZED -> *` est explicitement interdite
TEST-ID: TC-INV-08
Reference spec: INV-275-08-envelope-encryption

GIVEN
  - Les flux PD-275 executes (mise a jour confirmations, revocation, soumission)
WHEN
  - Les artefacts temporaires eventuels produits par ces flux sont inspectes dans les stockages persistants accessibles
THEN
  - Aucun secret cryptographique en clair n'est present
AND
  - Si un artefact cryptographique temporaire existe, il est chiffre au repos (AES-256-GCM ou envelope HSM)

6. Tests de non-regression

Test ID Objet Observable Commentaire
TC-NR-01 Couverture des 5 comportements nouveaux (checks 28-32) Rapport de tests mappe vers TC-NOM-01/02/04/05/06/07/08 Couvre CA-07.
TC-NR-02 Non-regression des checks Prolog deja conformes (1-27) Rapport Prolog post-changement conserve OK sur checks historiques Garantit absence d'impact collateral de PD-275.
TC-NR-03 Soumission nominale signer ACTIVE intacte submitBatch() accepte un signer ACTIVE valide Verifie que le guard n'introduit pas de faux refus.
TC-NR-04 Finalisation nominale au seuil intacte finalizeBatch() accepte quand confirmation_count >= FINALITY_DEPTH Evite regression bloquante du flux metier.
TC-NR-05 Integrite schema apres cycle up/down/up Colonnes/contraintes attendues presentes apres reapplication Verifie stabilite migration reversible.

7. Tests negatifs et adversariaux

Test ID Entree invalide / abus Resultat attendu Observable
TC-NEG-01 confirmation_count = -1 Rejet ERR-CONFIRMATION-COUNT-INVALID Valeur persistante inchangee
TC-NEG-02 confirmation_count = 2147483648 Rejet ERR-CONFIRMATION-COUNT-INVALID Valeur persistante inchangee
TC-NEG-03 submitBatch() avec adresse inconnue Rejet fail-closed ERR-SIGNER-NOT-FOUND Aucun batch cree
TC-NEG-04 submitBatch() avec signer REVOKED Rejet ERR-SIGNER-REVOKED Aucun effet de bord
TC-NEG-05 Double revocation meme adresse Rejet ERR-SIGNER-ALREADY-REVOKED Audit trail d'origine inchange
TC-NEG-06 Tentative de reactivation REVOKED -> ACTIVE Transition refusee Statut reste REVOKED
TC-NEG-07 Finalisation avec confirmation_count nul et FINALITY_DEPTH >= 1 Rejet ERR-FINALITY-INSUFFICIENT Etat batch inchange
TC-NEG-08 Echec de persistence audit pendant revocation Rejet ERR-AUDIT-TRAIL-MISSING Aucune mutation partielle

8. Observabilite requise pour les tests

  • Etat systeme : lecture deterministe de anchor_batch (etat + confirmation_count) et signer_registry (status, revokedAt, revokedBy, contraintes schema).
  • Reponse API : code d'acceptation/refus et code erreur metier explicite (ERR-*) pour chaque appel.
  • Journal d'audit : trace datee et attribuee de chaque revocation reussie, plus trace de refus sur erreurs de securite.
  • Evenement signe / horodate : horodatage verifiable de revokedAt et horodatage du rapport Prolog archive.
  • Export probatoire : artefacts horodates et consultables (rapport de tests, rapport Prolog, etat schema/migrations) permettant re-execution et verification tierce.

9. Regles non testables

Regle Raison Impact
Politique normative exacte de revokedBy (Q-04) Le format impose (user id vs service account vs cle technique) n'est pas contractualise dans la specification. Majeur
Valeur par defaut officielle de FINALITY_DEPTH par environnement (Q-01) Le seuil est testable en parametre, mais la conformite de la valeur par environnement n'est pas verifiable sans decision de reference. Majeur
Normalisation/collision d'adresse signer (Q-03) Regles de checksum/casse non figees, impossible d'assertion definitive sur unicite metier multi-format. Majeur
Exhaustivite des etats anchor_batch hors FINALIZED (Q-02) Le modele fourni est partiel; la couverture de toutes transitions sortantes globales reste incompletable sans liste canonique. Bloquant

10. Verdict QA

  • ⚠️ Testable partiellement (avec reserves listees)
  • Motif : les flux PD-275 et les invariants centraux sont testables et automatisables, mais les ambiguities Q-01/Q-02/Q-03/Q-04 empechent un verdict "testable integralement".
  • Condition de levee des reserves : figer les decisions de specification manquantes puis rejouer les tests TC-INV-07B, TC-NEG-03/04, TC-NOM-02/03 avec referentiels valides.