Aller au contenu

PD-295 — Scénarios de tests contractuels

1. Références

  • Spécification : PD-295-specification.md
  • Epic : EPIC-XX (non communiqué dans la spécification au 2026-04-12)

2. Matrice de couverture

ID Invariant ID Critère ID Test Couverture Commentaire
INV-295-01 CA-295-01 TC-NOM-01 Oui Scan contractuel + robustesse non bloquante
INV-295-02 CA-295-02 TC-NOM-02 Oui Conformité modèle de données veille
INV-295-03 CA-295-03 TC-NOM-03 Oui Verbatim brut des 4 réponses PO
INV-295-04 CA-295-04 TC-NOM-04 Oui Indexation clarifications JSONL + FAISS
INV-295-05 CA-295-05 TC-NOM-05 Oui Formule reuse_score exacte 0.4/0.4/0.2
INV-295-06 CA-295-06 TC-NOM-06 Oui Jointure {story,gate,tags_hash} univoque
INV-295-07 CA-295-07 TC-NOM-07 Oui Tri secondaire reuse_score
INV-295-08 CA-295-08 TC-NOM-08 Oui Migration initiale scope: story
INV-295-09 CA-295-09 TC-NOM-09, TC-NOM-16 Oui Seuil promotion story→domain
INV-295-10 CA-295-09 TC-NOM-09, TC-NOM-16 Oui Seuil promotion domain→global
INV-295-11 CA-295-10 TC-NOM-10, TC-NOM-16 Oui Règle stale >56j + nb_injections==0
INV-295-12 CA-295-11 TC-NOM-11 Oui Archive absente de l’index actif
INV-295-13 CA-295-12 TC-NOM-12 Oui Bloc 3 sections, cardinalités max 5/3/3
INV-295-14 CA-295-13 TC-NOM-13, TC-ERR-06 Oui aucun résultat sans blocage
INV-295-15 CA-295-14 TC-NOM-14, TC-ERR-04, TC-ERR-05, TC-ERR-09 Oui Erreur source non bloquante
INV-295-16 CA-295-17 TC-NOM-15, TC-NR-03, TC-NR-04 Oui Stack contractuelle + exclusions hors périmètre
INV-295-TR-01 CA-295-09 TC-NOM-16 Oui STORY_ACTIVE → DOMAIN_ACTIVE autorisée
INV-295-TR-02 CA-295-15 TC-ERR-07 Oui STORY_ACTIVE → GLOBAL_ACTIVE interdite
INV-295-TR-03 CA-295-10 TC-NOM-16 Oui STORY_ACTIVE → ARCHIVED autorisée si stale
INV-295-TR-04 CA-295-15 TC-ERR-07 Oui DOMAIN_ACTIVE → STORY_ACTIVE interdite
INV-295-TR-05 CA-295-09 TC-NOM-16 Oui DOMAIN_ACTIVE → GLOBAL_ACTIVE autorisée
INV-295-TR-06 CA-295-10 TC-NOM-16 Oui DOMAIN_ACTIVE → ARCHIVED autorisée si stale
INV-295-TR-07 CA-295-15 TC-ERR-07 Oui GLOBAL_ACTIVE → DOMAIN_ACTIVE interdite
INV-295-TR-08 CA-295-15 TC-ERR-07 Oui GLOBAL_ACTIVE → STORY_ACTIVE interdite
INV-295-TR-09 CA-295-10 TC-NOM-16 Oui GLOBAL_ACTIVE → ARCHIVED autorisée si stale
INV-295-TR-10 CA-295-16 TC-ERR-11 Oui ARCHIVED → STORY_ACTIVE interdite
INV-295-TR-11 CA-295-16 TC-ERR-11 Oui ARCHIVED → DOMAIN_ACTIVE interdite
INV-295-TR-12 CA-295-16 TC-ERR-11 Oui ARCHIVED → GLOBAL_ACTIVE interdite
INV-295-TR-13 CA-295-16 TC-ERR-11 Oui ARCHIVED terminal (→ * interdit)

3. Scénarios de test – Flux nominaux

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

GIVEN
  - Corpus de test fixe dans `ProbatioVault-doc/docs/veille/` avec 3 fiches valides et 2 invalides
WHEN
  - Le flux B1 d’indexation veille est exécuté
THEN
  - Le scan couvre le motif `ProbatioVault-doc/docs/veille/**/*.md`
  - `data/veille.jsonl` contient exactement 3 lignes
