Aller au contenu

PD-277 — Décomposition en tâches agents

1. Matrice des dépendances

ID Agent Module (CC) Description Produit Consomme Dépend de Niveau
T1 agent-developer pd277-migration Migration DDL : 3 colonnes vault_secure.legal_rekey *-PD277-AddNonceAndCertificateColumns.ts [] 0
T2 agent-developer pd277-entity-extension Extension entité LegalReKey (3 @Column) legal-rekey.entity.ts [] 0
T3 agent-developer pd277-error-codes 5 codes d'erreur PD-277 legal-pre.exception.ts [] 0
T4 agent-developer pd277-tsp-interface Extension TspVerificationResult (2 champs optionnels) tsp-verifier.interface.ts [] 0
T5 agent-developer pd277-tsp-stub Extension TspVerifierStub pour certificateId tsp-verifier.stub.ts tsp-verifier.interface.ts [T4] 1
T6 agent-developer pd277-rekey-manager-controls Anti-rejeu nonce + PKI binding dans LegalReKeyManagerService legal-rekey-manager.service.ts legal-rekey.entity.ts, legal-pre.exception.ts, tsp-verifier.interface.ts [T2, T3, T4] 1
T7 agent-developer pd277-rekey-repository Garde d'immuabilité certificats dans LegalReKeyRepository legal-rekey.repository.ts legal-rekey.entity.ts [T2] 1
T8 agent-qa-unit-integration pd277-tests Tests unitaires + intégration (TC-NOM, TC-ERR, TC-INV, TC-NEG, TC-NR) *.spec.ts, test/legal-pre/** Tous les modules T1-T7 [T1, T2, T3, T4, T5, T6, T7] 2

2. Stratégie de parallélisation

parallelization:
  strategy: by_level
  levels:
    - level: 0
      tasks: [1, 2, 3, 4]
      agents: [agent-developer, agent-developer, agent-developer, agent-developer]
      branches:
        - "feature/PD-277-l0-migration"
        - "feature/PD-277-l0-entity"
        - "feature/PD-277-l0-errors"
        - "feature/PD-277-l0-tsp-interface"
      estimated_time: "1h"
    - level: 1
      tasks: [5, 6, 7]
      agents: [agent-developer, agent-developer, agent-developer]
      branches:
        - "feature/PD-277-l1-tsp-stub"
        - "feature/PD-277-l1-rekey-manager"
        - "feature/PD-277-l1-rekey-repository"
      estimated_time: "2h"
    - level: 2
      tasks: [8]
      agents: [agent-qa-unit-integration]
      branches:
        - "feature/PD-277-l2-tests"
      estimated_time: "3h"
  total_sequential_time: "10h"
  total_parallel_time: "6h"
  speedup_factor: 1.67
  git_strategy: branch_per_level

3. Détail des tâches

Tâche 1 — Migration DDL (AddNonceAndCertificateColumns)

  • Agent : agent-developer
  • Niveau : 0
  • Dépend de : []
  • Contract : pd277-migration
  • Fichiers :
  • src/database/migrations/{timestamp}-PD277-AddNonceAndCertificateColumns.ts
  • Description : Créer la migration TypeORM qui ajoute 3 colonnes à vault_secure.legal_rekey :
  • used_nonces JSONB NOT NULL DEFAULT '[]'::jsonb
  • owner_certificate_id VARCHAR(255) NOT NULL DEFAULT ''
  • recipient_certificate_id VARCHAR(255) NOT NULL DEFAULT ''

La méthode up() exécute les 3 ALTER TABLE ADD COLUMN. La méthode down() exécute les 3 ALTER TABLE DROP COLUMN correspondants.

Invariants : INV-277-02, INV-277-04, CA-277-09.

Justification DEFAULT transitoire : Le DEFAULT '' pour les certificats est une décision d'implémentation (H-277-T01) pour compatibilité avec les LegalReKey pré-existants. Protégé par le contrôle fail-closed en T6 (certificats vides → rejet PRE_CERTIFICATE_BINDING_FAILED).

Interdit : modifier des colonnes existantes, créer de nouvelles tables, modifier des triggers ou supprimer des index.


Tâche 2 — Extension entité LegalReKey

  • Agent : agent-developer
  • Niveau : 0
  • Dépend de : []
  • Contract : pd277-entity-extension
  • Fichiers :
  • src/modules/legal-pre/entities/legal-rekey.entity.ts
  • Description : Ajouter 3 propriétés TypeORM à l'entité LegalReKey existante :
  • usedNonces: string[] avec @Column('jsonb', { name: 'used_nonces', default: () => "'[]'" })
  • ownerCertificateId: string avec @Column('varchar', { name: 'owner_certificate_id', length: 255 })
  • recipientCertificateId: string avec @Column('varchar', { name: 'recipient_certificate_id', length: 255 })

Invariants : INV-277-02, INV-277-04, INV-277-05, INV-277-07, INV-277-08.

Les @Column produisent automatiquement les faits Prolog entity_column(legal_re_key, ...) via extract-facts.py (INV-277-07).

Interdit : modifier des @Column existants, ajouter des valeurs à LegalReKeyStatus, modifier select:false sur encryptedKfrags, modifier les index existants.


Tâche 3 — Codes d'erreur PD-277

  • Agent : agent-developer
  • Niveau : 0
  • Dépend de : []
  • Contract : pd277-error-codes
  • Fichiers :
  • src/modules/legal-pre/errors/legal-pre.exception.ts
  • Description : Ajouter les 5 codes d'erreur spécifiques PD-277 dans le fichier d'exceptions existant :
Code Constante HTTP
ERR-NONCE-MISSING ERR_NONCE_MISSING 400
ERR-NONCE-FORMAT ERR_NONCE_FORMAT 400
PRE_NONCE_REPLAY_DETECTED ERR_NONCE_REPLAY 409
PRE_CERTIFICATE_BINDING_FAILED ERR_CERTIFICATE_BINDING 400
ERR-PERSISTENCE-CONTROL ERR_PERSISTENCE_CONTROL 500

Chaque code d'erreur est déterministe (même entrée → même code).

Interdit : modifier les codes d'erreur PD-81 existants (ERR-81-*), utiliser des codes génériques sans distinction nonce/certificat, retourner HTTP 200 sur erreur.


Tâche 4 — Extension interface TSP

  • Agent : agent-developer
  • Niveau : 0
  • Dépend de : []
  • Contract : pd277-tsp-interface
  • Fichiers :
  • src/modules/legal-pre/interfaces/tsp-verifier.interface.ts
  • Description : Étendre TspVerificationResult avec 2 champs optionnels :
  • ownerCertificateId?: string
  • recipientCertificateId?: string

L'interface ITspVerifier existante n'est PAS modifiée (rétrocompatibilité). Seul le type de résultat est enrichi.

Invariants : INV-277-04.

Interdit : supprimer des champs existants, modifier la signature de ITspVerifier.verify().


Tâche 5 — Extension stub TSP

  • Agent : agent-developer
  • Niveau : 1
  • Dépend de : [T4]
  • Contract : pd277-tsp-stub
  • Fichiers :
  • src/modules/legal-pre/providers/tsp-verifier.stub.ts
  • Description : Enrichir TspVerifierStub pour retourner des certificateId dans le résultat de vérification :
  • ownerCertificateId : chaîne non vide cohérente avec le mandat
  • recipientCertificateId : chaîne non vide cohérente avec le mandat

Le stub reste un stub — aucune vérification cryptographique réelle. Les TODO traces existants (AC-81-01-PARTIAL) sont préservés.

En mode nominal, le stub retourne toujours des certificats valides. En configuration de test explicite (TC-ERR-06, TC-NEG-05), il peut retourner des certificats invalides/expirés/révoqués.

Interdit : logique métier dans le stub, appels réseau, suppression de champs existants.


Tâche 6 — Contrôles anti-rejeu nonce + PKI certificate binding

  • Agent : agent-developer
  • Niveau : 1
  • Dépend de : [T2, T3, T4]
  • Contract : pd277-rekey-manager-controls + pd277-rekey-repository
  • Fichiers :
  • src/modules/legal-pre/services/legal-rekey-manager.service.ts
  • src/modules/legal-pre/repositories/legal-rekey.repository.ts
  • Description : Tâche principale de PD-277. Deux responsabilités dans le même agent (propriétaire des 2 modules) :

6a — Anti-rejeu nonce (reEncryptWithNonce) : 1. Valider format nonce (UUID v4 lowercase, 36 chars, regex stricte) → ERR-NONCE-MISSING si absent, ERR-NONCE-FORMAT si hors format 2. Transaction SERIALIZABLE : - Charger le LegalReKey - Vérifier binding PKI valide (certificats non vides) → sinon PRE_CERTIFICATE_BINDING_FAILED (fail-closed sur ReKeys hérités) - Vérifier nonce ∉ used_nonces (opérateur JSONB @>) → PRE_NONCE_REPLAY_DETECTED si déjà présent - Insérer nonce dans used_nonces (opérateur JSONB ||) - Appeler preService.reEncrypt() 3. Rollback complet si une étape échoue 4. Retourner résultat seulement après COMMIT 5. Erreurs de sérialisation (40001) → ERR-PERSISTENCE-CONTROL

6b — PKI certificate binding (generateLegalReKey) : 1. Après verifyBobIdentity() (existant), extraire les certificateId depuis TspVerificationResult 2. Valider non-nullité et non-vacuité des 2 IDs 3. Valider validité des certificats (non expirés, non révoqués, compatibles mandat) → sinon PRE_CERTIFICATE_BINDING_FAILED 4. Persister les certificateId dans le LegalReKey à la création

6c — Garde d'immuabilité (repository) : - updateStatus() ne touche JAMAIS les champs certificats - Vérification explicite si un DTO de mise à jour contient ces champs → rejet fail-closed

Invariants : INV-277-01 à 05.

Interdit : modifier PreService.reEncrypt(), retry automatique sur erreur 40001, comparaison nonce côté applicatif (toujours DB), Math.random(), accepter nonce hors UUID v4, certificats fournis par l'appelant (résolution interne uniquement), méthode de modification des certificats après création.

Décision architecturale : Le nonce est contrôlé au niveau LegalReKeyManagerService, en amont de l'appel à PreService. C'est conforme au principe de séparation : legal-pre gère la conformité, crypto/pre gère la cryptographie. Alternative rejetée : contrôle dans PreService (violerait le périmètre PD-41).


Tâche 7 — Vérification faits Prolog (non-agent)

Cette tâche est une vérification manuelle par l'orchestrateur, pas un agent autonome. Après merge de T2 (entity extension), vérifier que extract-facts.py produit les 3 faits attendus :

entity_column(legal_re_key, used_nonces, jsonb).
entity_column(legal_re_key, owner_certificate_id, varchar).
entity_column(legal_re_key, recipient_certificate_id, varchar).

Aucune modification de extract-facts.py requise (INV-277-07). Vérification intégrée dans la CI via run_audit. (24/24 checks).


Tâche 8 — Tests unitaires et d'intégration

  • Agent : agent-qa-unit-integration
  • Niveau : 2
  • Dépend de : [T1, T2, T3, T4, T5, T6]
  • Contract : pd277-tests
  • Fichiers :
  • src/modules/legal-pre/**/*.spec.ts
  • test/legal-pre/**
  • Description : Couvrir l'intégralité de la matrice de tests PD-277 :

Nominaux (TC-NOM-01 à 05) : - TC-NOM-01 : PKI binding nominal (generateReKey avec certificats) - TC-NOM-02 : Anti-rejeu nonce (1er succès + 2e rejet) - TC-NOM-03 : Vérification faits Prolog générés - TC-NOM-04 : Audit 24/24 (intégration CI) - TC-NOM-05 : Migration up/down

Erreurs (TC-ERR-01 à 10) : - TC-ERR-01/02 : Nonce manquant/format invalide - TC-ERR-03 : Nonce replay - TC-ERR-04/05/06 : Certificats absents/invalides/incohérents - TC-ERR-07 : Erreur persistance → rollback - TC-ERR-08 : Tentative modification certificats → rejet - TC-ERR-09/10 : Facts obsolètes, audit < 24/24

Invariants (TC-INV-03, 05, 06, 08) : - TC-INV-03 : Nonce replay sans duplication - TC-INV-05/06 : Certificat owner/recipient absent → rejet total - TC-INV-08 : Snapshot StatusEnum avant/après

Négatifs (TC-NEG-01 à 06) : - TC-NEG-01 : Variations casse/espaces nonce - TC-NEG-02 : Concurrence réelle (Promise.all, PAS séquentiel) - TC-NEG-03 : Même nonce sur 2 LegalReKey → les 2 réussissent - TC-NEG-04 : Substitution certificats post-création - TC-NEG-05 : Certificat expiré/révoqué - TC-NEG-06 : Facts anciens réutilisés

Non-régression (TC-NR-01 à 04) : - TC-NR-01 : Stabilité 22 checks initiaux - TC-NR-02 : Absence d'impact hors legal-pre - TC-NR-03 : Migration up/down répétable - TC-NR-04 : Suppression ReKey → suppression used_nonces

Contraintes : - Utiliser crypto.randomUUID() pour les nonces de test - TC-NEG-02 doit utiliser Promise.all (concurrence réelle) - Ne PAS mocker la transaction SERIALIZABLE en intégration - Ne PAS modifier PreService ou UmbralProvider

4. Décisions architecturales

DA-1 : Nonce contrôlé au niveau LegalReKeyManagerService

  • Approche choisie : Le contrôle anti-rejeu est dans LegalReKeyManagerService.reEncryptWithNonce(), en amont de PreService.reEncrypt().
  • Alternatives rejetées :
  • Contrôle dans PreService : viole le périmètre PD-41 et mélange conformité légale et cryptographie bas niveau.
  • Contrôle dans le controller : trop haut niveau, pas transactionnel.
  • Trade-off : PreService ne sait rien du nonce, ce qui impose que tout appelant de reEncrypt passe par reEncryptWithNonce.

DA-2 : Modules repository et service dans le même agent

  • Approche choisie : T6 combine pd277-rekey-manager-controls et pd277-rekey-repository dans un seul agent (agent-nonce-pki).
  • Alternatives rejetées :
  • 2 agents séparés : introduirait une dépendance cyclique (le service appelle le repository, le repository protège les invariants du service).
  • Trade-off : agent légèrement plus complexe mais cohésion fonctionnelle forte (invariants INV-277-05 partagés).

5. Résumé

Métrique Valeur
Total tâches agents 7 (+ 1 vérification orchestrateur)
Niveaux de parallélisation 3
Temps séquentiel estimé 10h
Temps parallèle estimé 6h
Speedup factor 1.67x
Stratégie Git branch_per_level
Agents developer 6 tâches (T1-T6)
Agents QA 1 tâche (T8)
Vérification orchestrateur 1 tâche (T7 — faits Prolog)

Graphe d'exécution

Niveau 0 ─────────────────────────────────────────
  T1 (migration)  T2 (entity)  T3 (errors)  T4 (interface)
    │                │  │           │            │  │
    │                │  │           │            │  │
Niveau 1 ─────────────────────────────────────────
    │             T7 (repo) T6 (manager)    T5 (stub)
    │                │           │               │
    │                │           │               │
Niveau 2 ─────────────────────────────────────────
    └──────────── T8 (tests) ────────────────────┘