Aller au contenu

PD-296 — Scénarios de tests contractuels

1. Références

  • Spécification : PD-296-specification.md
  • Epic : EPIC-XX

2. Matrice de couverture

ID Invariant ID Critère ID Test Couverture Commentaire
INV-296-01 CA-296-02, CA-296-07 TC-NOM-07 Oui Vérifie exactement 5 checkpoints officiels par story et sur tous les projets ciblés.
INV-296-02 CA-296-01 TC-NOM-01, TC-ERR-04 Oui STEP1_SPEC_COHERENCE requis avant passage step 2.
INV-296-03 CA-296-02 TC-NOM-02, TC-ERR-05 Oui STEP4_CONTRACTS_FORMAL avant Gate 5.
INV-296-04 CA-296-12 TC-NOM-03, TC-ERR-05 Oui /gov-check-plan phase formelle pré-Gate 5 obligatoire.
INV-296-05 CA-296-02 TC-NOM-04, TC-ERR-06 Oui STEP6_CODE_FORMAL avant step 7.
INV-296-06 CA-296-02 TC-NOM-05, TC-ERR-07 Oui GATE8_FINAL_FORMAL avant Gate 8.
INV-296-07 CA-296-03 TC-ERR-04, TC-ERR-05, TC-ERR-06, TC-ERR-07 Oui Tout FAIL bloque la transition aval.
INV-296-08 CA-296-04, CA-296-10 TC-ERR-08, TC-ERR-09 Oui Fail-closed sur indisponibilité et timeout.
INV-296-09 CA-296-08 TC-ERR-13 Oui Jira Done interdit si FAIL formel ouvert.
INV-296-10 CA-296-07 TC-NOM-07 Oui Pas d’exception projet/domaine.
INV-296-11 CA-296-05, CA-296-06 TC-NOM-08 Oui Article VIII présent et référencé.
INV-296-12 CA-296-11 TC-INV-01, TC-NEG-02 Oui FSM fermée aux 4 états autorisés.
INV-296-13 CA-296-03 TC-INV-02, TC-NEG-03, TC-NEG-12 Oui Toute transition hors §5.4 rejetée.
INV-296-14 CA-296-11 TC-NOM-09, TC-ERR-03 Oui Contrat D-296-14 strictement validé.
INV-296-15 CA-296-09 TC-NOM-10, TC-NOM-12, TC-ERR-10, TC-ERR-11, TC-NEG-09 Oui Lock, idempotence, réconciliation, rate-limit couverts.
INV-296-16 CA-296-11 TC-ERR-01, TC-ERR-02, TC-NEG-01, TC-NEG-04, TC-NEG-05, TC-NEG-06, TC-NEG-07, TC-NEG-08 Oui Données invalides rejetées avec blocage.
INV-296-17 CA-296-03 TC-INV-03, TC-ERR-12 Oui Aucun mode warning/informative/skip.
INV-296-18 CA-296-01..CA-296-12 TC-INV-04 Partielle Couverture définie intégralement, réserves de testabilité listées en §9.

3. Scénarios de test – Flux nominaux

TEST-ID: TC-NOM-01
Référence spec: INV-296-02, CA-296-01

GIVEN
  - Story `PD-296`, projet `ia-governance`, spec valide sauvegardée
  - Environnement de test déterministe avec journal d’audit horodaté UTC
WHEN
  - L’événement `SPEC_SAVED` déclenche `STEP1_SPEC_COHERENCE` avec verdict `GO`
THEN
  - La transition d’état suit `PENDING -> RUNNING -> PASSED`
  - La transition step 1 -> step 2 est autorisée
AND
  - Un résultat `formal_check_result_json` conforme `D-296-14` est archivé
TEST-ID: TC-NOM-02
Référence spec: INV-296-03, CA-296-02

GIVEN
  - `PD-296-plan.md` et `code-contracts.yaml` valides sauvegardés
WHEN
  - L’événement `PLAN_AND_CONTRACTS_SAVED` déclenche `STEP4_CONTRACTS_FORMAL` avec verdict `GO`
THEN
  - Le checkpoint `STEP4_CONTRACTS_FORMAL` passe à `PASSED`
  - La story devient éligible au pré-Gate 5
AND
  - Aucun blocage Gate 5 n’est présent
TEST-ID: TC-NOM-03
Référence spec: INV-296-04, CA-296-12

GIVEN
  - Step 4 validé et session `/gov-check-plan` en phase 4
