Aller au contenu

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_state ne contient pas de colonne state — l'etat est toujours derive. »
  • Plan C2 : « TsaDegradationState : singleton row (flags, maintenanceMode, lastTransitionAt, flagActivationTimestamps). Note : pas de colonne state. »
  • CC-265-02 (invariant) : « INV-265-11: Table tsa_degradation_state singleton (flags + state + timestamps) » — mentionne state comme 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.ts est present.
  • CC-265-12 (files) : Ne liste pas non plus ce fichier. Seul tsa-audit-event.service.ts est 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 refusalReasonCode MAINTENANCE correspond a tsaServiceState=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, tsaServiceState et tsaServiceDegradationFlags sont inconnus. Retourner refusalReasonCode=MAINTENANCE sans que maintenanceMode=true ni que l'etat soit MAINTENANCE cree 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 rehorodatageProcessingDeadline de 24h). »
  • Spec S5.2 : rehorodatageProcessingDeadline est 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_BREACH et KEY_ARCHIVED_SLA_BREACH a l'enum reasonCode (S5.9) comme « extension documentee ».
  • Spec S5.9 : Definit 13 valeurs pour reasonCode. Ne mentionne ni KEY_RETIRED_SLA_BREACH ni KEY_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 503 pour 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 :

  1. (MAJEUR) DIV-01 : Mettre a jour l'invariant CC-265-02 pour retirer « state » (aligner sur DA-05 : « flags + maintenanceMode + timestamps »).
  2. (MAJEUR) DIV-02 : Assigner tsa-key-lifecycle-metadata.entity.ts a un seul owner (CC-265-02 ou CC-265-07).
  3. (MAJEUR) DIV-03 : Ajouter audit-reason-code.enum.ts dans les fichiers de CC-265-03 (ou CC-265-12).
  4. (MAJEUR) DIV-04 : Revoir le refusalReasonCode du fail-closed startup — soit utiliser un code specifique, soit documenter la convention MAINTENANCE-sans-RBAC dans le plan.
  5. (MAJEUR) DIV-05 : Parametrer l'intervalle du scheduler re-horodatage en fonction de rehorodatageProcessingDeadline, ou ajouter une contrainte croisee (ex: rehorodatageCheckInterval <= rehorodatageProcessingDeadline / 2).
  6. (MAJEUR) DIV-06 : Qualifier les 2 reasonCode ajoutes (SLA_BREACH) — soit les retirer, soit documenter dans la spec une clause d'extensibilite des enums d'audit.
  7. (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).