Aller au contenu

PD-275 — Specification Review (v2)

Documents d'entrée

  • Spécification : PD-275-specification.md (v2 — corrigée post Gate 3 v1 RESERVE)
  • Tests : PD-275-tests.md (v2 — 33 scénarios, 12 invariants)
  • Domaine : crypto-proof (conformité formelle Prolog)

Learnings injectés

  • PD-274 (Gate ⅜) : stories conformité formelle convergent en v1 GO (>9.0) — faux positifs ~70%
  • PD-277 (Gate ⅗) : contractualiser format + faits Prolog + types SQL dès v1
  • PD-55 (Gate ⅗/8) : définir RFC/formats/bornes dès la spec ; immutabilité TypeORM explicite ; PostgreSQL interdit subqueries dans index partiels
  • PD-264 (Gate 8) : migration DDL type-change pattern réutilisable
  • PD-177 (Gate ⅗/8) : fail-closed NestJS interceptor ; role authorization ; defense-in-depth

Corrections v1 → v2 — Vérification de levée des écarts

Écart v1 Gravité v1 Correction v2 Levé ?
C-01 (chemin nominal finalizeBatch) Majeur CA-02b ajouté, T3 couvre acceptation Oui
HD-02 (concurrence revoke/submit) Majeur INV-275-11, INV-275-12, §10.7, T12, T13 Oui
RS-01 (autorisation revokeSigner) Majeur INV-275-09, CA-04b, T10 Oui
RS-02 (revokedBy auth-derived) Majeur INV-275-10, CA-04c, T11, ERR-REVOKEDBY-SPOOFING Oui

1) Ambiguïtés

A-01 (reconduit — atténué)

Type : Ambiguïté
Référence : Spec §3 (Définitions) / §5 (Modèle d'états batch)
Description : L'état `NON_FINALIZED` est utilisé dans le modèle d'états batch (§5) comme
  état source de la transition vers `FINALIZED`, mais n'est défini nulle part dans §3
  (Définitions). Q-02 reconnaît explicitement l'incomplétude. La spec v2 n'apporte
  pas de changement sur ce point. Cependant, la note de cadrage est cohérente : la spec
  contractualise uniquement les transitions identifiées dans le périmètre PD-275 et
  déclare Q-02 comme question ouverte. INV-275-07 s'applique aux « états identifiés »,
  ce qui limite le scope vérifiable au modèle partiel déclaré.
Impact : TC-INV-07B vérifie un modèle partiel déclaré, pas la complétude réelle.
  Acceptable si Q-02 est traité en story ultérieure avec machine à états batch complète.
Gravité : Majeur (atténué par Q-02 explicite et §5 checklist)

A-02 (reconduit — inchangé)

Type : Ambiguïté
Référence : Spec §5 Flux F1 / INV-275-03-confirmation-persistence
Description : Le mécanisme de mise à jour de `confirmation_count` n'est pas spécifié.
  Flux F1 dit « Le nombre observé est persisté » sans définir l'interface (API, événement,
  job interne). INV-275-03 réfère à « le mécanisme de suivi des confirmations » sans le
  nommer. Note domaine crypto-proof : si ce mécanisme est pré-existant et hors scope PD-275,
  la spec devrait le déclarer explicitement en §2 (Exclu) ou en hypothèse.
Impact : TC-NOM-01 assume « une mise à jour de confirmations valide est appliquée » —
  le test est formulable mais l'interface à tester est ambiguë.
Gravité : Mineur

A-03 (reconduit — inchangé)

Type : Ambiguïté
Référence : Spec §5 Flux F1 step 4
Description : « Le batch reste dans son état courant tant que les conditions de finalisation
  ne sont pas remplies » — cela implique-t-il que la mise à jour de `confirmation_count`
  pourrait déclencher implicitement une finalisation si les conditions sont remplies ?
  Ou la finalisation est-elle toujours un acte explicite (Flux F2) ? La distinction entre
  mise à jour passive (F1) et finalisation active (F2) n'est pas contractualisée.
