PD-264 — Specification Review (Gate 3 — v3)¶
Auditeur : Claude (auditeur technique indépendant) Date : 2026-02-24 Documents audités : - PD-264-specification.md (v3) - PD-264-tests.md (v3)
Historique : - v1 : RESERVE (7.06/10) — 14 constats (1 bloquant, 6 majeurs, 7 mineurs) - v2 : RESERVE (7.75/10) — corrections AMB-01..04, NT-01..02, INC-03, HYP-01 - v3 : corrections MAJ-01, MAJ-03, MAJ-06, MAJ-07, MAJ-09, MAJ-11, BLOQ-05
Learnings contextuels injectés :
| Story | Learning | Pertinence |
|---|---|---|
| PD-55 (Gate 3) | Définir RFC 8785, ordre canonique, formats dès la spec évite 3 itérations | Vérifié — formalisme RFC 3161 présent |
| PD-55 (Gate 5) | Immutabilité périmètre lot et triggers DB nécessitent PostgreSQL réel | Pertinent — TC-264-09 s'appuie sur trigger PD-55 |
| PD-55 (Gate 8) | Faux positifs sécurité non bloquants si protections structurelles couvrent | Pertinent — analyse TC-264-07 timing |
| PD-264 (Gate 3 v1) | INV-264-13 atomicité : préciser scope DB vs append-only/Merkle | Corrigé v3 — scope borné DB atomique + post-commit asynchrone |
Bilan des corrections v3¶
| Constat v2 | Gravité v2 | Statut v3 | Commentaire |
|---|---|---|---|
| #5 (BLOQ — atomicité INV-264-13) | Bloquant | RÉSOLU | v3 BLOQ-05 : scope borné DB atomique, append-only/Merkle post-commit idempotents, rattrapage via worker réconciliation PD-55 |
| #1 (MAJ — nullabilité DDL nonce) | Majeur | RÉSOLU | v3 MAJ-01 : NOT NULL explicite en DDL + migration VARCHAR(64)->BYTEA documentée |
| #3 (MAJ — garde d'entrée automate) | Majeur | RÉSOLU | v3 MAJ-03 : garde d'entrée formalisée, TC-264-01 mis à jour |
| #6 (MAJ — observable CSPRNG TC-264-08) | Majeur | RÉSOLU | v3 MAJ-06 : analyse statique grep/AST + runtime taille + Chi² ajoutés |
| #7 (MAJ — vecteur attaque TC-264-09) | Majeur | RÉSOLU | v3 MAJ-07 : UPDATE SQL direct explicité, trigger PD-55 nommé |
| #9 (MAJ — escalade timing TC-264-07) | Majeur | RÉSOLU | v3 MAJ-09 : procédure rerun + escalade/audit définie, bloquant Gate 8 |
| #11 (MAJ — NR exhaustivité) | Majeur | RÉSOLU | v3 MAJ-11 : justification d'exhaustivité (3 interfaces + 2 propriétés transversales) |
7/7 constats majeurs et bloquants v2 : RÉSOLUS.
Constats résiduels d'audit (v3)¶
CONSTAT-R01¶
Type : Ambiguïté
Référence : Spec §5 (Modèle de données) — migration VARCHAR(64) -> BYTEA NOT NULL
Description : La spec (v3 MAJ-01) contractualise la migration de la colonne héritée PD-55 (VARCHAR(64) nullable) vers BYTEA NOT NULL (16 octets). Cependant, elle ne spécifie pas la stratégie de traitement des données existantes. Si des tokens PD-55 existent déjà avec un nonce en VARCHAR(64) — éventuellement nul — la migration ALTER COLUMN nécessite un plan de conversion (hex string -> binary ? valeur par défaut pour NULL ? rejet des lignes sans nonce ?). Le comportement attendu pour les données PD-55 existantes n'est pas contractualisé.
Impact : L'implémenteur ne sait pas comment traiter les lignes existantes lors de la migration DDL. Un choix incorrect pourrait corrompre la traçabilité probatoire héritée ou bloquer la migration.
Gravité : Majeur
CONSTAT-R02¶
Type : Incohérence Spec↔Tests
Référence : Spec §5 (migration DDL) / Tests — aucun TC de migration
Description : La spec contractualise une migration DDL significative (changement de type + NOT NULL + CHECK constraint) mais aucun scénario de test ne couvre la migration elle-même : exécution réussie, intégrité des données post-migration, down migration. Les préconditions communes des tests (§Préambule) supposent un schéma déjà en état cible.
Impact : Un échec de migration en environnement avec données PD-55 existantes ne serait détecté qu'en déploiement, pas en CI.
Gravité : Majeur
CONSTAT-R03¶
Type : Hypothèse dangereuse
Référence : Spec §9 (hypothèse PD-55) / TC-264-09 + TC-264-19
Description : La migration DDL (VARCHAR(64)->BYTEA) modifie la colonne nonce sur laquelle opèrent le trigger d'immutabilité PD-55 (TC-264-09) et le worker de réconciliation PD-55 (TC-264-19 Cas B). Si le trigger PD-55 contient une logique dépendante du type VARCHAR (ex : comparaison de chaînes) ou si le worker de réconciliation fait des hypothèses sur le format du nonce, la migration pourrait casser silencieusement ces mécanismes hérités.
Impact : Les tests NR pourraient passer sur un schéma propre (créé en cible) mais échouer sur une migration réelle depuis le schéma PD-55. Le changement de type de colonne est un vecteur de régression non couvert.
Gravité : Majeur
CONSTAT-R04¶
Type : Ambiguïté
Référence : Spec §5 — contrainte DDL "vérification taille octet_length(nonce) = 16 côté base"
Description : La spec (v3 MAJ-01) qualifie cette contrainte DDL CHECK de "recommandée" alors que l'INV-264-01 impose un nonce de 128 bits comme obligation fail-closed. Le statut "recommandé" est contractuellement ambigu pour un auditeur.
Impact : L'implémenteur pourrait omettre la CHECK constraint en interprétant "recommandée" comme optionnelle, affaiblissant la défense en profondeur.
Gravité : Mineur
CONSTAT-R05¶
Type : Incohérence Spec↔Tests
Référence : Spec §8 (procédure d'escalade TC-264-07) / Tests TC-264-07
Description : La procédure d'escalade (v3 MAJ-09) est bien définie (rerun unique + audit obligatoire) mais le verdict "ESCALADE" n'est pas un résultat binaire pass/fail. Le TC-264-07 ne spécifie pas comment le pipeline CI doit interpréter ce verdict (exit code ? artefact ? tag ?). De plus, le TC-264-07 est "non bloquant Gate 3/5" mais "bloquant Gate 8" — cette dualité n'est pas reflétée dans les prérequis CI du TC.
Impact : En CI, un test qui retourne "ESCALADE" est indéterminé sans convention explicite de traitement pipeline.
Gravité : Mineur
CONSTAT-R06¶
Type : Ambiguïté
Référence : Spec §3 — état RESPONSE_REJECTED / TC-264-11
Description : Les TC de rejet (TC-264-02, TC-264-03) indiquent "aucune écriture DB" pour les réponses rejetées, ce qui implique que RESPONSE_REJECTED est un état transitoire en mémoire. Or TC-264-11 exige de "tenter chaque transition interdite" depuis RESPONSE_REJECTED, ce qui suppose un état matérialisé. Si RESPONSE_REJECTED n'est qu'un résultat de validation en mémoire (pas de persistance), l'interdiction de transition est triviale (rien à modifier) et le test perd sa valeur probante.
Impact : Ambiguïté sur la nature de l'état REJECTED (transitoire vs persisté) et sur la valeur probante du test TC-264-11.
Gravité : Mineur
CONSTAT-R07¶
Type : Non testable
Référence : CA-264-12 / TC-264-17 (Nightly TSA qualifiée réelle)
Description : TC-264-17 dépend d'un service externe (TSA qualifiée) sans SLA contractualisé dans le périmètre PD-264. Le comportement attendu en cas d'indisponibilité TSA n'est pas défini (skip ? fail ? retry ?). Le test est non déterministe par nature.
Impact : Un échec nightly dû à l'indisponibilité TSA est indiscernable d'un échec fonctionnel réel.
Gravité : Mineur
CONSTAT-R08¶
Type : Ambiguïté
Référence : Spec §3 — transition REQUEST_EMITTED -> RESPONSE_RECEIVED
Description : La spec §8 affirme "Aucune transition temporelle identifiée" mais l'attente d'une réponse TSA après REQUEST_EMITTED est intrinsèquement temporelle. Le timeout est explicitement hors périmètre PD-264 (§4 exclut "Client QTSA complet") mais l'automate d'états de §3 est incomplet sans ce chemin. Un implémenteur de l'automate ne trouvera pas de sortie pour l'état REQUEST_EMITTED en cas de non-réponse.
Impact : Automate d'états spécifié incomplet pour l'état REQUEST_EMITTED sans réponse (reconnu hors périmètre mais visible pour un audit de l'automate).
Gravité : Mineur
CONSTAT-R09¶
Type : Incohérence Spec↔Tests
Référence : Spec §8 (aucun invariant Chi²) / TC-264-08 (v3 MAJ-06)
Description : TC-264-08 (v3) introduit un test Chi² d'uniformité au seuil alpha=0.01 comme observable statistique. Cette exigence ne découle d'aucun invariant ni critère d'acceptation de la spec. Le TC crée une obligation de test qui n'a pas de correspondance contractuelle. Si ce test échoue, aucune règle de la spec n'est violée formellement.
Impact : Exigence de test orpheline (Chi²) sans ancrage dans les invariants. Un échec Chi² ne constitue pas un écart contractuel auditable.
Gravité : Mineur
CONSTAT-R10¶
Type : Incohérence Spec↔Tests
Référence : Spec §6 INV-264-06 vs INV-264-13 — cohérence atomicité
Description : INV-264-06 stipule : "Aucune écriture DB, journal append-only ou inclusion Merkle ne se produit avant validation complète du nonce." INV-264-13 (v3) stipule que la persistance DB est atomique (transaction) tandis que append-only/Merkle sont post-commit et asynchrones. Lus conjointement, les deux invariants sont cohérents (rien avant validation → persistance atomique → append-only asynchrone). Lus isolément, INV-264-06 pourrait être interprété comme exigeant une atomicité englobant les trois opérations, ce qui contredirait INV-264-13.
Impact : Risque d'interprétation contradictoire par un implémenteur lisant INV-264-06 sans INV-264-13.
Gravité : Mineur
CONSTAT-R11¶
Type : Incohérence Spec↔Tests
Référence : INV-264-09, matrice de couverture / TC-264-17
Description : INV-264-09 (Conformité ASN.1/DER) est couvert par TC-264-04 et TC-264-14. TC-264-04 utilise un mock TSA qui est conforme par construction (tautologie). La véritable validation ASN.1/DER sur un artefact réel ne vient que du nightly (TC-264-17), qui n'est pas mappé à INV-264-09 dans la matrice de couverture.
Impact : La couverture CI de INV-264-09 repose sur un mock conforme par construction. Le nightly qui fournit la preuve réelle n'est pas traçable à cet invariant dans la matrice.
Gravité : Mineur
Synthèse v3¶
| Gravité | Nombre |
|---|---|
| Bloquant | 0 |
| Majeur | 3 |
| Mineur | 8 |
Constats majeurs résiduels¶
| # | Type | Référence | Résumé |
|---|---|---|---|
| R01 | Ambiguïté | §5 migration | Stratégie de traitement des données PD-55 existantes non contractualisée |
| R02 | Incohérence Spec↔Tests | §5 / Tests | Migration DDL sans scénario de test dédié |
| R03 | Hypothèse dangereuse | §9, TC-264-09/19 | Trigger/worker PD-55 potentiellement incompatibles post-migration VARCHAR->BYTEA |
Constats mineurs résiduels¶
| # | Type | Référence | Résumé |
|---|---|---|---|
| R04 | Ambiguïté | §5 | CHECK constraint "recommandée" vs obligation fail-closed |
| R05 | Incohérence Spec↔Tests | §8, TC-264-07 | Verdict "ESCALADE" non binaire en CI |
| R06 | Ambiguïté | §3, TC-264-11 | État RESPONSE_REJECTED transitoire vs persisté |
| R07 | Non testable | TC-264-17 | Dépendance TSA externe sans SLA |
| R08 | Ambiguïté | §3 | Timeout REQUEST_EMITTED hors périmètre mais automate incomplet |
| R09 | Incohérence Spec↔Tests | TC-264-08 | Chi² orphelin — exigence sans invariant |
| R10 | Incohérence Spec↔Tests | INV-264-06 vs INV-264-13 | Lecture isolée potentiellement contradictoire |
| R11 | Incohérence Spec↔Tests | INV-264-09, matrice | Mock tautologique ; TC-264-17 non mappé à INV-264-09 |
Note d'évaluation¶
Les 3 constats majeurs résiduels (R01, R02, R03) sont thématiquement liés : ils concernent tous la migration DDL VARCHAR(64)->BYTEA et ses implications sur les données existantes et les mécanismes PD-55. Ce cluster peut être résolu par une seule action de clarification (stratégie de migration documentée + TC de migration + vérification compatibilité trigger/worker PD-55).
Aucune correction proposée. Aucune reformulation. Aucune implémentation.