PD-299 — Review de specification¶
Review effectuée en mode FACTUEL. Aucune correction proposée, aucune reformulation, aucune implémentation. Seuls les écarts sont listés.
1. Périmètre de la review¶
- Documents audités :
PD-299-specification.md(révision 2026-04-23 21:58).PD-299-tests.md(révision 2026-04-23 21:58) — limité aux ambiguïtés, contradictions, règles non testables a priori, hypothèses dangereuses, risques sécurité/conformité, sans conclure sur la couverture.- Domaine de la story :
workflow(confirmé pardocs/epics/workflow/PD-299-consolidation-pd298/). La note contextuellecrypto-proofne s'applique PAS. - Portée cible :
ProbatioVault-app(A1..A8) +ProbatioVault-ia-governance(B1..B6) + scope partielProbatioVault-backend(B2 uniquement, cf. §10.1). - Rappel : la spec v1 ambiguïté
min(raw,6.0)dans le diagramme a été corrigée (le Mermaid écrit désormaistest_coverage:=6.0 (exact, ignore raw)), elle n'est donc plus reprise ici.
2. Écarts — Ambiguïtés¶
E-AMB-01 — Terminologie « cap » vs forçage exact¶
Type : Ambiguïté
Référence : specification §3 (Définitions « Cap Gate 8 »), §4 INV-299-12, §5.5 F-299-08, §6 ERR-299-08 + tests TC-NOM-11, TC-ERR-08, TC-NR-03
Description :
§3 définit « Cap Gate 8 : Règle imposant `test_coverage = 6.0` exactement en cas de zéro test ». Sémantiquement un « cap » est un plafond (valeur finale = min(raw, cap)). Or :
- INV-299-12 impose « forcé à exactement 6.0 ».
- F-299-08 impose « forcé à exactement 6.0, quelle que soit la valeur brute ».
- TC-NOM-11 Cas B (raw=4.2) exige un score final=6.0 (donc un relèvement, pas un plafonnement).
Le mot « cap » coexiste avec une sémantique d'« assignation exacte » qui n'est pas un plafonnement.
Impact :
Lecture contradictoire possible pour l'implémenteur : un cap « classique » (min) produirait 4.2 là où la règle attendue est 6.0. Risque d'interprétation divergente dans une équipe tierce, y compris lors d'audits futurs. Le glossaire §3 est directement contredit par les invariants §4.
Gravité : Majeur
E-AMB-02 — Taille minimale de companion_injected_block contradictoire (§5.1 vs §5.2)¶
Type : Ambiguïté
Référence : specification §5.1 D-299-19, §5.2 paramètre `companion_context_addition`
Description :
- §5.1 D-299-19 déclare la taille : `1..2048 bytes additionnels` (minimum = 1).
- §5.2 paramètre `companion_context_addition` déclare : `min=0`, `max=2` KiB.
Les deux bornes inférieures divergent (1 byte vs 0 KiB). L'unité diffère également (`bytes` vs `KiB`) sans conversion explicite.
Impact :
Une implémentation qui accepte un bloc vide (0 KiB) satisferait §5.2 et violerait §5.1. Non-déterminisme sur le seuil de rejet `ERR-299-11` (« Story companion sans source canonique exploitable »). Le test TC-NOM-13 assert `<= 2 KiB` mais ne borne pas le minimum.
Gravité : Majeur
E-AMB-03 — Glob de comptage test_file_count non qualifié (profondeur)¶
Type : Ambiguïté
Référence : specification §3 (Définitions « Zéro test »), §4 INV-299-12, §5.1 D-299-14, §5.5 F-299-08, §6 ERR-299-08 + tests TC-NOM-11, TC-ERR-08, TC-NEG-09
Description :
Le glob imposé est `*.{test,spec}.{ts,tsx}` sans précision de récursivité. Dans la plupart des shells/outils (POSIX, Node glob par défaut, `find` sans `-maxdepth`), ce motif seul ne traverse pas les sous-dossiers. `**/*.{test,spec}.{ts,tsx}` aurait été univoque.
Impact :
- Si le glob est interprété non récursif : un projet dont les tests sont sous `src/sharing/__tests__/foo.test.ts` donne `test_file_count=0`, déclenche la règle déterministe INV-299-12 (forçage 6.0, NON_CONFORME) à tort.
- TC-NEG-09 stipule « Module contenant uniquement `foo.spec.tsx` » sans chemin explicite, reproduisant l'ambiguïté côté tests.
Gravité : Bloquant (risque de faux positif déterministe avec blocage Gate 8).
E-AMB-04 — Échelle de l'évaluation : « module » vs « projet »¶
Type : Ambiguïté
Référence : specification §3 (Définitions « Zéro test » : « sur le module livré »), §4 INV-299-12 (« si projet ∈ {app,backend} »), §5.5 F-299-08 (« Pour autres projets : scoring arithmétique standard »), §5.1 D-299-14, §5.2 paramètre `gate8_zero_test_trigger`
Description :
La règle change d'échelle entre sections :
- §3 parle de comptage « sur le module livré ».
- §4 INV-299-12 conditionne sur `project_code`.
- §5.5 F-299-08 parle de « projet ».
`cross_module_point_path` et §5.6 parlent explicitement de « module ». La relation entre « module livré » et `project_code` n'est ni précisée (sous-dossier ? racine ? module npm ?), ni mappée dans le modèle de données §5.1.
Impact :
Indéterminisme sur le périmètre de comptage : pour PD-299 qui livre sur `ProbatioVault-app` + `ProbatioVault-ia-governance` + partiellement `ProbatioVault-backend` (scope B2), faut-il compter les tests de tout le projet `app` ou seulement de `src/sharing/` ? Le test TC-NOM-11 ne précise pas de chemin (`project_code=app, test_file_count=0` sans cible).
Gravité : Bloquant
E-AMB-05 — « Non-répudiation minimale » non définie techniquement¶
Type : Ambiguïté
Référence : specification §4 INV-299-09, §5.5 F-299-11, §5.1 D-299-21
Description :
INV-299-09 et F-299-11 utilisent la formule « non-répudiation minimale via trace Atlassian ». Le terme « non-répudiation » a une définition normative (ISO/IEC 10181-4, eIDAS) qui implique signature cryptographique ou mécanisme équivalent. Un commentaire Jira (`jira_comment_id`) n'apporte pas de non-répudiation au sens normatif : authentification par cookie/token, compte potentiellement compromis, possibilité de suppression/édition côté admin Atlassian.
Impact :
Le terme « non-répudiation » crée une ambiguïté juridique/audit. Un auditeur interprétant la formule au sens normatif rejettera la preuve D-299-21. Voir aussi §10.2 qui exclut explicitement « preuve cryptographique d'intention », ce qui contredit le mot « non-répudiation » employé en §4.
Gravité : Majeur
E-AMB-06 — approver_id : deux formats acceptés sans discriminant formel¶
Type : Ambiguïté
Référence : specification §5.1 D-299-21 (« approver_id = email ou Jira username »)
Description :
Deux formats sont autorisés (email RFC 5322 ou Jira username) sans regex discriminante, sans règle de choix, sans contrainte sur la collision possible entre les deux espaces de nommage Jira (username & email).
Impact :
L'observabilité de l'assertion TC-NOM-18 « approver_id (email ou Jira username) » n'a pas d'observable strict : une valeur `admin` est-elle valide ? `jean.dupont@exemple.com` ou `jean.dupont` ? Deux approbations distinctes peuvent viser le même humain sous deux identifiants sans être détectées comme doublons.
Gravité : Majeur
E-AMB-07 — Relation « story companion → story source » non définie¶
Type : Ambiguïté
Référence : specification §3 (Définition « Story companion »), §4 INV-299-14, §5.5 F-299-09, §9 H-299-01, §6 ERR-299-11 + tests TC-NOM-13, TC-ERR-11
Description :
§3 définit « Story companion : Story dépendante d'une story source, nécessitant reprise explicite des arbitrages/invariants de la source ». La spécification ne décrit AUCUN mécanisme pour :
- déterminer qu'une story donnée EST companion ;
- résoudre `story_source_id` à partir de `companion_story_id` ;
- établir la relation de manière auditable (référence dans le besoin ? dans le plan ? en métadonnée Jira ?).
H-299-01 se contente de « La relation est disponible et exploitable » sans la contractualiser.
Impact :
Étape F-299-09 (« assemble-prompt charge la source canonique companion ») non opérationnalisable : aucune entrée de modèle de données ne référence cette relation. Le contrôle TC-NOM-13 suppose disponible `<story_source_id>-specification.md` sans formalisation du lien. Faux positifs/négatifs probables côté B3.
Gravité : Majeur
E-AMB-08 — « Source humaine » du bloc 6a non définie¶
Type : Ambiguïté
Référence : specification §4 INV-299-16, §7 CA-299-14, §8 (scénario 15/TC-NOM-15)
Description :
INV-299-16 impose un bloc « Données résolues (pré-implémentation) avec source humaine ». Le terme « source humaine » n'est défini ni en §3 ni en §5.1. Le format attendu (nom de champ, structure, format d'identification humaine, lien Jira ou signature) n'est pas spécifié.
Impact :
TC-NOM-15 se limite à « champ de source humaine explicite », observable purement syntaxique et arbitraire. Deux implémentations conformes peuvent produire des artefacts radicalement différents. Non-déterminisme pour la revue documentaire.
Gravité : Majeur
E-AMB-09 — « Message explicite » attendu non qualifié¶
Type : Ambiguïté
Référence : specification §5.5 F-299-03, F-299-06, §6 ERR-299-03, ERR-299-04, ERR-299-07 + tests TC-NOM-07, TC-ERR-03, TC-ERR-04, TC-ERR-07, TC-NR-02
Description :
Plusieurs flux exigent « message explicite », « erreur explicite », « motif de blocage mentionne explicitement » sans définir :
- canal (UI React Native ? journal technique ? exception typée ?) ;
- libellé minimal ;
- classe/typage d'erreur (hors D-299-11 qui est fermé).
Impact :
Aucune assertion testable déterministe. Les tests TC-NOM-07, TC-ERR-07 parlent de « message explicite » sans libellé cible, seul D-299-11 (fallback `maskIp`) est contractuellement fermé.
Gravité : Majeur
E-AMB-10 — Allowlist metadata : défaut vide contredit par Q-299-06¶
Type : Ambiguïté
Référence : specification §5.1 D-299-09 (« 0 clé autorisée par défaut »), §10.2 Q-299-06
Description :
§5.1 et §5.2 fixent un défaut de 0 clé (`metadata_allowlist_keys_count_default = 0`). §10.2 Q-299-06 pose simultanément la question : « Le schéma allowlist `metadata` doit-il rester vide (`{}`) ou contenir des clés explicites à l'initialisation ? »
La spec ferme la décision (0 par défaut) dans une section et la rouvre dans une autre.
Impact :
Incohérence interne : INV-299-05 est testable contre la valeur explicite « 0 par défaut », mais l'implémenteur peut raisonnablement répondre à Q-299-06 par « j'initialise avec 2 clés », ce qui créerait un test contradictoire avec TC-ERR-05.
Gravité : Majeur
E-AMB-11 — Comptage « cross-module » : plusieurs points ou un seul autorisé ?¶
Type : Ambiguïté
Référence : specification §5.2 paramètre `cross_module_missing_points_tolerance`, §4 INV-299-11, §6 ERR-299-09
Description :
§5.2 fixe `cross_module_missing_points_tolerance = 0`. Mais la définition §3 de « 6c.bis » mentionne « les points cross-module du plan sont effectivement dans le diff » sans préciser :
- la source de la liste canonique (champ du plan ? convention ?) ;
- le format d'un « point cross-module » (simple chemin ? tuple chemin+module ?).
D-299-16 est typé « Chemin POSIX relatif » uniquement, ce qui pourrait signifier un seul chemin par point.
Impact :
Test TC-NOM-09 suppose « Plan contenant 2 cross_module_point_path valides » sans règle pour les résoudre. Risque que 6c.bis n'identifie pas correctement la liste en l'absence de convention explicite dans le plan.
Gravité : Mineur
E-AMB-12 — authorization_header regex autorise plusieurs espaces¶
Type : Ambiguïté
Référence : specification §5.1 D-299-07 (`^Bearer [ ]+[!-~]+$`), §5.5 F-299-03, tests TC-NOM-04, TC-NEG-02
Description :
La regex impose `[ ]+` entre `Bearer` et la valeur du token : « un ou plusieurs espaces ». TC-NEG-02 donne comme exemple invalide `"Bearer abc def"` (double espace + espace interne). Pourtant la regex `[ ]+` acceptera plusieurs espaces entre `Bearer` et le token si le token n'a pas d'espace interne. L'exemple TC-NEG-02 est ambigu : c'est l'espace interne du token qui invalide, pas le double espace.
Impact :
Incohérence entre regex (§5.1) et cas négatif (TC-NEG-02). Un reviewer strict appliquant la regex valide `"Bearer xyz"` alors que le test semble attendre son rejet. Écart mineur par rapport à RFC 6750 (espace unique exigé).
Gravité : Mineur
3. Écarts — Contradictions¶
E-CON-01 — D-299-19 bornes min incompatibles entre §5.1 et §5.2¶
Type : Contradiction
Référence : specification §5.1 D-299-19, §5.2 `companion_context_addition`
Description :
§5.1 : « 1..2048 bytes additionnels » (min=1).
§5.2 : `min=0`, max=2 KiB.
Les deux tableaux sont normatifs ; l'un accepte le bloc vide, l'autre non.
Impact :
Contradiction formelle. Voir E-AMB-02 pour les conséquences opérationnelles.
Gravité : Bloquant
E-CON-02 — §5.4 Comportement NON_CONFORME → ESCALADE : critère différent dans Mermaid¶
Type : Contradiction (terminologique)
Référence : specification §5.4 tableau « État NON_CONFORME », §5bis diagramme d'état (« v3 non-conforme or convergence plateau »)
Description :
Tableau §5.4 : « plafond itérations atteint ou plateau convergence ».
Diagramme Mermaid : « v3 non-conforme or convergence plateau ».
« v3 non-conforme » correspond à la 3ᵉ itération spécifiquement, « plafond itérations atteint » est plus générique. L'équivalence « plafond = v3 » n'est jamais contractualisée dans §5.1 ou §5.2 (pas de paramètre `max_iterations`).
Impact :
Un reviewer strict peut interpréter différemment le déclencheur d'escalade : à la 3ᵉ itération même si le plafond est autre (ex. fixé à 2 ou 4 par ailleurs). Le test TC-NOM-19 « Chaque transition explicitement AUTORISÉE en §5.4 est demandée » ne matérialise pas ce plafond numériquement.
Gravité : Majeur
E-CON-03 — §10.2 hors périmètre contredit « non-répudiation minimale »¶
Type : Contradiction
Référence : specification §4 INV-299-09, §5.5 F-299-11, §10.2 (« intention réelle d'un approbateur humain au-delà de la trace Atlassian hors périmètre »)
Description :
§4/§5.5 déclarent la preuve D-299-21 comme établissant une « non-répudiation minimale ». §10.2 exclut simultanément la « vérification automatique de l'intention réelle » et la « preuve cryptographique d'intention ». Or la non-répudiation, au sens normatif, vise justement à lier un acte à une intention authentifiée.
Impact :
La section contractuelle §4 revendique une propriété juridique (non-répudiation) que §9/§10.2 déclarent hors périmètre. Contradiction formelle sur le niveau d'assurance visé.
Gravité : Majeur
E-CON-04 — INV-299-12 applicable à backend mais backend hors scope §2¶
Type : Contradiction
Référence : specification §2 (« Inclus » limite `backend` à l'absence de modifications), §4 INV-299-12, §5.1 D-299-02 (enum `project_code` = `app|backend|ia-governance`), §10.1 (« ProbatioVault-backend (scope B2 uniquement) »)
Description :
§2 « Inclus » ne mentionne aucune livraison sur `ProbatioVault-backend` (seules les cibles `app` et `ia-governance` sont listées). INV-299-12 applique pourtant la règle déterministe Gate 8 à `backend` sur le comptage `test_file_count=0`. §10.1 ajoute une ligne « (scope B2 uniquement) » qui n'apparaît pas en §2.
Impact :
Périmètre d'application de l'invariant incohérent entre §2 (périmètre) et §4 (invariants). Un reviewer ne peut pas établir si PD-299 doit faire tourner la règle B2 sur `backend` (et l'auditer), ou l'exclure. Le test TC-ERR-08 utilise `project_code=backend` sans résoudre la question.
Gravité : Majeur
E-CON-05 — F-299-08 « Pour autres projets : scoring arithmétique standard inchangé » vs §5.4 Mermaid¶
Type : Contradiction
Référence : specification §5.5 F-299-08, §5bis diagramme d'état
Description :
F-299-08 écrit « Pour autres projets : scoring arithmétique standard inchangé. »
Diagramme §5bis : la transition `CHECKING -> NON_CONFORME` conditionne sur « project in app/backend && test_count==0 OR arithmetic non-conforme ». Pour `ia-governance`, seule la branche « arithmetic non-conforme » s'applique — cohérent.
Mais le diagramme liste également `CHECKING -> GO: arithmetic GO (if no zero-test trigger)`. Sans trigger actif (ia-governance), la condition « if no zero-test trigger » est trivialement vraie, ce qui est cohérent, mais aucun test Gate 8 explicite `project_code=ia-governance` avec scoring GO n'existe (TC-ERR-13 est le seul cas ia-governance, NON_CONFORME potentiel).
Impact :
Contradiction mineure entre généralité du Mermaid et formulation textuelle F-299-08. Risque de scope non testé (ia-governance avec passage GO).
Gravité : Mineur
E-CON-06 — Tests §1 : référence Epic EPIC-XX placeholder¶
Type : Contradiction (interne)
Référence : tests §1 (« Epic : EPIC-XX ») + spec §10.1 (Q-299-01 « Référence épique exacte non fournie »)
Description :
Le fichier de tests référence `EPIC-XX` comme épique, tandis que Q-299-01 acte l'absence de référence métier. La spec et les tests divergent : la spec assume l'ignorance, les tests utilisent un placeholder non résolu.
Impact :
Traçabilité incomplète. Un audit RTM (`story-rfc-map.jsonl`) ne peut pas résoudre `EPIC-XX`.
Gravité : Mineur
E-CON-07 — §5.3 « Aucune transition temporelle » mais §5.2 contient legal_notice_retention_days¶
Type : Contradiction
Référence : specification §5.2 (paramètre `legal_notice_retention_days`, unité `jours`), §5.3 (« Aucune transition temporelle identifiée »), §5.3 note contractuelle sur la rétention 90 jours
Description :
§5.3 déclare « aucune transition temporelle » mais §5.2 contient un paramètre borné à `[90,90] jours`. La note contractuelle précise que la rétention est « donnée textuelle à valider » — ce qui n'élimine pas la contradiction avec la ligne §5.2.
Impact :
Incohérence mineure. Un reviewer pourrait interpréter §5.2 comme un SLA (blocage si expiration) ; §5.3 et §10.2 disent explicitement qu'il s'agit d'une donnée textuelle. Risque d'implémentation d'un mécanisme d'expiration non demandé.
Gravité : Mineur
4. Écarts — Règles non testables¶
E-NT-01 — INV-299-09 « non-répudiation minimale » non observable strictement¶
Type : Non testable
Référence : specification §4 INV-299-09, §5.5 F-299-11, §10.2 exclusion
Description :
La propriété « non-répudiation » au sens strict exige des garanties cryptographiques qu'aucun observable de la spec ne capture. La vérification opérationnelle (D-299-21 : présence de `jira_comment_id` non vide + `approver_id` + `approved_at`) ne prouve que la traçabilité, pas la non-répudiation.
Impact :
INV-299-09 tel que nommé est testable uniquement au sens « preuve de trace Jira ». Le libellé induit un observable juridique que les tests ne vérifient pas (ils ne vérifient ni la signature, ni l'authenticité cryptographique).
Gravité : Majeur
E-NT-02 — INV-299-16 « source humaine » observable arbitraire¶
Type : Non testable
Référence : specification §4 INV-299-16, §7 CA-299-14, tests TC-NOM-15
Description :
Le critère « champ de source humaine » n'a pas de format spécifié (voir E-AMB-08). Le test TC-NOM-15 est réduit à vérifier la présence d'un libellé non-vide choisi arbitrairement.
Impact :
Observable syntaxique ne garantissant ni l'authenticité, ni la valeur métier du champ. Aucune règle de falsifiabilité.
Gravité : Majeur
E-NT-03 — « Message explicite » (F-299-03, F-299-06, ERR-299-*)¶
Type : Non testable
Référence : specification §5.5, §6 + tests TC-NOM-07, TC-ERR-03, TC-ERR-04, TC-ERR-07
Description :
Aucun libellé-cible, aucune classe d'erreur, aucun canal (UI/log/exception) n'est contractualisé pour les messages « explicites ». Voir E-AMB-09.
Impact :
Les scénarios concernés ne disposent pas d'observable déterministe ; chaque reviewer LLM appliquera son propre critère.
Gravité : Majeur
E-NT-04 — Unicité et non-collision des jira_comment_id / approver_id¶
Type : Non testable
Référence : specification §5.1 D-299-21, §5.5 F-299-11, §7 CA-299-16 + tests TC-NOM-18, TC-ERR-12
Description :
La spec exige la présence d'un `jira_comment_id` non vide et de deux approbations (PO + LEGAL) par texte, mais ne contractualise :
- ni l'unicité du `jira_comment_id` entre PO et LEGAL (un même commentaire pourrait être référencé pour les deux rôles) ;
- ni la distinction des `approver_id` entre rôles (une même personne pourrait porter PO+LEGAL sur un même texte).
Impact :
Une preuve formellement valide mais cryptographiquement fragile (même acteur humain + même commentaire + deux rôles) est acceptable selon la lettre de la spec. Aucun test ne rejette ce cas.
Gravité : Majeur
E-NT-05 — INV-299-17 « schéma valide » de plan_extension_item.ratification_ref¶
Type : Non testable
Référence : specification §5.1 D-299-20 (ratification_ref?), §4 INV-299-17
Description :
Le champ `ratification_ref` est noté optionnel (`?`), mais la spec n'exige pas sa présence quand `status=RATIFIED`. Aucun observable ne lie `RATIFIED` ↔ `ratification_ref non vide`.
Impact :
Un reviewer peut estimer qu'un item `RATIFIED` sans `ratification_ref` est acceptable. TC-NOM-17 accepte « uniquement des items RATIFIED » sans vérifier la présence de la preuve de ratification. Faille auditable.
Gravité : Majeur
E-NT-06 — « Message utilisateur explicite » en blocage offline (INV-299-07)¶
Type : Non testable
Référence : specification §4 INV-299-07, §5.5 F-299-06, §6 ERR-299-07 + tests TC-NOM-07, TC-ERR-07
Description :
La contrainte « erreur explicite » n'a ni libellé fermé, ni classe d'erreur, ni canal UI fermé.
Impact :
Voir E-NT-03. Observable non déterministe sur l'IHM.
Gravité : Majeur
5. Écarts — Incohérences Spec ↔ Tests¶
E-IST-01 — TC-ERR-04 exemple CRLF ambigu vs regex D-299-07¶
Type : Incohérence Spec↔Tests
Référence : specification §5.1 D-299-07 ; tests TC-ERR-04, TC-NEG-02
Description :
TC-ERR-04 donne comme header invalide :
```
"Bearer
X-Test:1"
```
La regex `^Bearer [ ]+[!-~]+$` rejette ce cas parce que `!-~` exclut LF. TC-NEG-02 donne deux exemples :
- `"Bearer abc def"` (double espace + espace interne du token → espace interne hors plage `!-~` → rejeté) ;
- `"Bearer \nX-Test:1"` (LF).
Le test valide deux mécanismes de rejet différents (plage de caractères, pas la largeur du délimiteur), sans clarifier lequel.
Impact :
L'intention de la spec est bien de rejeter CRLF ; l'exemple `"Bearer abc def"` introduit une confusion avec le `[ ]+` autorisant plusieurs espaces entre `Bearer` et le token. Voir E-AMB-12.
Gravité : Mineur
E-IST-02 — TC-ERR-13 non déterministe sur ia-governance « zéro test »¶
Type : Incohérence Spec↔Tests
Référence : specification §5.5 F-299-08, §6 ERR-299-13 ; tests TC-ERR-13
Description :
TC-ERR-13 : « project_code=ia-governance, test_file_count=0 → règle cap zéro-test non appliquée → verdict suit scoring arithmétique standard ». Aucun score individuel n'est fourni, donc le verdict final n'est pas déterministe (GO/RESERVE/NON_CONFORME possible).
Impact :
TC-ERR-13 n'a pas d'observable de verdict testable ; il se contente de vérifier l'absence d'application de la règle cap. L'intention est correcte mais l'assertion finale est indéterminée.
Gravité : Mineur
E-IST-03 — TC-NEG-09 sans chemin explicite du test file¶
Type : Incohérence Spec↔Tests
Référence : specification §5.1 D-299-14 + tests TC-NEG-09
Description :
TC-NEG-09 : « Module contenant uniquement `foo.spec.tsx` → test_file_count=1, cap non déclenché ». Aucun chemin n'est précisé (racine ? sous-dossier ?). Voir E-AMB-03 (non récursivité du glob).
Impact :
Si `foo.spec.tsx` est placé sous `src/sharing/__tests__/foo.spec.tsx`, la règle glob telle qu'écrite ne le comptera pas ; TC-NEG-09 échouera contre-intuitivement.
Gravité : Majeur
E-IST-04 — Couverture INV-299-18 agrégée et non individualisée¶
Type : Incohérence Spec↔Tests
Référence : specification §4 INV-299-18, §5.4 (tableaux transitions Gate 8) ; tests TC-NOM-19, TC-NOM-20, TC-NOM-21, TC-ERR-14
Description :
INV-299-18 impose que toute transition non listée soit rejetée. TC-NOM-19 affirme tester « chaque transition autorisée », TC-NOM-20 teste les 3 états terminaux. Aucune preuve exhaustive individuelle par transition n'est instanciée dans les tests : pas de matrice explicite. TC-ERR-14 choisit une « transition non listée » générique.
Impact :
Couverture INV-299-18 formellement déclarative (« chaque ... »), non exhaustivement matérialisée. Une implémentation oubliant une transition autorisée précise ne serait pas nécessairement détectée.
Gravité : Mineur
E-IST-05 — TC-NOM-13 ne vérifie pas le contenu extrait¶
Type : Incohérence Spec↔Tests
Référence : specification §4 INV-299-14, §5.5 F-299-09 ; tests TC-NOM-13
Description :
TC-NOM-13 vérifie la présence des sections « Invariants » et « Arbitrages » + `source_story_id` + taille ≤ 2 KiB. Il ne vérifie pas que le contenu extrait correspond fidèlement au contenu source (ex. hash, longueur, extrait de ligne). Un extractor défaillant pouvant produire des sections vides mais titrées passerait.
Impact :
Observable partiel ; la propriété « arbitrages PO + invariants source issus de la source canonique » n'est pas vérifiée strictement.
Gravité : Majeur
E-IST-06 — TC-NOM-04 n'assert pas l'absence de log du token¶
Type : Incohérence Spec↔Tests
Référence : specification §4 INV-299-04, §5.1 D-299-06 (token opaque sensitive) ; tests TC-NOM-04
Description :
TC-NOM-04 vérifie la conformité du header `Authorization` mais n'assert pas que le token `auth_access_token` n'est pas loggué dans les traces telemetry, logs techniques ou rapports d'erreur. La sensibilité déclarée D-299-06 « Sensitive » n'est reliée à aucun contrôle d'observabilité.
Impact :
Risque de leak du token dans les journaux sans test de non-régression. Voir E-SEC-01.
Gravité : Majeur
E-IST-07 — TC-NOM-18 « email ou Jira username » sans assertion de discrimination¶
Type : Incohérence Spec↔Tests
Référence : specification §5.1 D-299-21 + tests TC-NOM-18
Description :
TC-NOM-18 admet les deux formats sans clarifier la règle de reconnaissance. L'observable se limite à « approver_id non vide ». Le test ne détecte pas les cas à risque (ex. `admin` ambigu entre username et préfixe d'email).
Impact :
Observable faible ; voir E-AMB-06.
Gravité : Mineur
E-IST-08 — TC-NOM-17 n'échantillonne pas les trois kind¶
Type : Incohérence Spec↔Tests
Référence : specification §5.1 D-299-20 (`kind ∈ {endpoint,header,timeout}`) + tests TC-NOM-17
Description :
TC-NOM-17 vérifie « uniquement des items RATIFIED avec kinds valides » sans imposer la présence des trois `kind` distincts dans le corpus testé. Un détecteur qui n'accepte qu'un kind (ex. `endpoint` seul) passerait.
Impact :
Couverture fonctionnelle de l'énumération D-299-20 non matérialisée.
Gravité : Mineur
E-IST-09 — TC-NR-04 « bloc stable entre mises à jour » sans baseline¶
Type : Incohérence Spec↔Tests
Référence : tests TC-NR-04
Description :
TC-NR-04 énonce « Bloc arbitrages/invariants source toujours présent après update template prompt ». Aucune baseline versionnée du template n'est désignée pour l'assertion (hash attendu, extrait de référence). Régression détectable uniquement si la baseline est fournie à l'exécution.
Impact :
Non-régression insuffisamment ancrée ; observable non fermé.
Gravité : Mineur
6. Écarts — Hypothèses dangereuses¶
E-HD-01 — H-299-01 « relation companion disponible » non contractualisée¶
Type : Hypothèse dangereuse
Référence : specification §9 H-299-01, §4 INV-299-14
Description :
L'hypothèse suppose que la relation companion→source est « disponible et exploitable », sans préciser le mécanisme (convention de nommage PD ? champ du besoin ? Jira link ? data-index ?). Voir E-AMB-07.
Impact :
Si la convention n'existe pas ou diffère selon le projet, B3 est non déterministe et F-299-09 inapplicable sans retour d'erreur contractualisé. H-299-01 masque une dette contractuelle critique.
Gravité : Majeur
E-HD-02 — Idempotence implicite de detect-plan-extensions¶
Type : Hypothèse dangereuse
Référence : specification §4 INV-299-17, §5.5 F-299-10
Description :
La phase 4 de `/gov-check-plan` est décrite comme exécutable unique (non idempotent). Si elle est relancée après correction partielle, la spec ne précise pas si l'état antérieur est réinitialisé ou accumulé.
Impact :
Risque de faux négatif si l'historique de `status=UNRATIFIED` conserve un item déjà traité, ou de faux positif si la réexécution double-compte.
Gravité : Mineur
E-HD-03 — Comportement sur CRLF dans auth_access_token non traité par D-299-06¶
Type : Hypothèse dangereuse
Référence : specification §5.1 D-299-06 (« ASCII printable sans espace »)
Description :
D-299-06 exclut l'espace mais autorise tout ASCII printable, donc `!-~` inclusif. Les caractères de contrôle (CR/LF/NUL) ne sont pas dans `!-~`, donc exclus implicitement — OK. En revanche, le test TC-NEG-02 concerne le header composé, pas le token nu. Si un token invalide contenant CR passe en amont de la regex D-299-07, aucune règle D-299-06 « nue » ne le rejette au niveau du stockage/acquisition.
Impact :
Protection multi-couche non contractualisée ; la défense se joue entièrement à la construction du header.
Gravité : Mineur
E-HD-04 — Fermeture FSM Gate 8 vs gardes hors-FSM¶
Type : Hypothèse dangereuse
Référence : specification §4 INV-299-18, §5.4 commentaire (« Les transitions workflow (6c→6c.bis→7, Gate 5) sont des gardes séquentielles hors FSM »)
Description :
Le périmètre de la FSM fermée est strictement Gate 8. Les gardes séquentielles (6c.bis, Gate 5) ne sont pas modélisées formellement. Leur interaction avec la FSM Gate 8 (ex. : quand 6c.bis bloque, Gate 8 n'est pas entamé) n'est pas décrite en machine d'états.
Impact :
Un enchaînement d'orchestration cassé (ex. : Gate 5 bloqué mais FSM Gate 8 PENDING) n'est pas détecté par la FSM. La clôture Art. I/V/VIII nécessite une sémantique d'orchestration hors portée de §5.4.
Gravité : Mineur
E-HD-05 — Atomicité du check NON_CONFORME → PENDING (réévaluation)¶
Type : Hypothèse dangereuse
Référence : specification §5.4 (« Comportement retour », « séquentiellement, non atomiquement »)
Description :
La spec assume explicitement une évaluation non atomique ; le premier check en échec suffit. Si deux checks concurrents s'exécutent (parallélisation d'infra), la précédence du « premier échec » devient non déterministe. Aucune règle d'exclusivité n'est contractualisée.
Impact :
Reproductibilité affaiblie en environnement concurrentiel. TC-NOM-21 suppose un ordre déterministe non garanti.
Gravité : Mineur
6bis. Cohérence des diagrammes (§5bis)¶
E-DIA-01 — Transition NON_CONFORME → ESCALADE : libellé divergent¶
Type : Incohérence Spec↔Tests (diagrammes)
Référence : specification §5.4 tableau « État NON_CONFORME », §5bis diagramme d'état (« v3 non-conforme or convergence plateau »)
Description :
Le tableau dit « plafond itérations atteint ou plateau convergence », le diagramme dit « v3 non-conforme or convergence plateau ». Voir E-CON-02.
Impact :
Incohérence textuelle entre les deux représentations du même passage.
Gravité : Mineur
E-DIA-02 — Diagramme de séquence : absence de type de retour de diff_paths()¶
Type : Incohérence Spec↔Tests (diagrammes)
Référence : specification §5bis séquence, §5.1 D-299-17
Description :
L'appel `Git ->> GI : diff_paths()` et la soustraction `missing = cross_module_point_path - diff_paths` ne référencent pas explicitement D-299-17 (format POSIX). Le type du retour `diff_paths()` n'est pas formellement dérivé des données §5.1.
Impact :
Faiblesse de traçabilité type entre séquence et modèle données.
Gravité : Mineur
E-DIA-03 — Diagramme de séquence : source_block non relié à D-299-19¶
Type : Incohérence Spec↔Tests (diagrammes)
Référence : §5bis séquence (`load_canonical(source_story_spec, sections=invariants+arbitrages)`), §5.1 D-299-19
Description :
Le retour `source_block + source_story_id` n'est pas formellement typé D-299-19 ; les contraintes de taille (§5.2 `companion_context_addition`) ne sont pas rappelées dans la séquence.
Impact :
Faiblesse mineure de cohérence structurelle.
Gravité : Mineur
E-DIA-04 — Couverture complète des transitions : OK¶
Type : Observation (pas un écart)
Référence : §4 INV-299-18, §5.4 tableaux, §5bis diagramme d'état
Description :
Toutes les transitions listées en §5.4 apparaissent dans le Mermaid avec statut cohérent (AUTORISÉE ↔ transition présente ; INTERDITE ↔ libellée « INTERDITE » dans le diagramme). Les 3 états terminaux sont individuellement annotés `-> * INTERDITE (etat terminal)`. Pas d'écart structurel identifié.
Impact :
Observation positive.
Gravité : n/a
7. Écarts — Risques sécurité / conformité¶
E-SEC-01 — auth_access_token : absence de règle de masquage dans logs/telemetry¶
Type : Risque sécu/conformité
Référence : specification §4 INV-299-04, §5.1 D-299-06 (sensitive), §8 (observabilité tests)
Description :
Le token est déclaré « Sensitive » dans D-299-06 sans règle de masquage dans les journaux, les rapports d'erreur ni la telemetry. INV-299-04 n'impose qu'un format de header ; rien n'exige la non-persistance du token côté reporting (crash log, Sentry, logs techniques).
Impact :
Risque de leak du token en clair. Aucune assertion de non-régression (voir E-IST-06).
Gravité : Majeur
E-SEC-02 — « Non-répudiation minimale » induit une assurance fausse¶
Type : Risque sécu/conformité
Référence : specification §4 INV-299-09, §5.5 F-299-11, §10.2 exclusion
Description :
Voir E-AMB-05, E-CON-03, E-NT-01. Le vocabulaire « non-répudiation » peut être cité en audit légal/RGPD en surestimant le niveau d'assurance réel (simple traçabilité Jira).
Impact :
Risque de contestation juridique en cas d'incident : un approbateur peut plausiblement répudier un commentaire Jira (compte compromis, admin ayant édité, signature absente). La spec ne protège pas ce risque.
Gravité : Majeur
E-SEC-03 — Unicité non contrôlée (jira_comment_id, approver_id)¶
Type : Risque sécu/conformité
Référence : specification §5.1 D-299-21, §4 INV-299-09, §7 CA-299-16 + tests TC-NOM-18
Description :
Rien dans la spec n'interdit :
- qu'un même `jira_comment_id` soit utilisé pour PO et LEGAL sur un même texte ;
- qu'un même `approver_id` porte PO + LEGAL sur un même texte ;
- que le même triplet soit réutilisé pour plusieurs `text_id`.
Impact :
Contournement du principe de séparation des pouvoirs (Art. II CONSTITUTIONAL, validation croisée). Une approbation mono-acteur est acceptée formellement.
Gravité : Majeur
E-SEC-04 — Glob non récursif : faux positif Gate 8 exploitable¶
Type : Risque sécu/conformité
Référence : specification §3, §4 INV-299-12, §5.1 D-299-14, §5.5 F-299-08
Description :
Voir E-AMB-03. Un attaquant/contributeur négligent placerait ses tests sous `src/sharing/__tests__/` ; la règle glob non récursive renverrait 0, bloquant la story à tort OU (inversement) les tests seraient valides mais non détectés par les contrôles Gate 8 standards.
Impact :
Conformité Gate 8 : déclenchement déterministe dépend d'une convention d'arborescence non formalisée. Risque de blocage ou de bypass selon la définition réelle du glob.
Gravité : Bloquant
E-SEC-05 — authorization_header regex laxiste vis-à-vis de RFC 6750¶
Type : Risque sécu/conformité
Référence : specification §5.1 D-299-07
Description :
La regex `^Bearer [ ]+[!-~]+$` admet plusieurs espaces entre `Bearer` et la valeur du token. RFC 6750 exige un seul espace. Comportement non sécurité-critique en soi, mais peut dérouter des middlewares amont/aval.
Impact :
Interop douteuse, potentiel rejet aval par un reverse proxy plus strict.
Gravité : Mineur
E-SEC-06 — ratification_ref facultatif pour un item RATIFIED¶
Type : Risque sécu/conformité
Référence : specification §5.1 D-299-20, §4 INV-299-17
Description :
Voir E-NT-05. Une extension plan→spec peut être marquée `RATIFIED` sans référence de ratification, ce qui supprime la preuve auditée de la décision PO.
Impact :
Contournement possible de l'Art. II CONSTITUTIONAL : la ratification peut être déclarée sans preuve. Bloquant pour l'auditabilité.
Gravité : Bloquant
E-SEC-07 — approver_id regex implicite (email/username) sans contrôle¶
Type : Risque sécu/conformité
Référence : specification §5.1 D-299-21
Description :
Aucun format imposé sur `approver_id` (voir E-AMB-06). L'usurpation par caractère invisible (ex. `admin` vs `аdmin` cyrillique) n'est pas contrée ; aucun contrôle de cohérence annuaire n'est requis.
Impact :
Risque d'usurpation d'identité à faible coût dans le champ texte libre.
Gravité : Majeur
E-SEC-08 — Tests négatifs (TC-NEG-*) ne couvrent pas l'injection Unicode/homoglyphe¶
Type : Risque sécu/conformité
Référence : tests §7 TC-NEG-*, spec §5.1 D-299-06, D-299-21
Description :
Les tests négatifs vérifient CRLF et espaces, mais n'exercent pas les vecteurs typiquement manqués : normalisation Unicode, homoglyphes, BOM, caractères de contrôle hors ASCII.
Impact :
Couverture sécurité de TC-NEG-* limitée au périmètre ASCII.
Gravité : Mineur
8. Synthèse¶
| Gravité | Nombre d'écarts |
|---|---|
| Bloquant | 5 (E-AMB-03, E-AMB-04, E-CON-01, E-SEC-04, E-SEC-06) |
| Majeur | 18 |
| Mineur | 16 |
Les points bloquants portent sur :
- Ambiguïté sur la récursivité du glob de comptage des tests (E-AMB-03 / E-SEC-04) — impact déterministe sur Gate 8.
- Ambiguïté sur l'échelle « module » vs « projet » pour la règle zéro test (E-AMB-04).
- Contradiction formelle sur la borne min du bloc companion (E-CON-01).
- Ratification
RATIFIEDsansratification_refobligatoire (E-SEC-06) — impact Art. II CONSTITUTIONAL.
Les points majeurs concentrent :
- Le vocabulaire « non-répudiation » contredit par §10.2 (E-AMB-05, E-CON-03, E-NT-01, E-SEC-02).
- L'absence de contraintes d'unicité sur
jira_comment_id/approver_id(E-NT-04, E-SEC-03, E-SEC-07). - L'indéterminisme des « messages explicites » (E-AMB-09, E-NT-03, E-NT-06).
- Le périmètre
backendpartiel (E-CON-04). - L'absence de masquage contractualisé du token (E-SEC-01, E-IST-06).
Les points mineurs portent majoritairement sur la terminologie entre §5.4 texte et Mermaid, la couverture test agrégée vs individuelle, et l'interopérabilité regex.
9. Observations hors écarts (contexte)¶
- La correction de l'ambiguïté
min(raw,6.0)(revue v1) est bien intégrée dans §5bis (« test_coverage:=6.0 (exact, ignore raw) »). Cohérent avec INV-299-12 et TC-NOM-11. - L'introduction d'INV-299-18 (fermeture FSM Gate 8) est alignée avec la checklist machine à états §5.4 et bien reflétée dans le Mermaid d'état.
- La section §10.2 ajoute une transparence bienvenue sur les limites de vérification automatique, mais ouvre simultanément la contradiction E-CON-03 avec le vocabulaire des §4/§5.5.
⚠️ Aucune correction proposée dans ce livrable. ⚠️ Aucune reformulation. ⚠️ Aucune implémentation.