Aller au contenu

PD-284 — Décomposition (Step 6a)

Stratégie de parallélisation

Mode : sequential — 15 composants fortement interdépendants (C2→C1, C3→C1, C4→C1+C2, C5→C1+C2+C4, C7→C3+C4+C5+C6, C8→C5+C6, C9→C5, C10→C1+C5, C14→C8+C9+C10+C5, C15→C14). La chaîne critique traverse 7 niveaux ; la parallélisation apporterait un speedup < 1.3x pour une complexité de merge significative.

Graphe de dépendances (DAG)

Level 0 : T1(C1), T13(C13)                                    ← indépendants (types + telemetry)
Level 1 : T2(C2→C1), T3(C3→C1), T6(C6→C1), T12(C12→C1)      ← dépendent de C1
Level 2 : T4(C4→C1,C2), T5(C5→C1,C2,C4)                      ← dépendent de C2
Level 3 : T7(C7→C3,C4,C5,C6), T8(C8→C5,C6)                   ← orchestration + bouton
Level 4 : T9(C9→C5), T10(C10→C1,C5), T11(C11→C1)             ← UI cards + notifications
Level 5 : T14(C14→C8,C9,C10,C5), T15(C15→C14)                ← écran + navigation
Level 6 : T16(Tests→all)                                       ← tests unitaires + intégration

Manifest des tâches

Level 0 — Fondations (types + telemetry)

T1 — seal-types (C1)

  • Agent : agent-developer
  • Module : seal-types
  • Contract : CC seal-types
  • Fichiers : src/types/seal.ts
  • Description : Types TypeScript : union littérale SealState (7 états), branded types SealId/DocumentId, types événements SSE, payloads, DegradationFlag, ExpertFields, SealConfig, FailureReason, TsaTimestamp, PositionInQueue. Regex de validation par champ (§5.6).
  • Dépendances : aucune
  • Branche : feature/PD-284-t01-seal-types
  • Critères de done :
  • src/types/seal.ts créé
  • Union SealState couvre exactement les 7 états §5.7
  • Branded types SealId, DocumentId non substituables à string
  • Compilation TypeScript sans erreur

T13 — seal-telemetry (C13)

  • Agent : agent-developer
  • Module : seal-telemetry
  • Contract : CC seal-telemetry
  • Fichiers : src/seal/telemetry.ts
  • Description : Journalisation structurée { event_type, seal_id, timestamp, details }. Fonctions : logControlledError, logDeduplication, logSequenceGap, logTransitionRejected. Dédup loguée uniquement en mode debug.
  • Dépendances : aucune (types primitifs suffisants, couplage C1 ajouté au level 1 si nécessaire)
  • Branche : feature/PD-284-t13-seal-telemetry
  • Critères de done :
  • src/seal/telemetry.ts créé
  • 4 fonctions exportées (logControlledError, logDeduplication, logSequenceGap, logTransitionRejected)
  • Aucun artefact sensible dans les logs
  • Compilation TypeScript sans erreur

Level 1 — Modules dépendant de C1

