---
issueRef: "#174"
version: 5
updatedBy: {"kind":"user"}
updatedAt: 1785419506129
---

## #174 — Cadrage Main (2026-07-28)

### Symptôme utilisateur
Parfois, au lancement d'un chrono, l'affichage ne reste pas sur GameTime et retourne à l'accueil de la montre.

### Position
Ce ticket est un **suivi plus précis** de `#127`, mais avec un déclencheur confirmé supplémentaire : le lancement/changement d'état du chrono.

### Attendu
- tant qu'une séance est active, le retour gestuel ou le réveil écran doit favoriser le retour à GameTime ;
- un changement de projection de séance ou de chrono ne doit pas éjecter l'utilisateur hors de l'app ;
- l'app montre doit rester le point de focus naturel pendant la séance, sans demander de relancer manuellement l'app.

### Axes à instruire ensuite
- ongoing activity / reprise d'activité ;
- task affinity / launch mode / intent de retour ;
- interaction entre foreground service, écran ambient et navigation Flutter ;
- différence entre "écran éteint puis réveil" et "lancement d'un chrono".

## Cadrage Architect (2026-07-28)

Statut : **cadrage exploitable, prêt pour lot frontend natif montre**.

### Causes techniques plausibles
- `MainActivity` Wear est trop passive : pas de `onResume`, pas de `onNewIntent`, pas de logique de reentry/resync.
- La reprise dépend surtout du flux Flutter `EventChannel` et de `requestLatestProjection(...)`, sans ré-ancrage explicite de l'activity.
- Les intents ongoing/notification utilisent seulement `SINGLE_TOP | CLEAR_TOP`, sans action dédiée "ouvrir la séance active".
- Si `POST_NOTIFICATIONS` manque, l'ongoing activity peut ne pas fournir de point d'ancrage système.
- Le foreground service watch ne tourne que pour `phase == running`, donc l'UI peut perdre son point d'appui natif pendant certaines transitions alors que la séance existe encore.

### Correctif minimal recommandé
- Corriger côté watch natif, sans changement de contrat métier.
- Ajouter une vraie voie de réentrée locale :
  - intent explicite `ACTION_OPEN_ACTIVE_SESSION` ;
  - même intent réutilisé par ongoing activity et foreground notification ;
  - `onNewIntent` et `onResume` dans `MainActivity` qui appellent `requestLatestProjection(...)` + `requestCapabilityRefresh(...)`.
- Garder côté natif la dernière projection utile reçue ; si elle indique une séance active **encore fraîche ou rapidement reconfirmée**, la réouverture doit retomber sur GameTime, pas sur l'accueil système.
- Si la séance n'est plus confirmée, ne pas forcer de reopen : cela doit rester distingué de `#175`.

### Impacts
- Contrats bridge : aucun changement obligatoire.
- Natif watch :
  - action/extra de reentry ;
  - cache de dernière projection utile ;
  - resync explicite sur resume/new intent.
- UI Flutter montre : pas de changement structurel, au plus un resync plus agressif au retour foreground.
- DevBackend : non requis pour le correctif minimal.

### Garde-fous vs #175
- `#174` : le téléphone est vivant, la séance existe, mais l'activity montre décroche ou ne se ré-ancre pas.
- `#175` : la projection doit expirer quand la source téléphone disparaît durablement.
- Donc le reopen forcé de `#174` ne doit se faire que si la projection locale est encore fraîche ou si un resync confirme rapidement la séance.

### Lots recommandés
1. `F1 [DevFrontend] Reentry natif montre`
2. `F2 [DevFrontend] Robustesse réveil/ambient`
3. `QA1 [QA] Validation montre ancrée`