AND
  - Les 2 fiches invalides sont ignorées, journalisées sur stderr, sans arrêt global
TEST-ID: TC-NOM-02
Référence spec: INV-295-02, CA-295-02

GIVEN
  - `data/veille.jsonl` produit depuis un corpus valide
WHEN
  - Validation contractuelle des champs §5.1 (regex/enums/tailles)
THEN
  - 100% des lignes passent les contraintes D-295 applicables à la veille
AND
  - Aucune ligne invalide n’est acceptée silencieusement
TEST-ID: TC-NOM-03
Référence spec: INV-295-03, CA-295-03

GIVEN
  - Step 0 avec exactement 4 réponses PO verbatim (chaînes sentinelles connues)
WHEN
  - B2 persistance clarifications est exécuté
THEN
  - Le fichier `PD-XX-clarifications.md` est créé dans le dossier epic de la story
  - Les 4 réponses y sont présentes en verbatim brut, sans résumé ni filtrage
AND
  - L’ordre des réponses est conservé
TEST-ID: TC-NOM-04
Référence spec: INV-295-04, CA-295-04

GIVEN
  - Un fichier `PD-XX-clarifications.md` valide déjà persisté
WHEN
  - L’indexation clarifications est exécutée
THEN
  - `data/clarifications.jsonl` est présent
  - L’index FAISS clarifications est présent
AND
  - Une recherche `/clarifications --domain --project` retrouve la clarification persistée
TEST-ID: TC-NOM-05
Référence spec: INV-295-05, CA-295-05

GIVEN
  - Dataset déterministe:
    L1: `nb_injections=2`, `nb_stories_gate8_go_apres_injection=1`, `nb_domains_distincts=3`
    L2: `nb_injections=0`, `nb_stories_gate8_go_apres_injection=2`, `nb_domains_distincts=1`
WHEN
  - B3 calcule les scores
THEN
  - `reuse_score(L1)=1.8` et `reuse_score(L2)=1.0`
AND
  - Les coefficients appliqués sont exactement 0.4/0.4/0.2
TEST-ID: TC-NOM-06
Référence spec: INV-295-06, CA-295-06

GIVEN
  - `learnings.jsonl` et `data/learnings-scores.jsonl` avec clés de jointure contrôlées
WHEN
  - Jointure `{story,gate,tags_hash}` est évaluée
THEN
  - Chaque ligne score référence exactement 1 learning
AND
  - Aucune correspondance 0 ou multiple n’est tolérée
TEST-ID: TC-NOM-07
Référence spec: INV-295-07, CA-295-07

GIVEN
  - Deux learnings avec similarité identique et `reuse_score` différents (0.8 vs 0.6)
WHEN
  - Recherche learnings est exécutée
THEN
  - Le learning `reuse_score=0.8` est classé avant `0.6`
AND
  - La différence d’ordre est observable dans la liste retournée
TEST-ID: TC-NOM-08
Référence spec: INV-295-08, CA-295-08

GIVEN
  - Corpus historique avec entrées mixtes: avec et sans champ `scope`
WHEN
  - Migration initiale B4 est exécutée
THEN
  - 100% des entrées sans `scope` deviennent `scope: story`
AND
  - Les entrées déjà typées conservent leur scope initial
TEST-ID: TC-NOM-09
Référence spec: INV-295-09, INV-295-10, CA-295-09

GIVEN
  - 4 learnings:
    S1 `scope=story`, `reuse_score=0.29`
    S2 `scope=story`, `reuse_score=0.30`
    D1 `scope=domain`, `reuse_score=0.59`
    D2 `scope=domain`, `reuse_score=0.60`
WHEN
  - Promotion B4 est exécutée
THEN
  - S2 passe `story→domain`, S1 reste `story`
  - D2 passe `domain→global`, D1 reste `domain`
AND
  - Les seuils sont appliqués strictement à 0.3 et 0.6
TEST-ID: TC-NOM-10
Référence spec: INV-295-11, CA-295-10

GIVEN
  - 4 learnings:
    A `age=57j`, `nb_injections=0`
    B `age=56j`, `nb_injections=0`
    C `age=57j`, `nb_injections=1`
    D `age=10j`, `nb_injections=0`
WHEN
  - Éviction B4 est exécutée
THEN
  - Seul A est déplacé vers `learnings-archive.jsonl`
AND
  - B, C, D ne sont pas archivés