WHEN
  - L’événement `CHECK_PLAN_PHASE4_START` déclenche `GATE5_PLAN_FORMAL` avec verdict `GO`
THEN
  - Le checkpoint `GATE5_PLAN_FORMAL` est `PASSED`
  - La soumission Gate 5 est autorisée
AND
  - La phase formelle est visible dans les traces avant le verdict Gate 5
TEST-ID: TC-NOM-04
Référence spec: INV-296-05, CA-296-02

GIVEN
  - Step 6c terminé pour `PD-296`
WHEN
  - L’événement `STEP6C_DONE` déclenche `STEP6_CODE_FORMAL` avec verdict `GO`
THEN
  - Le checkpoint `STEP6_CODE_FORMAL` est `PASSED`
  - La transition step 6 -> step 7 est autorisée
AND
  - L’audit lie explicitement `story_id`, `checkpoint_id`, `verdict`
TEST-ID: TC-NOM-05
Référence spec: INV-296-06, CA-296-02

GIVEN
  - `/gov-accept` a terminé la phase 2 pour `PD-296`
WHEN
  - L’événement `GOV_ACCEPT_PHASE2_DONE` déclenche `GATE8_FINAL_FORMAL` avec verdict `GO`
THEN
  - Le checkpoint `GATE8_FINAL_FORMAL` est `PASSED`
  - La soumission Gate 8 est autorisée
AND
  - Aucune fermeture n’est bloquée par un FAIL formel
TEST-ID: TC-NOM-06
Référence spec: CA-296-01

GIVEN
  - Story `PD-296` exécutée depuis step 0 puis step 1
WHEN
  - Les contrôles de cohérence sont lancés au step 0 puis au step 1
THEN
  - Deux exécutions distinctes de `coherence` sont observables dans les traces
  - Les deux exécutions portent des `correlation_id` distincts
AND
  - L’exécution step 1 est rattachée à `STEP1_SPEC_COHERENCE`
TEST-ID: TC-NOM-07
Référence spec: INV-296-01, INV-296-10, CA-296-07

GIVEN
  - 8 stories de test, une par `project_code`: backend, app, site, infra, doc, formal, pixel-governance, ia-governance
  - Toutes les entrées D-296 valides
WHEN
  - Le workflow `/gov` complet est exécuté avec verdicts `GO`
THEN
  - Chaque story exécute exactement les 5 `checkpoint_id` canoniques, une seule fois chacun
  - Aucun filtre projet/domaine n’exclut un checkpoint
AND
  - Les transitions aval sont autorisées uniquement après `PASSED`
TEST-ID: TC-NOM-08
Référence spec: INV-296-11, CA-296-05, CA-296-06

GIVEN
  - Révision de dépôt figée
WHEN
  - Contrôle de contenu sur `governance/CONSTITUTIONAL.md` et `CLAUDE.md`
THEN
  - L’Article VIII "Vérification formelle" est détectable et exact dans `CONSTITUTIONAL.md`
  - `CLAUDE.md` contient une référence explicite à l’Article VIII
AND
  - Les deux preuves sont archivées en export probatoire
TEST-ID: TC-NOM-09
Référence spec: INV-296-14, CA-296-11

GIVEN
  - Une exécution complète avec 5 checkpoints `PASSED`
WHEN
  - Chaque `formal_check_result_json` est validé contre D-296-14 + contraintes D-296-01..D-296-15
THEN
  - Les clés requises sont toutes présentes
  - Les formats/regex/tailles sont conformes
AND
  - La validation schéma réussit pour chaque checkpoint
TEST-ID: TC-NOM-10
Référence spec: INV-296-15, CA-296-09

GIVEN
  - Checkpoint déjà exécuté avec `idempotency_key=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef`
WHEN
  - La même requête (clé identique, payload identique) est rejouée dans `idempotency_window_h`
THEN
  - Le résultat retourné est identique (verdict, état, code d’échec, détails)
  - Aucun second run n’est créé
AND
  - L’audit marque le replay idempotent sans effet secondaire
TEST-ID: TC-NOM-11
Référence spec: INV-296-13, §5.4 retour `FAILED_BLOCKING -> PENDING`

GIVEN
  - Un checkpoint en `FAILED_BLOCKING` avec `details[]` renseigné
  - Artefact corrigé et nouvel événement déclencheur valide
WHEN
  - Une relance est demandée
THEN
  - La transition suit `FAILED_BLOCKING -> PENDING -> RUNNING -> PASSED`
  - Les `details[]` historiques d’échec restent conservés
