Aller au contenu

PD-265 — Rapport de confrontation (Gate 5 — v2)

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 Plan d'implementation
PD-265-code-contracts.yaml 4 Code contracts inter-agents
PD-265-review-step5-v2.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 : flags comme source de verite Spec S5.4, plan DA-05, CC-265-03 et tests (TC-ERR-12, TC-NOM-02) convergent tous sur le principe : tsaServiceDegradationFlags est la source de verite, tsaServiceState est derive.

CONV-04 — NTS fail-closed Spec INV-265-01, plan C4+C9, CC-265-04 et tests TC-NOM-01/TC-ERR-01 convergent sur le principe : tout echec NTS bloque l'emission TST.

CONV-05 — 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-06 — 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.

CONV-07 — 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-08 — 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-09 — 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-10 — 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-11 — 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-12 — 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-13 — 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-14 — Hors perimetre aligne Plan S10 reprend fidelement les exclusions de la spec S2. Aucun element hors perimetre n'est traite.

3. Divergences

Les conflits ne sont JAMAIS lisses. Chaque divergence est rendue visible.

DIV-01 (BLOQUANT) — Calcul de tsaServiceState : DA-05 vs Spec S5.4

  • Spec S5.4 : Quand tsaServiceDegradationFlags contient 1 seul element, l'etat prend une valeur specifique (DEGRADED_NTS, DEGRADED_REVOCATION, DEGRADED_TRUSTLIST, DEGRADED_KEY_LIFECYCLE). L'etat DEGRADED (composite) n'apparait que si >=2 flags actifs.
  • Plan DA-05 : « flags.length > 0 -> DEGRADED (prefixe par le flag prioritaire pour affichage, mais l'etat composite expose tous les flags) ». Aucune distinction 1 flag vs >=2 flags.
  • Incoherence interne au plan : Le plan S5 (mapping tests) mentionne pourtant state=DEGRADED_NTS pour TC-NOM-01 et state=DEGRADED_REVOCATION pour TC-ERR-02, ce qui contredit DA-05.
  • Tests : TC-NOM-01 attend DEGRADED_NTS, TC-ERR-02 attend DEGRADED_REVOCATION, TC-ERR-05 attend DEGRADED_KEY_LIFECYCLE — tous avec un seul flag. Conforme a la spec, contradictoire avec DA-05.
  • Impact : Le refusalReasonCode norme (S5.1) depend directement de tsaServiceState. Si l'implementation suit DA-05 litteralement, les refus API seront non conformes et les tests echoueront.

DIV-02 (BLOQUANT) — Enums reasonCode / refusalReasonCode : Plan DA-02 vs Spec S5.1/S5.9

  • Spec : Deux enums distinctes :
  • refusalReasonCode (S5.1) : MAINTENANCE | NTS_DEGRADED | REVOCATION_DEGRADED | TRUSTLIST_DEGRADED | KEY_LIFECYCLE_DEGRADED | COMPOSITE_DEGRADED (6 valeurs)
  • reasonCode (S5.9 evenements d'audit) : NTS_TIMEOUT | NTS_OFFSET | OCSP_REVOKED | OCSP_UNKNOWN | OCSP_STALE | CRL_LISTED | CRL_UNAVAILABLE | CRL_STALE | TL_STALE | TL_UNTRUSTED | KEY_OVERDUE | REH_TIMESTAMP_DEADLINE | MAX_DEGRADED_DURATION (13 valeurs)
  • Plan DA-02 : Un seul enum combine RefusalReasonCode de 16 valeurs qui fusionne les deux domaines et introduit des renommages/ajouts :
  • Ajouts non dans la spec : KEY_RETIRED_SLA_BREACH, KEY_ARCHIVED_SLA_BREACH
  • Renommages : TL_STALE -> TRUSTLIST_EXPIRED, TL_UNTRUSTED -> TRUSTLIST_AUTHORITY_ABSENT, MAX_DEGRADED_DURATION -> MAX_DEGRADED_EXCEEDED
  • Suppressions : OCSP_UNKNOWN, OCSP_STALE, CRL_UNAVAILABLE, CRL_STALE (4 codes spec absents du plan)
  • Fusion : les refusal codes (NTS_DEGRADED, REVOCATION_DEGRADED, etc.) sont melanges avec les audit event reason codes
  • COMPOSITE_DEGRADED (refusal code spec) absent de l'enum plan
  • Code contracts CC-265-03 : Mentionne RefusalReasonCode (un seul fichier enum refusal-reason-code.enum.ts), confirmant la fusion.
  • Tests : Les tests utilisent les valeurs spec (refusalReasonCode="NTS_DEGRADED" dans TC-NOM-01, reasonCode dans les evenements d'audit) — coherents avec la spec, pas avec le plan.
  • Impact : L'enum plan est non conforme aux formats contractuels de la spec. Les evenements d'audit et refus API ne passeront pas la validation si les noms different. Un audit tiers echouera.

DIV-03 (MAJEUR) — Agregation NTS multi-serveurs non specifiee

  • Spec S5.4 : Definit la condition NTS (mesure NTS impossible OU abs(ntsOffsetMs) > ntsAlertThreshold) mais ne precise pas la strategie de reduction quand ntsReferenceServers contient 2+ serveurs.
  • Plan DA-01 : Introduit une strategie worst-case (ANY serveur KO -> flag NTS). Decision architecturale documentee avec justification.
  • CC-265-04 : Impose DA-01 comme invariant du code contract : « DA-01: Agregation worst-case — si ANY serveur KO, flag active ».
  • Tests TC-NOM-11 : Testent uniquement la mesure sur les serveurs autorises, pas le cas de desaccord inter-serveurs.
  • Impact : Le plan comble un gap de la spec, ce qui est legitime en DA. Cependant, le code contract eleve cette DA au rang d'invariant alors qu'elle n'est pas dans la spec. Deux implementations pourraient produire des resultats differents. Un test de desaccord inter-serveurs manque.

DIV-04 (MAJEUR) — Comportement cache non initialise / DB indisponible

  • Plan DA-05 : Le cache memoire est « rafraichi au demarrage (onModuleInit) et synchronise a chaque modification ». Les guards/metriques lisent depuis le cache.
  • Spec INV-265-01 : Exige fail-closed (en cas de doute, blocage emission TST).
  • Aucun document ne contractualise le comportement si : (a) le cache est vide au demarrage (DB down), (b) le cache se desynchronise, © le service C3 n'a pas termine son init quand un TST est demande.
  • Impact : Risque de fail-open (emission TST autorisee en absence de donnees de flags). L'INV-265-01 pourrait etre viole silencieusement.

DIV-05 (MAJEUR) — Chevauchement de fichiers entre code contracts CC-265-02 et CC-265-07

  • CC-265-02 (entities, owner: agent-foundation) : liste src/modules/tsa/entities/tsa-key-lifecycle-metadata.entity.ts
  • CC-265-07 (key lifecycle, owner: agent-lifecycle) : liste le meme fichier src/modules/tsa/entities/tsa-key-lifecycle-metadata.entity.ts
  • Impact : Deux agents (agent-foundation et agent-lifecycle) ont la responsabilite du meme fichier. Risque de conflit d'implementation en multi-agents et tracabilite d'ownership non deterministe.

DIV-06 (MAJEUR) — Incoherence DA-05 vs CC-265-02 sur la persistance de state

  • Plan DA-05 : « L'etat derive (tsaServiceState) n'est jamais persiste — il est calcule a la volee ».
  • Plan C2 (entity description) : « TsaDegradationState : singleton row (flags, state, maintenanceMode, lastTransitionAt, flagActivationTimestamps) » — la colonne state existe.
  • CC-265-02 (invariant) : « Table tsa_degradation_state singleton (flags + state + timestamps) » — confirme la persistance de state.
  • Impact : Contradiction interne au plan. Si state est une colonne DB, il est persiste. Si DA-05 prevaut, la colonne ne devrait pas exister. L'implementation pourrait diverger selon l'interpretation.

DIV-07 (MAJEUR) — Code contract CC-265-04 impose DA-01 comme invariant

  • CC-265-04 (invariants) : « DA-01: Agregation worst-case — si ANY serveur KO, flag active » est liste comme invariant.
  • Spec : Ne definit pas de strategie d'agregation multi-serveurs (cf. DIV-03).
  • Impact : Les invariants d'un code contract devraient etre tracables vers un invariant spec ou un critere d'acceptation. DA-01 est une decision plan, pas un invariant contractuel. Risque de non-conformite si un auditeur exige la tracabilite des invariants vers la spec.

DIV-08 (MAJEUR) — Framework de test non documente

  • Plan S13 (Contraintes techniques) : Mentionne des fichiers *.spec.ts et l'execution CI mais ne specifie pas le framework de test (Jest, Vitest, ou autre).
  • Plan S11 (Perimetre de test) : Definit 3 niveaux (Unit, Integration, E2E) sans mentionner le runner.
  • Impact : Ambiguite sur les mocks (Jest auto-mock vs Vitest), les timers (fake timers API), et la compatibilite ESM/CJS. Non-reproductibilite CI potentielle.

DIV-09 (MINEUR) — HTTP 503 non specifie dans la spec

  • Plan C9 : Fixe HTTP 503 pour le refus d'emission TST.
  • Spec S5.4 : Contractualise le contenu (refusalReasonCode, tsaServiceState, tsaServiceDegradationFlags) mais ne fixe pas le code HTTP.
  • Impact : Faible. Le choix HTTP 503 (Service Unavailable) est semantiquement correct. Mais le contrat d'API n'est pas ferme pour un audit d'interoperabilite.

DIV-10 (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-11 (MINEUR) — Variables CI non documentees

  • Plan S11/S13 : Prevoit des tests d'integration avec PostgreSQL reelle et mocks HSM, mais ne documente pas les variables CI requises (DATABASE_URL, parametres BullMQ/Redis, CI=true).
  • Impact : Risque de non-reproductibilite CI. Tests verts en local / rouges en CI.

4. Zones d'ombre

ZO-01 — Fail-closed du cache au demarrage Aucun document ne specifie le comportement de canEmitTst() si le cache C3 n'est pas initialise au moment d'une requete TST (ex: DB indisponible au onModuleInit). La spec exige fail-closed, mais le plan ne contractualise pas ce cas.

ZO-02 — Cas de desaccord inter-serveurs NTS La spec ne definit pas d'agregation multi-serveurs. Le plan introduit DA-01 (worst-case). Les tests ne couvrent pas le scenario de desaccord (1 serveur OK, 1 serveur > seuil). Ce cas est critique pour le fail-closed NTS.

ZO-03 — Concurrence schedulers / endpoint API Le plan prevoit 5+ schedulers cadences (NTS, OCSP/CRL, TL, key lifecycle SLA, re-horodatage, escalation) et un endpoint API MAINTENANCE. Aucun document ne traite la concurrence d'acces simultane a TsaDegradationStateService (2 schedulers modifiant les flags en parallele).

ZO-04 — Down migration PostgreSQL CC-265-02 exige « Migration reversible (down migration) » mais le plan ne detaille pas le contenu de la down migration (drop tables ? conservation donnees ?).

ZO-05 — Canal de notification on-call La spec S5.9 et le plan C12/C13 mentionnent « notification exploitation (on-call) via canal contractuel » mais aucun document ne definit le canal (Webhook, PagerDuty, email, Slack).

ZO-06 — Endpoint de status/health Le plan cree TsaMonitoringController pour le endpoint MAINTENANCE, mais aucun endpoint de health/status n'est defini pour exposer l'etat TSA en lecture (GET). La spec ne l'exige pas explicitement, mais les operateurs en auraient besoin.

ZO-07 — Politique de re-horodatage en DEGRADED_KEY_LIFECYCLE La spec S5.4 autorise le re-horodatage en DEGRADED_KEY_LIFECYCLE sous 3 conditions (flag unique, cert valide, TL valide). Le plan DA-03 implemente ce path conditionnel. La review v1 notait que ce choix est « contestable » (R-11). Aucun test ne verifie les 3 conditions individuellement (seul le path global est teste).

5. Recommandation

  • Proceder — convergence confirmee, aucun conflit bloquant
  • Rework necessaire — divergences a resoudre avant de continuer
  • Escalade — decision humaine requise sur un point structurant

Actions requises avant re-soumission Gate 5 :

  1. (BLOQUANT) DIV-01 : Corriger DA-05 pour aligner le calcul de tsaServiceState sur la spec S5.4 (distinction 1 flag -> DEGRADED_* vs >=2 flags -> DEGRADED).
  2. (BLOQUANT) DIV-02 : Separer les deux enums (refusalReasonCode et reasonCode) conformement a la spec. Restaurer les codes manquants (OCSP_UNKNOWN, OCSP_STALE, CRL_UNAVAILABLE, CRL_STALE, COMPOSITE_DEGRADED). Aligner les nommages (TL_STALE, TL_UNTRUSTED, MAX_DEGRADED_DURATION). Les ajouts DA-02 (KEY_RETIRED_SLA_BREACH, KEY_ARCHIVED_SLA_BREACH) peuvent rester comme extension documentee.
  3. (MAJEUR) DIV-05 : Resoudre le chevauchement tsa-key-lifecycle-metadata.entity.ts — assigner a un seul owner.
  4. (MAJEUR) DIV-06 : Trancher si state est persiste ou derive. Aligner DA-05, C2 et CC-265-02.
  5. (MAJEUR) DIV-04 : Contractualiser le comportement fail-closed du cache C3 au demarrage.
  6. (MAJEUR) DIV-07 : Retirer DA-01 des invariants CC-265-04 ou le qualifier comme « decision architecturale ».
  7. (MAJEUR) DIV-08 : Documenter le framework de test dans S13.