TEST-ID: TC-NOM-11
Référence spec: INV-295-12, CA-295-11

GIVEN
  - Un learning archivé fortement pertinent + un learning actif faiblement pertinent
WHEN
  - Injection step 0 interroge l’index actif
THEN
  - Le learning archivé n’apparaît jamais dans les résultats
AND
  - Le learning actif peut apparaître
TEST-ID: TC-NOM-12
Référence spec: INV-295-13, CA-295-12

GIVEN
  - Corpus où chaque source retourne plus que la limite (>=7 résultats)
WHEN
  - Injection unifiée B5 est exécutée
THEN
  - Le bloc Markdown contient exactement 3 sections (learnings, veille, clarifications)
  - Les cardinalités effectives sont limitées à 5/3/3
AND
  - Aucune 4e section n’est produite
TEST-ID: TC-NOM-13
Référence spec: INV-295-14, CA-295-13

GIVEN
  - Source clarifications valide mais sans hit
WHEN
  - Injection B5 est exécutée
THEN
  - La section clarifications affiche exactement `aucun résultat`
AND
  - Le step 0 se termine sans blocage
TEST-ID: TC-NOM-14
Référence spec: INV-295-15, CA-295-14

GIVEN
  - Source veille en erreur technique (ex: dépendance indisponible)
WHEN
  - Injection B5 est exécutée
THEN
  - La section veille est vide
  - Une erreur est tracée sur stderr
AND
  - Le step 0 continue et rend le bloc Markdown
TEST-ID: TC-NOM-15
Référence spec: CA-295-17

GIVEN
  - La spécification canonique PD-295
WHEN
  - Contrôle documentaire de la section 10 est effectué
THEN
  - Les mentions Python, FAISS, Ollama, Markdown, YAML sont présentes
AND
  - Les technologies Swift et Spring sont absentes
TEST-ID: TC-NOM-16
Référence spec: INV-295-TR-01, INV-295-TR-03, INV-295-TR-05, INV-295-TR-06, INV-295-TR-09, CA-295-09, CA-295-10

GIVEN
  - Matrice de 5 learnings:
    T1 `story`, `reuse_score=0.30`
    T2 `story`, `age=57j`, `nb_injections=0`
    T3 `domain`, `reuse_score=0.60`
    T4 `domain`, `age=57j`, `nb_injections=0`
    T5 `global`, `age=57j`, `nb_injections=0`
WHEN
  - Moteur de transitions B4 est exécuté
THEN
  - T1: `story→domain` autorisée
  - T2: `story→archived` autorisée
  - T3: `domain→global` autorisée
  - T4: `domain→archived` autorisée
  - T5: `global→archived` autorisée
AND
  - Chaque transition autorisée modifie le scope attendu

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

TEST-ID: TC-ERR-01
Référence spec: ERR-295-01

GIVEN
  - Un lot mixte de lignes valides + 1 ligne invalide au format §5.1
WHEN
  - Le traitement de la source est exécuté
THEN
  - La ligne invalide est rejetée
  - Un message est tracé sur stderr
AND
  - Les lignes valides continuent d’être traitées
TEST-ID: TC-ERR-02
Référence spec: ERR-295-02

GIVEN
  - Une fiche veille avec frontmatter incomplet dans le corpus
WHEN
  - B1 indexation veille est exécuté
THEN
  - La fiche invalide est ignorée
AND
  - L’indexation des autres fiches continue
TEST-ID: TC-ERR-03
Référence spec: ERR-295-03

GIVEN
  - `learnings-injections.jsonl` absent ou inaccessible
WHEN
  - B3 scoring est exécuté
THEN
  - Le scoring est calculé avec le corpus disponible
  - Un log stderr est produit
AND
  - Les learnings sans historique exploitable sont traités avec score absent équivalent à 0 en usage aval
TEST-ID: TC-ERR-04
Référence spec: ERR-295-04

GIVEN
  - Échec Ollama (timeout 30000 ms ou indisponibilité) sur une source
WHEN
  - Injection B5 est exécutée
THEN
  - La section de la source en échec est vide
  - Erreur consignée sur stderr
AND
  - Step 0 reste non bloqué
TEST-ID: TC-ERR-05
Référence spec: ERR-295-05

GIVEN
  - Index FAISS d’une source absent ou corrompu
WHEN
  - Injection B5 est exécutée
THEN
  - La section de la source concernée est vide
  - Erreur consignée sur stderr
