Aller au contenu

PD-103 — Decomposition multi-agents

1. Analyse de l'existant (codebase probe)

ProbatioVault-app

Element Statut Impact
src/capture/ N'existe pas Creation complete
src/seal/state-machine.ts Existe Pattern FSM a copier (ALLOWED_TRANSITIONS, InvalidTransitionError, monotone)
src/seal/orchestrator.ts Existe Pattern orchestration multi-etapes a suivre
src/export/crypto-pipeline.ts Existe Pattern pipeline crypto (hash + encrypt)
src/crypto/aes-gcm.ts Existe Reutilise tel quel pour AES-256-GCM
src/crypto/zeroize.ts Existe Reutilise pour withZeroize() / zeroization DEK
@noble/hashes v1.5.0 Installe SHA3-256 via @noble/hashes/sha3
react-native-quick-crypto Non installe Decision : utiliser @noble/hashes (deja present, pur JS, Hermes-compatible)
expo-screen-capture v8.0.9 Installe Capture ecran disponible
zustand v5.0.8 Installe Store pattern via useSealStore.ts
zod v4.3.6 Installe Validation schemas
Jest config Mock expo-screen-capture deja present Tests unitaires prets
Vitest config src/crypto/__tests__/ separe Tests crypto ESM-only

ProbatioVault-backend

Element Statut Impact
src/modules/capture/ N'existe pas Creation complete
src/modules/documents/services/deposit.service.ts Existe Pattern pg_advisory_xact_lock pour idempotence
src/modules/urgent-seal/services/seal-crypto.service.ts Existe Pattern DEK wrapping AES-256-GCM
Rate-limit Redis Existe Extension config pour /documents/capture
BullMQ Existe Queues async post-commit
Migration pattern {timestamp}-PD103-{Description}.ts Naming confirme

ProbatioVault-infra

Element Statut Impact
terraform/modules/s3-captures/ N'existe pas Nouveau module Terraform
Pattern module main.tf + variables.tf + outputs.tf Confirme

2. Decision trace

