diff --git a/STATUS.md b/STATUS.md
index 375c292..8d4eb58 100644
--- a/STATUS.md
+++ b/STATUS.md
@@ -156,7 +156,7 @@ Dix-neuf chantiers de canaux et d'IA, chacun avec son plan détaillé. État au
- **V1** — **visiteur web** : `visitapp-web` build ✅, les 13 types de section rendus, assistant IA inclus ; **il ne manque que le Dockerfile et l'entrée `app.myinfomate.be` au compose**. Bloquant, le plan Essentiel vendu par l'onboarding est web-only. Plus l'**écran Guide IA**. La **Médiathèque** (basculée en V1 le 2026-09-02) est **codée de bout en bout le même jour** — index inverse des usages, panneau de détail, facettes, suppression protégée, les deux bugs corrigés ; `dotnet test` 236/236 et `flutter build web` verts, **mais la checklist de 15 points reste à passer dans un navigateur** (colonne « À tester » du kanban). Voir [v1-mediatheque-plan.md](v1-mediatheque-plan.md).
- **Livrés** — export PDF des stats à la demande, historique 13 mois pour tous les plans, refonte de l'écran Statistiques (⚠️ jamais ouvert dans un navigateur).
-- **V2** — module Studio (génération IA d'images), Personnages (une entité `Persona` unifiant trois plans), TTS pré-généré, kiosk web, VR Meta Quest, import IA + RAG. 🛠️ **Studio : lots 0 à 6 codés et commités (branche `studio`, pas encore poussée), calibrage §9.4 fait le 2026-09-15** (≈ 3 $ réels, unité de crédit arrêtée : 1 crédit = 0,015 $ de coût fal, prix de vente avec marge). Lot 7 : échantillons de style et figures d'archétypes embarqués, reste l'écoute des voix. **Lots 8 et 8bis codés et commités le 2026-09-15, jamais exécutés en réel** — narrateurs assignables et chaîne de résolution, génération audio Gemini TTS → MP3 (1 crédit par minute, état « à régénérer »), onglet Narrateurs du parcours, blocs sur l'article et le point de carte, cartes Narration et Personnages dans l'écran Configuration, portrait du narrateur et écran « les personnes que vous allez rencontrer » sur les trois apps visiteur, lecteur audio dans la fiche d'un point de carte (lot 8e, ajouté le même soir). ⚠️ Au passage, les apps visiteur ne jouaient pas un audio rangé par identifiant de ressource — corrigé. **À faire** : passer [test-plan-studio-narration.md](test-plan-studio-narration.md) (clé Gemini + ffmpeg), extraits d'écoute des voix, test du conservateur (gate lot 4), push de la branche `studio`. Le prérequis « le backend ne sait pas écrire dans le bucket » est levé depuis le lot 0.
+- **V2** — module Studio (génération IA d'images), Personnages (une entité `Persona` unifiant trois plans), TTS pré-généré, kiosk web, VR Meta Quest, import IA + RAG. 🛠️ **Studio : lots 0 à 6 codés et commités (branche `studio`, pas encore poussée), calibrage §9.4 fait le 2026-09-15** (≈ 3 $ réels, unité de crédit arrêtée : 1 crédit = 0,015 $ de coût fal, prix de vente avec marge). Lot 7 : échantillons de style et figures d'archétypes embarqués, reste l'écoute des voix. **Lots 8 et 8bis codés et commités le 2026-09-15, jamais exécutés en réel** — narrateurs assignables et chaîne de résolution, génération audio Gemini TTS → MP3 (1 crédit par minute, état « à régénérer »), onglet Narrateurs du parcours, blocs sur l'article et le point de carte, cartes Narration et Personnages dans l'écran Configuration, portrait du narrateur et écran « les personnes que vous allez rencontrer » sur les trois apps visiteur, lecteur audio dans la fiche d'un point de carte (lot 8e, ajouté le même soir). ⚠️ Au passage, les apps visiteur ne jouaient pas un audio rangé par identifiant de ressource — corrigé. **À faire** : passer [test-plan-studio-narration.md](test-plan-studio-narration.md) (clé Gemini + ffmpeg), extraits d'écoute des voix, lot 8f (la narration et le casting dans l'app VR, carte 315), test du conservateur (gate lot 4), push de la branche `studio`. Le prérequis « le backend ne sait pas écrire dans le bucket » est levé depuis le lot 0.
- 📄 **La frontière entre le Studio IA et le canal XR est tranchée depuis le 2026-09-11** : [v2/immersif-frontiere-plan.md](v2/immersif-frontiere-plan.md). Les deux plans se renvoyaient la balle (le Studio mettait la 3D en « dépend du chantier VR », le plan VR décrivait les POI sur GLB sans dire d'où venait le GLB). Trois couches : ressources immersives (360/GLB, **se vendent sans casque**), consommation, et le Studio comme *source d'approvisionnement* de la première. **Cinq décisions de rétro-compat touchent des lots antérieurs à la 3D** — à lire avant la première migration du Studio, pas en arrivant au lot 11.
- ✅ **Le backend du canal XR est fait le 2026-09-11** (lot `XR-1` de [v2/vr-quest-unity-plan.md](v2/vr-quest-unity-plan.md)) : `Device.AppType` + migration, `DeviceController` résout l'`ApplicationInstance` sur le canal au lieu de `Tablet` en dur, `Get` filtre par canal, `ApiKeyAppType.VrApp`, `appType` dans `manager_api_new`. 224 tests au vert. Et **`XR-3` était déjà fait** — l'export est ouvert aux apps depuis `9cc45c5`, le plan était en retard sur le code.
- ✅ **`XR-2` fait le 2026-09-12 — le canal VR est administrable.** L'écran XR est une coquille à deux sous-onglets : « Configuration » réutilise `AppConfigurationLinkScreen` tel quel (déjà générique sur l'`appType`, zéro code neuf), « Casques » est la grille avec pincode d'appairage, état connecté, batterie, version et dernier vu. i18n FR/EN/NL. ⚠️ Deux affirmations du plan étaient fausses : la grille kiosk liste des `AppConfigurationLink`, pas des `Device` (le filtre par canal était déjà implicite, et le paramètre `appType` de `/api/device` ne sert pas à cet écran), et batterie/version/dernier vu ne sont que dans `DeviceDetailDTO` — donc un appel de détail par casque, assumé sur une flotte qui se compte en unités. Ne restent que deux puces documentaires de `XR-3` (contrat d'export versionné, décision multilingue).
diff --git a/kanban.html b/kanban.html
index 54aabbd..6eac356 100644
--- a/kanban.html
+++ b/kanban.html
@@ -462,7 +462,7 @@
1Migration v3
2Bugs ouverts
12À tester
- 39Planifié
+ 40Planifié
9Bascule prod
66Fait récemment
@@ -706,7 +706,7 @@
- Planifié
39
+ Planifié
40
@@ -1117,6 +1117,31 @@
v2/studio-plan.md §3.8 — lots 7 et 8
+
+ VRStudio IAV2 · après le test du lot 8 sur les trois apps, avec le casque
+ Studio dans l'app VR — mention IA, narration, casting (lot 8f)
+ Le lot 8 (narrateurs, audio généré, portrait, casting) a été livré sur les trois apps visiteur — web, mobile, tablette — mais pas sur l'app Quest, qui lit pourtant le contenu par l'export de configuration (ConfigurationExport.cs). Relevé le 2026-09-15.
+ Ce que fait la VR aujourd'hui : Map et Parcours rendus en liste de points, sans lire audioIds ; hotspots de maquette 3D dont l'audio vient des contenus du point, pas de l'audio par langue ; ni portrait du narrateur, ni écran « les personnes que vous allez rencontrer ».
+ À faire :
+
+ - Export Unity :
audioIds des points et des étapes, narratorName / narratorPortraitUrl sur la ressource, casting de la configuration.
+ - Lecture de l'audio narré d'un point et d'une étape, portrait à côté (audio spatialisé sur un hotspot).
+ - Serveur : rendre narrables les points d'une maquette 3D — la section maquette comme conteneur dans la chaîne de
NarratorResolver (aujourd'hui, un point sans SectionMapId est refusé par NarrationService).
+ - Écran d'entrée du casting au lancement de la visite.
+
+ 🔎 Repasse du 2026-09-15 sur les lots Studio 0 à 8 (code de vr-app relu) — ce qui touche le visiteur et manque au casque :
+
+ - Lot 6, mention « image générée par IA » — manquante.
ConfigurationExport.Resource ne lit pas origin : les images d'un Slider, la photo d'un point et les médias d'un hotspot s'affichent sans mention. ProvenanceManifest.AiGenerated existe dans le manifeste mais rien ne le remplit depuis l'export. À ajouter avec le reste — c'est l'obligation d'information de l'AI Act, pas un confort.
+ - Lot 8, audio narré — manquant (points 1 et 2 ci-dessus). Le commentaire d'un hotspot vient de ses contenus ; la narration écrit dans
audioIds, que le casque ne lit pas.
+ - Lot 8bis, casting — manquant (point 4).
+ - Lot 7, personnages — couture prévue, pas faite.
ScenePersona.PersonaId est « null en V1, la couture vers l'entité Persona » : les personnages GLB d'une scène ne sont pas reliés aux fiches Personnages (nom, portrait, voix). Relève plutôt du lot 11 (3D).
+ - Sans objet : lots 0 à 5 (serveur et manager), crédits et calibrage. Le correctif « audio rangé par identifiant » de 8d ne s'applique pas : le casque résout déjà ses médias par identifiant via
FindResource.
+ - Hors Studio, vu en passant : un Parcours est rendu « comme une Map » à partir de
section.Points, or ses étapes vivent dans guidedPaths — un Parcours s'ouvre probablement vide sur le casque. À vérifier casque en main.
+
+ ⛔ Pas avant : que le plan de test test-plan-studio-narration.md soit passé sur les trois autres apps, et avec le casque en main — rien de ceci ne se vérifie sans l'éditeur Unity. Le dépôt vr-app n'a toujours ni remote ni commit.
+ v2/studio-plan.md — lot 8f
+
+
studiovideoIAquelques euros, une soirée — débloque une décision produit
Test « faire vivre un lieu » — 8 s au Fourneau
diff --git a/kanban/cards/5-planifie/315-narration-et-casting-en-vr.md b/kanban/cards/5-planifie/315-narration-et-casting-en-vr.md
new file mode 100644
index 0000000..742ebda
--- /dev/null
+++ b/kanban/cards/5-planifie/315-narration-et-casting-en-vr.md
@@ -0,0 +1,27 @@
+---
+title: Studio dans l'app VR — mention IA, narration, casting (lot 8f)
+area: vr backend
+horizon: v2
+tags: VR, Studio IA
+flag: warn | V2 · après le test du lot 8 sur les trois apps, avec le casque
+src: v2/studio-plan.md — lot 8f
+---
+Le lot 8 (narrateurs, audio généré, portrait, casting) a été livré sur les trois apps visiteur — web, mobile, tablette — mais pas sur l'app Quest, qui lit pourtant le contenu par l'export de configuration (ConfigurationExport.cs). Relevé le 2026-09-15.
+Ce que fait la VR aujourd'hui : Map et Parcours rendus en liste de points, sans lire audioIds ; hotspots de maquette 3D dont l'audio vient des contenus du point, pas de l'audio par langue ; ni portrait du narrateur, ni écran « les personnes que vous allez rencontrer ».
+À faire :
+
+- Export Unity :
audioIds des points et des étapes, narratorName / narratorPortraitUrl sur la ressource, casting de la configuration.
+- Lecture de l'audio narré d'un point et d'une étape, portrait à côté (audio spatialisé sur un hotspot).
+- Serveur : rendre narrables les points d'une maquette 3D — la section maquette comme conteneur dans la chaîne de
NarratorResolver (aujourd'hui, un point sans SectionMapId est refusé par NarrationService).
+- Écran d'entrée du casting au lancement de la visite.
+
+🔎 Repasse du 2026-09-15 sur les lots Studio 0 à 8 (code de vr-app relu) — ce qui touche le visiteur et manque au casque :
+
+- Lot 6, mention « image générée par IA » — manquante.
ConfigurationExport.Resource ne lit pas origin : les images d'un Slider, la photo d'un point et les médias d'un hotspot s'affichent sans mention. ProvenanceManifest.AiGenerated existe dans le manifeste mais rien ne le remplit depuis l'export. À ajouter avec le reste — c'est l'obligation d'information de l'AI Act, pas un confort.
+- Lot 8, audio narré — manquant (points 1 et 2 ci-dessus). Le commentaire d'un hotspot vient de ses contenus ; la narration écrit dans
audioIds, que le casque ne lit pas.
+- Lot 8bis, casting — manquant (point 4).
+- Lot 7, personnages — couture prévue, pas faite.
ScenePersona.PersonaId est « null en V1, la couture vers l'entité Persona » : les personnages GLB d'une scène ne sont pas reliés aux fiches Personnages (nom, portrait, voix). Relève plutôt du lot 11 (3D).
+- Sans objet : lots 0 à 5 (serveur et manager), crédits et calibrage. Le correctif « audio rangé par identifiant » de 8d ne s'applique pas : le casque résout déjà ses médias par identifiant via
FindResource.
+- Hors Studio, vu en passant : un Parcours est rendu « comme une Map » à partir de
section.Points, or ses étapes vivent dans guidedPaths — un Parcours s'ouvre probablement vide sur le casque. À vérifier casque en main.
+
+⛔ Pas avant : que le plan de test test-plan-studio-narration.md soit passé sur les trois autres apps, et avec le casque en main — rien de ceci ne se vérifie sans l'éditeur Unity. Le dépôt vr-app n'a toujours ni remote ni commit.
diff --git a/v2/studio-plan.md b/v2/studio-plan.md
index 8b44147..261fa51 100644
--- a/v2/studio-plan.md
+++ b/v2/studio-plan.md
@@ -1468,7 +1468,7 @@ Le lot « Bastogne » : plusieurs personnages qui racontent chacun leurs station
coût de régénération par ligne, rien de régénéré avant validation.
- Côté visiteur : portrait canon statique à côté du lecteur audio.
-> **Découpage du 2026-09-15.** **8a — fait** : `NarratorPersonaId` (étape, point, article), `DefaultNarratorPersonaId` (parcours, carte, configuration), `Configuration.GuidePersonaId`, `NarratorResolver` (chaîne de §3.8, source renvoyée pour distinguer hérité / choisi, personnage archivé sauté), migration `AddNarrators`, DTO serveur et Dart. **8b — fait** (décisions de Thomas du 15/09 : bouton explicite, crédits Studio, MP3 via ffmpeg) : `NarrationService` + `api/Narration/{kind}/{id}` (état par langue : absent / à jour / à régénérer / déposé à la main) et `/generate` (réserve, job Hangfire, `Resource` audio `Generated`, ancienne narration supprimée, fichier déposé gardé). Gemini 2.5 Flash TTS ≈ 0,015 $/min = **1 crédit par minute entamée**, par langue. Empreinte texte + personnage + version de voix dans `AiProvenance`. `GeoPoint.AudioIds` ajouté. ⚠️ Jamais exécuté contre Gemini ni ffmpeg réels : pas de clé ni de ffmpeg en local. **8c — fait côté parcours** : onglet « Narrateurs » dans l'éditeur de parcours (défaut du parcours, surcharge par étape en gris hérité / gras choisi, « toutes les étapes suivent le défaut » confirmé, état et coût par ligne, total confirmé avant génération), `NarrationApi` écrit à la main. Puis, même jour : bloc « Narration audio » sur l'article (narrateur, état, génération), carte « Narration » de l'écran Configuration (guide de la visite, narrateur par défaut), onglet et bloc masqués sans Studio. ⚠️ Piège corrigé : l'étape et l'article gardent leur liste d'audios en local, un enregistrement après génération détachait la narration — le client recopie les audios rangés par le serveur à chaque relecture et relit toutes les 5 s après une génération (3 min max). Puis **les points de carte** : narrateur par défaut dans les réglages de la carte, bloc Narration audio dans la fiche du point (éditeur `GeoPointEditor`, l'ancienne fenêtre n'est plus utilisée) ; les audios rangés sont recopiés en local sans relancer d'enregistrement. ⚠️ **Côté visiteur, un point de carte n'avait pas de lecteur audio** : l'audio généré existait sans s'entendre. **8e — ajouté au lot le 2026-09-15** : lecteur audio (et portrait du narrateur) dans la fiche d'un point sur les trois apps visiteur, dans la langue de visite, par l'identifiant de ressource. ⚠️ Écran jamais affiché : analysé, pas lancé. **8d — fait** : `ResourceDTO.narratorName` / `narratorPortraitUrl` remplis pour un audio narré (depuis sa provenance, donc la voix réellement entendue) sur le détail de ressource et l'export ; portrait + nom à côté du lecteur sur web (article, parcours liste et carte), mymuseum-visitapp (article en ligne, parcours contenu et carte) et tablet-app (article). ⚠️ Bug trouvé au passage : les deux apps visiteur ne lisaient l'audio d'une étape que si `audioIds` portait une **URL**, et le web lisait l'article de même — un audio rangé par identifiant n'avait jamais de lecteur. Résolu par l'identifiant de ressource. Hors ligne : pas de portrait. Plan de test : [../test-plan-studio-narration.md](../test-plan-studio-narration.md).
+> **Découpage du 2026-09-15.** **8a — fait** : `NarratorPersonaId` (étape, point, article), `DefaultNarratorPersonaId` (parcours, carte, configuration), `Configuration.GuidePersonaId`, `NarratorResolver` (chaîne de §3.8, source renvoyée pour distinguer hérité / choisi, personnage archivé sauté), migration `AddNarrators`, DTO serveur et Dart. **8b — fait** (décisions de Thomas du 15/09 : bouton explicite, crédits Studio, MP3 via ffmpeg) : `NarrationService` + `api/Narration/{kind}/{id}` (état par langue : absent / à jour / à régénérer / déposé à la main) et `/generate` (réserve, job Hangfire, `Resource` audio `Generated`, ancienne narration supprimée, fichier déposé gardé). Gemini 2.5 Flash TTS ≈ 0,015 $/min = **1 crédit par minute entamée**, par langue. Empreinte texte + personnage + version de voix dans `AiProvenance`. `GeoPoint.AudioIds` ajouté. ⚠️ Jamais exécuté contre Gemini ni ffmpeg réels : pas de clé ni de ffmpeg en local. **8c — fait côté parcours** : onglet « Narrateurs » dans l'éditeur de parcours (défaut du parcours, surcharge par étape en gris hérité / gras choisi, « toutes les étapes suivent le défaut » confirmé, état et coût par ligne, total confirmé avant génération), `NarrationApi` écrit à la main. Puis, même jour : bloc « Narration audio » sur l'article (narrateur, état, génération), carte « Narration » de l'écran Configuration (guide de la visite, narrateur par défaut), onglet et bloc masqués sans Studio. ⚠️ Piège corrigé : l'étape et l'article gardent leur liste d'audios en local, un enregistrement après génération détachait la narration — le client recopie les audios rangés par le serveur à chaque relecture et relit toutes les 5 s après une génération (3 min max). Puis **les points de carte** : narrateur par défaut dans les réglages de la carte, bloc Narration audio dans la fiche du point (éditeur `GeoPointEditor`, l'ancienne fenêtre n'est plus utilisée) ; les audios rangés sont recopiés en local sans relancer d'enregistrement. ⚠️ **Côté visiteur, un point de carte n'avait pas de lecteur audio** : l'audio généré existait sans s'entendre. **8e — ajouté au lot le 2026-09-15** : lecteur audio (et portrait du narrateur) dans la fiche d'un point sur les trois apps visiteur, dans la langue de visite, par l'identifiant de ressource. **8f — à faire, ajouté le 2026-09-15** : la même chose dans l'app VR, oubliée par le lot (le plan ne visait que trois fronts) — export Unity (`audioIds`, narrateur de la ressource, casting), lecture de l'audio narré d'un point et d'une étape avec le portrait, points de maquette 3D rendus narrables côté serveur (la section maquette comme conteneur), écran d'entrée du casting. **Repasse des lots 0 à 8 le même soir** : manque aussi la **mention IA du lot 6** (l'export Unity ne lit pas `origin`, les images générées s'affichent sans mention) ; la couture `ScenePersona.PersonaId` → `Persona` (lot 7) reste à faire, plutôt au lot 11 ; et un Parcours semble s'ouvrir vide sur le casque (étapes dans `guidedPaths`, pas dans `points`). Après le test du lot 8 sur les trois apps, avec le casque : carte kanban 315. ⚠️ Écran jamais affiché : analysé, pas lancé. **8d — fait** : `ResourceDTO.narratorName` / `narratorPortraitUrl` remplis pour un audio narré (depuis sa provenance, donc la voix réellement entendue) sur le détail de ressource et l'export ; portrait + nom à côté du lecteur sur web (article, parcours liste et carte), mymuseum-visitapp (article en ligne, parcours contenu et carte) et tablet-app (article). ⚠️ Bug trouvé au passage : les deux apps visiteur ne lisaient l'audio d'une étape que si `audioIds` portait une **URL**, et le web lisait l'article de même — un audio rangé par identifiant n'avait jamais de lecteur. Résolu par l'identifiant de ressource. Hors ligne : pas de portrait. Plan de test : [../test-plan-studio-narration.md](../test-plan-studio-narration.md).
### Lot 8bis — Casting visiteur *(petit, juste après le lot 8)*