AND
  - Les verrous aval restent actifs jusqu’au nouveau `PASSED`
TEST-ID: TC-NOM-12
Référence spec: INV-296-15

GIVEN
  - Un run orphelin en `RUNNING` au-delà de `orphan_threshold_sec`
  - État dégradé actif nécessitant `clearing_success_cycles_required=2`
WHEN
  - Le scanner de réconciliation s’exécute puis deux cycles consécutifs `PASSED` sont observés
THEN
  - Le run orphelin est converti en `FAILED_BLOCKING` avec `failure_code=INTERNAL_ERROR`
  - L’état dégradé est levé seulement après 2 cycles `PASSED` consécutifs
AND
  - Les traces montrent l’intervalle de scan appliqué (`reconciliation_interval_sec`)

4. Scénarios de test – Cas d’erreur

TEST-ID: TC-ERR-01
Référence spec: ERR-296-01, D-296-01, INV-296-16

GIVEN
  - Payload avec `story_id="pd-296"` (regex invalide)
WHEN
  - Le checkpoint est soumis
THEN
  - Rejet immédiat avec état `FAILED_BLOCKING`
  - Progression aval interdite
AND
  - Aucun run `RUNNING` n’est démarré
TEST-ID: TC-ERR-02
Référence spec: ERR-296-02, D-296-03, INV-296-16

GIVEN
  - Payload avec `checkpoint_id="STEP9_UNKNOWN"`
WHEN
  - Le checkpoint est soumis
THEN
  - Rejet immédiat avec `FAILED_BLOCKING`
  - Aucun mapping step/gate n’est exécuté
AND
  - L’erreur est journalisée en audit
TEST-ID: TC-ERR-03
Référence spec: ERR-296-03, D-296-14, INV-296-14

GIVEN
  - Résultat formel sans clé obligatoire `details`
WHEN
  - Le moteur tente d’enregistrer `formal_check_result_json`
THEN
  - Rejet avec `failure_code=INTERNAL_ERROR`
  - État checkpoint `FAILED_BLOCKING`
AND
  - Aucune transition aval n’est autorisée
TEST-ID: TC-ERR-04
Référence spec: ERR-296-04, INV-296-07, CA-296-03

GIVEN
  - `STEP1_SPEC_COHERENCE` retourne `verdict=FAIL`, `failure_code=CONTRADICTION_DETECTED`
WHEN
  - La progression vers step 2 est demandée
THEN
  - Step 2 est refusé
  - Les contradictions sont visibles dans `details[]`
AND
  - Le blocage est tracé avec `checkpoint_id` concerné
TEST-ID: TC-ERR-05
Référence spec: ERR-296-05, INV-296-07

GIVEN
  - `STEP4_CONTRACTS_FORMAL` ou `GATE5_PLAN_FORMAL` retourne `FAIL`
WHEN
  - Une soumission Gate 5 est tentée
THEN
  - Gate 5 est refusée
  - Le checkpoint reste `FAILED_BLOCKING`
AND
  - Aucun verdict Gate 5 n’est publié
TEST-ID: TC-ERR-06
Référence spec: ERR-296-06, INV-296-07

GIVEN
  - `STEP6_CODE_FORMAL` retourne `FAIL`
WHEN
  - Une transition vers step 7 est tentée
THEN
  - Step 7 est interdit
  - La story reste bloquée sur la boucle de correction step 6
AND
  - Le blocage persiste jusqu’à nouveau `PASSED`
TEST-ID: TC-ERR-07
Référence spec: ERR-296-07, INV-296-07

GIVEN
  - `GATE8_FINAL_FORMAL` retourne `FAIL`
WHEN
  - Une soumission Gate 8 est tentée
THEN
  - Gate 8 est refusée
  - La clôture reste interdite
AND
  - Le statut Jira n’atteint pas `Done`
TEST-ID: TC-ERR-08
Référence spec: ERR-296-08, INV-296-08, CA-296-04

GIVEN
  - Outil formel indisponible au déclenchement checkpoint
WHEN
  - Le checkpoint démarre
THEN
  - Résultat `verdict=FAIL`, `failure_code=TOOL_UNAVAILABLE`
  - État final `FAILED_BLOCKING`
AND
  - Aucun mode dégradé non bloquant n’est appliqué
TEST-ID: TC-ERR-09
Référence spec: ERR-296-09, INV-296-08, CA-296-10

GIVEN
  - Checkpoint en `RUNNING` dépasse son SLA configuré