Impact : Si F1 peut déclencher implicitement F2, le modèle de test change (TC-NOM-01
  devrait vérifier l'absence de transition implicite).
Gravité : Mineur

A-04 (reconduit — inchangé)

Type : Ambiguïté
Référence : Spec §5 Flux F4 / H-01
Description : Flux F4 requiert « une identité signer » à la soumission, mais ne précise
  pas comment cette identité est transmise (paramètre explicite, dérivée du contexte
  d'authentification, extraite du batch). H-01 reconnaît la dépendance PD-177 mais ne
  fournit pas de contrat d'interface.
Impact : L'implémentation de CA-05 est bloquée si le mécanisme de résolution signer
  n'est pas contractualisé.
Gravité : Majeur

2) Contradictions

C-01 (LEVÉ)

Type : Contradiction (LEVÉE en v2)
Référence : Spec CA-02 / CA-02b
Description : La spec v2 a ajouté CA-02b qui couvre explicitement le chemin nominal
  d'acceptation : « finalizeBatch() autorise la transition vers FINALIZED si
  confirmation_count >= FINALITY_DEPTH ». Le scénario T3 est correctement mappé
  à CA-02b. TC-NOM-03 a une base contractuelle claire.
Impact : Aucun.
Gravité : LEVÉ

C-02 (reconduit — inchangé)

Type : Contradiction
Référence : Tests §3 TC-NOM-02 (Flux nominaux) vs §4 TC-ERR-02 (Cas d'erreur)
Description : TC-NOM-02 et TC-ERR-02 testent exactement le même scénario (finalizeBatch
  avec confirmation_count = D-1 → refus ERR-FINALITY-INSUFFICIENT). TC-NOM-02 est classé
  dans « Flux nominaux » alors qu'il teste un refus. Duplication exacte avec classification
  contradictoire.
Impact : Ambiguïté sur le test faisant foi. Risque de double maintenance.
Gravité : Mineur

C-03 (reconduit — inchangé)

Type : Contradiction
Référence : Tests §3 TC-NOM-07 vs §4 TC-ERR-04
Description : TC-ERR-04 et TC-NOM-07 testent le même scénario (submitBatch avec adresse
  absente → ERR-SIGNER-NOT-FOUND). Duplication exacte entre sections.
Impact : Même que C-02.
Gravité : Mineur

C-04 (reconduit — inchangé)

Type : Contradiction
Référence : Tests §3 TC-NOM-06 vs §4 TC-ERR-05
Description : TC-ERR-05 et TC-NOM-06 testent le même scénario (submitBatch avec signer
  REVOKED → ERR-SIGNER-REVOKED). Duplication exacte entre sections.
Impact : Même que C-02.
Gravité : Mineur

3) Règles non testables

NT-01 (reconduit — inchangé)

Type : Non testable
Référence : INV-275-08-envelope-encryption / TC-INV-08
Description : TC-INV-08 inspecte « les artefacts temporaires éventuels produits par ces
  flux ». Le mot « éventuels » rend l'observable conditionnel. Si PD-275 ne produit aucun
  artefact cryptographique temporaire (aucun flux ne mentionne de DEK, ReKey ou fragment),
  le test est vacuement vrai et l'invariant est non falsifiable dans ce périmètre.
Impact : L'invariant ne peut pas échouer, donc il n'apporte aucune garantie testable.
  Note : invariant obligatoire domaine crypto/blockchain — sa présence est un garde-fou
  contractuel même si vacuement satisfait dans PD-275.
Gravité : Mineur

NT-02 (reconduit — atténué)

Type : Non testable
Référence : INV-275-07-state-machine-complete / TC-INV-07B
Description : TC-INV-07B vérifie la complétude du modèle d'états batch, mais le document
  de test §9 reconnaît que l'exhaustivité des états `anchor_batch` hors `FINALIZED` est
  « incompletable sans liste canonique » (Q-02). Le test ne peut vérifier que le modèle
  partiel déclaré, pas la complétude réelle. La spec v2 ajoute une checklist machine à
  états (§5) qui confirme la couverture des transitions identifiées. Le bloquant est
  atténué : le modèle partiel est complet pour les transitions DANS le périmètre PD-275.
Impact : INV-275-07 est satisfait pour le périmètre PD-275 mais pas pour le modèle
  batch global. Acceptable si Q-02 est traité en story ultérieure.
Gravité : Majeur (réduit de Bloquant à Majeur — le modèle partiel est désormais cohérent)

4) Incohérences Spec ↔ Tests

IST-01 (reconduit — inchangé)

Type : Incohérence Spec↔Tests
Référence : Spec CA-07 / Tests TC-NR-01
Description : CA-07 exige « Les tests couvrent les 5 comportements nouveaux (checks
  28–32) ». TC-NR-01 est un méta-test : « Rapport de tests mappé vers
  TC-NOM-01/02/04/05/06/07/08 ». Ce n'est pas un test comportemental mais une vérification
  de traçabilité. Le mapping liste 7 tests pour 5 checks sans expliciter la
  correspondance check→test.
Impact : L'observable « Rapport de tests prouvant les scénarios requis » est un artefact
  documentaire, pas un test exécutable automatisé.
Gravité : Mineur

