Cinquante-six chantiers clos entre le 5 et le 13 août 2026.
+ Cinquante-sept chantiers clos entre le 5 et le 13 août 2026. Le lot F est clos.
+
+ Le lot F est clos — canal vocal des stats, et L9 qui n'était pas un chantier
+ Le vocal est un attribut, pas un canal, comme tranché le 12/08. StatisticsService.track porte isVoice, qui pose "voice": true dans VisitEvent.Metadata — colonne existante, donc aucune migration et le gel du lot B tient. Le serveur expose « sessions ayant utilisé le vocal » et statistics_screen lit cet agrégat au lieu d'appTypeDistribution['Voice'], qui ne se serait jamais rempli.
+ ⚠️ Le sectionView vocal part après la synthèse, pas avant : un déclenchement dont le TTS échoue n'a rien fait entendre, le compter serait faux. ⛔ Aucun événement par question posée — elles sont déjà dans VisitorQuestion. ⚠️ Le test InMemory ne prouve rien ici, le provider évaluant le filtre côté client : un test Postgres a été ajouté à côté, il se saute sans démon Docker.
+ ⛔ L9 était un malentendu de doc, pas du travail. La « cible Assistant / Persona » du Mode preview est exactement ce que le §5 du Guide IA a livré le 11/08. Les trois autres cibles (iframes mobile/web/kiosk, viewports, preview-token) sont hors V1. ⚠️ Mais l'aperçu polluait les stats du client : chaque essai de personnalité par le gestionnaire était journalisé comme une question de visiteur. Corrigé — et le drapeau d'hier, IsAutoTriggered, est renommé IsVisitorQuestion (défaut true) parce que son vrai sens couvrait déjà les deux cas. dotnet test 218.
+
+
Une conversation, plusieurs surfaces — miroir vocal et conversationId
Le chat écrit, le vocal et le proactif partagent désormais une seule conversation, portée par VisitAppContext.assistant. Les trois AssistantService séparés ont disparu ; le maxHistory: 6 du vocal s'aligne sur 10, deux surfaces qui partagent une conversation ne pouvant pas la tronquer différemment selon le point d'entrée. La concision vocale vient d'isVoice, qui change le prompt côté serveur.
diff --git a/v1-plan.md b/v1-plan.md
index 85cdf5b..6f7ab73 100644
--- a/v1-plan.md
+++ b/v1-plan.md
@@ -186,10 +186,24 @@ Ne change pas : la popup de traduction (un niveau justifié, langues verticales,
✅ **`conversationId` est enfin envoyé, et le champ manquait dans le client généré** — c'est ce qui expliquait que personne ne l'envoyait. Ajouté à la main dans `manager_api_new`. Il est renouvelé quand la conversation est vidée : sinon la visite entière d'un même visiteur n'en formerait qu'une. **2 tests serveur** fixent le lien entre deux tours et le repli — la branche `Guid.NewGuid()` n'était couverte par rien.
+✅ **Canal vocal des stats livré le 2026-08-13, et L9 refermé.** `dotnet test` **218** (dont un test Postgres), APK `dev` ✅, `flutter build web` ✅.
+
+**Le vocal est un attribut, pas un canal** — la correction du 12/08 est appliquée telle quelle. `StatisticsService.track` porte `isVoice`, qui pose `"voice": true` dans `VisitEvent.Metadata` — **colonne existante, donc aucune migration et le gel du lot B tient**. `StatsSummaryDTO.VoiceSessions` compte les **sessions ayant utilisé le vocal**, et `statistics_screen` lit cet agrégat au lieu d'`appTypeDistribution['Voice']`, qui ne se serait jamais rempli.
+
+⚠️ **Le `sectionView` vocal est émis après la synthèse, pas avant** : un déclenchement dont le TTS échoue n'a rien fait entendre, le compter serait faux. ⛔ **Aucun événement par question posée**, conformément à l'arbitrage : elles sont déjà dans `VisitorQuestion` et remontent dans l'onglet Guide IA.
+
+⚠️ **Le test InMemory ne prouve rien ici** — le provider évalue le `Contains` côté client, donc une requête intraduisible passerait au vert. Un test Postgres a été ajouté à côté ; il se saute sans démon Docker, comme les 14 autres.
+
+⛔ **L9 : la convergence n'était pas un chantier, c'était un malentendu de doc.** La « cible Assistant / Persona » du Mode preview (`todo-features.md:599-603`) est **exactement** ce que le §5 du Guide IA a livré le 11/08 — `_sendPreview` interroge le vrai `/api/AI/chat`. Les trois autres cibles du Mode preview (mobile, web, kiosk en iframe, sélecteur de viewport, preview-token) sont une feature bien plus large, **hors V1**. Rien à coder.
⚠️ **Mais l'aperçu polluait les stats du client** : chaque essai de personnalité par le gestionnaire était journalisé comme une question de visiteur. Corrigé dans la même passe — voir le renommage ci-dessous.
+
+⚠️ **`IsAutoTriggered` renommé en `IsVisitorQuestion` (défaut `true`).** Le nom d'hier ne couvrait qu'un des deux cas : le vrai sens n'est pas « déclenché automatiquement » mais « ce tour n'est pas une question de visiteur », ce qui vaut aussi pour l'aperçu du gestionnaire. Renommé pendant qu'un seul commit en dépendait. Le défaut à `true` est délibéré : une app visiteur déjà publiée, qui n'envoie pas le champ, continue de journaliser — **un test le fixe**.
+
**Ce qui reste au lot F, et dans quel repo** — le backend ne bloque plus rien :
-- ~~`manager-app`~~ ✅ **livré le 2026-08-13** : bouton du Customer Portal et diviseur `aiTokensPerQuestion`. `flutter analyze lib` **sans erreur**, `flutter build web` ✅. Détail ci-dessous.
-- `mymuseum-visitapp` : déclenchement proactif (+ M3), miroir de la conversation vocale, émission des événements vocaux. C'est désormais **tout le reste du lot F**, et le plus gros.
-- Non commencé, indépendant : l'aperçu de conversation (**L9**).
+- ~~`manager-app`~~ ✅ **livré le 2026-08-13** : bouton du Customer Portal et diviseur `aiTokensPerQuestion`.
+- ~~`mymuseum-visitapp`~~ ✅ **livré le 2026-08-13** : déclenchement proactif (+ M3), miroir de la conversation vocale, émission des événements vocaux.
+- ~~L9, aperçu de conversation~~ ⛔ **sans objet** — livré par DB3 le 11/08, le reste du Mode preview est hors V1.
+
+🎉 **Le lot F est clos le 2026-08-13.** Ce qui reste avant la bascule : le **lot J** (RGPD), **K6** (publier les APK), **K9** (repasse visuelle de la borne, sacrifiable), le **lot H** (tests, dont D0 et §21 sur device), **D5**, et le **lot I** (infra + bascule).
**Volet proactif + M3 du 2026-08-13 (`mymuseum-visitapp`) — ce que le code a corrigé de l'énoncé :**