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¶
-
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é.
-
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. -
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.
-
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é).