IST-02 (reconduit — inchangé)

Type : Incohérence Spec↔Tests
Référence : Spec §6 ERR-SIGNER-NOT-FOUND / Tests TC-ERR-03
Description : TC-ERR-03 teste revokeSigner(address) avec adresse absente du registre.
  La spec §6 mentionne ERR-SIGNER-NOT-FOUND pour « soumission/révocation » mais le Flux F3
  (révocation) ne traite pas explicitement le cas adresse absente — il dit « Le système
  résout l'entrée signer_registry correspondante » puis « Si statut ACTIVE ». Le cas
  « adresse introuvable » dans le flux de révocation n'a pas de step explicite dans F3.
Impact : Le test suppose un comportement (refus fail-closed) cohérent avec INV-275-01,
  mais le flux ne le documente pas.
Gravité : Mineur

IST-03 (reconduit — inchangé)

Type : Incohérence Spec↔Tests
Référence : Matrice couverture §2 / TC-NOM-09
Description : La matrice mappe TC-NOM-09 à INV-275-03-confirmation-persistence et CA-08.
  Or TC-NOM-09 teste la réversibilité migration (up/down/up). Le lien avec INV-275-03
  est indirect — TC-NOM-09 vérifie que le schéma est restauré, pas que confirmation_count
  est correctement persisté. Le mapping devrait pointer vers CA-08 seul.
Impact : Traçabilité imprécise dans la matrice de couverture.
Gravité : Mineur

IST-04 (nouveau)

Type : Incohérence Spec↔Tests
Référence : Spec INV-275-09-revoke-authorization / Tests TC-NOM-04
Description : TC-NOM-04 (GIVEN « Une identité de révocation valide est fournie pour
  revokedBy ») ne vérifie pas explicitement que l'appelant porte le rôle ADMIN ou
  SIGNER_ADMIN. Le test couvre INV-275-05 (audit trail) mais pas INV-275-09
  (autorisation). Le mapping dans la matrice §2 ne référence pas INV-275-09 pour
  TC-NOM-04. Seul TC-NOM-10 (T10 dans la spec) couvre CA-04b (refus non-autorisé),
  mais le chemin nominal autorisé de TC-NOM-04 ne précise pas le rôle utilisé.
Impact : TC-NOM-04 ne prouve pas que le garde d'autorisation laisse passer les rôles
  autorisés — il prouve seulement l'audit trail. La matrice §2 devrait mapper
  INV-275-09 vers un test nominal avec rôle explicite.
Gravité : Mineur

IST-05 (nouveau)

Type : Incohérence Spec↔Tests
Référence : Spec INV-275-11 / INV-275-12 / Tests matrice §2
Description : Les invariants INV-275-11 (signer-concurrency-serialization) et
  INV-275-12 (single-revocation-audit-event) sont nouveaux en v2 mais ne figurent pas
  dans la matrice de couverture §2. Les tests TC-NOM-12 (T12) et TC-NOM-13 (T13) dans
  §8 de la spec couvrent ces invariants, mais la matrice §2 du document de tests ne
  les référence pas car elle n'a pas été mise à jour pour les invariants v2.
Impact : Traçabilité formelle incomplète pour les 2 invariants de concurrence.
  Les tests existent dans la spec mais le document tests §2 ne les mappe pas.
Gravité : Majeur

5) Hypothèses dangereuses

HD-01 (reconduit — inchangé)

Type : Hypothèse dangereuse
Référence : Spec §5 Flux F3 / INV-275-05-revocation-atomic-audited
Description : La spec exige « transition atomique » pour la révocation mais ne spécifie pas
  le mécanisme d'atomicité. En contexte PostgreSQL+TypeORM (§10.1), une transaction suffit.
  La spec v2 contractualise le SELECT...FOR UPDATE (INV-275-11) ce qui confirme que
  l'atomicité est transactionnelle PostgreSQL. Mais si revokedAt/revokedBy étaient
  persistés dans un système distinct (event store, audit log externe), l'atomicité
  cross-système ne serait pas garantie.
Impact : Atténué par §10.5 (« Aucune écriture async hors scope PD-275 ») et §10.7
  (« écritures d'audit dans la même transaction que la transition d'état »).
Gravité : Mineur (résolu par §10.7)

HD-02 (LEVÉ)

Type : Hypothèse dangereuse (LEVÉE en v2)
Référence : Spec §5 Flux F3 / Flux F4 / §10.7
Description : La spec v2 contractualise explicitement la sérialisation par SELECT...FOR
  UPDATE (INV-275-11), la contrainte d'unicité de transition (INV-275-12), et détaille
  la sémantique concurrente dans Flux F4 step 6. Les scénarios T12 et T13 couvrent
  les races revoke/revoke et revoke/submit.