T2 — seal-state-machine (C2)

  • Agent : agent-developer
  • Module : seal-state-machine
  • Contract : CC seal-state-machine
  • Fichiers : src/seal/state-machine.ts
  • Description : Machine d'états monotone. ALLOWED_TRANSITIONS en Record<SealState, readonly SealState[]> exhaustif. SEALED et FAILED_TIMEOUT terminaux (tableau vide). canTransition() et transition() avec log. Aucune transition retour.
  • Dépendances : T1 (C1 — SealState)
  • Branche : feature/PD-284-t02-state-machine
  • Critères de done :
  • src/seal/state-machine.ts créé
  • ALLOWED_TRANSITIONS couvre les 7 états comme clé (exhaustiveness TS)
  • INV-284-06, INV-284-07, INV-284-08 couverts
  • Transition invalide lève une erreur (pas d'acceptation silencieuse)
  • Compilation TypeScript sans erreur

T3 — seal-sse-client (C3)

  • Agent : agent-developer
  • Module : seal-sse-client
  • Contract : CC seal-sse-client
  • Fichiers : src/seal/sse-client.ts
  • Description : Client SSE fetch-based (ou wrapper CE-SSE-01 si HT-03 invalidée). Backoff exponentiel delay = base × factor^attempt (1s/2s/4s). Failover polling 5s après 3 échecs. Plafond cumulé 30s. Tentative SSE parallèle à chaque cycle polling. Retour SSE → arrêt polling.
  • Dépendances : T1 (C1 — types événements)
  • Branche : feature/PD-284-t03-sse-client
  • Critères de done :
  • src/seal/sse-client.ts créé
  • Interface SSEClient + SSEClientConfig exportées
  • Backoff exponentiel implémenté avec paramètres configurables
  • INV-284-09 respecté (pas de badge offline sur échec SSE seul)
  • Compilation TypeScript sans erreur

T6 — seal-api (C6)

  • Agent : agent-developer
  • Module : seal-api
  • Contract : CC seal-api
  • Fichiers : src/seal/api-client.ts
  • Description : Client API : postUrgentSeal({ document_id }) et getSealStatus(sealId). Validation Zod sur réponses. Timeout 30s. Aucun endpoint hors contrat (INV-284-13).
  • Dépendances : T1 (C1 — branded types, schemas)
  • Branche : feature/PD-284-t06-seal-api
  • Critères de done :
  • src/seal/api-client.ts créé
  • 2 fonctions exportées (postUrgentSeal, getSealStatus)
  • Validation Zod sur chaque réponse
  • INV-284-13 couvert (aucun endpoint additionnel)
  • Compilation TypeScript sans erreur

T12 — seal-secure-storage (C12)

  • Agent : agent-developer
  • Module : seal-secure-storage
  • Contract : CC seal-secure-storage
  • Fichiers : src/seal/secure-storage.ts
  • Description : Persistance tsa_token_ref, clés SSE, tokens auth via expo-secure-store avec kSecAttrAccessibleWhenUnlockedThisDeviceOnly. Fonctions : storeSensitiveArtifact, getSensitiveArtifact, purgeSealArtifacts, purgeAllSealData, purgeStaleSealArtifacts. Purge à logout/deleteAccount/fermeture SSE.
  • Dépendances : T1 (C1 — types artefacts)
  • Branche : feature/PD-284-t12-secure-storage
  • Critères de done :
  • src/seal/secure-storage.ts créé
  • 5 fonctions exportées
  • INV-284-10 couvert (artefacts sensibles en SecureStore uniquement)
  • INV-284-11 couvert (artefacts publics NON stockés ici)
  • Attribut iCloud restore désactivé
  • Compilation TypeScript sans erreur

Level 2 — Event processor + Store

T4 — seal-event-processor (C4)

  • Agent : agent-developer
  • Module : seal-event-processor
  • Contract : CC seal-event-processor
  • Fichiers : src/seal/event-processor.ts
  • Description : Cache FIFO ring buffer N=100 pour event_id. Ordonnancement sequence_number avec fenêtre de grâce 200ms (performance.now()). Gap persistant → GET resync. Validation Zod payload par état (§5.12). Guard seal_id != actif. Transition validée via C2.
  • Dépendances : T1 (C1), T2 (C2 — canTransition)
  • Branche : feature/PD-284-t04-event-processor
  • Critères de done :
  • src/seal/event-processor.ts créé
  • Cache FIFO ring buffer (pas LRU, pas Set)
  • Fenêtre grâce 200ms avec performance.now() (pas Date.now())
  • Validation Zod des champs obligatoires par état
  • INV-284-06 couvert (transition interdite → rejet + toast)
  • Compilation TypeScript sans erreur

T5 — seal-store (C5)

  • Agent : agent-developer
  • Module : seal-store
  • Contract : CC seal-store
  • Fichiers : src/store/useSealStore.ts
  • Description : Zustand store : état scellement actif, progression, degradationFlag brut serveur, mode transport (SSE/polling), artefacts publics en mémoire. Sélecteurs granulaires par champ (perf CA-284-14). Flag degradation_flag inconnu → none + telemetry silencieuse.
  • Dépendances : T1 (C1), T2 (C2 — SealStateMachine), T4 (C4 — EventProcessor)
  • Branche : feature/PD-284-t05-seal-store
  • Critères de done :
  • src/store/useSealStore.ts créé
  • INV-284-05 couvert (aucun calcul local de seuil dégradation)
  • INV-284-11 couvert (artefacts publics en state, pas en SecureStore)
  • Sélecteurs granulaires exportés (pas de sélecteur monolithique)
  • Pas de persistance AsyncStorage
  • Compilation TypeScript sans erreur

Level 3 — Orchestrateur + Bouton

T7 — seal-orchestrator (C7)

  • Agent : agent-developer
  • Module : seal-orchestrator
  • Contract : CC seal-orchestrator
  • Fichiers : src/seal/orchestrator.ts
  • Description : Coordination flux A : POST → GET status → init store → SSE. Debounce 2s (SEC-02). Disable optimistic bouton. R-02 : GET échoue → toast + init RECEIVED + SSE. Notification terminale via C11. Cleanup SSE/polling à destruction. purgeStaleSealArtifacts() au démarrage (learning PD-283/PD-262).
  • Dépendances : T3 (C3 — SSEClient), T4 (C4 — EventProcessor), T5 (C5 — SealStore), T6 (C6 — API)
  • Branche : feature/PD-284-t07-orchestrator
  • Critères de done :
  • src/seal/orchestrator.ts créé
  • CA-284-05 couvert (séquence POST→GET→SSE stricte)
  • R-02 implémenté (fallback RECEIVED si GET échoue)
  • Debounce 2s sur déclenchement
  • Cleanup SSE/polling complet
  • Compilation TypeScript sans erreur

T8 — urgent-button (C8)

  • Agent : agent-developer
  • Module : urgent-button
  • Contract : CC urgent-button
  • Fichiers : src/components/seal/UrgentSealButton.tsx
  • Description : Bouton scellement urgent. account_type = minorreturn null (INV-284-02). != minor → bouton visible (INV-284-01). Disabled si quota <= 0 OU has_active_urgent_seal (INV-284-03). Tooltips contractuels exacts (INV-284-04). R-03 : has_active_urgent_seal absent → false + telemetry. Debounce onPress.
  • Dépendances : T5 (C5 — store pour état), T6 (C6 — API pour déclenchement)
  • Branche : feature/PD-284-t08-urgent-button
  • Critères de done :
  • src/components/seal/UrgentSealButton.tsx créé
  • INV-284-01 à INV-284-04 couverts
  • Tooltip Quota épuisé ce mois (texte exact)
  • Tooltip Scellement urgent déjà en cours (texte exact)
  • Debounce 2s sur handler onPress
  • Compilation TypeScript sans erreur

Level 4 — Composants UI

T9 — seal-progress-card (C9)

  • Agent : agent-developer
  • Module : seal-progress-card
  • Contract : CC seal-progress-card
  • Fichiers : src/components/seal/SealProgressCard.tsx
  • Description : Carte de progression 5 étapes visuelles (Capture, TSA, Merkle, Blockchain, Scellé). Mapping §2.1b. Badges dégradation (delayed → jaune, critical → rouge). Badge Hors ligne via NetInfo (INV-284-09). position_in_queue en QUEUED_PRIORITY. failure_reason overlay en FAILED_TIMEOUT. React.memo sur sous-composants.
  • Dépendances : T5 (C5 — store)
  • Branche : feature/PD-284-t09-progress-card
  • Critères de done :
  • src/components/seal/SealProgressCard.tsx créé
  • 5 étapes visuelles conformes au mapping §2.1b
  • INV-284-05 couvert (badges = flags serveur, pas de calcul local)
  • INV-284-09 couvert (badge offline = perte réseau seule)
  • React.memo sur sous-composants
  • Compilation TypeScript sans erreur

T10 — expert-panel (C10)

  • Agent : agent-developer
  • Module : expert-panel
  • Contract : CC expert-panel
  • Fichiers : src/components/seal/ExpertPanel.tsx
  • Description : Panneau mode expert. Absent si mode_expert=false (CA-284-15). Map EXPERT_FIELDS_BY_STATE : hash_document dès RECEIVED, tsa_token_ref dès TSA_SEALED (via C12.getSensitiveArtifact), merkle_root dès ANCHOR_PENDING, blockchain_tx_hash + proof_package_url à SEALED. Donnée invalide (regex §5.6) → champ masqué + toast 5s. Ajout mode_expert: boolean dans useSettingsStore.
  • Dépendances : T1 (C1 — types), T5 (C5 — store)
  • Branche : feature/PD-284-t10-expert-panel
  • Critères de done :
  • src/components/seal/ExpertPanel.tsx créé
  • CA-284-15 couvert (panneau absent si mode_expert=false)
  • CA-284-16 couvert (champs progressifs par état)
  • INV-284-11 couvert (artefacts publics non traités comme sensibles)
  • mode_expert ajouté dans useSettingsStore
  • Compilation TypeScript sans erreur

T11 — seal-notifications (C11)

  • Agent : agent-developer
  • Module : seal-notifications
  • Contract : CC seal-notifications
  • Fichiers : src/seal/notifications.ts
  • Description : sendSealNotification(type, sealId) et buildSealDeepLink(sealId). Notification succès à SEALED, échec à FAILED_TIMEOUT. Titre max 50 chars, body max 100 chars (troncature). Deep-link schéma interne probatiovault://seal/{uuid} (SEC-01 whitelist).
  • Dépendances : T1 (C1 — types)
  • Branche : feature/PD-284-t11-notifications
  • Critères de done :
  • src/seal/notifications.ts créé
  • INV-284-12 couvert (deep-link valide vers seal_id)
  • Troncature titre/body respectée
  • Validation whitelist schéma URL interne
  • Compilation TypeScript sans erreur

Level 5 — Écran + Navigation

T14 — seal-detail-screen (C14)

  • Agent : agent-developer
  • Module : seal-detail-screen
  • Contract : CC seal-detail-screen
  • Fichiers : src/screens/vault/SealDetailScreen.tsx
  • Description : Écran détail scellement intégrant C8 (UrgentSealButton), C9 (SealProgressCard), C10 (ExpertPanel). useEffect cleanup : arrêt SSE/polling + purge artefacts sensibles session. Navigation deep-link via route seal/:id.
  • Dépendances : T8 (C8), T9 (C9), T10 (C10), T5 (C5)
  • Branche : feature/PD-284-t14-seal-detail-screen
  • Critères de done :
  • src/screens/vault/SealDetailScreen.tsx créé
  • Intégration C8, C9, C10 dans un layout cohérent
  • useEffect cleanup complet (pas de memory leak SSE/polling)
  • Route seal/:id résolvable
  • Compilation TypeScript sans erreur

T15 — seal-navigation (C15)

  • Agent : agent-developer
  • Module : seal-navigation
  • Contract : CC seal-navigation
  • Fichiers : src/navigation/seal-linking.ts
  • Description : Config linking Expo : route seal/:id → SealDetailScreen avec paramètre sealId. Validation UUID du paramètre. SEC-01 : whitelist schéma URL interne (probatiovault://seal/{uuid}), rejet schémas externes.
  • Dépendances : T14 (C14 — SealDetailScreen)
  • Branche : feature/PD-284-t15-seal-navigation
  • Critères de done :
  • src/navigation/seal-linking.ts créé
  • Route seal/:id résolue vers SealDetailScreen
  • Validation UUID sur paramètre sealId
  • Whitelist schéma URL stricte
  • Compilation TypeScript sans erreur

Level 6 — Tests

T16 — Suite de tests (tous TC-*)

  • Agent : agent-qa-unit-integration
  • Module : tous (C1-C15)
  • Contract : tous les CC
  • Fichiers :
  • src/types/__tests__/seal.test.ts
  • src/seal/__tests__/state-machine.test.ts
  • src/seal/__tests__/sse-client.test.ts
  • src/seal/__tests__/event-processor.test.ts
  • src/store/__tests__/useSealStore.test.ts
  • src/seal/__tests__/api-client.test.ts
  • src/seal/__tests__/orchestrator.test.ts
  • src/components/seal/__tests__/UrgentSealButton.test.tsx
  • src/components/seal/__tests__/SealProgressCard.test.tsx
  • src/components/seal/__tests__/ExpertPanel.test.tsx
  • src/seal/__tests__/notifications.test.ts
  • src/seal/__tests__/secure-storage.test.ts
  • src/seal/__tests__/telemetry.test.ts
  • src/screens/vault/__tests__/SealDetailScreen.test.tsx
  • src/navigation/__tests__/seal-linking.test.ts
  • Description : Tests unitaires + intégration couvrant tous les TC contractuels (TC-NOM-01 à TC-NOM-18, TC-ERR-01 à TC-ERR-09, TC-INV-09 à TC-INV-11, TC-NEG-01 à TC-NEG-10, TC-NR-01 à TC-NR-09). Couverture >= 80% lignes et branches.
  • Dépendances : T1-T15 (toutes les tâches)
  • Branche : feature/PD-284-t16-tests
  • Critères de done :
  • Tous les fichiers de test créés
  • TC-NOM-01 à TC-NOM-18 implémentés avec // TC-NOM-XX dans le nom ou commentaire
  • TC-ERR-01 à TC-ERR-09 implémentés
  • TC-INV-09, TC-INV-10, TC-INV-11 implémentés
  • TC-NEG-01 à TC-NEG-10 implémentés
  • TC-NR-01 à TC-NR-09 implémentés
  • Couverture >= 80% lignes et branches
  • 0 erreur ESLint
  • npm test passe sans échec

Matrice de couverture composant → invariant

Composant Invariants couverts TC principaux
C1 (seal-types) INV-284-06 (types états) TC-NOM-18
C2 (state-machine) INV-284-06, INV-284-07, INV-284-08 TC-NOM-05, TC-ERR-04, TC-ERR-06
C3 (sse-client) INV-284-09 TC-NOM-08, TC-NOM-09, TC-NR-03
C4 (event-processor) INV-284-06 TC-NOM-16, TC-NOM-17, TC-ERR-03, TC-ERR-05, TC-ERR-09
C5 (seal-store) INV-284-05, INV-284-11 TC-NOM-10, TC-INV-11
C6 (seal-api) INV-284-13 TC-ERR-01, TC-ERR-02, TC-INV-10
C7 (orchestrator) CA-284-05 TC-NOM-04, TC-NR-04
C8 (urgent-button) INV-284-01, INV-284-02, INV-284-03, INV-284-04 TC-NOM-01, TC-NOM-02, TC-NOM-03, TC-NOM-15
C9 (progress-card) INV-284-05, INV-284-09 TC-NOM-10, TC-NOM-14
C10 (expert-panel) INV-284-11, CA-284-15, CA-284-16 TC-NOM-11, TC-NOM-12, TC-ERR-07
C11 (notifications) INV-284-12 TC-NOM-06, TC-NOM-07, TC-ERR-08
C12 (secure-storage) INV-284-10, INV-284-11 TC-INV-09
C13 (telemetry) TC-ERR-03, TC-ERR-04, TC-ERR-05
C14 (detail-screen) TC-NR-05, TC-NR-06
C15 (navigation) INV-284-12 (deep-link) TC-NOM-06, TC-NOM-07

Parallelization

strategy: sequential
levels:
  - level: 0
    tasks: [1, 13]
    agents: [agent-developer, agent-developer]
    branches:
      - "feature/PD-284-t01-seal-types"
      - "feature/PD-284-t13-seal-telemetry"
  - level: 1
    tasks: [2, 3, 6, 12]
    agents: [agent-developer, agent-developer, agent-developer, agent-developer]
    branches:
      - "feature/PD-284-t02-state-machine"
      - "feature/PD-284-t03-sse-client"
      - "feature/PD-284-t06-seal-api"
      - "feature/PD-284-t12-secure-storage"
  - level: 2
    tasks: [4, 5]
    agents: [agent-developer, agent-developer]
    branches:
      - "feature/PD-284-t04-event-processor"
      - "feature/PD-284-t05-seal-store"
  - level: 3
    tasks: [7, 8]
    agents: [agent-developer, agent-developer]
    branches:
      - "feature/PD-284-t07-orchestrator"
      - "feature/PD-284-t08-urgent-button"
  - level: 4
    tasks: [9, 10, 11]
    agents: [agent-developer, agent-developer, agent-developer]
    branches:
      - "feature/PD-284-t09-progress-card"
      - "feature/PD-284-t10-expert-panel"
      - "feature/PD-284-t11-notifications"
  - level: 5
    tasks: [14, 15]
    agents: [agent-developer, agent-developer]
    branches:
      - "feature/PD-284-t14-seal-detail-screen"
      - "feature/PD-284-t15-seal-navigation"
  - level: 6
    tasks: [16]
    agents: [agent-qa-unit-integration]
    branches:
      - "feature/PD-284-t16-tests"
total_tasks: 16
total_components: 15
git_strategy: sequential_branch_per_task

Decision Trace

Décision Alternatives considérées Justification
sequential vs by_level by_level (parallélisation L0-L1) 15 composants avec chaîne de dépendances longue (C1→C2→C4→C5→C7→C14→C15). Speedup parallèle < 1.3x pour complexité merge significative. Séquentiel recommandé par l'instruction.
Tests en level 6 séparé Tests intégrés dans chaque tâche Agent QA dédié pour cohérence inter-composants, couverture TC contractuels croisée, et matrice de couverture unifiée
C13 (telemetry) en L0 C13 en L1 avec dépendance C1 La telemetry utilise des types primitifs (string, object). Le couplage C1 est faible (seal_id: string dans les logs). Mise en L0 pour paralléliser avec C1.
C12 (secure-storage) en L1 C12 en L4 avec les UI C12 est un module utilitaire bas-niveau (SecureStore), pas un composant UI. Les composants UI (C10) et l'orchestrateur (C7) en dépendent — le placer tôt débloque la chaîne.
1 branche par tâche 1 branche par niveau Tâches dans un même niveau touchent des fichiers distincts, isolation des merges, rollback granulaire