Aller au contenu

PD-264 — Revue d'acceptabilité (post-correction)

1. Références

  • Spécification : PD-264-specification.md (v3)
  • Tests contractuels : PD-264-tests.md (19 TC + 3 TC-MIG + 5 NR)
  • Acceptabilité existante : PD-264-acceptability.md
  • Date de revue : 2026-02-24
  • Reviewer : Auditeur technique indépendant (Claude — revue post-correction Gate 8)

2. Suivi des écarts (append-only)

[2026-02-24] — Suivi R-01

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • Le catch global du processor (batch-timestamp.processor.ts:202-226) utilise toujours TsaErrorCode.QTSA_UNREACHABLE comme code d'erreur par défaut pour toutes les exceptions, y compris les erreurs non-QTSA (ex : Batch not found, Database error).
  • Aucune correction n'a été apportée sur ce point.
  • L'écart est mitigé : le client QTSA n'est pas encore implémenté (stub intentionnel), et le code d'erreur sera différencié lors de PD-265.
  • Preuve de vérification :
  • Fichier : src/modules/tsa/processors/batch-timestamp.processor.ts:212TsaErrorCode.QTSA_UNREACHABLE dans le catch global
  • Test : batch-timestamp.processor.spec.ts:139 — confirme que QTSA_UNREACHABLE est retourné même pour une erreur DB

[2026-02-24] — Suivi R-02

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • L'early-return dans compareEqual() (nonce.service.ts:99-101) est toujours présent : si les tailles diffèrent, return false est exécuté avant timingSafeEqual.
  • Le risque est évalué négligeable car validatePresence() garantit que les deux nonces font exactement 16 octets avant tout appel à compareEqual() dans le flux nominal (nonce-validation.service.ts:110 vérifie la taille avant compareEqual à la ligne 119).
  • Aucune correction requise — accepté par design.
  • Preuve de vérification :
  • Fichier : src/modules/tsa/services/nonce.service.ts:98-103 — early-return pour tailles différentes
  • Fichier : src/modules/tsa/services/nonce-validation.service.ts:110-116 — vérification taille avant appel compareEqual

[2026-02-24] — Suivi R-03 / D-01

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • Le placeholder QTSA (batch-timestamp.processor.ts:174-184) retourne toujours QTSA_UNREACHABLE avec le message QTSA client not yet implemented.
  • Il s'agit d'une dette technique intentionnelle et documentée, planifiée pour PD-265.
  • Le code est explicitement commenté aux lignes 186-201 avec le flux futur.
  • Preuve de vérification :
  • Fichier : src/modules/tsa/processors/batch-timestamp.processor.ts:177-184 — stub QTSA
  • Test : batch-timestamp.processor.spec.ts:78-92 — vérifie le retour QTSA_UNREACHABLE pour batch sealed

[2026-02-24] — Suivi S-01

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • Identique à R-01 — le errorCode est masqué par QTSA_UNREACHABLE dans le catch global.
  • Pas de correction apportée ; sera traité avec PD-265.
  • Preuve de vérification :
  • Voir R-01 ci-dessus.

[2026-02-24] — Suivi S-02

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • L'interface BatchTimestampJobResult (batch-timestamp.processor.ts:56-86) expose toujours errorMessage: string brut dans le résultat de job.
  • Le risque est accepté : les jobs BullMQ ne sont pas exposés en API REST directement. L'errorMessage n'est accessible qu'en interne via le dashboard Bull ou les logs.
  • Aucune fuite d'information possible vers un utilisateur final.
  • Preuve de vérification :
  • Fichier : src/modules/tsa/processors/batch-timestamp.processor.ts:85 — champ errorMessage dans l'interface
  • Fichier : src/modules/tsa/processors/batch-timestamp.processor.ts:203error.message exposé brut

[2026-02-24] — Suivi T-01

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • TC-264-06 (nonce-integration.spec.ts:133-153) simule la concurrence en séquentiel avec un mock : premier appel findOne retourne null, second retourne { id: 'just-inserted-token' }.
  • Ce n'est pas une vraie concurrence PostgreSQL avec FOR UPDATE ou INSERT ... ON CONFLICT.
  • Mitigation : la contrainte UNIQUE INDEX idx_timestamp_token_nonce est validée structurellement par TC-MIG-01 (nonce-migration.spec.ts:84-91), et PostgreSQL garantit l'unicité même sous charge concurrente.
  • Preuve de vérification :
  • Test : nonce-integration.spec.ts:134-153 — mock séquentiel
  • Test : nonce-migration.spec.ts:84-91CREATE UNIQUE INDEX vérifié dans les SQL exécutés

[2026-02-24] — Suivi T-02

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • TC-264-09 (immutabilité post-insertion) n'a pas de test UPDATE réel sur PostgreSQL.
  • La vérification est indirecte : TC-MIG-03 (nonce-migration.spec.ts:139-158) valide que le trigger trg_timestamp_token_immutable est recréé après migration, et que la fonction timestamp_token_immutable() est référencée.
  • Un test d'intégration avec UPDATE réel nécessite une base PostgreSQL de test.
  • Preuve de vérification :
  • Test : nonce-migration.spec.ts:140-147 — vérification CREATE TRIGGER exactement 1 fois
  • Test : nonce-migration.spec.ts:153-157 — référence à timestamp_token_immutable()

