---
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`