# Decision Alternatives considerees Choix Justification
D1 Librairie SHA3-256 mobile react-native-quick-crypto (natif) vs @noble/hashes/sha3 (pur JS) @noble/hashes/sha3 Deja installe, Hermes-compatible, evite ajout native module + rebuild EAS. Si P95 > 3s sur images larges, escalade vers module natif (HT-103-01).
D2 AES-256-GCM mobile react-native-quick-crypto vs src/crypto/aes-gcm.ts existant Reutiliser src/crypto/aes-gcm.ts Code prouve en production (PD-284, PD-248). Pas de nouvelle dependance.
D3 RSA-OAEP wrapping mobile react-native-quick-crypto vs expo-crypto expo-crypto (deja installe) Expo SDK 54 fournit RSA-OAEP via expo-crypto. Evite ajout native module. Verifier support SHA-256 digest dans expo-crypto sinon fallback WebCrypto polyfill.
D4 Zeroization DEK Custom vs src/crypto/zeroize.ts existant Reutiliser withZeroize() Pattern deja valide et teste (PD-284). Limitation GC documentee dans spec.
D5 FSM capture Custom vs copie src/seal/state-machine.ts Copie + adaptation Pattern monotone prouve. 8 etats vs 6 pour seal. Ajout gardes specifiques (hash+encrypt pour CAPTURED->UPLOADING).
D6 Store capture Redux vs Zustand Zustand Coherence projet (tous les stores sont Zustand). Pattern useSealStore.ts.
D7 Idempotence backend Application-level vs pg_advisory_xact_lock pg_advisory_xact_lock Pattern identique a deposit.service.ts (INV-60-02). Lock sur capture_id normalis lowercase.
D8 Journal append-only Table separee vs colonne JSON Table capture_audit_log separee INSERT-ONLY avec trigger BEFORE UPDATE/DELETE. Separation mutation (capture_events) vs immutable (journal).
D9 GC orphelins S3 S3 lifecycle rules seules vs cron reconciliation Cron + lifecycle rules Double protection : lifecycle rules comme filet, cron pour detection active + audit log.
D10 Parallelisation agents sequential vs by_level (waves) by_level 4 waves avec max 5 agents paralleles. Reduit le temps total de ~15 agents sequentiels a ~4 waves.
D11 Projet des tests mobile Jest seul vs Jest + Vitest Jest pour capture + Vitest pour crypto pure Coherence : les tests crypto ESM (@noble/*) sont deja sous Vitest. Les tests d'integration capture restent sous Jest.
D12 Upload multipart Custom vs AWS SDK @aws-sdk/lib-storage @aws-sdk/lib-storage (Upload class) Gestion automatique chunking, retry, abort. Deja utilise cote backend. Cote mobile : implementation manuelle car pas d'AWS SDK RN.

3. Liste ordonnee des taches

Wave 1 — Fondations (5 agents paralleles, aucune dependance inter-agents)

T1 : capture-types (agent-developer, app)

  • Scope : Types partages et branded types pour le domaine capture
  • Fichiers :
  • src/capture/types.ts
  • src/types/capture.ts (re-export branded types)
  • Dependances : aucune
  • Invariants couverts : INV-103-28 (enum CaptureState), INV-103-31 (CaptureId branded)
  • Tests : aucun (types purs)
  • Estimation : XS

T2 : capture-state-machine (agent-developer, app) — CC-1

  • Scope : FSM monotone 8 etats, gardes de transition, terminal enforcement
  • Fichiers :
  • src/capture/state-machine.ts
  • src/capture/__tests__/state-machine.test.ts
  • Dependances : T1 (types)
  • Pattern source : Copier src/seal/state-machine.ts puis adapter
  • Invariants couverts : INV-103-20..29, INV-103-38, INV-103-28
  • TC couverts : TC-INV-02, TC-INV-09, TC-INV-10, TC-NOM-12, TC-ERR-02
  • Estimation : S

T3 : capture-crypto (agent-developer, app) — CC-2

  • Scope : Pipeline crypto local (SHA3-256, AES-256-GCM, RSA-OAEP wrapping, zeroization)
  • Fichiers :
  • src/capture/crypto-pipeline.ts
  • src/capture/kek-provider.ts
  • src/capture/__tests__/crypto-pipeline.test.ts (Jest, mocks crypto)
  • src/capture/__tests__/crypto-pipeline.vitest.ts (Vitest, real crypto)
  • Dependances : aucune (utilise src/crypto/aes-gcm.ts et src/crypto/zeroize.ts existants)
  • Invariants couverts : INV-103-01..03, INV-103-06, INV-103-09, INV-103-30, INV-103-32, INV-103-39
  • TC couverts : TC-INV-01, TC-INV-03, TC-INV-12, TC-ERR-05, TC-ERR-07
  • Decisions : D1 (@noble/hashes), D2 (aes-gcm existant), D3 (expo-crypto RSA), D4 (zeroize existant)
  • Estimation : M

T4 : capture-ocr (agent-developer, app) — CC-3

  • Scope : OCR local Apple Vision, non-bloquant, desactivable
  • Fichiers :
  • src/capture/ocr-service.ts
  • src/capture/__tests__/ocr-service.test.ts
  • Dependances : aucune
  • Invariants couverts : INV-103-04, INV-103-05
  • TC couverts : TC-NOM-02, TC-NOM-03, TC-ERR-03
  • Estimation : S

T5 : capture-purge (agent-developer, app) — CC-7

  • Scope : purgeStale() au demarrage, suppression locale post-UPLOADED, watchdog TTL differe
  • Fichiers :
  • src/capture/purge-manager.ts
  • src/capture/__tests__/purge-manager.test.ts
  • Dependances : aucune
  • Invariants couverts : INV-103-07, INV-103-38
  • TC couverts : TC-NOM-04, TC-NOM-17, TC-ERR-11
  • Estimation : S

T6 : capture-migration (agent-developer, backend) — CC-13

  • Scope : Migration DDL : tables capture_events + capture_audit_log
  • Fichiers :
  • src/database/migrations/1743638400000-PD103-CreateCaptureEvents.ts
  • src/database/migrations/1743638400001-PD103-CreateCaptureAuditLog.ts
  • Dependances : aucune
  • Invariants couverts : INV-103-10, INV-103-37
  • Colonnes cles :
  • capture_events : capture_id (PK, lowercase), status, signature_status, hsm_signature_ref, payload_canonical_sha256, dek_wrapped, kek_id, seal_delayed, seal_delayed_conforming_cycles, created_at, updated_at
  • capture_audit_log : id, capture_id, event_type, payload_json, created_at + trigger BEFORE UPDATE/DELETE RAISE EXCEPTION
  • Contrainte : ALTER TYPE ADD VALUE -> commitTransaction() AVANT toute clause WHERE (learning PD-282)
  • Estimation : S

Wave 2 — Services dependants (4 agents paralleles)

T7 : capture-store (agent-developer, app) — CC-5

  • Scope : Zustand store persistant pour etat capture + differe + progression
  • Fichiers :
  • src/store/useCaptureStore.ts
  • src/store/__tests__/useCaptureStore.test.ts
  • Dependances : T1 (types), T2 (state-machine)
  • Pattern source : src/store/useSealStore.ts
  • Estimation : S

T8 : capture-upload (agent-developer, app) — CC-4

  • Scope : Upload single + multipart S3, retry borne, integrite Content-MD5, annulation, reprise differee
  • Fichiers :
  • src/capture/upload-service.ts
  • src/capture/multipart-upload.ts
  • src/capture/__tests__/upload-service.test.ts
  • Dependances : T3 (crypto — besoin du ciphertext)
  • Invariants couverts : INV-103-06, INV-103-22, INV-103-23, INV-103-29
  • TC couverts : TC-NOM-05, TC-NOM-13, TC-NOM-14, TC-ERR-01, TC-ERR-04, TC-ERR-14
  • Estimation : L

T9 : capture-kek-keyring (agent-developer, backend) — CC-11

  • Scope : Keyring KEK backend (courante + historiques), unwrap DEK, codes 422/503
  • Fichiers :
  • src/modules/capture/services/kek-keyring.service.ts
  • src/modules/capture/__tests__/kek-keyring.service.spec.ts
  • Dependances : aucune (mais T6 migration utile pour integration)
  • Pattern source : src/modules/urgent-seal/services/seal-crypto.service.ts
  • Invariants couverts : INV-103-09, INV-103-30, INV-103-34
  • TC couverts : TC-NOM-16, TC-INV-13, TC-ERR-16, TC-ERR-17
  • Estimation : M

T10 : capture-idempotence (agent-developer, backend) — CC-10

  • Scope : Calcul payload_canonical_sha256, serialisation JSON deterministe, comparaison fingerprint
  • Fichiers :
  • src/modules/capture/services/capture-idempotence.service.ts
  • src/modules/capture/__tests__/capture-idempotence.service.spec.ts
  • Dependances : aucune
  • Pattern source : src/modules/documents/services/deposit.service.ts (pg_advisory_xact_lock)
  • Invariants couverts : INV-103-31, INV-103-37
  • TC couverts : TC-NOM-15, TC-INV-06, TC-ERR-13
  • Decisions : D7 (pg_advisory_xact_lock)
  • Estimation : M

Wave 3 — Orchestration (3 agents, M12 depend de M9)

T11 : capture-orchestrator (agent-developer, app) — CC-6

  • Scope : Coordination sequentielle purgeStale -> capture -> hash -> encrypt -> wrap -> upload -> purge locale
  • Fichiers :
  • src/capture/orchestrator.ts
  • src/capture/api-client.ts
  • src/capture/notifications.ts
  • src/capture/index.ts (barrel export)
  • src/capture/__tests__/orchestrator.test.ts
  • Dependances : T2 (state-machine), T3 (crypto), T4 (ocr), T5 (purge), T7 (store), T8 (upload)
  • Pattern source : src/seal/orchestrator.ts
  • Invariants couverts : INV-103-03, INV-103-07, INV-103-12, INV-103-24, INV-103-31
  • TC couverts : TC-NOM-01, TC-NOM-06, TC-NOM-08 (push)
  • Estimation : L

T12 : capture-ingest (agent-developer, backend) — CC-9

  • Scope : POST /documents/capture — controller, DTO, validation, skew, unwrap, idempotence, persistance
  • Fichiers :
  • src/modules/capture/capture.module.ts
  • src/modules/capture/capture.controller.ts
  • src/modules/capture/services/capture-ingest.service.ts
  • src/modules/capture/dto/create-capture.dto.ts
  • src/modules/capture/entities/capture-event.entity.ts
  • src/modules/capture/entities/capture-audit-log.entity.ts
  • src/modules/capture/__tests__/capture-ingest.service.spec.ts
  • src/modules/capture/__tests__/capture.controller.spec.ts
  • Dependances : T6 (migration), T9 (kek-keyring), T10 (idempotence)
  • Invariants couverts : INV-103-08, INV-103-10, INV-103-11, INV-103-25
  • TC couverts : TC-NOM-07, TC-NOM-08, TC-ERR-06, TC-ERR-08, TC-ERR-10, TC-ERR-12
  • Estimation : XL

T13 : capture-reconciliation (agent-developer, backend) — CC-12

  • Scope : Cron 10min : scan non-terminaux, SEAL_DELAYED trigger/clearing, GC orphelins S3, re-enqueue
  • Fichiers :
  • src/modules/capture/services/capture-reconciliation.service.ts
  • src/modules/capture/__tests__/capture-reconciliation.service.spec.ts
  • Dependances : T12 (capture-ingest — besoin entity + service references)
  • Invariants couverts : INV-103-11, INV-103-33, INV-103-35, INV-103-36
  • TC couverts : TC-INV-07, TC-INV-08, TC-INV-11, TC-INV-14, TC-ERR-09
  • Decisions : D8 (journal separe), D9 (cron + lifecycle)
  • Estimation : L

Wave 4 — UI + Infra + Integration tests (3 agents paralleles)

T14 : capture-ui (agent-developer, app) — CC-8

  • Scope : Ecran capture, previsualisation, validation/annulation, toggle OCR, progression upload
  • Fichiers :
  • src/screens/capture/CaptureScreen.tsx
  • src/components/capture/CapturePreview.tsx
  • src/components/capture/CaptureProgress.tsx
  • src/components/capture/CaptureButton.tsx
  • src/hooks/useCapture.ts
  • src/i18n/locales/fr/capture.json
  • src/i18n/locales/en/capture.json
  • src/screens/capture/__tests__/CaptureScreen.test.tsx
  • Dependances : T11 (orchestrator)
  • TC couverts : (UI, non contractuels directement)
  • Estimation : M

T15 : capture-tests-integration (agent-developer, backend) — CC-14

  • Scope : Tests d'integration backend complets (controller + service + DB)
  • Fichiers :
  • src/modules/capture/__tests__/capture-ingest.integration.spec.ts
  • src/modules/capture/__tests__/capture-reconciliation.integration.spec.ts
  • src/modules/capture/__tests__/capture-idempotence.integration.spec.ts
  • Dependances : T12 (capture-ingest), T13 (reconciliation)
  • TC couverts : TC-INV-04, TC-INV-05, TC-INV-07, TC-INV-11
  • Estimation : L

T16 : capture-s3-config (agent-developer, infra) — CC-15

  • Scope : Module Terraform bucket S3 captures avec lifecycle rules orphelins
  • Fichiers :
  • terraform/modules/s3-captures/main.tf
  • terraform/modules/s3-captures/variables.tf
  • terraform/modules/s3-captures/outputs.tf
  • terraform/s3-captures-module.tf (instantiation)
  • Dependances : aucune
  • Invariants couverts : INV-103-33
  • Estimation : S

4. Strategie de parallelisation

Mode : by_level (4 waves)

Wave 1 (5 agents)  ─────────────────────────────────────────
  T1:types  T2:fsm  T3:crypto  T4:ocr  T5:purge  T6:migration

Wave 2 (4 agents)  ─────────────────────────────────────────
  T7:store  T8:upload  T9:kek-keyring  T10:idempotence

Wave 3 (3 agents, T13 apres T12)  ──────────────────────────
  T11:orchestrator  T12:ingest  →  T13:reconciliation

Wave 4 (3 agents)  ─────────────────────────────────────────
  T14:ui  T15:tests-integration  T16:s3-config

Verification TypeScript incrementale : Apres chaque wave, executer npx tsc --noEmit sur le projet cible (learning PD-254/282/265/283/85).

5. Graphe de dependances

graph TD
    subgraph "Wave 1"
        T1[T1: types]
        T2[T2: state-machine]
        T3[T3: crypto-pipeline]
        T4[T4: ocr-service]
        T5[T5: purge-manager]
        T6[T6: migration]
    end

    subgraph "Wave 2"
        T7[T7: capture-store]
        T8[T8: upload-service]
        T9[T9: kek-keyring]
        T10[T10: idempotence]
    end

    subgraph "Wave 3"
        T11[T11: orchestrator]
        T12[T12: capture-ingest]
        T13[T13: reconciliation]
    end

    subgraph "Wave 4"
        T14[T14: capture-ui]
        T15[T15: tests-integration]
        T16[T16: s3-config]
    end

    T1 --> T2
    T1 --> T7
    T2 --> T7
    T2 --> T11
    T3 --> T8
    T3 --> T11
    T4 --> T11
    T5 --> T11
    T7 --> T11
    T8 --> T11
    T6 --> T12
    T9 --> T12
    T10 --> T12
    T12 --> T13
    T11 --> T14
    T12 --> T15
    T13 --> T15

6. Matrice de couverture TC -> Taches

Test ID Tache(s) Niveau
TC-NOM-01 T3, T8, T11 Integration
TC-NOM-02 T4 Unit
TC-NOM-03 T4 Unit
TC-NOM-04 T5 Unit
TC-NOM-05 T8 Integration
TC-NOM-06 T11 Integration
TC-NOM-07 T12 Integration
TC-NOM-08 T12 (garde), T11 (push) Integration
TC-NOM-09 Pipeline existant Integration
TC-NOM-10 T3, T11 Perf
TC-NOM-11 T8, T11 Perf
TC-NOM-12 T2 Unit
TC-NOM-13 T8 Integration
TC-NOM-14 T8, T5 Integration
TC-NOM-15 T10 Integration
TC-NOM-16 T9 Integration
TC-NOM-17 T5 Unit
TC-ERR-01 T8 Unit
TC-ERR-02 T2 Unit
TC-ERR-05 T3 Unit
TC-ERR-06 T12 Unit
TC-ERR-07 T3 Unit
TC-ERR-08 T12 Unit
TC-ERR-09 T13 Unit
TC-ERR-10 T12 Integration
TC-ERR-11 T5 Unit
TC-ERR-12 T12 Unit
TC-ERR-13 T10 Unit
TC-ERR-16 T9 Unit
TC-ERR-17 T9 Unit
TC-INV-01 T3, T11 Integration
TC-INV-02 T2 Unit
TC-INV-03 T3 Unit + Vitest
TC-INV-04 T15 Integration
TC-INV-05 T15 Integration
TC-INV-06 T10 Unit
TC-INV-07 T13, T15 Integration
TC-INV-08 T13 Unit
TC-INV-09 T8, T5 Integration
TC-INV-10 T2 Unit
TC-INV-11 T13, T15 Integration
TC-INV-12 T3 Unit (Vitest)
TC-INV-13 T9 Unit
TC-INV-14 T13 Unit

7. TODO restants / STUBS

ID Stub Story destination Impact
STUB-01 Pipeline scellement (Merkle leaf enqueue) PD-56 Transitions PENDING_SEAL -> SEALED -> ANCHOR_CONFIRMED non testables E2E
STUB-02 Worker HSM signature PD-55 Garde INV-103-08 testable en mock uniquement
STUB-03 Ancrage blockchain PD-41 Transition SEALED -> ANCHOR_CONFIRMED stubbe
STUB-04 Push notification iOS (APNs) PD-41 / config EAS Notification mock cote mobile

8. Risques identifies

Risque Probabilite Severite Mitigation
SHA3-256 pur JS trop lent (>3s P95 sur images >100MB) Moyenne Haute Benchmark TC-NOM-10 des wave 1. Si echec : module natif JSI.
expo-crypto ne supporte pas RSA-OAEP-SHA256 Faible Haute Verifier API expo-crypto. Fallback : WebCrypto polyfill ou react-native-quick-crypto.
expo-screen-capture transcodage implicite PNG Faible Critique TC-NR-01 (hash triplet corpus) apres chaque upgrade SDK.
Watchdog TTL ne s'execute pas (app killed iOS) Haute Moyenne purgeStale() au prochain lancement couvre ce cas.
Orphelins S3 multipart non supprimes immediatement Moyenne Faible Lifecycle rules S3 + GC cron M12 comme double filet.

# ──────────────────────────────────────────────────
# MANIFEST YAML — PD-103 Decomposition multi-agents
# ──────────────────────────────────────────────────

manifest:
  story_id: "PD-103"
  story_title: "Capture probatoire d'ecran et scellement automatique"
  spec_version: "v3"
  tests_version: "v3"
  plan_version: "v1"
  code_contracts: "PD-103-code-contracts.yaml"
  created_at: "2026-04-03"
  strategy: by_level

  waves:
    - id: wave-1
      name: "Fondations"
      parallel: true
      tasks:
        - id: T1
          name: capture-types
          agent: agent-developer
          project: app
          contract: null
          files:
            - "src/capture/types.ts"
            - "src/types/capture.ts"
          depends_on: []
          invariants: ["INV-103-28", "INV-103-31"]
          tests: []
          estimate: XS

        - id: T2
          name: capture-state-machine
          agent: agent-developer
          project: app
          contract: CC-1
          files:
            - "src/capture/state-machine.ts"
            - "src/capture/__tests__/state-machine.test.ts"
          depends_on: [T1]
          invariants: ["INV-103-20", "INV-103-21", "INV-103-22", "INV-103-23", "INV-103-24", "INV-103-25", "INV-103-26", "INV-103-27", "INV-103-28", "INV-103-29", "INV-103-38"]
          tests: ["TC-INV-02", "TC-INV-09", "TC-INV-10", "TC-NOM-12", "TC-ERR-02"]
          estimate: S

        - id: T3
          name: capture-crypto
          agent: agent-developer
          project: app
          contract: CC-2
          files:
            - "src/capture/crypto-pipeline.ts"
            - "src/capture/kek-provider.ts"
            - "src/capture/__tests__/crypto-pipeline.test.ts"
            - "src/capture/__tests__/crypto-pipeline.vitest.ts"
          depends_on: []
          invariants: ["INV-103-01", "INV-103-02", "INV-103-03", "INV-103-06", "INV-103-09", "INV-103-30", "INV-103-32", "INV-103-39"]
          tests: ["TC-INV-01", "TC-INV-03", "TC-INV-12", "TC-ERR-05", "TC-ERR-07"]
          estimate: M

        - id: T4
          name: capture-ocr
          agent: agent-developer
          project: app
          contract: CC-3
          files:
            - "src/capture/ocr-service.ts"
            - "src/capture/__tests__/ocr-service.test.ts"
          depends_on: []
          invariants: ["INV-103-04", "INV-103-05"]
          tests: ["TC-NOM-02", "TC-NOM-03", "TC-ERR-03"]
          estimate: S

        - id: T5
          name: capture-purge
          agent: agent-developer
          project: app
          contract: CC-7
          files:
            - "src/capture/purge-manager.ts"
            - "src/capture/__tests__/purge-manager.test.ts"
          depends_on: []
          invariants: ["INV-103-07", "INV-103-38"]
          tests: ["TC-NOM-04", "TC-NOM-17", "TC-ERR-11"]
          estimate: S

        - id: T6
          name: capture-migration
          agent: agent-developer
          project: backend
          contract: CC-13
          files:
            - "src/database/migrations/1743638400000-PD103-CreateCaptureEvents.ts"
            - "src/database/migrations/1743638400001-PD103-CreateCaptureAuditLog.ts"
          depends_on: []
          invariants: ["INV-103-10", "INV-103-37"]
          tests: []
          estimate: S

    - id: wave-2
      name: "Services dependants"
      parallel: true
      tasks:
        - id: T7
          name: capture-store
          agent: agent-developer
          project: app
          contract: CC-5
          files:
            - "src/store/useCaptureStore.ts"
            - "src/store/__tests__/useCaptureStore.test.ts"
          depends_on: [T1, T2]
          invariants: []
          tests: []
          estimate: S

        - id: T8
          name: capture-upload
          agent: agent-developer
          project: app
          contract: CC-4
          files:
            - "src/capture/upload-service.ts"
            - "src/capture/multipart-upload.ts"
            - "src/capture/__tests__/upload-service.test.ts"
          depends_on: [T3]
          invariants: ["INV-103-06", "INV-103-22", "INV-103-23", "INV-103-29"]
          tests: ["TC-NOM-05", "TC-NOM-13", "TC-NOM-14", "TC-ERR-01", "TC-ERR-04", "TC-ERR-14"]
          estimate: L

        - id: T9
          name: capture-kek-keyring
          agent: agent-developer
          project: backend
          contract: CC-11
          files:
            - "src/modules/capture/services/kek-keyring.service.ts"
            - "src/modules/capture/__tests__/kek-keyring.service.spec.ts"
          depends_on: []
          invariants: ["INV-103-09", "INV-103-30", "INV-103-34"]
          tests: ["TC-NOM-16", "TC-INV-13", "TC-ERR-16", "TC-ERR-17"]
          estimate: M

        - id: T10
          name: capture-idempotence
          agent: agent-developer
          project: backend
          contract: CC-10
          files:
            - "src/modules/capture/services/capture-idempotence.service.ts"
            - "src/modules/capture/__tests__/capture-idempotence.service.spec.ts"
          depends_on: []
          invariants: ["INV-103-31", "INV-103-37"]
          tests: ["TC-NOM-15", "TC-INV-06", "TC-ERR-13"]
          estimate: M

    - id: wave-3
      name: "Orchestration"
      parallel: false
      tasks:
        - id: T11
          name: capture-orchestrator
          agent: agent-developer
          project: app
          contract: CC-6
          files:
            - "src/capture/orchestrator.ts"
            - "src/capture/api-client.ts"
            - "src/capture/notifications.ts"
            - "src/capture/index.ts"
            - "src/capture/__tests__/orchestrator.test.ts"
          depends_on: [T2, T3, T4, T5, T7, T8]
          invariants: ["INV-103-03", "INV-103-07", "INV-103-12", "INV-103-24", "INV-103-31"]
          tests: ["TC-NOM-01", "TC-NOM-06"]
          estimate: L

        - id: T12
          name: capture-ingest
          agent: agent-developer
          project: backend
          contract: CC-9
          files:
            - "src/modules/capture/capture.module.ts"
            - "src/modules/capture/capture.controller.ts"
            - "src/modules/capture/services/capture-ingest.service.ts"
            - "src/modules/capture/dto/create-capture.dto.ts"
            - "src/modules/capture/entities/capture-event.entity.ts"
            - "src/modules/capture/entities/capture-audit-log.entity.ts"
            - "src/modules/capture/__tests__/capture-ingest.service.spec.ts"
            - "src/modules/capture/__tests__/capture.controller.spec.ts"
          depends_on: [T6, T9, T10]
          invariants: ["INV-103-08", "INV-103-10", "INV-103-11", "INV-103-25"]
          tests: ["TC-NOM-07", "TC-NOM-08", "TC-ERR-06", "TC-ERR-08", "TC-ERR-10", "TC-ERR-12"]
          estimate: XL

        - id: T13
          name: capture-reconciliation
          agent: agent-developer
          project: backend
          contract: CC-12
          files:
            - "src/modules/capture/services/capture-reconciliation.service.ts"
            - "src/modules/capture/__tests__/capture-reconciliation.service.spec.ts"
          depends_on: [T12]
          invariants: ["INV-103-11", "INV-103-33", "INV-103-35", "INV-103-36"]
          tests: ["TC-INV-07", "TC-INV-08", "TC-INV-11", "TC-INV-14", "TC-ERR-09"]
          estimate: L

    - id: wave-4
      name: "UI + Tests integration + Infra"
      parallel: true
      tasks:
        - id: T14
          name: capture-ui
          agent: agent-developer
          project: app
          contract: CC-8
          files:
            - "src/screens/capture/CaptureScreen.tsx"
            - "src/components/capture/CapturePreview.tsx"
            - "src/components/capture/CaptureProgress.tsx"
            - "src/components/capture/CaptureButton.tsx"
            - "src/hooks/useCapture.ts"
            - "src/i18n/locales/fr/capture.json"
            - "src/i18n/locales/en/capture.json"
            - "src/screens/capture/__tests__/CaptureScreen.test.tsx"
          depends_on: [T11]
          invariants: []
          tests: []
          estimate: M

        - id: T15
          name: capture-tests-integration
          agent: agent-developer
          project: backend
          contract: CC-14
          files:
            - "src/modules/capture/__tests__/capture-ingest.integration.spec.ts"
            - "src/modules/capture/__tests__/capture-reconciliation.integration.spec.ts"
            - "src/modules/capture/__tests__/capture-idempotence.integration.spec.ts"
          depends_on: [T12, T13]
          invariants: []
          tests: ["TC-INV-04", "TC-INV-05", "TC-INV-07", "TC-INV-11"]
          estimate: L

        - id: T16
          name: capture-s3-config
          agent: agent-developer
          project: infra
          contract: CC-15
          files:
            - "terraform/modules/s3-captures/main.tf"
            - "terraform/modules/s3-captures/variables.tf"
            - "terraform/modules/s3-captures/outputs.tf"
            - "terraform/s3-captures-module.tf"
          depends_on: []
          invariants: ["INV-103-33"]
          tests: []
          estimate: S

  summary:
    total_tasks: 16
    total_files: ~55
    projects: [app, backend, infra]
    waves: 4
    max_parallel_agents: 5
    estimated_agent_hours: "T1:XS T2:S T3:M T4:S T5:S T6:S T7:S T8:L T9:M T10:M T11:L T12:XL T13:L T14:M T15:L T16:S"
    invariants_covered: 39
    test_ids_covered: 48
    stubs: ["PD-56 (Merkle)", "PD-55 (TSA/HSM)", "PD-41 (blockchain/notification)"]