Aller au contenu

PD-295 — Tests v3

1. Références

  • Spécification : PD-295-specification-v3.md
  • Epic : tooling
  • JIRA : PD-295

2. Matrice de couverture

ID Invariant ID Critère ID Test Couverture Commentaire
INV-295-01 CA-295-02 TC-NOM-02, TC-NR-03 Oui Stack inchangée, dim 768.
INV-295-02 TC-NR-01, TC-NR-02 Oui Non-régression skills + compounder.
INV-295-03 CA-295-01, CA-295-03 TC-NOM-01, TC-NOM-03 Oui Corpus veille + filtres.
INV-295-04 CA-295-04, CA-295-05 TC-NOM-04 Oui Persistance local + Ringbearer.
INV-295-05 CA-295-04 TC-NOM-05 Oui Verbatim + schéma clarifications.
INV-295-06 CA-295-07 TC-NOM-07 Oui Parallèle, source inchangée.
INV-295-07 CA-295-08 TC-NOM-07 Oui Formule tanh bornée.
INV-295-08 CA-295-09 TC-NOM-10 Oui scope présent partout.
INV-295-09 CA-295-10 TC-NOM-11, TC-NOM-11-bis Oui Promotions + blocage nb_domains=0.
INV-295-10 CA-295-11 TC-NOM-12 Oui Éviction contractuelle stricte.
INV-295-11 CA-295-10 TC-ERR-13, TC-NEG-08 Oui Transitions interdites rejetées.
INV-295-12 CA-295-12, CA-295-13 TC-NOM-13 Oui 3 sections + 5/3/3 + “aucun résultat”.
INV-295-13 CA-295-14 TC-NOM-14 Oui Traces par source/story/step/domain/project.
INV-295-14 CA-295-06, CA-295-25 TC-NOM-06, TC-NOM-13, TC-ERR-04 Oui Flags obligatoires + propagation B5.
INV-295-15 CA-295-15 TC-NOM-15, TC-NR-04 Oui Ordre reindex-all.
INV-295-16 TC-ERR-08, TC-NOM-10-bis Oui Commit requis seulement si migration effective.
INV-295-17 CA-295-20, CA-295-27 TC-NOM-16, TC-NOM-24, TC-NOM-32 Oui Baseline + delta CS-1.
INV-295-18 CA-295-16 TC-NOM-17, TC-NOM-18, TC-NOM-19, TC-NOM-20, TC-ERR-09, TC-ERR-10, TC-ERR-11 Oui Double lock + arbitrage quota/idempotence.
INV-295-19 CA-295-08 TC-NOM-09, TC-NOM-25 Oui Jointure {story,gate,tag_hash} + fallback.
INV-295-20 CA-295-22, CA-295-24 TC-NOM-14, TC-NOM-26, TC-NOM-26-bis, TC-NOM-28, TC-ERR-14, TC-ERR-14-bis Oui Vault key + version active/archivée + fail-closed.
INV-295-21 CA-295-23, CA-295-26 TC-NOM-27, TC-NOM-27-bis, TC-ERR-14 Oui Purge 3 déclencheurs.
INV-295-22 CA-295-21 TC-NOM-08, TC-ERR-16 Oui Top3 obligatoire + observable d’échec.
INV-295-23 TC-NEG-03 Oui count == len(result_ids).

3. Scénarios de test – Flux nominaux

Préconditions communes : horloge UTC figée, fixtures versionnées, environnement isolé réinitialisé.

