Aller au contenu

PD-41 — Scénarios de tests contractuels (référence)


📚 Navigation User Story | Document | | | ---------- | -- | | 📋 [Spécification](PD-41-specification.md) | | | 🛠️ [Plan d'implémentation](PD-41-plan.md) | | | 🧪 **Tests** | *(ce document)* | | ✅ [Critères d'acceptation](PD-41-acceptability.md) | | | 📝 [Retour d'expérience](PD-41-rex.md) | | [← Retour à crypto-proof](../PD-189-epic.md) · [↑ Index User Story](index.md)

1. Références

  • Spécification : PD-41-specification.md
  • Epic : EPIC-189
  • Template : PD-XX-tests.md

2. Matrice de couverture

ID Invariant ID Critère ID Test Couverture Commentaire
INV-01 CA8 TC-SEC-01 Oui Vérifie absence d'exposition de secrets (outputs + logs).
INV-01 TC-INV-01 Oui (partiel) Ne prouve pas l'absence de dérivation interne, seulement l'absence de fuite observable.
INV-02 CA5 TC-NOM-02 Oui generateReKey() fonctionne sans clés privées.
INV-02 CA9 TC-SEC-02 Oui/Partiel Refus d'opération nécessitant clé privée ; code d'erreur non spécifié.
INV-03 CA1 TC-ERR-01 Oui formatVersion inconnue → rejet.
INV-03 CA7 TC-VAL-02 Oui Codes d'erreur stables (mêmes entrées).
INV-04 CA7 TC-VAL-02 Oui Déterminisme de validation (mêmes entrées → même verdict).
INV-05 CA11 TC-ERR-06 ⚠️ Partiel / dépendant harness Induction contrôlée d'une erreur Umbral non définie contractuellement.
INV-05 CA2 TC-ERR-02 Oui Rejet sans résultat partiel.
INV-05 CA3 TC-ERR-04 Oui Rejet sans résultat partiel.
INV-05 CA4 TC-ERR-05 Oui Rejet sans résultat partiel.
INV-06 CA13 TC-CTX-01 Oui Contexte obligatoire contextId cohérent entre artefacts.
INV-07 CA10 TC-ERR-07 Oui Limites de taille appliquées (champs, artefacts, requête, cardinalité) avec rejet PAYLOAD_TOO_LARGE ; seuils conseillés en annexe B (informatif).
INV-08 CA8 TC-SEC-01 / TC-AUD-01 Oui Vérifie l'absence de champs interdits en logs/audit et la présence d'une entrée d'audit minimale avec uniquement les champs autorisés.
CA12 TC-NOM-01 Oui Readiness "prêt / non prêt" exact (health).
CA12 TC-ERR-08 Oui Service non prêt → generateReKey() rejeté avec code SERVICE_NOT_READY.
CA5 TC-NOM-02 Oui ReKey conforme au format PRE-1.0 (annexe 11) incluant artefactType, scheme, threshold, kfrags.
CA5 TC-FMT-REKEY-01/02 Oui Rejet des ReKey au format PRE-1.0 invalide (clé publique, threshold/kfrags incohérents).
CA6 TC-NOM-03 Oui ReEncryptedData (CFrag) conforme au format PRE-1.0 (annexe 11) avec capsuleDigest, threshold.
CA6 TC-FMT-CAPS-01 / TC-FMT-CFRAG-01 Oui Rejet des Capsule/CFrag PRE-1.0 invalides (digest, clés, threshold).
CA13 TC-CTX-01 / TC-ERR-09 Oui Acceptation avec contextId cohérent ; rejet INVALID_CONTEXT sinon.
CA7 TC-VAL-01 Oui validate() retourne VALID/INVALID + code(s) stables (codes normatifs).
CA14 TC-VAL-01 Oui Codes d’erreur conformes à la table normative.
CA2 TC-ERR-02 Oui Clé publique invalide rejetée (INVALID_PUBLIC_KEY).
CA3 TC-ERR-04 Oui ReKey incompatible rejetée (REKEY_MISMATCH).
CA4 TC-ERR-05 Oui Capsule/ciphertext invalide rejetée.
CA1 TC-ERR-01 Oui Version non supportée (UNSUPPORTED_VERSION).

Note périmètre : le rejet « Non autorisé » (ancien E8) est hors périmètre du service PRE (authz applicative amont) et n’est pas couvert par les présents scénarios.


3. Scénarios de test – Flux nominaux

Note de testabilité contractuelle : les formats PRE-1.0 des artefacts sont définis en annexe 11 de la spécification. Les tests se basent sur ces schémas (champs obligatoires, longueurs, encodage base64url sans padding) et sur les blocs JSON de référence fournis en section 11 (pas de fichiers séparés).

TEST-ID: TC-NOM-01
Référence spec: Flux N1, CA12

GIVEN
  - Une instance du service PRE déployée.
WHEN
  - On interroge l'endpoint/commande de health/readiness.
THEN
  - La réponse expose :
      - version du service
      - version Umbral
      - statut "prêt" ou "non prêt"
TEST-ID: TC-NOM-02
Référence spec: Flux N2, CA5, INV-02

GIVEN
  - Une clé publique Alice valide.
  - Une clé publique Bob valide.
  - Des paramètres cryptographiques valides (selon contrat effectif du service).
WHEN
  - On appelle generateReKey().
THEN
  - L'appel réussit.
  - La réponse contient un artefact "ReKey" JSON conforme au format PRE-1.0 : `formatVersion="PRE-1.0"`, `artefactType="ReKey"`, `scheme="umbral-v1"`, `ownerPublicKey`/`recipientPublicKey` base64url (44 caractères, clé compressée secp256k1), `threshold.t/n` cohérents, `kfrags` (taille = n, chacun ≤ 1024 octets décodés), `scope` optionnel ≤ 128 caractères.
  - Aucune clé privée n'est exigée ni transmise.
TEST-ID: TC-NOM-03
Référence spec: Flux N3, CA6

GIVEN
  - Un ciphertext valide (ou composant PRE requis par le contrat effectif).
  - Une capsule Umbral valide.
  - Une ReKey valide (issue de TC-NOM-02).
WHEN
  - On appelle reEncrypt().
THEN
  - L'appel réussit.
  - La réponse contient un artefact re-chiffré (CFrag/ReEncryptedData) JSON conforme au format PRE-1.0 : `formatVersion="PRE-1.0"`, `artefactType="CFrag"`, `scheme="umbral-v1"`, `ownerPublicKey`/`recipientPublicKey` base64url (44 caractères), `capsuleDigest` base64url (32 octets décodés, 43 caractères encodés), `threshold.t/n` cohérents, `cfrag` ≤ 1024 octets décodés, `scope` optionnel ≤ 128 caractères.
TEST-ID: TC-CTX-01
Référence spec: INV-06, CA13, Flux N2/N3/N4, annexe 11

GIVEN
  - Des artefacts PRE-1.0 (ReKey, Capsule, CFrag) porteurs du même `contextId` conforme (ASCII 16-128 chars).
WHEN
  - On appelle reEncrypt() ou validate() avec cet ensemble cohérent.
THEN
  - L'appel réussit (si les autres préconditions sont valides).
  - Le `contextId` est présent et identique sur tous les artefacts.
TEST-ID: TC-VAL-01
Référence spec: Flux N4, CA7, INV-04

GIVEN
  - Un artefact de type "clé publique" valide.
WHEN
  - On appelle validate() sur cet artefact.
THEN
  - Le résultat est VALID.
AND
  - Le format de réponse inclut : { verdict ∈ (VALID, INVALID), codes[] }.
TEST-ID: TC-SEC-01
Référence spec: CA8, INV-01/08, Annexe C

GIVEN
  - Un appel nominal à reEncrypt().
WHEN
  - On consulte les outputs et les logs applicatifs/audit.
THEN
  - Aucun champ interdit n'apparaît (plaintext, payload, capsule complète, kfrag/cfrag complets, clés privées, secrets dérivés).
  - Les logs/audit ne contiennent que des champs autorisés (contextId, identifiants de clés, formatVersion, artefactType, code d’erreur, horodatage).
TEST-ID: TC-AUD-01
Référence spec: CA8, INV-08, Annexe C

GIVEN
  - Une opération PRE réussie et une opération PRE en échec.
WHEN
  - On consulte les entrées d’audit correspondantes.
THEN
  - Chaque opération génère une entrée d’audit.
  - Aucune donnée sensible n’apparaît.
  - Le niveau de détail est constant (pas de debug conditionnel).

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

TEST-ID: TC-ERR-01
Référence spec: E1, CA1, S3, INV-03

GIVEN
  - Une requête validate() (ou un appel exposant formatVersion) avec formatVersion inconnue.
WHEN
  - On exécute l'appel.
THEN
  - Le résultat est INVALID / rejet.
  - Le code d'erreur inclut "UNSUPPORTED_VERSION".
  - Aucun artefact partiel n'est retourné comme valide.
TEST-ID: TC-ERR-02
Référence spec: E2, CA2, S4, INV-05

GIVEN
  - Une clé publique mal encodée (ou de taille/courbe non conforme).
WHEN
  - On appelle generateReKey().
THEN
  - L'appel échoue.
  - Le code d'erreur inclut "INVALID_PUBLIC_KEY".
  - La réponse ne contient aucun artefact ReKey partiel exploitable.
TEST-ID: TC-ERR-03
Référence spec: E3 (paramètres invalides), INV-05

GIVEN
  - Des paramètres cryptographiques incohérents (ex: seuil > parts, valeurs hors bornes), selon le contrat effectif.
WHEN
  - On appelle generateReKey().
THEN
  - L'appel échoue avec code `INVALID_PARAMETERS`.
  - La réponse ne contient aucun artefact ReKey/KFrag partiel exploitable.
TEST-ID: TC-FMT-REKEY-01
Référence spec: E2/E4, CA5, annexe 11 (clés publiques)

GIVEN
  - Une ReKey PRE-1.0 avec `ownerPublicKey` ou `recipientPublicKey` de longueur incorrecte (≠ 44 caractères base64url d'une clé compressée secp256k1), bloc JSON `rekey-invalid-key` (section 11).
WHEN
  - On appelle validate() ou reEncrypt() avec cette ReKey.
THEN
  - L'appel est rejeté avec code `INVALID_PUBLIC_KEY` (E2) ou équivalent, sans artefact partiel.
TEST-ID: TC-FMT-REKEY-02
Référence spec: E3/E4, CA3, CA5, annexe 11 (threshold/kfrags)

GIVEN
  - Une ReKey PRE-1.0 avec `threshold.t > threshold.n` ou un nombre de `kfrags` ≠ n, bloc JSON `rekey-invalid-threshold` (section 11).
WHEN
  - On appelle generateReKey() (validation) ou reEncrypt() avec cette ReKey.
THEN
  - L'appel est rejeté (E3/E4) sans artefact partiel exploitable.
TEST-ID: TC-FMT-CAPS-01
Référence spec: E5, CA4, annexe 11 (Capsule)

GIVEN
  - Une Capsule PRE-1.0 avec `ciphertextDigest` de longueur incorrecte (< 32 octets) ou `capsule` hors limite, bloc JSON `capsule-invalid-digest` (section 11).
WHEN
  - On appelle reEncrypt() ou validate() avec cette capsule.
THEN
  - L'appel est rejeté (E5), sans artefact re-chiffré.
TEST-ID: TC-FMT-CFRAG-01
Référence spec: E4/E5, CA6, annexe 11 (CFrag)

GIVEN
  - Un CFrag PRE-1.0 avec `capsuleDigest` non conforme (longueur incorrecte) ou `threshold` incohérent, bloc JSON `cfrag-invalid-digest` (section 11).
WHEN
  - On appelle validate() ou l'assemblage avec la capsule associée.
THEN
  - L'appel est rejeté (E4/E5) sans artefact accepté.
TEST-ID: TC-ERR-04
Référence spec: E4, CA3, S5

GIVEN
  - Une ReKey générée pour Alice→Bob.
  - Une tentative reEncrypt() avec un destinataire incohérent (ex: clés publiques ne correspondant pas au couple).
WHEN
  - On appelle reEncrypt().
THEN
  - L'appel échoue.
  - Le code d'erreur inclut "REKEY_MISMATCH".
TEST-ID: TC-ERR-05
Référence spec: E5, CA4

GIVEN
  - Un ciphertext et/ou une capsule manquants / structure non cohérente.
WHEN
  - On appelle reEncrypt().
THEN
  - L'appel échoue avec code `INVALID_ARTEFACT`.
  - Aucun artefact re-chiffré n'est retourné.
TEST-ID: TC-ERR-06
Référence spec: E6, CA11, INV-05

GIVEN
  - Une condition provoquant une erreur interne Umbral lors d'une opération (échec cryptographique).
WHEN
  - On appelle generateReKey() ou reEncrypt().
THEN
  - L'appel échoue explicitement.
  - Le code d'erreur est `CRYPTO_FAILURE`.
  - Aucun résultat partiel n'est retourné comme valide.
NOTE
  - **Non déterministe** : aucun déclencheur contractuel ne permet de provoquer une erreur Umbral de façon déterministe en black-box ; la couverture est indirecte via les autres rejets fail-closed.
TEST-ID: TC-ERR-07
Référence spec: E7, CA10, S6, INV-07

GIVEN
  - Un artefact ou un champ dépassant une limite de taille applicable (ex: champ kfrag > limite, capsule > limite artefact, ou requête agrégant trop d’artefacts).
  - Les limites existent et sont appliquées à plusieurs niveaux : champs individuels, artefacts PRE, requête globale et cardinalité des éléments.
WHEN
  - On appelle reEncrypt().
THEN
  - L'appel échoue avec code "PAYLOAD_TOO_LARGE".
NOTE
  - Les seuils chiffrés peuvent suivre l'annexe B (informatif) mais le mécanisme de limite et le rejet sont opposables.
  - Le contrôle peut être effectué après décodage (ex: base64) et/ou avant décodage pour prévenir l'inflation d'encodage.
TEST-ID: TC-ERR-08
Référence spec: E8, CA12, S8

GIVEN
  - Umbral indisponible / configuration incorrecte.
WHEN
  - On appelle generateReKey().
THEN
  - L'appel échoue avec code "SERVICE_NOT_READY".
AND
  - L'endpoint/commande readiness indique "non prêt".
TEST-ID: TC-ERR-09
Référence spec: E9, CA13, S9

GIVEN
  - Deux artefacts PRE-1.0 (par ex. ReKey et Capsule) portant des `contextId` différents, absents ou multiples.
WHEN
  - On appelle generateReKey(), reEncrypt() ou validate() avec ces artefacts.
THEN
  - L'appel échoue avec code "INVALID_CONTEXT".
  - Aucun artefact partiel n'est retourné comme valide.

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

Invariant Test(s) dédiés Observable Commentaire
INV-01 (non-divulgation plaintext) TC-INV-01, TC-SEC-01 Sorties API + logs + audit Teste la non fuite. Ne peut pas prouver l'absence de dérivation interne.
INV-02 (pas de clés privées) TC-NOM-02, TC-SEC-02 Requêtes/erreurs Vérifie qu'aucun flux contractuel n'exige une clé privée.
INV-03 (versionnage) TC-ERR-01 Réponse validate / rejet formatVersion inconnue → rejet.
INV-04 (validation déterministe) TC-VAL-02 Résultat stable Mêmes entrées → mêmes verdicts/codes.
INV-05 (fail-closed) TC-ERR-02..06 Absence d'artefacts partiels Tous rejets doivent être complets, sans artefact "semi-valide".
INV-06 (liaison contexte) TC-CTX-01, TC-ERR-09 ContextId cohérent Contexte obligatoire et vérifié (rejet INVALID_CONTEXT sinon).
INV-07 (limites de taille) TC-ERR-07 Code PAYLOAD_TOO_LARGE Contrôle multi-niveaux (champs, artefacts, requête, cardinalité).
INV-08 (audit sans secrets) TC-SEC-01, TC-AUD-01 Logs/audit Absence de champs interdits, audit minimal avec seuls les champs autorisés.

6. Tests de non-régression

Test ID Objet Observable Commentaire
TC-NR-01 Stabilité des codes d'erreur (régressions de contrat) Diff de réponses sur mêmes entrées Rejouer TC-ERR-01/02/04/07 sur chaque version ; toute variation = rupture contractuelle.
TC-NR-02 Stabilité readiness Health/readiness Rejouer TC-NOM-01 après upgrades Umbral/infra.
TC-NR-03 Non fuite en logs Scan logs Rejouer TC-SEC-01 sur chaque build.

7. Tests négatifs et adversariaux

Test ID Entrée invalide / abus Résultat attendu Observable
TC-NEG-01 Payload malicieux : champs inattendus, surcharges JSON, encodages exotiques Rejet fail-closed Réponse API + absence de crash + logs sans secrets
TC-NEG-02 Flood de requêtes (DoS applicatif) Hors périmètre PRE (rate limiting/applicatif amont)
TC-NEG-03 Tentative d'injection de secret dans champs "metadata" Rejet ou acceptation neutre mais aucun secret en logs/audit Logs/audit

Note : la spec impose des limites de taille (INV-07) mais exclut explicitement le rate limiting du périmètre PRE ; TC-NEG-02 est hors périmètre.


8. Observabilité requise pour les tests

Pour rendre les scénarios ci-dessus automatisables, les éléments suivants doivent être observables sans accès au code :

  • Réponse API : status / verdict (VALID/INVALID), codes d'erreur, formatVersion lorsque applicable.
  • Schémas PRE-1.0 : champs obligatoires (artefactType, scheme, ownerPublicKey, etc.), tailles des clés (44 caractères base64url), digests (43 caractères base64url), threshold.t/n, contextId (ASCII 16-128, identique entre artefacts), taille des kfrags/cfrags (≤ 1024 octets décodés), absence de champs additionnels.
  • Limites de taille : existence du mécanisme multi-niveaux (champ, artefact, requête, cardinalité) et rejet PAYLOAD_TOO_LARGE ; vérification possible après décodage et/ou avant décodage (inflation d'encodage).
  • Health/Readiness : version service, version Umbral, état prêt/non prêt.
  • Logs applicatifs & audit : accès en lecture (test env) pour vérifier l'absence de champs interdits (plaintext, payload, capsule/kfrag/cfrag complets, clés privées, secrets dérivés) et la présence exclusive des champs autorisés (contextId, identifiants de clés, formatVersion, artefactType, code d'erreur, horodatage).
  • Traçabilité minimale : existence d'entrées d'audit pour chaque opération (succès/échec) sans exfiltration de données sensibles, avec un niveau de détail constant (pas de debug conditionnel).

11. Blocs JSON contractuels PRE-1.0 (référence)

Blocs à copier tels quels pour les tests TC-NOM-02/03, TC-FMT-REKEY-01/02, TC-FMT-CAPS-01 et TC-FMT-CFRAG-01 (aucun fichier séparé requis).

Bloc rekey-valid

{
  "formatVersion": "PRE-1.0",
  "artefactType": "ReKey",
  "scheme": "umbral-v1",
  "ownerPublicKey": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAh",
  "recipientPublicKey": "AgQGCAoMDhASFBYYGhweICIkJigqLC4wMjQ2ODo8PkBC",
  "contextId": "ctx-doc-123456789",
  "threshold": { "t": 2, "n": 3 },
  "scope": "doc-123",
  "kfrags": [
    "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4_QA",
    "AwYJDA8SFRgbHiEkJyotMDM2OTw_QkVIS05RVFdaXWBjZmlsb3J1eHt-gYSHio2Qk5aZnJ-ipairrrG0t7q9wA",
    "BQoPFBkeIygtMjc8QUZLUFVaX2RpbnN4fYKHjJGWm6Clqq-0ub7DyM3S19zh5uvw9fr_BAkOExgdIicsMTY7QA"
  ]
}

Bloc rekey-invalid-key (clé publique longueur invalide)

{
  "formatVersion": "PRE-1.0",
  "artefactType": "ReKey",
  "scheme": "umbral-v1",
  "ownerPublicKey": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyA",  // 1 char manquant
  "recipientPublicKey": "AgQGCAoMDhASFBYYGhweICIkJigqLC4wMjQ2ODo8PkBC",
  "contextId": "ctx-doc-123456789",
  "threshold": { "t": 2, "n": 3 },
  "kfrags": []
}

Bloc rekey-invalid-threshold (threshold/kfrags incohérents)

{
  "formatVersion": "PRE-1.0",
  "artefactType": "ReKey",
  "scheme": "umbral-v1",
  "ownerPublicKey": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAh",
  "recipientPublicKey": "AgQGCAoMDhASFBYYGhweICIkJigqLC4wMjQ2ODo8PkBC",
  "contextId": "ctx-doc-123456789",
  "threshold": { "t": 3, "n": 2 },
  "kfrags": [
    "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4_QA"
  ]
}

Bloc capsule-valid

{
  "formatVersion": "PRE-1.0",
  "artefactType": "Capsule",
  "scheme": "umbral-v1",
  "ownerPublicKey": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAh",
  "contextId": "ctx-doc-123456789",
  "ciphertextDigest": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyA",
  "capsule": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4_QEFCQ0RFRkdISUpLTE1OT1A",
  "scope": "doc-123"
}

Bloc capsule-invalid-digest (digest trop court)

{
  "formatVersion": "PRE-1.0",
  "artefactType": "Capsule",
  "scheme": "umbral-v1",
  "ownerPublicKey": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAh",
  "contextId": "ctx-doc-123456789",
  "ciphertextDigest": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHy",  // longueur < 32 octets
  "capsule": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4_QEFCQ0RFRkdISUpLTE1OT1A"
}

Bloc cfrag-valid

{
  "formatVersion": "PRE-1.0",
  "artefactType": "CFrag",
  "scheme": "umbral-v1",
  "ownerPublicKey": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAh",
  "recipientPublicKey": "AgQGCAoMDhASFBYYGhweICIkJigqLC4wMjQ2ODo8PkBC",
  "contextId": "ctx-doc-123456789",
  "capsuleDigest": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyA",
  "threshold": { "t": 2, "n": 3 },
  "cfrag": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4_QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9g"
}

Bloc cfrag-invalid-digest (capsuleDigest non conforme)

{
  "formatVersion": "PRE-1.0",
  "artefactType": "CFrag",
  "scheme": "umbral-v1",
  "ownerPublicKey": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAh",
  "recipientPublicKey": "AgQGCAoMDhASFBYYGhweICIkJigqLC4wMjQ2ODo8PkBC",
  "contextId": "ctx-doc-123456789",
  "capsuleDigest": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHy",  // longueur < 32 octets
  "threshold": { "t": 2, "n": 3 },
  "cfrag": "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4_QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9g"
}


9. Règles non testables

Règle Raison Impact
CA9 : "refuse toute opération nécessitant une clé privée" (codes) La spec n'impose pas un code d'erreur normé ni un format de requête "avec clé privée" ; testable sur le rejet, pas sur le diagnostic. Mineur (observabilité du motif)
CA11 / E6 : "erreur Umbral" (provoquer déterministement) Aucune procédure contractuelle ne décrit comment provoquer une erreur interne Umbral en environnement de test. Mineur à Majeur selon exigences d'audit (si test obligatoire)

10. Verdict QA

  • ⚠️ Testable partiellement (avec réserves listées)
  • Les invariants/critères principaux sont couverts par des scénarios automatisables.
  • Réserves bloquantes pour une preuve de conformité "sans interprétation" :
    • INV-06 (liaison contexte) non testable faute de définition.
    • INV-07 / CA10 (limites de taille) testables seulement de façon qualitative, pas normative.