WHEN
  - L’échéance timeout est atteinte
THEN
  - Transition forcée `RUNNING -> FAILED_BLOCKING`
  - `failure_code=TIMEOUT`
AND
  - La progression aval reste interdite
TEST-ID: TC-ERR-10
Référence spec: ERR-296-10, INV-296-15

GIVEN
  - Un lock distribué actif sur (`story_id=PD-296`, `checkpoint_id=STEP4_CONTRACTS_FORMAL`)
WHEN
  - Un second déclenchement concurrent est reçu sur le même scope
THEN
  - La requête concurrente retourne `verdict=FAIL`, `failure_code=CONCURRENT_RUN`
  - Le checkpoint est bloquant pour cette tentative
AND
  - Aucun second run parallèle n’est créé
TEST-ID: TC-ERR-11
Référence spec: ERR-296-11, INV-296-15

GIVEN
  - Requête A enregistrée avec `idempotency_key=K1`
WHEN
  - Requête B est rejouée avec `idempotency_key=K1` et payload différent
THEN
  - Rejet explicite de la relance
  - Blocage de progression maintenu
AND
  - Le résultat de la requête A n’est pas écrasé
TEST-ID: TC-ERR-12
Référence spec: ERR-296-12, INV-296-17

GIVEN
  - Un checkpoint `FAILED_BLOCKING` ouvert
WHEN
  - Une tentative de bypass/force passage est soumise
THEN
  - Rejet explicite de la tentative
  - État de blocage inchangé
AND
  - Traçabilité d’audit obligatoire présente
TEST-ID: TC-ERR-13
Référence spec: ERR-296-13, INV-296-09, CA-296-08

GIVEN
  - Au moins un checkpoint formel `FAILED_BLOCKING` non corrigé
WHEN
  - Transition Jira vers `Done` demandée
THEN
  - Transition refusée
  - Statut Jira inchangé
AND
  - Motif de refus lié au checkpoint formel enregistré

5. Tests d’invariants (non négociables)

Invariant Test(s) dédiés Observable Commentaire
INV-296-01 TC-NOM-07 Compte exact des 5 checkpoints canoniques par story Exécution systématique.
INV-296-02 TC-NOM-01, TC-ERR-04 STEP1_SPEC_COHERENCE avant step 2 Blocage si FAIL.
INV-296-03 TC-NOM-02, TC-ERR-05 STEP4_CONTRACTS_FORMAL avant Gate 5 Aucun passage sans PASSED.
INV-296-04 TC-NOM-03 Phase formelle visible en pré-Gate 5 Vérification de séquencement.
INV-296-05 TC-NOM-04, TC-ERR-06 STEP6_CODE_FORMAL avant step 7 Blocage déterministe.
INV-296-06 TC-NOM-05, TC-ERR-07 GATE8_FINAL_FORMAL avant Gate 8 Clôture interdite sur FAIL.
INV-296-07 TC-ERR-04..TC-ERR-07 Aucune transition aval avec FAIL Fail blocking strict.
INV-296-08 TC-ERR-08, TC-ERR-09 TOOL_UNAVAILABLE/TIMEOUT => FAIL Fail-closed.
INV-296-09 TC-ERR-13 Jira Done interdit avec FAIL ouvert Contrôle cross-module.
INV-296-10 TC-NOM-07 Même comportement sur 8 project_code Sans exception.
INV-296-11 TC-NOM-08 Article VIII présent + référence CLAUDE Contrôle documentaire.
INV-296-12 TC-INV-01, TC-NEG-02 États autorisés uniquement: PENDING/RUNNING/PASSED/FAILED_BLOCKING FSM fermée.
INV-296-13 TC-INV-02, TC-NEG-03, TC-NEG-12 Transitions non listées rejetées Terminalité incluse.
INV-296-14 TC-NOM-09, TC-ERR-03 Validation schéma D-296-14 Machine-readable obligatoire.
INV-296-15 TC-NOM-10, TC-NOM-12, TC-ERR-10, TC-ERR-11, TC-NEG-09 Lock/idempotence/réconciliation/rate-limit actifs Concurrence robuste.
INV-296-16 TC-ERR-01, TC-ERR-02, TC-NEG-01, TC-NEG-04..08 Toute donnée invalide rejetée + blocage Intégrité des entrées.
INV-296-17 TC-INV-03, TC-ERR-12 Absence totale de mode warning only, informative only, skip Non contournable.
INV-296-18 TC-INV-04 Audit de couverture INV/CA vs tests Réserves de testabilité §9.