Impact : Aucun.
Gravité : LEVÉ

HD-03 (reconduit — inchangé)

Type : Hypothèse dangereuse
Référence : Spec H-04 / INV-275-01-fail-closed
Description : H-04 reconnaît le risque de « refus généralisés fail-closed en phase initiale »
  si le registre n'est pas seedé. Combiné avec INV-275-01 (deny by default pour signer
  inconnu), un déploiement sans seed stratégie bloque toute soumission. Q-05 identifie
  ce point comme question ouverte.
Impact : Indisponibilité complète du service d'ancrage post-déploiement si seed non
  effectué.
Gravité : Majeur

6) Risques sécurité / conformité

RS-01 (LEVÉ)

Type : Risque sécu/conformité (LEVÉ en v2)
Référence : Spec INV-275-09-revoke-authorization / CA-04b / T10
Description : La spec v2 contractualise le contrôle d'autorisation pour revokeSigner() :
  seuls les rôles ADMIN ou SIGNER_ADMIN sont autorisés. INV-275-09 est explicite, CA-04b
  fournit l'observable, T10 teste le refus pour rôle non autorisé. Le cas d'erreur
  ERR-REVOKE-UNAUTHORIZED est documenté.
Impact : Aucun.
Gravité : LEVÉ

RS-02 (LEVÉ)

Type : Risque sécu/conformité (LEVÉ en v2)
Référence : Spec INV-275-10-revokedBy-auth-derived / CA-04c / T11
Description : La spec v2 contractualise que revokedBy est dérivé exclusivement du
  contexte d'authentification (JWT sub ou service account identity) et ne peut pas être
  injecté via input métier. INV-275-10 est explicite, CA-04c fournit l'observable avec
  deux comportements acceptables (ignoré ou refusé), T11 teste l'anti-usurpation avec
  ERR-REVOKEDBY-SPOOFING. Le cas d'erreur est documenté dans §6.
Impact : Aucun.
Gravité : LEVÉ

Synthèse

Gravité Nombre IDs
LEVÉ 4 C-01, HD-02, RS-01, RS-02
Majeur 4 A-01, A-04, HD-03, IST-05
Mineur 10 A-02, A-03, C-02, C-03, C-04, NT-01, HD-01, IST-01, IST-02, IST-03, IST-04

Bilan v1 → v2

Les 4 écarts majeurs identifiés en v1 (C-01, HD-02, RS-01, RS-02) sont tous levés en v2 grâce à l'ajout de : - 4 nouveaux invariants (INV-275-09 à INV-275-12) - 3 nouveaux critères d'acceptation (CA-02b, CA-04b, CA-04c) - 4 nouveaux scénarios de test (T10, T11, T12, T13) - 2 nouveaux cas d'erreur (ERR-REVOKE-UNAUTHORIZED, ERR-REVOKEDBY-SPOOFING) - 1 section technique contractualisée (§10.7 concurrence)

Écarts résiduels significatifs

  1. A-01 / NT-02 (Majeur) : le modèle d'états batch reste partiel (Q-02). Acceptable dans le périmètre PD-275 si Q-02 est traité en story ultérieure. Le bloquant v1 est réduit à Majeur car la checklist machine à états (§5) confirme la complétude du modèle partiel déclaré.

  2. A-04 (Majeur) : l'interface de résolution de l'identité signer pour submitBatch() dépend de PD-177 (H-01). Non bloquant si PD-177 est livré et fournit le contrat d'interface.

  3. HD-03 (Majeur) : le risque d'indisponibilité fail-closed post-déploiement sans seed stratégie (Q-05) reste ouvert. Opérationnel, pas un écart de spécification.

  4. IST-05 (Majeur) : la matrice de couverture du document tests n'a pas été mise à jour pour les invariants v2 (INV-275-11, INV-275-12). Les tests T12/T13 existent dans la spec mais le mapping formel manque dans le document tests §2.

Note domaine crypto-proof

Conformément aux learnings PD-274 (Gate 3), les stories de conformité formelle convergent typiquement en v1 GO avec ~70% de faux positifs LLM. Les écarts résiduels v2 sont essentiellement : - des questions ouvertes explicitement déclarées (Q-01 à Q-05) — pas des oublis - des incohérences de traçabilité mineures (duplications de tests, matrice non à jour) - un écart de complétude lié au scope partiel assumé (modèle batch)

La spec v2 est nettement plus solide que la v1 sur les axes critiques (sécurité, concurrence, auditabilité).