[2026-02-24] — Suivi T-03

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • 3 tests placeholders confirmés :
    • TC-264-14 (nonce-integration.spec.ts:296-313) : expect(true).toBe(true) — dépend de fixtures DER QTSA
    • TC-264-15 (nonce-integration.spec.ts:319-325) : expect(true).toBe(true) — Prolog hors Jest
    • TC-264-17 (nonce-integration.spec.ts:365-373) : expect(true).toBe(true) — nightly pipeline uniquement
  • Les 3 sont documentés avec justification dans les commentaires du code.
  • Ces placeholders seront résolus quand le client QTSA sera implémenté (PD-265) et le pipeline nightly configuré.
  • Preuve de vérification :
  • Fichier : nonce-integration.spec.ts:311expect(true).toBe(true) (TC-264-14)
  • Fichier : nonce-integration.spec.ts:323expect(true).toBe(true) (TC-264-15)
  • Fichier : nonce-integration.spec.ts:371expect(true).toBe(true) (TC-264-17)

[2026-02-24] — Suivi T-04

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • TC-264-08 ne contient pas de test Chi² en CI. Le test (nonce.service.spec.ts:34-61) vérifie :
    • La taille 16 octets sur 10 000 nonces
    • L'unicité de 1 000 nonces
    • L'usage CSPRNG par proxy comportemental
  • Le test Chi² sur la distribution des octets est planifié dans le pipeline nightly.
  • La spécification le qualifie d'observable statistique complémentaire (non bloquant CI).
  • Preuve de vérification :
  • Test : nonce.service.spec.ts:54-60 — 10 000 nonces validés taille 16
  • Test : nonce.service.spec.ts:42-51 — 1 000 nonces uniques

[2026-02-24] — Suivi T-05

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • TC-264-19 (nonce-integration.spec.ts:253-288) simule le crash au niveau mock, pas par fault injection PostgreSQL réelle.
  • Cas A : la validation passe mais repository.save() n'est jamais appelé — simule un crash avant commit.
  • Cas B : mock save résolu — simule le commit réussi.
  • La vraie atomicité transactionnelle est garantie par PostgreSQL ; le test vérifie la logique applicative.
  • Preuve de vérification :
  • Test : nonce-integration.spec.ts:254-268 — Cas A sans appel save
  • Test : nonce-integration.spec.ts:270-287 — Cas B avec mock save

[2026-02-24] — Suivi T-06

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • TC-264-07 (nonce-timing.spec.ts:240-301) utilise Cliff's delta comme seul critère bloquant (expect(Math.abs(delta)).toBeLessThan(0.147)).
  • Les p-values Welch t-test et Mann-Whitney U sont calculées mais informatives uniquement (lignes 286-299).
  • Divergence avec la spécification qui demande p_ttest >= 0.01 ET p_mwu >= 0.01 ET |Cliff's delta| < 0.147 comme critère conjoint.
  • Justification pragmatique documentée : à N=100K, MWU a une puissance statistique excessive et détecte des différences sub-nanoseconde non exploitables (lignes 276-279).
  • Le protocole d'escalade MAJ-09 est documenté dans les commentaires (lignes 281-283).
  • Preuve de vérification :
  • Test : nonce-timing.spec.ts:284 — seul assert sur Cliff's delta
  • Test : nonce-timing.spec.ts:287-299 — p-values logguées en warning, non bloquantes

[2026-02-24] — Suivi D-02

  • Statut précédent : OUVERT
  • Statut actuel : OUVERT
  • Justification factuelle :
  • L'automate d'états n'est pas exercé end-to-end dans le processor (batch-timestamp.processor.ts:167-184).
  • Le processor appelle validateRequestNonce() et generate(), puis retourne QTSA_UNREACHABLE avant d'atteindre la phase RESPONSE_RECEIVED.
  • Le flux complet (lignes 186-201) est commenté en tant que « future implementation ».
  • L'automate est exercé end-to-end dans les tests unitaires (nonce-integration.spec.ts:54-92, nonce-validation.service.spec.ts:197-293), mais pas dans le processor réel.
  • Preuve de vérification :
  • Fichier : batch-timestamp.processor.ts:174-184 — arrêt avant RESPONSE_RECEIVED
  • Test : nonce-integration.spec.ts:54-92 — TC-264-04 exerce l'automate complet en isolation

3. Verdict d'acceptabilité (courant)

Verdict actuel : ⚠️ ACCEPTÉ AVEC RÉSERVES Date : 2026-02-24 Motif synthétique : 0 écart CRITIQUE, 0 écart MAJEUR. 9 écarts MINEUR uniques + 1 suggestion, tous documentés avec mitigation. Les écarts principaux (R-01/S-01, R-03/D-01/D-02, T-03) sont liés au stub QTSA intentionnel (PD-265). Les 95 tests PD-264 passent à 100%. Coverage 95.38% > 80%.


4. Historique des verdicts

Date Verdict Version / commit Commentaire
2026-02-24 ⚠️ ACCEPTÉ AVEC RÉSERVES 5c81a46 (feature/PD-264-nonce-tsa-rfc3161) Verdict initial : 0 CRITIQUE, 0 MAJEUR, 9 MINEUR uniques. Tous écarts liés au stub QTSA (PD-265) ou limitations mock CI vs PG réel. 95/95 tests PASS, 95.38% coverage. GO recommandé pour Gate 8.