TEST-ID: TC-NOM-01
Référence spec: INV-295-03, CA-295-01, §5.1.2
GIVEN un lot veille valide
WHEN collecte B1 vers data/veille.jsonl
THEN nombre d’entrées identique et schéma conforme
AND aucun rejet journalisé
TEST-ID: TC-NOM-02
Référence spec: INV-295-01, CA-295-02, §5.2
GIVEN corpus veille valide
WHEN indexation B1
THEN index FAISS lisible en dim 768
AND toute autre dimension rejetée
TEST-ID: TC-NOM-03
Référence spec: INV-295-03, CA-295-03, §5.5
GIVEN index veille hétérogène
WHEN recherche --impact fort --verdict signal
THEN tous les résultats respectent les filtres
AND aucun hors filtre
TEST-ID: TC-NOM-04
Référence spec: INV-295-04, CA-295-04, CA-295-05, §5.6
GIVEN step 0 local et Ringbearer + 4 réponses PO
WHEN phase clarification se termine
THEN PD-XX-clarifications.md écrit dans les 2 modes
AND horodatage clarification <= début rédaction besoin
TEST-ID: TC-NOM-05
Référence spec: INV-295-05, §5.1.3, §5.3.1
GIVEN réponses PO UTF-8 multi-lignes
WHEN persistance + collecte JSONL clarifications
THEN Q1..Q4 conservées verbatim (égalité binaire)
AND data/clarifications.jsonl conforme au schéma canonique
TEST-ID: TC-NOM-06
Référence spec: INV-295-14, CA-295-06, §5.6
GIVEN corpus clarifications multi-domaines/projets
WHEN search-clarifications --domain D --project P
THEN exécution réussie avec résultats strictement (D,P)
AND trace source=clarification émise
TEST-ID: TC-NOM-07
Référence spec: INV-295-06, INV-295-07, CA-295-07, CA-295-08, §5.7
GIVEN hash H0 de learnings.jsonl et cas contrôlés
WHEN compute-learning-scores.py
THEN learnings-scores.jsonl écrit et hash final == H0
AND reuse_score respecte tanh(reuse_score_brut/10)
TEST-ID: TC-NOM-08
Référence spec: INV-295-22, CA-295-21, §5.7
GIVEN learnings-scores.jsonl peuplé
WHEN /morning exécuté
THEN sortie contient exactement 3 learnings top reuse_score
AND code retour = 0
TEST-ID: TC-NOM-09
Référence spec: INV-295-19, §5.1.4, §5.7
GIVEN 3 learnings et seulement 2 scores
WHEN search-learnings.py
THEN jointure par {story,gate,tag_hash}
AND learning sans score reçoit reuse_score=0.0 sans blocage
TEST-ID: TC-NOM-10
Référence spec: INV-295-08, CA-295-09, §5.8
GIVEN learnings historiques sans scope + commit préalable valide
WHEN migration B4
THEN toutes les lignes ont scope valide
AND aucune ligne sans scope
TEST-ID: TC-NOM-10-bis
Référence spec: INV-295-16, §5.8
GIVEN learnings déjà migrés (aucune ligne sans scope)
WHEN exécution B4 périodique sans nouveau commit
THEN pas de refus ERR-295-08
AND promotion/éviction continuent normalement
TEST-ID: TC-NOM-11
Référence spec: INV-295-09, CA-295-10, §5.4
GIVEN learnings aux seuils 0.29/0.30/0.59/0.60
WHEN promotion B4
THEN story->domain si score>=0.30 && nb_domains>=1
AND domain->global si score>=0.60 && nb_domains>=2
TEST-ID: TC-NOM-11-bis
Référence spec: INV-295-09, §3, §5.4
GIVEN learning avec reuse_score>=0.30 mais nb_domains=0
WHEN promotion B4
THEN aucune promotion story->domain
AND scope reste story
TEST-ID: TC-NOM-12
Référence spec: INV-295-10, CA-295-11, §5.8
GIVEN (a)57j/0inj, (b)56j/0inj, (c)57j/1inj
WHEN archivage B4
THEN seule (a) est archivée
AND (b)/(c) restent actives
TEST-ID: TC-NOM-13
Référence spec: INV-295-12, INV-295-14, CA-295-12, CA-295-13, CA-295-25, §5.9
GIVEN 3 sources disponibles, une source à count=0
WHEN injection B5 step 0
THEN bloc markdown 3 sections
AND cardinalités strictes: learnings=5, veille=3, clarifications=3
AND commande clarification observée avec --domain --project --top-k 3
AND section à count=0 affiche "aucun résultat"
TEST-ID: TC-NOM-14
Référence spec: INV-295-13, INV-295-20, CA-295-14, CA-295-22, §5.1.6
GIVEN exécution B5 avec --trace
WHEN lecture learnings-injections.jsonl
THEN 1 trace par source (learning/veille/clarification)
AND champs event,timestamp,story_id,step,source,domain,project,operation,key_version,signature présents
AND vérification HMAC valide
TEST-ID: TC-NOM-15
Référence spec: INV-295-15, CA-295-15, §5.5, §5.6
GIVEN reindex-all instrumenté
WHEN réindexation globale
THEN contracts/specs/plans avant veille/clarifications
AND ordre vérifiable en logs
TEST-ID: TC-NOM-16
Référence spec: INV-295-17, §5.7
GIVEN dataset injections + Gate 8 GO v1
WHEN analyze-compounding.py
THEN rapport ventilé par source
AND export probatoire disponible
TEST-ID: TC-NOM-17
Référence spec: INV-295-18, CA-295-16, §5.12
GIVEN B4 (EX+EX), B3 (SH+EX), B5 (SH+SH) en concurrence
WHEN exécutions parallèles
THEN ordre d’acquisition learnings->scores respecté
AND absence d’artefacts partiels
AND timeout 30s => ERR-295-09 fail-closed
TEST-ID: TC-NOM-18
Référence spec: INV-295-18, §5.9, §5.12
GIVEN 3 requêtes valides déjà acceptées dans 5 min glissantes
WHEN 4e requête step 0 soumise avec query différente
THEN rejet en premier par rate-limit (ERR-295-11)
AND idempotence n’est évaluée qu’après quota valide
TEST-ID: TC-NOM-19
Référence spec: INV-295-18, §5.12
GIVEN rejet quota pour story A
WHEN requête story B dans même fenêtre
THEN story B non impactée (isolation quota)
AND si quota OK, idempotence fonctionne normalement
TEST-ID: TC-NOM-20
Référence spec: INV-295-18, §5.12
GIVEN orphelins > orphan_threshold
WHEN job réconciliation
THEN MEMORY_DEGRADED + rattrapage
AND retour MEMORY_HEALTHY après 2 cycles conformes
TEST-ID: TC-NOM-21
Référence spec: CA-295-17, §7 bis
GIVEN fenêtre T+90j post-B5
WHEN measure-cs2.sh --window 90d
THEN CS-2 calculé selon formule contractuelle
AND valeur >= 30%
TEST-ID: TC-NOM-22
Référence spec: CA-295-18, §7 bis
GIVEN fenêtre mensuelle glissante
WHEN measure-cs3.sh
THEN occurrences clarification réutilisée calculées
AND valeur >= 1/mois
TEST-ID: TC-NOM-23
Référence spec: CA-295-19, §7 bis
GIVEN 5 premières stories post-B5
WHEN measure-cs4.sh
THEN nb stories avec veille impact fort|modere injectée calculé
AND valeur >= 5/5
TEST-ID: TC-NOM-24
Référence spec: CA-295-20, INV-295-17
GIVEN date merge B5 + 10 stories pré + 10 post (fixture)
WHEN measure-cs1-baseline.py + calcul CS-1
THEN baseline gelée pré-B5
AND delta CS-1 calculé reproductiblement
TEST-ID: TC-NOM-25
Référence spec: INV-295-19, §3, §5.1.5
GIVEN tags réordonnés équivalents
WHEN calcul tag_hash + jointure scores
THEN tag_hash identique et learning_id stable
AND tri secondaire par reuse_score déterministe
TEST-ID: TC-NOM-26
Référence spec: INV-295-20, CA-295-22
GIVEN événements B1..B5 signés
WHEN vérification avec clé Vault active
THEN toutes signatures valides
AND key_version active cohérente
TEST-ID: TC-NOM-26-bis
Référence spec: INV-295-20, §5.1.6
GIVEN événement historique signé avec key_version archivée
WHEN vérification audit
THEN vérificateur charge la clé depuis kv/pd-295/memory-audit-hmac/archive/{date}
AND signature valide
TEST-ID: TC-NOM-27
Référence spec: INV-295-21, CA-295-23
GIVEN clarifications à 17/18/19 mois
WHEN purge-clarifications.py via step 10
THEN 19 mois purgé
AND 17/18 mois conservés (règle >18)
TEST-ID: TC-NOM-27-bis
Référence spec: INV-295-21, CA-295-26
GIVEN stories REJECTED et DONE_WITH_ANOMALY + cron actif
WHEN hook on_story_close puis cron quotidien
THEN purge déclenchée dans les deux cas
AND traces distinctes des 3 déclencheurs (step10/hook/cron)
TEST-ID: TC-NOM-28
Référence spec: §5.4, CA-295-24, INV-295-20
GIVEN learning en archive
WHEN restore-learning.py --id <learning_id>
THEN learning restauré scope=story
AND événement audit signé avec key_version Vault
TEST-ID: TC-NOM-29
Référence spec: CA-295-17, §7 bis
GIVEN datasets learnings pré-B5 + injections fenêtre 90j
WHEN measure-cs2.sh
THEN formule CS-2 appliquée strictement
AND résultat reproductible
TEST-ID: TC-NOM-30
Référence spec: CA-295-18, §7 bis
GIVEN événements clarifications sur 30j glissants
WHEN measure-cs3.sh
THEN formule CS-3 appliquée strictement
AND stories contributrices listées
TEST-ID: TC-NOM-31
Référence spec: CA-295-19, §7 bis
GIVEN 5 premières stories post-B5 identifiées
WHEN measure-cs4.sh
THEN formule CS-4 appliquée strictement
AND résultat >=5/5 requis
TEST-ID: TC-NOM-32
Référence spec: CA-295-27, INV-295-17
GIVEN baseline CS-1 gelée + 10 stories post-B5 réelles
WHEN calcul production CS-1
THEN CS-1 > 0
AND méthode identique à TC-NOM-24

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

