# hermes-mail-browser — `/inbox` renvoyait des mails perimes (staleness liste virtualisee OWA) **Date** : 2026-07-24 **Sphere** : hermes-tt **Composant** : `hermes-mail-browser` (port 3110, service Playwright/Edge headless pilotant OWA) ## Symptome Nabil signale que hermes-tt "ne voit pas les mails convenablement". Verification : `GET /inbox?limit=5` renvoyait 5 mails dates du samedi 18/07, avec un doublon (meme item en position 1 et 4), alors que la vraie boite avait des mails recus le jour meme (24/07). `GET /auth/status` montrait `current_url` pointant sur un message ouvert (`.../mail/inbox/id/AAkA...`), pas sur la racine de la boite. ## Cause racine Le service garde **un seul onglet Edge partage** entre tous les appels (`get_owa_page()` reutilise l'onglet existant sans jamais y renaviguer tant que le host correspond a OWA — meme si le chemin pointe vers un message ouvert). Les endpoints `/message/{index}`, `/message/{index}/attachments` et `/message/{index}/attachments/{filename}/text` font tous un `.click()` sur l'option a l'index demande pour ouvrir le message. Ce clic **scrolle la liste virtualisee d'OWA** (react-window / virtualisation type outlook) — seuls les elements proches de la position courante restent montes dans le DOM. Si `/inbox` est appele ensuite sans navigation fraiche, le selecteur `[role="listbox"]...[role="option"]` lit les items **actuellement montes**, pas le sommet reel de la boite → mails perimes, ordre incoherent, doublons possibles aux frontieres de rendu virtualise. Le bug ne se declenche pas au premier appel (onglet fraichement ouvert = sommet de la liste) mais des qu'un `/message/{index}` a ete appele avant — ce qui est le cas d'usage normal (hermes-tt lit l'inbox, ouvrait un message il y a plusieurs jours, puis relit l'inbox → resultat foireux persistant jusqu'au prochain redemarrage du conteneur). ## Fix Nouvelle fonction `go_to_inbox_root(page)` dans `main.py` : force un `page.goto(OWA_URL, wait_until="domcontentloaded")` + attente 2s. Appelee systematiquement en tete de logique dans les 4 endpoints qui lisent la liste par index : `/inbox`, `/message/{index}`, `/message/{index}/attachments`, `/message/{index}/attachments/{filename}/text`. Cout : ~2-3s de latence supplementaire par appel, juge acceptable (usage agent ponctuel, pas de boucle haute frequence) au profit de la fiabilite. Fichier modifie : `/volume1/docker/hermes-mail-browser/app/main.py` (backup avant patch : `main.py.bak_20260724_inbox_staleness`). `./app` est **bake dans l'image** (pas de bind mount) → `docker compose build` puis recreation du conteneur necessaires, pas un simple restart. ## Piege rencontre a la recreation (deja documente le 23/07, reconfirme) `data/profile/` est un volume persistant. A la recreation du conteneur, les fichiers de verrou Edge de l'ancien process (`SingletonLock`, `SingletonCookie`, `SingletonSocket` — des symlinks) survivent et bloquent le nouvel Edge au demarrage. Sequence correcte : 1. `docker compose stop hermes-mail-browser` (arret propre, pas juste up -d) 2. `rm` les 3 fichiers Singleton* dans `data/profile/` 3. `docker compose up -d` 4. Verifier `curl http://192.168.100.33:3110/auth/status` → `authenticated:true` SANS nouvelle authentification manuelle (cookies conserves, seul le verrou genait). ## Validation Apres fix + rebuild + recreation propre : - `authenticated:true`, `current_url` = racine `/mail/` (pas un message). - `/inbox` : mails du jour meme, bon ordre, pas de doublon. - Test de non-regression cible : `GET /message/0` (simule un clic anterieur) puis `GET /inbox` immediatement apres → toujours correct (c'etait precisement le scenario qui cassait avant le fix). ## A surveiller Le cout de `go_to_inbox_root()` sur `/message/{index}/attachments/{filename}/text` (deja une operation lente : clic + telechargement + extraction) ajoute un navigate de plus — pas mesure de degradation notable en test manuel mais a garder en tete si hermes-tt rapporte des timeouts sur cet endpoint precis.