1. Documents de référence
| Document | Source | Étape |
| PD-279-besoin.md | Claude (PO) | 0 |
| PD-279-specification.md | ChatGPT (gpt-5.3-codex) | 1 |
| PD-279-tests.md | ChatGPT (gpt-5.3-codex) | 2 |
| PD-279-review-step3.md | Claude (subprocess) | 3-P1 |
| PD-279-confrontation-step3-v1.md | ChatGPT (gpt-5.3-codex) | 3-P2 |
2. Synthèse des écarts
BLOQUANTS (2)
| ID | Source | Description |
| ECT-01 | Review Claude | security_level contradictoire : INV-04 exige ≥2 copies géo-distribuées mais le flux B (return-from-restitution) ne vérifie pas ce prérequis. Contradiction entre invariant et endpoint. |
| ECT-02 | Review Claude | Point de contrôle destruction (H-279-02) : la garde RESTITUTED → DISPOSED est interdite mais la spec ne garantit pas l'unicité du point de contrôle — le module destruction pourrait contourner via batch processing. |
MAJEURS (8)
| ID | Source | Description |
| DIV-01 | Review Claude | DISPOSED référencé dans la spec mais absent de l'enum actuel et hors périmètre — spec devrait éviter de référencer un état non implémenté dans les gardes. |
| DIV-02 | Review Claude | PENDING→RESTITUTED : la spec ne bloque pas explicitement cette transition — seul SEALED→RESTITUTED est autorisé mais la garde devrait rejeter tous les autres états. |
| DIV-03 | Review Claude | Priorité 403/409 non ordonnée : si un utilisateur non-autorisé tente de restituer un doc en mauvais état, quel code HTTP est prioritaire ? |
| DIV-04 | Review Claude | error_code métier pour 409 non normé : pas de constantes error_code pour distinguer les causes du 409 (mauvais état vs legal_lock vs copies insuffisantes). |
| DIV-05 | Review Claude | Routes destruction protégées non listées exhaustivement dans la spec. |
| DIV-06 | Review Claude | SLA post-100% sans effet coercitif : que se passe-t-il quand le deadline est dépassé ? Pas de transition automatique définie. |
| DIV-07 | Review Claude | at-least-once vs exactly-once : la restitution peut-elle être appelée plusieurs fois ? Idempotence non spécifiée. |
| AMB-01 | Review Claude | EXPIRED terminal vs hypothèse : la spec suppose EXPIRED = terminal mais ne l'explicite pas formellement dans le diagramme d'état. |
MINEURS (2)
| ID | Source | Description |
| MIN-01 | Review Claude | Down migration enum PostgreSQL sans oracle de test pour vérifier le rollback. |
| MIN-02 | Review Claude | Test adversarial security_level hors contrat API — test utile mais non contractuel. |
Divergences confrontation (4)
| ID | Source | Description | Criticité |
| CF-DIV-01 | Confrontation ChatGPT | Couverture tests annoncée exhaustive vs sections NON TESTABLE | MAJEUR |
| CF-DIV-02 | Confrontation ChatGPT | Q-279-01 omis dans résumé tests — incohérence traçabilité | MINEUR |
| CF-DIV-03 | Confrontation ChatGPT | Localisation artefact (process) | MINEUR |
| CF-DIV-04 | Confrontation ChatGPT | Niveau de preuve tests insuffisant (résumé vs contenu détaillé) | MAJEUR |
3. Scoring
Calcul par critère (base 10, déductions par écart) :
completeness (complétude)
- Base : 10
- ECT-01 (-2) : Contradication security_level → BLOQUANT
- ECT-02 (-2) : Point de contrôle destruction non garanti → BLOQUANT
- DIV-01 (-1) : DISPOSED hors enum référencé
- DIV-02 (-1) : Transition PENDING→RESTITUTED non bloquée
- Score : 4.0
testability (testabilité)
- Base : 10
- CF-DIV-01 (-1) : Sections NON TESTABLE vs couverture annoncée
- CF-DIV-04 (-1) : Niveau de preuve insuffisant
- DIV-07 (-1) : Idempotence non spécifiée → non testable
- Score : 7.0
clarity (clarté)
- Base : 10
- DIV-03 (-1) : Priorité 403/409 ambiguë
- DIV-04 (-1) : Error codes 409 non normés
- DIV-06 (-1) : SLA post-100% sans effet
- AMB-01 (-0.25) : EXPIRED terminal implicite
- Score : 6.75
traceability (traçabilité)
- Base : 10
- CF-DIV-02 (-0.25) : Q-279-01 omis
- DIV-05 (-1) : Routes destruction non listées
- MIN-01 (-0.25) : Down migration sans oracle
- Score : 8.5
Résumé scoring
| Critère | Score |
| completeness | 4.0 |
| testability | 7.0 |
| clarity | 6.75 |
| traceability | 8.5 |
| Moyenne | 6.5625 |
4. Verdict préliminaire
- completeness = 4.0 < 6 → NON_CONFORME (score < 6 sur au moins un critère)
- Moyenne = 6.5625 < 7 → NON_CONFORME (moyenne insuffisante)
Verdict : NON_CONFORME