TEST-ID: TC-ERR-01
Référence spec: ERR-295-01
GIVEN story/domain/project invalide
WHEN exécution commande
THEN rejet explicite + zéro écriture
TEST-ID: TC-ERR-02
Référence spec: ERR-295-02, §5.1.3
GIVEN clarification frontmatter invalide
WHEN collecte/indexation
THEN fichier ignoré + log explicite
TEST-ID: TC-ERR-03
Référence spec: ERR-295-03
GIVEN enum invalide
WHEN ingestion/recherche
THEN rejet/exclusion selon contexte
TEST-ID: TC-ERR-04
Référence spec: ERR-295-04, INV-295-14
GIVEN search-clarifications sans --domain ou --project
WHEN exécution
THEN rejet non exécutable
TEST-ID: TC-ERR-05
Référence spec: ERR-295-05
GIVEN 1 source indisponible, 2 disponibles
WHEN B5 step 0
THEN injection partielle maintenue + trace dégradée
TEST-ID: TC-ERR-06
Référence spec: ERR-295-06
GIVEN 3 sources indisponibles
WHEN B5 step 0
THEN blocage explicite
TEST-ID: TC-ERR-07
Référence spec: ERR-295-07
GIVEN learnings-scores.jsonl absent
WHEN promotion B4
THEN promotion désactivée + scopes inchangés
TEST-ID: TC-ERR-08
Référence spec: ERR-295-08, INV-295-16
GIVEN migration scope requise sans commit préalable
WHEN B4
THEN refus migration + aucun fichier modifié
TEST-ID: TC-ERR-09
Référence spec: ERR-295-09, INV-295-18
GIVEN lock requis non obtenable en 30s
WHEN opération critique
THEN fail-closed explicite + aucun effet de bord
TEST-ID: TC-ERR-10
Référence spec: ERR-295-10
GIVEN même clé idempotence + query_hash différent
WHEN rejeu dans fenêtre idempotence
THEN rejet conflit + pas de doublon
TEST-ID: TC-ERR-11
Référence spec: ERR-295-11
GIVEN quota 3/5min glissantes déjà atteint
WHEN nouvelle requête step 0
THEN rejet quota explicite
TEST-ID: TC-ERR-11-bis
Référence spec: ERR-295-18
GIVEN réponses PO incomplètes
WHEN po_question_timeout atteint
THEN step 0 interrompu
TEST-ID: TC-ERR-12
Référence spec: ERR-295-12
GIVEN échec écriture trace
WHEN injection B5
THEN injection maintenue + observabilité dégradée
TEST-ID: TC-ERR-13
Référence spec: INV-295-11, §5.4
GIVEN transition interdite demandée
WHEN exécution
THEN rejet explicite + état inchangé
TEST-ID: TC-ERR-14
Référence spec: ERR-295-13, INV-295-20
GIVEN signature absente/invalide ou key_version incohérente
WHEN vérification audit
THEN événement rejeté + alerte audit
TEST-ID: TC-ERR-14-bis
Référence spec: ERR-295-16, INV-295-20
GIVEN Vault indisponible au démarrage
WHEN commande /gov nécessitant audit est lancée
THEN fail-closed ERR-295-16
AND aucun événement audit n’est émis
TEST-ID: TC-ERR-15
Référence spec: ERR-295-15
GIVEN restore-learning.py --id absent/invalide
WHEN exécution
THEN rejet explicite + aucun mouvement archive/actif
TEST-ID: TC-ERR-16
Référence spec: ERR-295-19, INV-295-22
GIVEN /morning ne peut produire 3 entrées (fichier vide/incomplet)
WHEN exécution
THEN échec explicite (code retour !=0) avec ERR-295-19

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

