Cinquante-quatre chantiers clos entre le 5 et le 13 août 2026.
+ Cinquante-cinq chantiers clos entre le 5 et le 13 août 2026.
+
+ Les prompts du mode proactif ne polluent plus « Ce que demandent vos visiteurs »
+ Le dernier bloquant du proactif. RecordVisitorQuestion écrivait Question = request.Message : chaque passage devant une œuvre aurait ajouté une fausse question de visiteur — une consigne que le système s'écrit à lui-même — dans l'écran fait pour montrer ce que les humains demandent. Et HasAnswer se déduisant des sources, un prompt d'accueil sans citation aurait gonflé le bloc ambre des questions sans réponse. Même famille que WeatherSyncService noyant le journal d'audit.
+ Tranché : ne rien journaliser, plutôt que marquer d'un drapeau. Une ligne VisitorQuestion sert au rapport de trous de contenu et aux thèmes du lot J ; un prompt machine n'alimente ni l'un ni l'autre, et le garder « marqué » obligerait chaque futur agrégat à penser à l'exclure — la classe de panne qu'on venait de fermer sur AuditedTypes. ⚠️ Mais les jetons restent comptés : ces tours coûtent de l'argent réel au quota, et un audioguide proactif peut en consommer beaucoup. 2 tests fixent la paire — pas de ligne, compteur incrémenté — parce que c'est la combinaison qui compte.
+ Trois repos : manager-service (dotnet test 213), manager-app (manager_api_new étendu à la main, flutter build web ✅ — le client est partagé, donc vérifié) et mymuseum-visitapp (APK dev ✅).
+
+
Déclenchement proactif câblé, et M3 fermé avec lui
Quatre branchements : la garde, le cycle de vie, les points GPS, le réglage visiteur. APK dev vert. ⚠️ La garde recommandée par le plan aurait coûté de l'argent : _trigger appelle le LLM d'abord et ne parle qu'ensuite via activeVoiceOrchestrator?.ttsEngine, dont le ?. avale le cas « aucun mode vocal actif ». Avec proactiveModeEnabled seul, un visiteur traversant une zone avec l'app en poche et le vocal éteint consommait des jetons Gemini facturés au client pour une phrase que personne n'entend. La garde retenue interroge l'orchestrateur : la vraie condition n'est pas « quel matériel » mais « y a-t-il quelqu'un pour écouter ».
diff --git a/v1-plan.md b/v1-plan.md
index 8b0a84d..a2d2575 100644
--- a/v1-plan.md
+++ b/v1-plan.md
@@ -191,7 +191,13 @@ Ne change pas : la popup de traduction (un niveau justifié, langues verticales,
⚠️ **Deux pièges de format sur les points GPS, vérifiés plutôt que supposés.** `currentSections` porte des **maps JSON brutes**, pas des DTO (même idiome que `assistantSuggestions` et `ScannerDialog`), et `latitude`/`longitude` y sont des **chaînes** — c'est le type du `SectionDTO` généré. D'où `double.tryParse`. `meterZoneGPS` devient le rayon par section, la constante ne servant plus que de défaut : **c'est là que M3 se ferme**.
-⛔ **Un point n'est PAS livré, et il bloque l'activation du mode chez qui que ce soit.** `RecordVisitorQuestion` écrit `Question = request.Message` (`AiController:135`) — or le prompt d'un déclenchement automatique est une consigne machine (« Tu es un guide audio de musée. Le visiteur vient d'entrer dans la zone X. Accueille-le… »). Chaque passage devant une œuvre ajouterait donc **une fausse question de visiteur** dans l'onglet Guide IA, écran qui existe précisément pour montrer ce que les humains demandent. Et `HasAnswer` se déduisant des sources, un prompt d'accueil sans citation **gonflerait aussi le bloc ambre « questions sans réponse »**. C'est la famille de `WeatherSyncService` noyant le journal d'audit : le flot machine noie le signal humain dans l'écran fait pour lui. **À faire dans `manager-service` puis `mymuseum-visitapp`** : un drapeau sur `AiChatRequest`, et une journalisation qui distingue les tours machine — sans cesser de compter leurs jetons au quota, eux sont bien consommés. Le code proactif est en place et compile, mais **ne pas allumer le réglage avant ça**.
+✅ **Le bloquant est levé le 2026-08-13 — `AiChatRequest.IsAutoTriggered`.** `RecordVisitorQuestion` écrivait `Question = request.Message` (`AiController:135`), or le prompt d'un déclenchement automatique est une consigne machine (« Tu es un guide audio de musée. Le visiteur vient d'entrer dans la zone X. Accueille-le… »). Chaque passage devant une œuvre aurait ajouté **une fausse question de visiteur** dans l'onglet Guide IA, écran qui existe précisément pour montrer ce que les humains demandent — et, `HasAnswer` se déduisant des sources, aurait **gonflé le bloc ambre « questions sans réponse »**. Même famille que `WeatherSyncService` noyant le journal d'audit.
+
+> **Tranché : ne pas journaliser du tout, plutôt que marquer d'un drapeau.** Une ligne `VisitorQuestion` sert au rapport de trous de contenu et aux thèmes du lot J ; un prompt que le système s'est écrit à lui-même n'alimente ni l'un ni l'autre. La garder « marquée » obligerait **chaque futur agrégat** à penser à l'exclure — la classe de panne exacte qu'on venait de fermer sur `AuditedTypes`.
+>
+> ⚠️ **Mais les jetons restent comptés.** `RecordUsage` est appelé dans tous les cas : ces tours coûtent de l'argent réel au quota du client, et un audioguide proactif peut en consommer beaucoup. Les masquer du compteur serait pire que le bruit qu'on retire. **2 tests** fixent la paire — pas de ligne journalisée, compteur incrémenté — parce que c'est la combinaison qui compte, pas chaque moitié isolément.
+>
+> Trois repos, trois commits : `manager-service` (DTO + contrôleur + tests, `dotnet test` **213**), `manager-app` (`manager_api_new` étendu **à la main**, `flutter build web` ✅ — le client est partagé, donc vérifié) et `mymuseum-visitapp` (`AssistantService.chat` + l'appelant proactif, APK `dev` ✅).
✅ **Code mort supprimé le 2026-08-13 — `flutter analyze lib` rend zéro erreur, une première pour ce repo.** Trois fichiers Dart : `wake_word_service.dart`, `glasses_qr_scanner_service.dart` et `glasses_tts_service.dart` (l'ancien TTS ElevenLabs, importé par les deux seuls autres). Ils portaient les **4 erreurs** `kElevenLabsApiKey` / `kElevenLabsVoiceId` et l'APK se construisait quand même : personne ne les importait — un îlot hors du graphe de compilation, même mécanique que les 14 fichiers orphelins de `manager_api_new`. **C'étaient les ancêtres de `Services/Glasses/`.**
⚠️ **Piège d'homonymie, à ne pas re-déclencher** : `android/…/WakeWordService.kt` porte le même nom et est **bien vivant** — service natif déclaré au manifeste et piloté par `MainActivity`, c'est lui qui fait tourner le wake word. Seul le Dart est parti.
✅ **`impl/elevenlabs_tts_engine.dart` est conservé** : c'est l'implémentation de génération courante, gardée comme option si des clients jugeaient la voix Gemini insuffisante — beaucoup plus cher, donc pas un défaut.
⚠️ **Corollaire qui rétrécit le chantier du miroir vocal** : j'avais compté **cinq** `AssistantService` distincts, donc cinq historiques. Deux étaient dans ce code mort. **Il y en a trois de vivants** : le chat (`AssistantChatSheet:70`), le vocal (`MyInfoMateLlmClient:18`, `maxHistory: 6`) et le proactif (`geo_beacon_trigger_service:62`). À unifier, mais trois, pas cinq.