--- issueRef: "#173" version: 2 updatedBy: {"kind":"agent","agent_id":"57695b92-24d0-4876-837c-76116e70a6ae"} updatedAt: 1785272880037 --- ## #173 — Cadrage Main (2026-07-28) ### Décision produit La direction proposée est retenue : - **le téléphone décide** qu'un chrono arrive à 3, 2, 1, 0 ; - **la montre ne dérive pas seule** un événement métier "chrono terminé" ; - la montre reçoit une alerte à jouer et exécute l'haptique localement, même écran éteint si possible. ### Périmètre exact Ce ticket ne remplace pas `#164`, il le complète architecturalement. Il faut cadrer : - le contrat téléphone -> montre d'alerte chrono ; - la robustesse quand l'écran montre est éteint / ambient ; - la force/pattern haptique suffisant pour activité physique réelle ; - l'absence de doublon agressif ou de logique divergente entre téléphone et montre. ### Recommandation cible - téléphone : source des événements `countdownTick(3|2|1)` et `countdownFinished` ; - montre : simple exécution d'un pattern reçu, idempotent et court ; - support minimal hors écran : foreground/ongoing/session state suffisamment vivant pour que la montre puisse encore vibrer ; - si une alerte est ratée faute de connectivité, la projection confirmée doit rester cohérente et ne pas faire vibrer en retard plusieurs secondes après. ### Risques à cadrer - latence si l'on transporte chaque tick individuellement ; - duplication si la montre déclenche aussi localement ; - vibration faible selon OEM si on reste sur un impact standard ; - absence de vibration écran éteint si le process n'est pas au bon niveau de foreground/ongoing. ### Attendu suite Créer ensuite le lot d'architecture/implémentation qui tranche : - événements instantanés vs petits batches d'alertes planifiées ; - pattern haptique fort mais court ; - comportement dégradé sans connexion ; - QA sur montre réelle en mouvement. ## Cadrage Architect (2026-07-28) Statut : **cadrage exploitable, prêt pour découpage dev**. ### Architecture cible minimale - Le téléphone reste l'autorité unique des événements d'alerte chrono. - La montre n'infère plus seule une fin de chrono pour décider une vibration ; elle exécute une alerte explicite reçue du téléphone. - La projection d'état actuelle est conservée pour l'affichage, avec un **flux séparé phone -> watch d'alertes éphémères**. - Côté téléphone, une façade `WatchAlertPublisher` suffit au point où la logique chrono sait déjà qu'un `3/2/1/0/fin` se produit. ### Répartition téléphone / montre - Téléphone : - détecte `3`, `2`, `1`, `0`, `fin chrono`, `fin repos` si retenu ; - joue le son téléphone ; - publie une alerte structurée vers la montre ; - décide si une alerte est encore pertinente ou périmée. - Montre : - reçoit l'alerte ; - déclenche l'haptique locale forte ; - peut réveiller brièvement l'écran si faisable natif Wear ; - ne décide jamais seule qu'un `0` est atteint. ### Contrat phone -> watch recommandé - Nouveau DTO `WatchAlertEnvelope`, `schemaVersion = 5`, transporté via `MessageClient` sur un path type `/gametime/phone/alert`. - Champs clés : `alertId`, `sessionId`, `revision`, `kind`, `timerKind`, position courante, `scheduledForEpochMs`, `expiresAtEpochMs`, `pattern`. - `alertId` sert à la déduplication. - `scheduledForEpochMs` + `expiresAtEpochMs` servent à ignorer une alerte arrivée trop tard. ### Latence / duplication / retard - Envoi au moment de l'événement métier, pas à intervalle fixe. - La montre ignore : - tout `alertId` déjà joué ; - tout `sessionId` non cohérent avec la séance projetée courante ; - toute alerte reçue après son expiration. - TTL recommandé : - `3/2/1` : ~700 ms ; - `0/fin` : ~2000 ms. - Pas d'ACK obligatoire en v1 : une alerte manquée n'est pas rejouée après resync. ### Foreground / ambient / ongoing - S'appuyer sur l'existant : - `WatchOngoingActivityController` ; - `WatchHeartRateForegroundService` pendant `running`. - Ne pas créer un second service d'alerte. - Si un réveil écran bref est faisable, le réserver à `timerZero|timerFinished`, jamais à `3/2/1`. - En ambient, l'alerte doit rester haptique-first. ### Articulation avec #164 - `#164` reste le ticket observable audio/alertes chrono. - `#173` ajoute la prolongation architecturale vers la montre. - Le haptique montre actuel basé sur transition de projection devient au mieux un fallback transitoire ; la cible propre est le nouveau flux d'alertes explicites. ### Lots recommandés 1. `B1 [DevBackend] Contrat bridge alertes chrono + publisher téléphone` 2. `B2 [DevBackend] Déduplication / TTL / filtrage session` 3. `F1 [DevFrontend] Exécution locale alerte montre` 4. `F2 [DevFrontend] Intégration foreground/ambient` 5. `QA1 [QA] Validation alertes chrono phone/watch`