Invariant Test(s) dédiés Observable
INV-295-01 TC-NOM-02, TC-NR-03 Dim 768 + stack
INV-295-02 TC-NR-01, TC-NR-02 Non-régression
INV-295-03 TC-NOM-01, TC-NOM-03 Corpus + filtres
INV-295-04 TC-NOM-04 Persistance tous modes
INV-295-05 TC-NOM-05 Verbatim
INV-295-06 TC-NOM-07 Fichier parallèle
INV-295-07 TC-NOM-07 Formule tanh
INV-295-08 TC-NOM-10 Scope partout
INV-295-09 TC-NOM-11, TC-NOM-11-bis Promotion non vacuous
INV-295-10 TC-NOM-12 Éviction story
INV-295-11 TC-ERR-13, TC-NEG-08 Rejet transitions interdites
INV-295-12 TC-NOM-13 3 sections + 5/3/3
INV-295-13 TC-NOM-14 Traces complètes
INV-295-14 TC-NOM-06, TC-NOM-13, TC-ERR-04 Flags obligatoires + propagation
INV-295-15 TC-NOM-15 Ordre reindex
INV-295-16 TC-ERR-08, TC-NOM-10-bis Commit requis si migration effective
INV-295-17 TC-NOM-16, TC-NOM-24, TC-NOM-32 CS-1 + ventilation
INV-295-18 TC-NOM-17, TC-NOM-18, TC-NOM-19, TC-NOM-20, TC-ERR-09, TC-ERR-10, TC-ERR-11 Locks + quota + idempotence
INV-295-19 TC-NOM-09, TC-NOM-25 Jointure canonique + fallback
INV-295-20 TC-NOM-14, TC-NOM-26, TC-NOM-26-bis, TC-NOM-28, TC-ERR-14, TC-ERR-14-bis Vault/HMAC/version
INV-295-21 TC-NOM-27, TC-NOM-27-bis, TC-ERR-14 Rétention multi-déclencheurs
INV-295-22 TC-NOM-08, TC-ERR-16 /morning top3 observable
INV-295-23 TC-NEG-03 count/result_ids cohérents

