PD-265 — Rapport de confrontation (Gate 5 — v3)¶
Ce rapport est produit par l'orchestrateur Claude avant la gate PMO 5. Il confronte les documents produits pour identifier convergences, divergences et zones d'ombre.
1. Sources confrontees¶
| Document | Etape | Version |
|---|---|---|
| PD-265-specification.md | 1 (corrigee v3 post-Gate 3) | Specification corrigee complete |
| PD-265-tests.md | 2 (corriges v3 post-Gate 3) | Tests corriges complets |
| PD-265-plan.md | 4 (corrige post-Gate 5 v2) | Plan d'implementation v3 |
| PD-265-code-contracts.yaml | 4 (associe au plan v3) | Code contracts inter-agents |
| PD-265-review-step5-v3.md | 5 | Revue independante (OpenCode) |
2. Convergences¶
CONV-01 — 14 invariants couverts par le plan Les 14 invariants (INV-265-01 a INV-265-14) sont tous mappes a des composants et mecanismes explicites dans le plan S3. Chaque invariant a au moins un composant responsable et un observable identifie. Pas d'invariant orphelin.
CONV-02 — 12 criteres d'acceptation couverts par le plan Les 12 CA (CA-01 a CA-12) sont tous mappes dans le plan S4 avec composants, observables et risques. Pas de CA orphelin.
CONV-03 — Machine d'etats : derivation correcte (correction AMB-01-v2) Spec S5.4, plan DA-05 et tests convergent desormais tous sur le calcul de tsaServiceState : - maintenanceMode=true -> MAINTENANCE - flags.length === 0 ET maintenanceMode=false -> HEALTHY - flags.length === 1 -> etat specifique (DEGRADED_NTS, DEGRADED_REVOCATION, DEGRADED_TRUSTLIST, DEGRADED_KEY_LIFECYCLE) - flags.length >= 2 -> DEGRADED (composite)
DA-05 est desormais explicitement aligne sur la spec. Le BLOQUANT v2 est resolu.
CONV-04 — Deux enums separes conformes a la spec (correction AMB-02-v2) Le plan DA-02 definit desormais deux enums distincts : - refusalReasonCode (spec S5.1) : 6 valeurs exactes (MAINTENANCE | NTS_DEGRADED | REVOCATION_DEGRADED | TRUSTLIST_DEGRADED | KEY_LIFECYCLE_DEGRADED | COMPOSITE_DEGRADED) - reasonCode (spec S5.9) : 13 valeurs spec + 2 extensions documentees Les nommages spec sont respectes (TL_STALE, TL_UNTRUSTED, MAX_DEGRADED_DURATION). Les 4 codes manquants en v2 (OCSP_UNKNOWN, OCSP_STALE, CRL_UNAVAILABLE, CRL_STALE) sont restaures. Deux fichiers enum separes declares. Le BLOQUANT v2 est resolu.
CONV-05 — NTS fail-closed Spec INV-265-01, plan C4+C9, CC-265-04 et tests TC-NOM-01/TC-ERR-01 convergent : tout echec NTS bloque l'emission TST.
CONV-06 — Revocation OCSP/CRL avec fraicheur Spec INV-265-02 + S5.3/S5.4, plan C5, CC-265-05 et tests TC-NOM-03/TC-ERR-02/TC-ERR-03 convergent : OCSP=GOOD ET CRL=NOT_LISTED ET fraicheur <= maxAge pour clearing.
CONV-07 — Cycle de vie cles unidirectionnel Spec S5.5 (ACTIVE->RETIRED->ARCHIVED->DESTROYED), plan C7, CC-265-07 et tests TC-ERR-15 convergent : reactivation interdite, evenement d'audit sur tentative. DA-02 ajoute l'enforcement des SLA post-rotation.
CONV-08 — Re-horodatage avec deadline Spec INV-265-06, plan C8 et tests TC-NOM-05/TC-ERR-10 convergent : deadline rehorodatageProcessingDeadline, alerte CRITICAL si depassee, lien supersedesTstId.
CONV-09 — Trusted List ETSI avec cache TTL Spec INV-265-07, plan C6, CC-265-06 et tests TC-NOM-06/TC-ERR-04/TC-NOM-CLEAR-TRUSTLIST convergent.
CONV-10 — RBAC MAINTENANCE Spec INV-265-14/S5.4, plan C10, CC-265-10 et tests TC-NOM-09/TC-NEG-09 convergent : role TSA_OPERATOR, refus journalise.
CONV-11 — Audit JCS + cle dediee Spec INV-265-13/S5.9, plan C12, CC-265-12 et tests TC-NOM-08 convergent : canonicalisation RFC 8785, signatureKeyId dans chaque evenement, cle d'audit distincte de la cle TSA.
CONV-12 — Metriques contractuelles prefixe tsa_ Spec S5.9, plan C11, CC-265-11 et tests TC-NOM-12 convergent : prefixe tsa_, minimum contractuel de 10 metriques, cardinalite bornee.
CONV-13 — Contraintes croisees de configuration Spec S5.2, plan C1, CC-265-01 et tests TC-CROSS-01/TC-CROSS-02 convergent : maxDegradedDuration >= 3 x ntsCheckInterval et rehorodatageProcessingDeadline < rehorodatageLeadTime x 24.
CONV-14 — Idempotence et reprise post-crash Spec INV-265-09/S5.6, plan C2+C3+C8 et tests TC-ERR-11 convergent : persistance etat en base, rattrapage async sans duplication.
CONV-15 — Hors perimetre aligne Plan S10 reprend fidelement les exclusions de la spec S2. Aucun element hors perimetre n'est traite.
CONV-16 — Framework de test documente (correction AMB-07-v2) Plan S13 specifie desormais Jest avec ts-jest, jest.mock(), jest.useFakeTimers(), runner CI npm test -- --ci --coverage. Le MAJEUR v2 est resolu.
CONV-17 — Fail-closed au demarrage contractualise (correction AMB-04-v2 partielle) Plan DA-05 contractualise desormais le comportement au demarrage : l'application ne demarre pas si la DB est indisponible pendant plus de dbStartupTimeout. L'intention fail-closed de INV-265-01 est respectee. Cependant, le mecanisme specifique souleve de nouvelles questions (cf. DIV-04).
3. Divergences¶
Les conflits ne sont JAMAIS lisses. Chaque divergence est rendue visible.
DIV-01 (MAJEUR) — CC-265-02 mentionne colonne state vs DA-05 / C2 qui l'excluent¶
- Plan DA-05 : « La table
tsa_degradation_statene contient pas de colonnestate— l'etat est toujours derive. » - Plan C2 : «
TsaDegradationState: singleton row (flags, maintenanceMode, lastTransitionAt, flagActivationTimestamps). Note : pas de colonnestate. » - CC-265-02 (invariant) : « INV-265-11: Table tsa_degradation_state singleton (flags + state + timestamps) » — mentionne
statecomme colonne. - Impact : Le plan est internement coherent (DA-05 et C2 s'accordent), mais le code contract CC-265-02 n'a pas ete mis a jour. L'agent-foundation recevant CC-265-02 comme contrat pourrait creer une colonne
state, contredisant DA-05.
DIV-02 (MAJEUR) — Chevauchement de fichier CC-265-02 / CC-265-07¶
- CC-265-02 (owner: agent-foundation) : liste
src/modules/tsa/entities/tsa-key-lifecycle-metadata.entity.ts - CC-265-07 (owner: agent-lifecycle) : liste le meme fichier
src/modules/tsa/entities/tsa-key-lifecycle-metadata.entity.ts - Impact : Deux agents ont la responsabilite du meme fichier. Risque de conflit d'implementation en multi-agents et tracabilite d'ownership non deterministe.
DIV-03 (MAJEUR) — Fichier audit-reason-code.enum.ts absent des code contracts¶
- Plan DA-02 / C3 : Definit un fichier
src/modules/tsa/enums/audit-reason-code.enum.ts(15 valeurs) comme livrable du composant C3 (agent-foundation). - CC-265-03 (files) : Ne liste pas ce fichier. Seul
refusal-reason-code.enum.tsest present. - CC-265-12 (files) : Ne liste pas non plus ce fichier. Seul
tsa-audit-event.service.tsest present. - Impact : L'enum audit
reasonCode(15 valeurs) n'a pas de proprietaire contractuel dans les code contracts. Aucun agent ne recoit explicitement la responsabilite de ce fichier.
DIV-04 (MAJEUR) — Fail-closed startup : refusalReasonCode='MAINTENANCE' sans etat MAINTENANCE¶
- Plan DA-05 : « Si le cache C3 n'est pas initialise [...], le service retourne
{ allowed: false, refusalReasonCode: 'MAINTENANCE' }. » - Spec S5.4 : Le
refusalReasonCodeMAINTENANCE correspond atsaServiceState=MAINTENANCE, qui est active par action manuelle RBAC (maintenanceToggleAllowedRoles). - Spec S5.1 / CA-11 : Le refus d'emission DOIT exposer un motif norme et inclure
tsaServiceState+tsaServiceDegradationFlags. - Impact : Si le cache est non initialise,
tsaServiceStateettsaServiceDegradationFlagssont inconnus. RetournerrefusalReasonCode=MAINTENANCEsans quemaintenanceMode=trueni que l'etat soitMAINTENANCEcree une incoherence entre le motif de refus et l'etat reel. Les tests TC-NOM-09 attendent MAINTENANCE uniquement apres action RBAC.
DIV-05 (MAJEUR) — Scheduler re-horodatage fixe a 12h vs deadline configurable min 1h¶
- Plan C8 : « Scheduler cadence toutes les 12h (marge 12h vs deadline
rehorodatageProcessingDeadlinede 24h). » - Spec S5.2 :
rehorodatageProcessingDeadlineest configurable avec min=1h, max=168h. - Impact : Pour des configurations valides ou
rehorodatageProcessingDeadline < 12h(ex: 1h, 4h, 6h), le scheduler ne peut pas detecter les TST eligibles dans le delai contractuel. INV-265-06 (alerte si deadline depassee) serait systematiquement violee structurellement pour ces configurations.
DIV-06 (MAJEUR) — Extension reasonCode audit non prevue par la spec¶
- Plan DA-02 : Ajoute
KEY_RETIRED_SLA_BREACHetKEY_ARCHIVED_SLA_BREACHa l'enumreasonCode(S5.9) comme « extension documentee ». - Spec S5.9 : Definit 13 valeurs pour
reasonCode. Ne mentionne niKEY_RETIRED_SLA_BREACHniKEY_ARCHIVED_SLA_BREACH. Ne prevoit pas explicitement de mecanisme d'extension. - Review v3 : Qualifie cet ecart de BLOQUANT (evenements non conformes a l'enum spec).
- Impact : Les evenements d'audit produits avec ces codes ne correspondent pas a l'enum contractuel de la spec. Un systeme de validation strict pourrait les rejeter. La legitimite des extensions depend de l'interpretation de la spec vis-a-vis des ajouts non prevus.
DIV-07 (MAJEUR) — CC-265-04 eleve DA-01 au rang d'invariant¶
- CC-265-04 (invariants) : « DA-01: Agregation worst-case — si ANY serveur KO, flag active ».
- CC-265-04 (forbidden) : « Agregation par moyenne ou mediane (masquerait un serveur compromis) ».
- Spec : Ne definit pas de strategie d'agregation multi-serveurs NTS.
- Impact : Le code contract impose comme invariant un comportement qui est une decision architecturale (DA-01) non tracable vers la spec. Un audit de conformite spec vs implementation pourrait contester cette contrainte.
DIV-08 (MINEUR) — HTTP 503 non specifie dans la spec¶
- Plan C9 : Fixe
HTTP 503pour le refus d'emission TST en mode degrade/maintenance. - Spec S5.4 : Contractualise le contenu du refus (
refusalReasonCode,tsaServiceState,tsaServiceDegradationFlags) mais ne fixe pas le code HTTP. - Impact : Faible. Le choix HTTP 503 (Service Unavailable) est semantiquement correct. Le contrat d'API n'est pas ferme pour un audit d'interoperabilite, mais cela n'affecte pas la conformite fonctionnelle.
DIV-09 (MINEUR) — Dependances inter-PD sans statut¶
- Plan S10 : Mentionne PD-55, PD-264, PD-7 dans le hors-perimetre, et H-IMPL-01 a H-IMPL-05 dans les hypotheses.
- Aucun document ne liste le statut (DONE/TODO/STUB) de ces dependances ni la story de destination pour les stubs eventuels.
- Impact : Tracabilite inter-story incomplete. Risque d'hypotheses non verifiees en Gate 8.
DIV-10 (MINEUR) — Variables CI pour tests integration non documentees¶
- Plan S11/S13 : Prevoit des tests d'integration avec PostgreSQL reelle et mocks HSM.
- Plan S13 : Documente le runner CI (
npm test -- --ci --coverage) mais pas les variables d'environnement requises (DATABASE_URL, parametres BullMQ/Redis,CI=true). - Impact : Risque de non-reproductibilite CI.
DIV-11 (MINEUR) — dbStartupTimeout non contractualise dans la spec¶
- Plan DA-05 : Introduit
C1.dbStartupTimeout(configurable, defaut 30s) avec le comportement « l'application NE DEMARRE PAS si la DB est indisponible pendant plus de ce timeout ». - Spec S5.2 : Ne mentionne pas ce parametre dans les parametres contractualises.
- Impact : Faible en isolation (parametre d'implementation). Mais couplage avec DIV-04 : si le plan s'appuie sur ce parametre pour justifier le fail-closed startup, l'absence de contractualisation spec affaiblit la garantie.
4. Zones d'ombre¶
ZO-01 — Test de desaccord inter-serveurs NTS absent Le plan DA-01 introduit la strategie worst-case (si ANY serveur KO -> flag NTS). Les tests TC-NOM-01 (offset > seuil, 1 serveur implicite) et TC-NOM-11 (mesure sur serveurs autorises) ne couvrent pas le scenario de desaccord (1 serveur OK, 1 serveur > seuil). Ce cas est critique pour valider DA-01.
ZO-02 — Concurrence schedulers / endpoint API Le plan prevoit 6 schedulers cadences (NTS, OCSP/CRL, TL, key lifecycle SLA, re-horodatage, degradation escalation) et un endpoint API MAINTENANCE. Aucun document ne traite la concurrence d'acces simultane a TsaDegradationStateService (ex: 2 schedulers modifiant les flags en parallele). Le pattern write-through DB+cache suppose une serialisation implicite (transactions DB), mais ce point n'est pas documente.
ZO-03 — Down migration PostgreSQL CC-265-02 exige « Migration reversible (down migration) » mais ni le plan ni les code contracts ne detaillent le contenu de la down migration (drop tables ? conservation donnees ? impact sur les schedulers existants ?).
ZO-04 — Canal de notification on-call La spec S5.9 et le plan C12/C13 mentionnent « notification exploitation (on-call) via canal contractuel ». Aucun document ne definit le canal (Webhook, PagerDuty, email, Slack). Le plan C12 delegue a AuditLogService existant mais ne confirme pas que ce service supporte la notification on-call.
ZO-05 — Test MAINTENANCE -> HEALTHY absent Le plan V-09 mentionne « R-09 (MAINTENANCE->HEALTHY non teste) : ajout d'un test unitaire supplementaire pour ce path ». Mais le document de tests ne contient pas ce scenario. TC-NOM-10 teste MAINTENANCE -> DEGRADED (flags actifs) mais pas MAINTENANCE -> HEALTHY (aucun flag actif a la sortie).
ZO-06 — reference-clock.service.ts absent de CC-265-04 Le plan C4 documente l'extension de ReferenceClockService avec measureOffset(server) et mentionne le fichier existant. CC-265-04 ne liste pas ce fichier. L'extension d'un fichier existant par un agent sans declaration dans le code contract pourrait generer un conflit avec le proprietaire actuel du fichier.
5. Recommandation¶
- Proceder — convergence confirmee, aucun conflit bloquant
- Rework necessaire — divergences a resoudre avant de continuer
- Escalade — decision humaine requise sur un point structurant
Progression v2 -> v3 :
| Metrique | v2 | v3 | Delta |
|---|---|---|---|
| BLOQUANTS | 2 | 0 | -2 |
| MAJEURS | 5 | 7 | +2 |
| MINEURS | 3 | 4 | +1 |
| Convergences | 14 | 17 | +3 |
| Zones d'ombre | 7 | 6 | -1 |
Les deux BLOQUANTS v2 (calcul tsaServiceState et fusion enums) sont resolus. Quatre MAJEURS v2 sont resolus (DA-05 state calc, DA-02 enum fusion, Jest framework, fail-closed startup partiellement). Trois nouveaux MAJEURS apparaissent (fichier enum audit absent des CC, scheduler 12h vs deadline 1h, fail-closed MAINTENANCE code incoherent). Trois MAJEURS residuels v2 persistent (CC state column, CC file overlap, CC DA-01 invariant).
Actions requises avant re-soumission Gate 5 :
- (MAJEUR) DIV-01 : Mettre a jour l'invariant CC-265-02 pour retirer « state » (aligner sur DA-05 : « flags + maintenanceMode + timestamps »).
- (MAJEUR) DIV-02 : Assigner
tsa-key-lifecycle-metadata.entity.tsa un seul owner (CC-265-02 ou CC-265-07). - (MAJEUR) DIV-03 : Ajouter
audit-reason-code.enum.tsdans les fichiers de CC-265-03 (ou CC-265-12). - (MAJEUR) DIV-04 : Revoir le
refusalReasonCodedu fail-closed startup — soit utiliser un code specifique, soit documenter la convention MAINTENANCE-sans-RBAC dans le plan. - (MAJEUR) DIV-05 : Parametrer l'intervalle du scheduler re-horodatage en fonction de
rehorodatageProcessingDeadline, ou ajouter une contrainte croisee (ex:rehorodatageCheckInterval <= rehorodatageProcessingDeadline / 2). - (MAJEUR) DIV-06 : Qualifier les 2
reasonCodeajoutes (SLA_BREACH) — soit les retirer, soit documenter dans la spec une clause d'extensibilite des enums d'audit. - (MAJEUR) DIV-07 : Requalifier DA-01 dans CC-265-04 comme « decision architecturale » plutot qu'invariant, ou ajouter un test de desaccord inter-serveurs (ZO-01).