Date : 2026-02-25 Story : PD-250 — Job destruction définitive et bordereau Iteration : v1 Documents audités : PD-250-plan.md (v1), PD-250-code-contracts.yaml (v1)
Sources
- Review (P1) : PD-250-plan-review.md (ChatGPT, v1) — 1 BLOQUANT, 6 MAJEURS, 2 MINEURS
- Confrontation (P2) : PD-250-confrontation-step5.md (Claude, v1) — 7 divergences, 7 zones d'ombre
Synthèse des écarts consolidés (v1)
Écarts BLOQUANTS (1)
| # | Écart | Type | Source |
| BLQ-01 | TC-250-16 (audit ACID : non-perte, monotonie, complétude) mappé en test unitaire (destruction-audit.service.spec.ts) alors que le scénario exige un crash post-S3/pré-commit DB et une réconciliation réelle sur PostgreSQL. L'invariant INV-250-05 (mesurabilité audit) n'est pas démontrable en test mocké. | DIV | Review P1 (#1) + Confrontation P2 (DIV-01) |
Écarts MAJEURS (5)
| # | Écart | Type | Source |
| MAJ-01 | parentBatchId dans l'entity destruction_batches (plan TASK-13) mais la spec (§5.9) exige « dans l'audit log du nouveau batch ». Un auditeur externe consultant l'audit log ne peut pas reconstituer la filiation inter-batch. | ECT | Review P1 (#2) + Confrontation P2 (DIV-04) |
| MAJ-02 | Job préavis « exécuté quotidiennement » (spec §5.8), mais le plan lie le scheduling à destructionJobInterval [1-168h]. Si configuré > 24h, le préavis n'est plus quotidien. Variable de configuration dédiée requise. | ECT | Review P1 (#3) + Confrontation P2 (DIV-03) |
| MAJ-03 | Séquence PostgreSQL nommée audit_destruction_seq dans le plan vs audit_seq contractualisée dans INV-250-05. Divergence de nommage avec le contrat. | ECT | Review P1 (#4) + Confrontation P2 (DIV-02) |
| MAJ-04 | Backfill had_legal_lock repose sur legal_lock = true OR legal_lock_until IS NOT NULL. Si un legal_lock a été retiré (pas expiré, mais remis à false/null), le document ne sera pas détecté. Risque de contournement INV-250-12 (zeroization obligatoire). | SEC | Review P1 (#5,6) + Confrontation P2 (DIV-05) |
| MAJ-05 | INV-250-10 exige « toute erreur partielle observable (audit + alerte) ». Le plan formalise l'audit unitaire mais pas l'alerte unitaire — les alertes sont traitées au niveau batch/SLA global. Erreur silencieuse possible pour ERR-250-03/04. | DIV | Review P1 (#7) + Confrontation P2 (DIV-06) |
Écarts MINEURS (2)
| # | Écart | Type | Source |
| MIN-01 | Fichiers de structure (destruction.module.ts, destruction-batch.entity.ts, enums) sans code contract dédié. Risque faible (glue, pas de logique métier). | DIV | Confrontation P2 (DIV-07) |
| MIN-02 | Invariants de code contracts incluent des contraintes d'implémentation (ex: MAJ-25, MAJ-26) au même niveau que les INV spec. Dilution du périmètre contractuel. | AMB | Review P1 (#9) |
Scoring par critère (Gate AMBIGUITY)
feasibility (Faisabilité technique du plan)
- Base 10
- BLQ-01 : -2 (TC-250-16 non démontrable en test unitaire, stratégie tests d'intégration absente)
- Score : 8.0
coverage (Couverture des invariants/CA/ERR)
- Base 10
- MAJ-01 : -1 (parentBatchId absent de l'audit log)
- MAJ-05 : -1 (alerte unitaire non formalisée)
- MIN-01 : -0.25 (fichiers sans code contract)
- Score : 7.75
risk_mitigation (Atténuation des risques identifiés)
- Base 10
- MAJ-04 : -1 (backfill had_legal_lock potentiellement incomplet, risque INV-250-12)
- MAJ-02 : -1 (variable de configuration partagée préavis/destruction)
- MIN-02 : -0.25 (dilution périmètre contractuel)
- Score : 7.75
coherence (Cohérence plan↔spec↔tests)
- Base 10
- MAJ-03 : -1 (nom séquence audit divergent)
- MAJ-01 : -1 (parentBatchId entity vs audit log)
- Score : 8.0
Scores finaux
| Critère | Score |
| feasibility | 8.0 |
| coverage | 7.75 |
| risk_mitigation | 7.75 |
| coherence | 8.0 |
| Moyenne | 7.875 |