6. Tests de non-régression

Test ID Objet Observable
TC-NR-01 4 skills recherche existants Contrat E/S inchangé
TC-NR-02 gov-compounder compatible ascendant Exécution historique sans erreur
TC-NR-03 Stack non migrée Aucun artefact hors stack
TC-NR-04 reindex-all conserve phases historiques contracts/specs/plans avant nouvelles phases

7. Tests négatifs et adversariaux

Test ID Entrée invalide / abus Résultat attendu Observable
TC-NEG-01 source_path veille traversal (../../x.md) Ligne exclue + log Index propre
TC-NEG-02 Casse invalide (pd-295, Tooling) Rejet ERR-295-01 Zéro écriture
TC-NEG-03 count>0 avec result_ids[] vide Événement ignoré audit_inconsistent_trace
TC-NEG-04 query > 500 chars Rejet ERR-295-17 Erreur explicite
TC-NEG-05 scope=team Rejet migration/promotion Scope inchangé
TC-NEG-06 Âge exactement 56 jours, 0 injection Pas d’archivage Entrée active
TC-NEG-07 reuse_score=0.299 puis 0.300 Pas de promotion puis promotion Seuil binaire
TC-NEG-08 Tentative DOMAIN_ACTIVE -> STORY_ACTIVE auto Rejet État inchangé
TC-NEG-09 Saturation quota story A Story B non impactée Isolation
TC-NEG-10 Rejeu après fenêtre idempotence Accepté comme nouvelle tentative Nouvelle trace
TC-NEG-11 Lockfile orphelin mtime>60s Nettoyage puis acquisition Séquence cohérente
TC-NEG-12 Coefficients B3 différents de 0.40/0.40/0.20 Rejet config Erreur explicite
TC-NEG-13 Même clé idempotence, payload altéré ERR-295-10 Conflit détecté
TC-NEG-14 Signature HMAC altérée Rejet audit ERR-295-13
TC-NEG-15 restore-learning.py sans --id Rejet argument Aucun mouvement d’état
TC-NEG-16 Modification tags historique (dérive learning_id) Exclusion scoring learning_id_drift