AND
  - Step 0 reste non bloqué
TEST-ID: TC-ERR-06
Référence spec: ERR-295-06

GIVEN
  - Source valide retournant 0 résultat
WHEN
  - Injection B5 est exécutée
THEN
  - La section correspondante affiche exactement `aucun résultat`
AND
  - Aucun échec de workflow n’est déclenché
TEST-ID: TC-ERR-07
Référence spec: ERR-295-07, INV-295-TR-02, INV-295-TR-04, INV-295-TR-07, INV-295-TR-08, CA-295-15

GIVEN
  - Tentatives de transitions interdites:
    `story→global`, `domain→story`, `global→domain`, `global→story`
WHEN
  - Le moteur de transitions est sollicité
THEN
  - Chaque transition est refusée
  - Le scope reste inchangé
AND
  - Un refus explicite est journalisé sur stderr
TEST-ID: TC-ERR-08
Référence spec: ERR-295-08

GIVEN
  - Paramètres hors bornes contractuelles §5.2 (ex: `top_k_learnings_step0=4`, `embedding_dimension=769`)
WHEN
  - Validation de conformité contractuelle est exécutée
THEN
  - Verdict de conformité = KO
AND
  - Aucune tolérance implicite n’est appliquée
TEST-ID: TC-ERR-09
Référence spec: ERR-295-09

GIVEN
  - Écriture `PD-XX-clarifications.md` impossible (droits/path)
WHEN
  - B2 persistance est exécuté
THEN
  - Erreur consignée sur stderr
  - Aucune clarification n’est persistée
AND
  - Step 0 continue sans blocage
TEST-ID: TC-ERR-10
Référence spec: ERR-295-10

GIVEN
  - Une ligne score dont `{story,gate,tags_hash}` ne correspond à aucun learning
WHEN
  - Scoring/promotion est exécuté
THEN
  - Le learning non jointable est exclu du calcul et de la promotion
AND
  - Un log explicite est émis sur stderr
TEST-ID: TC-ERR-11
Référence spec: INV-295-TR-10, INV-295-TR-11, INV-295-TR-12, INV-295-TR-13, CA-295-16

GIVEN
  - Learning en état `ARCHIVED`
WHEN
  - Tentatives de sortie: `archived→story`, `archived→domain`, `archived→global`
THEN
  - Toutes les transitions sortantes sont refusées
  - Le scope reste `archived`
AND
  - Le caractère terminal est explicitement observable dans les traces

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

Invariant Test(s) dédiés Observable Commentaire
INV-295-01 TC-NOM-01, TC-ERR-02 Scan du chemin contractuel + ignore invalides sans arrêt Non-bloquant validé
INV-295-02 TC-NOM-02 1 fiche valide -> 1 ligne JSONL conforme Conformité §5.1
INV-295-03 TC-NOM-03 4 verbatims bruts persistés Sans résumé/filtrage
INV-295-04 TC-NOM-04 clarifications.jsonl + index FAISS présents Réutilisation possible
INV-295-05 TC-NOM-05 Scores exacts calculés Coefficients stricts
INV-295-06 TC-NOM-06, TC-ERR-10 Jointure univoque par clé Exclusion si impossible
INV-295-07 TC-NOM-07 Ordre secondaire par score Similarité égale contrôlée
INV-295-08 TC-NOM-08 Entrées sans scope migrées en story 100% attendu
INV-295-09 TC-NOM-09, TC-NOM-16 Promotion story→domain au seuil Refus sous seuil
INV-295-10 TC-NOM-09, TC-NOM-16 Promotion domain→global au seuil Refus sous seuil
INV-295-11 TC-NOM-10, TC-NOM-16 Archivage seulement stale + inj=0 Condition conjonctive stricte
INV-295-12 TC-NOM-11 Archive absente de l’index actif Éviction effective
INV-295-13 TC-NOM-12 Bloc 3 sections, cardinalités 5/3/3 max Contrat B5
INV-295-14 TC-NOM-13, TC-ERR-06 aucun résultat affiché Step 0 non bloqué
INV-295-15 TC-NOM-14, TC-ERR-04, TC-ERR-05, TC-ERR-09 Section vide + stderr Step 0 non bloqué
INV-295-16 TC-NR-04 Mécanismes exclus absents du périmètre PD-295 Anti-régression
INV-295-TR-01 TC-NOM-16 story→domain acceptée à >=0.3 Transition autorisée
INV-295-TR-02 TC-ERR-07 story→global refusée Transition interdite
INV-295-TR-03 TC-NOM-16 story→archived acceptée si stale Transition autorisée
INV-295-TR-04 TC-ERR-07 domain→story refusée Transition interdite
INV-295-TR-05 TC-NOM-16 domain→global acceptée à >=0.6 Transition autorisée
INV-295-TR-06 TC-NOM-16 domain→archived acceptée si stale Transition autorisée
INV-295-TR-07 TC-ERR-07 global→domain refusée Transition interdite
INV-295-TR-08 TC-ERR-07 global→story refusée Transition interdite
INV-295-TR-09 TC-NOM-16 global→archived acceptée si stale Transition autorisée
INV-295-TR-10 TC-ERR-11 archived→story refusée Terminal
INV-295-TR-11 TC-ERR-11 archived→domain refusée Terminal
INV-295-TR-12 TC-ERR-11 archived→global refusée Terminal
INV-295-TR-13 TC-ERR-11 archived→* interdit Terminal absolu