6. Tests de non-régression

Test ID Objet Observable Commentaire
TC-NR-01 Mapping déterministe step/gate -> checkpoint_id (F-296-01..05) Même mapping sur replays identiques Détecte dérive de routage.
TC-NR-02 Scope du guard limité aux commandes /gov listées §5.7 Aucun blocage hors scope /gov Évite effet global non voulu.
TC-NR-03 Conservation de l’historique après cycle correction details[] d’échec toujours présents après FAILED_BLOCKING -> PENDING -> PASSED Non-régression auditabilité.
TC-NR-04 Interdiction d’auto-retry (formal_retry_on_failure=0) Aucune relance automatique observée en erreur Contrat fail-closed préservé.
TC-NR-05 Terminalité PASSED stable Toute transition sortante depuis PASSED rejetée Non-régression FSM.

7. Tests négatifs et adversariaux

Test ID Entrée invalide / abus Résultat attendu Observable
TC-NEG-01 project_code="mobile" (hors enum D-296-02) Rejet + FAILED_BLOCKING Réponse erreur + audit INPUT_INVALID.
TC-NEG-02 checkpoint_state="DONE" Rejet immédiat État inchangé, pas de transition aval.
TC-NEG-03 Tentative RUNNING -> PENDING sans verdict Rejet transition interdite Journal FSM explicite.
TC-NEG-04 Payload avec verdict=FAIL et blocking=false Rejet du payload Contrôle cohérence D-296-08.
TC-NEG-05 artifact_path relatif ou hors racine autorisée Rejet + blocage Regex D-296-10 non satisfaite.
TC-NEG-06 idempotency_key non hex/longueur !=64 Rejet + blocage Validation D-296-11 échoue.
TC-NEG-07 correlation_id non UUID v4 Rejet + blocage Validation D-296-12 échoue.
TC-NEG-08 details[] >200 items ou item >500 chars Rejet + blocage Validation D-296-15 échoue.
TC-NEG-09 Dépassement rate_limit_checks_per_min_per_story Rejet (équivalent 429), pas de progression Compteur rate-limit incrémenté et refus tracé.
TC-NEG-10 Configuration formal_retry_on_failure=1 Rejet config + blocage Contrat §5.2 respecté.
TC-NEG-11 Configuration distributed_lock_ttl_sec=30 (hors bornes) Rejet config + blocage Validation bornes §5.2.
TC-NEG-12 Tentative de sortie depuis état PASSED Rejet (état terminal) FSM inchangée, trace de refus.

8. Observabilité requise pour les tests

  • État système : snapshot FSM par story_id/checkpoint_id, état Jira, état des verrous distribués, compteurs rate-limit.
  • Réponse API : statut de réponse, corps complet (checkpoint_state, verdict, failure_code, blocking, correlation_id), motif de rejet.
  • Journal d’audit : événements horodatés UTC incluant story_id, project_code, checkpoint_id, transition source/cible, acteur, décision.
  • Événement signé / horodaté : preuve d’intégrité (hash/signature) associée à chaque résultat formel et à chaque refus de transition.
  • Export probatoire : paquet vérifiable (JSON/JSONL + logs) corrélant entrées, verdicts, transitions FSM, refus Jira Done, et traces de concurrence/idempotence.

9. Règles non testables

Règle Raison Impact
mandatory_gates_formal=3 (G3/G5/G8) Aucun checkpoint_id Gate 3 dans D-296-03 et aucun flux Gate 3 en §5.5 Bloquant
CA-296-01 vs INV-296-01 (step 0 + step 1 vs “exactement 5 checkpoints”) Le statut de l’exécution coherence au step 0 dans le décompte contractuel n’est pas explicitement défini Majeur
Configurabilité des SLA §5.3 Nommage exact des clés de configuration non fourni (Q-296-04), test admin non déterministe Majeur
Percentile P95 de formal_timeout_sec Matériel/protocole de référence non spécifiés (Q-296-05), comparabilité objective impossible Majeur
Nature du mapping GO|FAIL (natif vs adaptateur) Ambiguïté contractuelle (Q-296-02), vérification boîte blanche non définie Majeur
Référence Epic exacte Identifiant parent non fourni dans l’entrée (Q-296-01) Mineur

10. Verdict QA

  • ✅ Testable intégralement : Non
  • ⚠️ Testable partiellement (avec réserves listées) : Oui
  • ❌ Non testable (refus contractuel) : Non