8. Observabilité requise pour les tests

  • État système : hash avant/après learnings.jsonl, learnings-scores.jsonl, learnings-archive.jsonl, état mémoire (MEMORY_DEGRADED/HEALTHY), état locks.
  • Réponse CLI : code retour, ERR-295-xx, message explicite, timestamp UTC.
  • Journal audit : événements RFC3339 UTC avec story_id, step, source, operation, key_version.
  • Signature : signature_hmac_sha256 valide ; clé Vault lue via kv/pd-295/memory-audit-hmac, archive vérifiée pour versions historiques.
  • Export probatoire : fixtures hashées, sorties, logs, rapport compounding, baseline CS-1, résultats CS-⅔/4.

9. Règles non testables

Règle Raison Impact
CA-295-17 Horizon T+90j réel Vérification continue
CA-295-18 Fenêtre mensuelle réelle Vérification continue
CA-295-19 Dépend des 5 premières stories réelles post-B5 Vérification continue
CA-295-27 Dépend de 10 stories post-B5 réelles Vérification continue

10. Verdict QA

  • Gate 8 : testable sur invariants techniques, sécurité audit Vault, et contrat d’orchestration.
  • Post-merge : CS-⅔/4 suivis en continu, CS-1 recalculé sur fenêtre glissante.

Changelog v2→v3

  • G3v2-B1 : ajout TC-NOM-26-bis et TC-ERR-14-bis ; TC-NOM-26/TC-ERR-14 alignés sur Vault + key_version.
  • G3v2-M1 : ajout TC-NOM-11-bis (blocage promotion si nb_domains==0).
  • G3v2-M2 : TC-NOM-13 durci avec cardinalité clarifications = 3.
  • G3v2-M3 : ajout TC-NOM-29/30/31 pour formules CS-2/CS-3/CS-4.
  • G3v2-M4 : TC-NOM-17 étendu aux locks B3 sur deux lockfiles.
  • G3v2-M5 : TC-NOM-13 vérifie propagation --domain --project --top-k 3.
  • G3v2-M6 : ajout TC-NOM-27-bis (purge via hook on_story_close + cron).
  • G3v2-M7 : TC-NOM-18 + TC-ERR-11 valident arbitrage rate-limit avant idempotence.
  • G3v2-M8 : TC-NOM-05 vérifie le schéma data/clarifications.jsonl.
  • G3v2-M9 : TC-NOM-28 vérifie que restore utilise la même politique clé Vault.
  • G3v2-M10 : TC-NEG-04 aligné sur ERR-295-17 QUERY_TOO_LONG.
  • G3v2-M11 : TC-NEG-03 aligné sur count == len(result_ids) avec log audit_inconsistent_trace.
  • Corrections mineures intégrées : TC-NOM-10-bis (migration one-shot), TC-ERR-16 (/morning observable), TC-NEG-12 rendu atteignable, TC-NEG-16 (dérive learning_id).