chore(ideai): synchronise etat de suivi (tickets, agents)
This commit is contained in:
86
.ideai/tickets/175/carnet.md
Normal file
86
.ideai/tickets/175/carnet.md
Normal file
@ -0,0 +1,86 @@
|
||||
---
|
||||
issueRef: "#175"
|
||||
version: 4
|
||||
updatedBy: {"kind":"user"}
|
||||
updatedAt: 1785315994252
|
||||
---
|
||||
|
||||
## #175 — Cadrage Main (2026-07-28)
|
||||
|
||||
### Symptôme utilisateur
|
||||
Si l'utilisateur tue l'app téléphone sans quitter d'abord la séance, la montre conserve une séance active apparente et continue d'ouvrir l'ancien écran de séance.
|
||||
|
||||
### Gravité
|
||||
Critique côté cohérence :
|
||||
- la montre affirme un état actif sans source de vérité confirmée ;
|
||||
- l'utilisateur peut croire que la séance continue alors que le téléphone a disparu du cycle ;
|
||||
- cela contredit le principe "logique métier côté téléphone".
|
||||
|
||||
### Décision de cadrage
|
||||
La montre ne doit pas garder indéfiniment un état "séance active" orphelin.
|
||||
|
||||
Comportement cible à trancher techniquement :
|
||||
- soit le téléphone envoie explicitement un état terminal/deconnexion avant extinction contrôlée ;
|
||||
- soit la montre invalide l'état de séance après une fenêtre d'absence de heartbeat/projection ;
|
||||
- soit combinaison des deux, avec dégradation vers un état clair "Téléphone indisponible" ou retour hors séance.
|
||||
|
||||
### Garde-fous
|
||||
- ne pas perdre une vraie séance lors d'une micro-coupure normale ;
|
||||
- ne pas laisser une séance fantôme persister après fermeture forcée ;
|
||||
- distinguer reconnexion brève et disparition durable du téléphone ;
|
||||
- l'écran montre doit refléter un état confirmé ou explicitement dégradé, jamais un faux "tout va bien".
|
||||
|
||||
### Attendu suite
|
||||
Ticket d'architecture/implémentation à sortir de celui-ci :
|
||||
- stratégie heartbeat / TTL projection ;
|
||||
- comportement UI montre si la source téléphone disparaît ;
|
||||
- tests kill téléphone / reprise / relance app.
|
||||
|
||||
## Cadrage Architect (2026-07-28)
|
||||
|
||||
Statut : **cadrage exploitable, prêt pour découpage dev**.
|
||||
|
||||
### Diagnostic
|
||||
Le bug vient du mécanisme de reprise montre : au démarrage ou à la reconnexion, la montre relit le dernier `DataItem` de projection et continue de l'afficher même si le téléphone a disparu. Le `WatchSessionViewModel` peut marquer la projection `stale` puis `connectionLost`, mais n'invalide jamais la projection elle-même.
|
||||
|
||||
### Décision d'architecture
|
||||
- Le téléphone reste l'unique source de vérité.
|
||||
- La projection montre doit être traitée comme un **cache temporaire**, jamais comme une preuve durable qu'une séance est encore active.
|
||||
- Une projection phone -> watch devient **expirable**.
|
||||
- Sans rafraîchissement explicite du téléphone dans une fenêtre courte, la montre doit considérer la projection invalide et revenir à un état `téléphone indisponible / aucune séance confirmée`.
|
||||
|
||||
### Mécanisme recommandé
|
||||
- Étendre `WatchSessionProjection` avec un TTL explicite, par exemple `expiresAtEpochMs`.
|
||||
- À chaque projection publiée, le téléphone renseigne `expiresAtEpochMs = now + ttl`.
|
||||
- Recommandation : TTL de `12s`, cohérent avec le refresh périodique existant toutes les `2s`.
|
||||
- Si l'app téléphone est killée, le heartbeat s'arrête ; la montre laisse expirer la projection.
|
||||
- Si le téléphone sait explicitement qu'il n'y a plus de séance, il publie `phase = noActiveSession` immédiatement comme aujourd'hui ; le TTL couvre le cas brutal.
|
||||
|
||||
### Comportement montre attendu
|
||||
- Avant expiration : garder l'écran courant, avec l'état `stale` existant si utile.
|
||||
- Après expiration durable :
|
||||
- remplacer localement la projection active par une projection synthétique `noActiveSession` ;
|
||||
- vider `sensorSample`, commandes pending, score optimiste ;
|
||||
- arrêter ongoing / foreground liés à la séance ;
|
||||
- afficher un état type `Téléphone indisponible / rouvre GameTime sur le téléphone`, pas l'ancienne séance.
|
||||
- Si le téléphone republie ensuite une projection valide, la montre se recale normalement.
|
||||
|
||||
### Garde-fous micro-coupures
|
||||
- Ne pas invalider sur simple `connectionLost` capability.
|
||||
- Invalider seulement quand aucune projection fraîche n'est reçue au-delà du TTL et qu'aucun ack/commande retour ne prouve une communication en cours.
|
||||
- Fenêtres recommandées :
|
||||
- refresh téléphone : `2s` inchangé ;
|
||||
- seuil `stale` : `6s` actuel conservé ;
|
||||
- expiration dure : `12s` à `15s`.
|
||||
|
||||
### Impacts
|
||||
- Contrat : `WatchSessionProjection` gagne `expiresAtEpochMs`, `schemaVersion` incrémentée.
|
||||
- Téléphone : renseigne ce champ à chaque publish.
|
||||
- Bridge natif watch : pas de refonte structurelle ; la lecture du dernier `DataItem` peut rester, mais ce snapshot sera auto-invalidé par TTL.
|
||||
- UI montre : ajouter l'invalidation locale dans `_syncFreshnessState()` ; injecter une projection synthétique `noActiveSession` après expiration.
|
||||
|
||||
### Lots recommandés
|
||||
1. `B1 [DevBackend] Projection expirable côté téléphone`
|
||||
2. `F1 [DevFrontend] Invalidation locale montre sur TTL expiré`
|
||||
3. `F2 [DevFrontend] Ajustements natifs reprise/ongoing`
|
||||
4. `QA1 [QA] Validation disparition source téléphone`
|
||||
16
.ideai/tickets/175/issue.md
Normal file
16
.ideai/tickets/175/issue.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
id: "3528d6d9-1b1a-4b77-ac36-6ab37470eba0"
|
||||
number: 175
|
||||
title: "[Bug] Séance fantôme sur la montre après fermeture forcée de l'application téléphone"
|
||||
status: "qa"
|
||||
priority: "critical"
|
||||
sprint: "abc4f969-b169-45f7-988c-daeeab762201"
|
||||
links: [{"target":"#100","kind":"relatesTo"},{"target":"#108","kind":"relatesTo"}]
|
||||
agentRefs: []
|
||||
createdBy: {"kind":"agent","agent_id":"57695b92-24d0-4876-837c-76116e70a6ae"}
|
||||
updatedBy: {"kind":"user"}
|
||||
createdAt: 1785257860731
|
||||
updatedAt: 1785315994252
|
||||
version: 4
|
||||
---
|
||||
Quand l'application téléphone est fermée de force pendant qu'une séance est encore active, la montre continue de croire qu'une séance est en cours : logo de séance toujours présent sur l'écran principal et retour vers le dernier écran de séance au tap. Il faut cadrer puis corriger la stratégie de vérité/déconnexion pour qu'une montre ne garde pas une séance fantôme sans source téléphone vivante.
|
||||
Reference in New Issue
Block a user