6. Tests de non-régression

Test ID Objet Observable Commentaire
TC-NR-01 Absence de migration moteur de stockage Aucun artefact de migration moteur requis pour PD-295 Conforme hors périmètre
TC-NR-02 Aucune refonte pipeline hors B1..B5 Les flux historiques hors B1..B5 restent inchangés au smoke test Non-régression fonctionnelle
TC-NR-03 Stack cible section 10 respectée Présence Python/FAISS/Ollama/Markdown/YAML, absence Swift/Spring Couvre CA-295-17
TC-NR-04 Mécanismes explicitement exclus restent hors périmètre Aucun comportement PD-295 n’introduit HMAC/Vault/JCS/PII filter/RGPD purge/etc. listés en exclusion Couvre INV-295-16
TC-NR-05 Archive reste exclue après réindexation complète Un learning archivé ne revient pas dans les résultats actifs Renforce INV-295-12

7. Tests négatifs et adversariaux

Test ID Entrée invalide / abus Résultat attendu Observable
TC-NEG-01 Batterie d’entrées invalides D-295-01..D-295-17 (regex, enum, tailles, types) Rejet/exclusion stricts selon colonne “Invalide” §5.1 Logs stderr + absence des entrées invalides dans artefacts
TC-NEG-02 Valeurs hors bornes sur chaque paramètre figé §5.2 Erreur de conformité contractuelle (KO) Verdict de test KO, aucune tolérance implicite
TC-NEG-03 Frontières stale: age=56, age=57, nb_injections=0/1 Seul age>56 ET nb_injections==0 archive Diff scope avant/après exécution
TC-NEG-04 clarification_filename invalide ou clarification_verbatim taille 0/>20000 Persistance refusée Absence de fichier/ligne + stderr
TC-NEG-05 Dimension embedding != 768 Indexation rejetée Erreur explicite + index non publié

8. Observabilité requise pour les tests

  • État système : présence/absence et contenu de data/veille.jsonl, data/clarifications.jsonl, data/learnings-scores.jsonl, learnings-archive.jsonl, index FAISS actifs.
  • Réponse API : sortie step 0 observable avec bloc Markdown à 3 sections, statut de continuation en cas d’erreur source.
  • Journal d’audit : traces stderr horodatées avec identifiant de cas d’erreur et motif de rejet/exclusion.
  • Événement signé / horodaté : horodatage requis; signature d’événement NON APPLICABLE dans le contrat PD-295 actuel.
  • Export probatoire : archive de campagne contenant fixtures, sorties JSONL/Markdown, logs stderr, et verdicts de conformité.

9. Règles non testables

Règle Raison Impact
Politique de tie-break final si similarité et reuse_score sont strictement égaux Non spécifiée en §10.2 (Q-295-03), donc ordre total non contractualisé Majeur
Enum exacte des valeurs autorisées pour project (D-295-04) Type “Enum” déclaré sans liste explicite des valeurs Majeur
Reproductibilité CS-1 post-merge Fenêtre baseline non définie (Q-295-02) Majeur
Procédure de “résolution manuelle” depuis ARCHIVED Mentionnée mais non spécifiée opérationnellement; seule l’interdiction automatique est testable Mineur

10. Verdict QA

  • Testable intégralement
  • Testable partiellement (avec réserves listées)
  • Non testable (refus contractuel)