Nouveaux blocs et outils

14 — ai.recit.dev et scenario.recit.dev : le scénariste, le MCP et la bible de personnages

Statut : accepté · Phase : P16 · Mis à jour : 25/10/2026.

Ce document part de l'idée brute de sites/plans/pages/archive/BACKLOG_IDEA.md (section « ai.recit.dev | scenario.recit.dev ») :

Documentation MCP / documentation scénariste pour créer des scénarios, exemple complet du site « lebrocoli.fr » : persona généré via Pet, mise en contexte, description textuelle de son décor, prompts des images à générer, histoires et animations qu'il peut avoir. Le but : un outil le plus standalone possible.

Il la pousse jusqu'à une spécification au même niveau que 08-formats.md, avec la même vision : une source, compilée une fois, racontée partout. Les questions du §8 ont été tranchées le 24/10/2026, sans l'utilisateur et à sa demande (décisions réversibles). Le 25/10 (pets.md), l'utilisateur a répondu sur « Pet » et le skill du brocoli : c'est le skill hatch-pet d'OpenAI, et le personnage s'appelle Broc (§2.2, D12). La licence et l'emplacement de l'image de Broc, sa voix et les lieux de lebrocoli.fr restent à l'utilisateur (06, « À l'utilisateur »). La fin du §8 liste ce qu'il faudra reporter dans les autres plans.

Placement, ports, domaines et règles communes aux plans 10 à 14 : 06-roadmap.md, section « Backlog : plans 10 à 14 ». En résumé : ce plan décrit un outillage, une documentation et un site, pas un format. Le plus utile et le moins risqué vient d'abord : un lot avancé en P7 (guide MCP, pages de doc, exemple scenario-lorem en Markdown simple, sans nouveau package). Le schéma de la bible, @recit/scenario et ai.recit.dev viennent en P16 Scenario, une fois que l'exemple a montré les champs vraiment utiles. Ce plan est propriétaire du personnage, de la bible et de la provenance des images (le plan 11 n'en lit que la partie visuelle), et du dossier unique examples/scenario-lebrocoli.

1. L'idée en une phrase

Écrire une fois le monde d'une histoire (personnages, décors, style, beats), et le raconter dans tous les formats, avec ou sans IA, sans que Récit n'appelle jamais un modèle.

Ce que cela apporte à Récit

Aujourd'hui, la chaîne de Récit est Markdown/MDX → Story → format. Elle sait raconter une source, mais pas la préparer. Pour une histoire racontée en stories, en webtoon et en vidéo, il faut décrire trois fois le même personnage, et rien ne garantit qu'il soit le même d'un format à l'autre, ni d'une image à l'autre.

L'idée ajoute une couche en amont, la bible : une source Markdown (ou un JSON typé) qui décrit une fois pour toutes les personnages, les décors, le style visuel et la structure narrative. Les récits de tous les formats y font référence par id, exactement comme ils font déjà référence aux données (:value, @recit/data) au lieu de recopier des chiffres.

Promesse de RécitCe que la bible y ajoute
Écrire une foisle personnage, son décor et son style sont écrits une fois, dans un fichier, et réutilisés par id
Raconter partoutle même personnage apparaît en carte de story, en case de webtoon, en plan vidéo, en annexe de livre et en fiche de doc
Markdown ou JSONla bible a sa forme JSON typée (kind: "bible"), validée par zod, comme les récits (09-langues-et-json.md)
Toutes les languesles textes de la bible se traduisent, les prompts et les images restent partagés entre langues
Aucune métrique inventée (règle emaki)devient aucun trait inventé : tout trait proposé par un agent est marqué inferred tant qu'un humain ne l'a pas validé
Le moteur n'appelle jamais de modèleRécit produit des prompts comme données et enregistre les images avec leur provenance. L'hôte (agent, outil local) génère

« Le plus standalone possible » se lit ainsi, en trois niveaux qui marchent chacun seul :

NiveauQui travailleCe que Récit fournit
0 — sans IAl'auteur, à la maingabarit npm create recit -- --template scenario-*, bible et récit en Markdown, CLI, rendu complet avec des images de remplacement
1 — avec un agentn'importe quel hôte MCP (Claude Code, Codex, autre) ou un agent qui lit des skills SKILL.mdoutils MCP déterministes, prompts MCP (gabarits de scénario), guides recit://guide/*, skills exportés depuis la même source
2 — avec imagesl'outil de génération choisi par l'auteur (local ou en ligne), hors de Récitprompts dérivés de la bible, register_asset avec fichier de provenance, contrôle de cohérence et de licence au build

Aucun niveau ne dépend d'un service hébergé par Récit ni d'un fournisseur d'IA donné.

2. Ce que la recherche a appris

2.1 lebrocoli.fr, le gabarit nommé par l'utilisateur

Ce que l'exemple a besoin de savoir (relevé public du 24/10/2026, à confirmer par l'utilisateur) :

  • c'est un blog d'événements (éditeur « Le Brocoli », Instagram @lebrocoli), rattaché à l'écosystème Base for Music ;
  • polices : Lexend (OFL) pour le texte, Monument Extended pour les titres. Monument Extended (Pangram Pangram) n'est gratuite qu'en usage personnel : elle ne peut pas entrer dans un exemple public. Unbounded (Google Fonts, NT Type, SIL OFL 1.1) la remplace dans le dépôt — décision du 25/10/2026, voir D13 ;
  • les vignettes du site viennent de gstatic, sans licence connue : elles ne sont jamais reprises ;
  • la mascotte (lebrocoli.png) est un brocoli plat au contour noir épais irrégulier, tête vert foncé, tige vert clair, sans visage ni texte, fond transparent. Les couleurs ont été estimées à l'œil, pas mesurées ;
  • le site ne donne au brocoli ni nom, ni personnalité, ni histoire. Le ton « sorties, musique, nuit, Paris » est une inférence tirée des contenus et de l'Instagram.

Conséquence : il n'existe ni nom, ni persona, ni histoire. L'exemple Récit doit construire la bible, en marquant comme inféré tout ce qui n'est pas validé par l'utilisateur, et n'embarquer que des polices et des images dont la licence est connue.

Mise à jour du 25/10 (pets.md, puis l'image elle-même) : l'utilisateur a donné au brocoli un nom, Broc, et une image de référence. pets.md la décrivait comme « un élégant personnage brocoli souriant en smoking noir et casquette » ; l'image fournie ne montre ni smoking ni casquette : un brocoli vert souriant au rendu 3D doux, en T-pose. Conformément à la règle « l'image fait foi » (D12), c'est la description de pets.md qui est corrigée, pas l'image. Ce n'est pas la mascotte plate et sans visage du site (lebrocoli.png) : Broc a un visage et un sourire. L'image est la source de vérité de son apparence ; elle est rangée dans examples/scenario-lebrocoli/cast/broc/reference.png (1024×1024) et reste © vguerand, tous droits réservés — pas sous la licence MIT du dépôt (D13). La voix et l'histoire ont été proposées le 25/10 dans sites/plans/pages/annexes/broc/, marquées inferred tant que l'utilisateur ne les a pas relues.

2.2 « Persona généré via Pet » : le skill hatch-pet (répondu le 25/10, vérifié)

L'utilisateur a répondu le 25/10 (pets.md) : « Pet » est le skill open source hatch-pet d'OpenAI, et « le skill du brocoli » est ce même skill, lancé avec l'image de référence de Broc et une consigne stricte : préserver le visage, les proportions, la couronne, les couleurs, les matières et le style 3D, sans vêtement ni accessoire ajouté. Faits vérifiés le 25/10/2026 sur le dépôt openai/skills (sources au §2.9) :

  • Entrées : un nom, une description, un preset de style (auto par défaut ; pixel, plush, clay, sticker, flat-vector, 3d-toy, painterly, brand-inspired) et, en option, une ou plusieurs images de référence, qui fixent l'identité du personnage. Sans référence, une image de base est d'abord générée depuis le texte. Un nom de marque seul déclenche une recherche (« brand discovery ») qui se termine par un « Generation handoff » limité à brand_name, brand_brief, avatar_seed, avoid et brand_sources.
  • Identité : l'image de base retenue est copiée en references/canonical-base.png ; chaque ligne d'animation est générée avec cette base (et un guide de mise en page) en entrée. Seule la base peut être générée sans image.
  • Génération déléguée : jusqu'à 10 tâches $imagegen (une base, neuf bandes). Le skill n'appelle aucune API d'image lui-même. imagegen (skill système de Codex) utilise l'outil intégré image_gen de l'hôte, sans clé, ou, seulement sur demande explicite, un script de repli qui appelle l'API OpenAI avec le paquet Python openai et OPENAI_API_KEY. Le SKILL.md ne nomme pas le modèle d'image. Le reste du pipeline est en Python (prepare_pet_run.py, extract_strip_frames.py, inspect_frames.py, compose_atlas.py, validate_atlas.py, make_contact_sheet.py, render_animation_previews.py) et jq.
  • Sortie : une planche (atlas) PNG ou WebP de 1536×1872, cases de 192×208, 8 colonnes sur 9 lignes, fond transparent (fond chroma retiré, sans résidu RVB caché), cases inutilisées entièrement transparentes, sans étiquette, bordure ni grille. Le paquet final est un dossier ${CODEX_HOME:-$HOME/.codex}/pets/<nom>/ avec pet.json (id, displayName, description, spritesheetPath: "spritesheet.webp") et spritesheet.webp. Le dossier de travail garde pet_request.json, imagegen-jobs.json, les prompts, une planche contact, des aperçus GIF et les rapports (final/validation.json, qa/review.json).
  • Lignes (references/animation-rows.md) : idle (6 images), running-right (8), running-left (8, miroir de running-right seulement après validation visuelle), waving (4), jumping (5), failed (8), waiting (6), running (6 ; travail en cours : réfléchir, taper, pas courir), review (6). Les durées sont données image par image (D12). La première image d'idle est l'image fixe pour prefers-reduced-motion.
  • Contrôles : extraction et inspection des images (les erreurs bloquent), validation de l'atlas (cases utilisées non vides, autres transparentes), puis relecture visuelle de la planche contact et des GIF (identité, style, direction, cadence, taille).
  • Format Codex : ce format à 9 lignes est celui de l'application Codex (« The Codex app contract currently uses all 9 states »). Il n'est décrit que dans le skill lui-même (references/codex-pet-contract.md) ; aucune documentation séparée d'OpenAI n'a été trouvée.
  • Variante v2 : le skill work-pets:create-pet de ChatGPT Work produit un format v2 à 11 lignes. Aucune copie publique officielle n'existe ; des sources tierces (Petdex) décrivent une grille 8×11 dont deux lignes sont laissées au client. Non vérifié : Récit ne le prend pas en charge (D12).
  • Licence : LICENSE.txt du dossier hatch-pet : Apache-2.0 ; celui d'imagegen aussi. Le README du dépôt précise que chaque skill porte sa licence dans son propre dossier.

Les autres pistes du 24/10 (/buddy de Claude Code, générateurs grand public, outil interne) sont abandonnées.

2.3 Agent Skills (SKILL.md)

Spécification ouverte (https://agentskills.io/specification, lue en entier) et article d'Anthropic (https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills) :

  • un dossier nom/ avec SKILL.md obligatoire, et en option scripts/, references/, assets/ ;
  • frontmatter : name (1 à 64 caractères, a-z0-9-, sans tiret au début, à la fin ni double, égal au nom du dossier), description (1 à 1024 caractères, dit quoi et quand, c'est elle qui déclenche le skill), et en option license, compatibility, metadata, allowed-tools (expérimental) ;
  • divulgation progressive : les métadonnées sont chargées au démarrage, le corps à l'activation, les ressources à la demande ; références à un seul niveau de profondeur ;
  • le format ne dépend d'aucun modèle : le même dossier se lit dans plusieurs hôtes.

Une décision antérieure prévoit déjà de publier le guide MCP comme skill « depuis une seule source, sur le principe de write-agents.mjs », décision renvoyée à P5. Ce plan la précise.

2.4 Le MCP d'emaki, base de @recit/mcp

Lu dans emaki/packages/mcp/src (guide.ts, server.ts) :

  • guide.ts est la source unique du guide agent : ressource MCP et recopie dans AGENTS.md par scripts/write-agents.mjs. Règles d'or : ne jamais inventer de métriques, suivre le schéma, une idée par scène, la boucle draft → validate → apply → render ;
  • server.ts : McpServer du SDK officiel, transport stdio, schémas d'outils issus des mêmes définitions zod que le moteur, coerceJson (certains clients envoient les objets en chaîne), erreurs précises par nœud ;
  • ses instructions disent qu'emaki n'appelle jamais de modèle : l'hôte réfléchit, les outils sont déterministes.

Spécification MCP, révision 2025-11-25 (sources secondaires, à vérifier sur modelcontextprotocol.io avant toute tâche qui en dépend) : côté serveur Resources, Prompts et Tools ; côté client Sampling, Roots et Elicitation (formulaires à types primitifs). Les Prompts porteraient des gabarits de scénario paramétrés. L'Elicitation permettrait de demander à l'auteur un champ manquant de la bible au lieu de l'inventer. Les deux sont plus tard (§6).

2.5 Écriture de scénario

  • Fountain (https://fountain.io/syntax) : balisage texte de scénario proche de Markdown (en-têtes INT./EXT., personnages en capitales, dialogues dessous, didascalies entre parenthèses, transitions en TO:). Enregistré à l'IANA comme variante Markdown et dans PRONOM. Parseur npm vérifié : fountain-js 1.2.4, MIT, sans dépendance.
  • Beat sheet Save the Cat (Blake Snyder) : 15 temps à positions relatives, dont les pourcentages varient selon les sources (Reedsy, Editor World). C'est une check-list, pas un moule. Pour des formats courts (stories, motion de 5 à 9 scènes selon le guide emaki, webtoon), des gabarits réduits suffisent : trois actes, ou accroche, tension, chute.
  • Bible de personnage : identité, silhouette, traits distinctifs, palette, matériaux, voix (registre, tics, mots interdits), valeurs et limites, relations, décors fétiches, poses et expressions, éléments à éviter, sources avec niveau de confiance, licence et provenance.
  • Décors : une fiche par lieu (lumière, heure, ambiance, palette, accessoires, cadrages types), référencée par id.

2.6 Prompts d'image et cohérence

Sources : getimg.ai, magichour.ai, apiframe.ai, HackerNoon (seed et reproductibilité), forum OpenAI (seed et DALL·E 3).

  • Aucun schéma standard de prompt indépendant du fournisseur n'existe : il faut le concevoir.
  • Hiérarchie de la cohérence : le seed donne une cohérence faible et ne survit pas d'un modèle à l'autre ; les images de référence donnent une cohérence forte ; un LoRA donne la plus forte mais demande un entraînement. La planche « turnaround » (face, trois-quarts, profil, dos) sur fond neutre est la pratique de référence. Le bloc d'identité est figé et recopié mot pour mot en tête de chaque prompt.

2.7 Droit et éthique

  • US Copyright Office, rapport Part 2 (29/01/2025) : un résultat issu d'un prompt seul n'est pas protégeable ; l'apport humain (dessin d'origine, sélection, retouche) l'est. La mascotte dessinée, si elle est d'origine humaine, est l'ancre protégeable ; les variantes générées sont des dérivés à documenter.
  • AI Act UE, article 50 : obligations applicables depuis le 2 août 2026 (marquage machine par les fournisseurs, signalement des deepfakes par les déployeurs, avec exceptions artistiques). Un Code de pratique volontaire existe ; sa date de finalisation varie selon les sources.
  • C2PA : @contentauth/c2pa-web ne fait que lire dans le navigateur ; l'écriture passe par Rust, c2patool ou Node. Aucune dépendance en V1 : un fichier de provenance JSON suffit, et l'on ne retire pas les manifestes C2PA des images d'entrée.

2.8 Ce que le dépôt fournit déjà

  • packages/core : unified, remark-directive 3.0.1, yaml 2.9.1, zod (catalogue). La bible se parse avec ces seuls outils.
  • packages/mcp : squelette (P4-V1 en cours importe le MCP d'emaki).
  • @recit/site-kit : table SITES (www 3000, docs 3001, presentation 3002, components 3010) ; ai.recit.dev prendra 3014 (table unique de 07-domaines.md §4).
  • Les plans 08 et 09 fixent déjà stories, toon, motion, book, le JSON typé et les langues.

2.9 Sources (vérifiées le 25/10/2026)

3. Décisions proposées

Chaque décision a une recommandation. Les questions du §8 ont été tranchées le 24/10 dans le sens des recommandations.

D1 — Format, fondation ou outil ?

OptionPourContre
A. Nouveau format scenario (une scène = un beat)un littéral de plus dans StoryFormat, schéma isoléun scénario est déjà un récit en stories, toon ou motion. Un format de plus dupliquerait leur rendu : contraire à la règle « une seule source de vérité par format »
B. Bible en YAML dans le frontmatteraucun parseur nouveaules longs textes (voix, décors) sont pénibles en YAML et se traduisent mal
C. Une source kind: "bible" + une fondation @recit/scenarioaucun format nouveau ; les récits de tous les formats y font référence par id ; texte en Markdown, traduisibleun troisième kind à ajouter dans 09 §2.2 (à côté de story et sidecar)

Recommandation : C, en deux temps. Ce plan relève de l'outillage, de la doc et d'un site, pas d'un format. D'abord (lot P7), la bible est un simple fichier Markdown lu par l'auteur et par son agent, sans package ni schéma. Ensuite (P16), kind: "bible" et @recit/scenario arrivent, si l'exemple montre qu'ils sont utiles. Un nouveau kind est un ajout compatible en v1 (règle de versionnement de 06, « Backlog »). La bible n'est pas un format de lecture : c'est une source de référence, comme les données de @recit/data. Elle se montre (fiches de personnages) grâce à des composants rendus dans les formats existants (D6), et elle sert aux récits par des attributs de scène communs (D4).

D2 — Syntaxe de la bible (Markdown)

Même grammaire que le reste de Récit : frontmatter, scènes --- id=… entry=…, directives :::. Dans une bible, une scène = une entrée : un personnage, un décor, un style, un prompt d'image ou un gabarit de beats. L'attribut s'appelle entry= et non type=, réservé aux blocs motion (registre des attributs de scène, 06, « Backlog »).

MarkdownMarkdown
--- title: Lorem Cast kind: bible lang: en bible: promptLang: en # language of the prompts, independent of the story language style: ink-flat # default style of the prompts beats: hook-tension-payoff # default beat template --- --- id=lorem entry=character ## Lorem Lorem is a small cheerful sprout who loves dolor sit amet after dark. :::identity Small round sprout, thick irregular black ink outline, two-tone green crown, light green stem, no face, no text, flat colors, transparent background. ::: :::traits - species: sprout - palette: crown=#2F5D1E, stem=#7FD14A, ink=#111111 - voice: short sentences, warm, playful {inferred} - forbidden: slang, real brand names - values: curiosity, kindness {inferred} ::: ::pose[Standing still, crown slightly swaying]{id=idle} ::pose[Waving with one leaf]{id=waving} ::pose[Small jump, both leaves up]{id=jumping} ::expression[Delighted]{id=happy} :::avoid - human face, eyes or mouth - text, letters or logos in the image ::: ::reference{src=./cast/lorem-canonical.png role=canonical} --- id=rooftop-night entry=set ## Rooftop at night A flat rooftop above dolor city, string lights, a small stage in the corner. :::traits - time: night - light: warm string lights, cool blue sky - ambience: distant jazz, light wind {inferred} - palette: sky=#1B2440, lights=#F4C46B - props: string lights, folding chairs, a small stage ::: ::shot[Wide, city skyline behind]{id=wide} ::shot[Medium, stage on the left]{id=medium} --- id=ink-flat entry=style ## Ink flat :::identity Flat vector illustration, thick hand-drawn black ink outlines, limited palette, no gradients, no texture. ::: --- id=p-rooftop-wave entry=prompt subject=lorem set=rooftop-night shot=medium pose=waving aspect=9:16 Lorem greets the crowd before the first song. --- id=hook-tension-payoff entry=beats 1. hook — a question or an image that stops the scroll 2. tension — dolor sit amet goes wrong 3. payoff — the resolution, then a call to action
ÉlémentRôle
kind: bibledit au parseur que le fichier est une bible, pas un récit. Se rend en fiches (D6), jamais en récit
entry=character | set | style | prompt | beatstype de l'entrée. Liste fermée
titre ## puis premier paragraphenom et résumé de l'entrée (textes localisables)
:::identitybloc d'identité figé, recopié mot pour mot en tête de chaque prompt. Non localisable
:::traitsliste clé: valeur. Les clés sont fermées par type (schéma zod) ; une clé inconnue est une erreur
{inferred} en fin d'élémenttrait proposé (par un agent ou par déduction), pas encore validé par un humain. Lu par l'analyseur {k=v} partagé (plan 12, DI0.2)
::pose, ::expression, ::shotlistes fermées propres à l'entrée, référencées par id depuis les récits
:::avoidéléments à exclure de toute image (prompt négatif)
::reference{src role}image de référence (canonical, turnaround, style, set)
entry=prompt + attributsprompt d'image décrit en données : sujet, décor, cadrage, pose, format. Le corps est l'action de l'image
entry=beatsgabarit de beats : liste ordonnée id — description

Règles :

  • référence inconnue (subject, set, pose, shot, style), id en double, clé de trait inconnue, couleur qui n'est pas un hex : erreur avec numéro de ligne (cast.md:24 …) ;
  • trait {inferred} : avertissement par défaut, erreur avec --strict (CI de publication) ;
  • personnage sans :::identity ou sans ::reference canonique : avertissement (la cohérence des images n'est pas assurée) ;
  • texte demandé dans une image (« text », « caption » dans l'action d'un prompt) : avertissement, car une image sans texte se partage entre les langues (§D5).

Deux gabarits de beats sont livrés en P16 : three-act et hook-tension-payoff. Ils sont des données, pas du code : l'auteur peut en écrire d'autres dans sa bible. save-the-cat est plus tard.

Rapport avec le plan 12 : la bible et le glossaire sont deux « collections d'entrées nommées ». BibleEntry étend Entry du plan 12 (id, name, summary, body, tags), et le marqueur {inferred} passe par l'analyseur {k=v} partagé. La différence de découpage est voulue et justifiée : dans un glossaire, une scène est une section de centaines d'entrées courtes (H2) ; dans une bible, une entrée porte des blocs propres (:::identity, ::pose, :::avoid) qui ne tiennent pas dans un titre, d'où une scène par entrée. La liste clé: valeur de :::traits reste une liste Markdown (les valeurs sont des phrases), et non une suite d'attributs {k=v}.

D3 — Schéma JSON typé

Schémas zod dans @recit/core/schema, comme ceux des formats (09 §2.1), JSON Schema généré par z.toJSONSchema et publié sur https://recit.dev/schema/v1/bible.json et .../asset.json.

TypeScriptTypeScript
type BibleSource = { $schema?: string; kind: "bible"; version: 1; meta: { title: Localized<string>; lang?: string }; settings?: { promptLang?: string; style?: string; beats?: string }; entries: BibleEntry[]; }; // Extends Entry from plan 12 (id, name, summary, body, tags). type BibleEntry = Entry & ( | { entry: "character"; identity: string; traits: CharacterTraits; poses: Ref[]; expressions: Ref[]; avoid: string[]; references: Reference[] } | { entry: "set"; identity?: string; traits: SetTraits; shots: Ref[]; references: Reference[] } | { entry: "style"; identity: string; references: Reference[] } | { entry: "prompt"; subject: string; set?: string; style?: string; shot: string; pose?: string; expression?: string; aspect: string; action: string; seed?: number; output?: { path: string; background: "transparent" | "chroma" | "scene" } } | { entry: "beats"; beats: { id: string; description: Localized<string> }[] } ); // Every trait keeps its status: validated by a human, or inferred. The single inferred model of Récit. type Trait<T> = { value: T; inferred?: true; source?: string };

Le JSON d'une image enregistrée (cover.png.json, à côté de l'image). C'est le seul schéma de provenance de Récit (AssetProvenance, kind: "asset"), aussi pour les images du plan 11 :

JSONJSON
{ "$schema": "https://recit.dev/schema/v1/asset.json", "kind": "asset", "version": 1, "asset": "cover.png", "prompt": "p-rooftop-wave", "origin": "ai", "tool": "lorem-generator", "model": "lorem-model", "date": "2026-10-24", "seed": 42, "references": ["cast/lorem-canonical.png"], "author": "Lorem Ipsum", "license": "CC-BY-4.0", "aiGenerated": true }
  • Personnage : ce plan est propriétaire. Le plan 11 n'ajoute qu'une vue dérivée (les ::pose d'une entrée entry=character servent d'états de sprite pixel), sans kind: "character".
  • origin : human, ai ou mixed. aiGenerated est dérivé de origin, gardé explicite pour les outils tiers.
  • Équivalence testée compile(md) == compile(toJson(md)) pour chaque bible, comme pour les récits (09 §2.4). recit convert --to json|md marche sur une bible.
  • Champs localisables : name, summary, descriptions de beats, voix. Champs jamais localisables : identity, prompts, palettes, poses, id, références, seeds (règle de 09 §2.3 : les champs non textuels ne se traduisent pas, et les prompts ont leur propre langue).

D4 — Comment un récit utilise la bible : attributs de scène communs

Un récit de n'importe quel format narratif pointe vers une bible dans son frontmatter et utilise des attributs de scène communs. Le cœur ne les connaît pas : ils viennent d'un plugin remark de @recit/scenario, chargé quand le frontmatter contient cast: (le cœur reste sans connaissance de format, 02 §2).

MarkdownMarkdown
--- title: Lorem Night format: stories lang: en cast: ./cast.md duration: 5s aspect: 9:16 --- --- id=s1 beat=hook set=rooftop-night cast=lorem pose=waving prompt=p-rooftop-wave # Lorem ipsum? --- id=s2 beat=tension set=rooftop-night shot=wide :::dialogue{cast=lorem mood=worried} Dolor sit amet… where is everyone? ::: --- id=s3 beat=payoff set=rooftop-night cast=lorem pose=jumping # Consectetur! ::cta[See the events]{href=https://example.com}
Attribut ou directiveRôle
cast: (frontmatter)chemin de la bible (ou de plusieurs : liste)
beat=temps narratif de la scène, pris dans le gabarit de beats de la bible. Métadonnée, sans effet de rendu
cast=, set=, shot=, pose=, expression=références vers la bible, vérifiées au build
prompt=<prompt-id>image de la scène : l'asset enregistré pour ce prompt s'il existe, sinon une image de remplacement (D7). Pas image=, déjà un champ de scène deck (09 §2.3)
:::dialogue{cast mood}plus tard : réplique d'un personnage, traduite dans chaque format par un tableau fermé (D6)

Règles :

  • référence inconnue : erreur avec numéro de ligne ;
  • recit validate applique les contrôles de scénario dès qu'un récit déclare cast: (pas de commande séparée) : beats manquants ou dans le désordre (avertissement), personnage cité mais absent du décor, prompt jamais utilisé, asset sans provenance (erreur en --strict) ;
  • :::dialogue dans un format qui n'a pas de correspondance (§D6) : erreur explicite, jamais une devinette.

D5 — Langues

  • La bible suit 09 §1 : cast.fr.md est une bible complète, de même structure et avec les mêmes id, où :::identity et les prompts sont recopiés tels quels (ils restent dans promptLang) ; recit i18n check contrôle la parité. Une traduction partielle (noms, résumés, voix, descriptions) va dans le compagnon cast.fr.json.
  • Les prompts restent dans bible.promptLang : traduire un récit ne change aucune image. Les images sont donc partagées entre langues (09 §1, variante cover.fr.png possible).
  • Par défaut, les prompts excluent le texte dans l'image (avoid implicite « text, letters ») : le texte d'une scène reste du texte HTML ou du lettrage généré, donc traduisible, comme les bulles du webtoon.
  • Ligne à ajouter au tableau « Ce que la langue change dans chaque format » de 09 §5 : « bible : noms, résumés et voix localisables ; identité, prompts, palettes et poses jamais localisés ; les images sont partagées entre langues ».

D6 — Rendu dans les autres formats

La bible ne crée pas de format de lecture, mais elle se montre et se raconte partout. En P16, seules les fiches en docs et les attributs de scène (cast, set, pose, prompt) en stories, motion et toon sont livrés. :::dialogue, les ponts ci-dessous et le registre des assets en report sont plus tard.

FormatCe que la bible y devientCe que :::dialogue y devient
docsune page « bible » : CharacterSheet, SetCard, PromptCard, BeatSheet (via <StoryEmbed> ou composants MDX)citation avec le nom du personnage
deckpont bible → deck : une entrée = une slide (pitch de personnage, moodboard de décor)citation (:::quote du deck) avec attribution
storiescarte « meet the cast » ; récit narratif avec cast, set, imagetexte de la carte, nom en surtitre
tooncases avec prompt=, décor et personnage vérifiés:::bubble ; sans x/y, bulles empilées en haut de case (option à ajouter au spec toon)
motionplans avec poses ; un personnage en pixel (bloc pixel du plan voisin) peut animer ses poses en framesbloc statement ou sous-titre
bookannexe back: [cast] (« Dramatis personae »)paragraphe de dialogue, tiret cadratin selon la typographie de la langue
reportregistre des assets : tableau des images, prompts, origine, licence, aiGenerated (utile pour l'AI Act et la relecture)non pertinent : erreur
roadmap, calendarnon pertinenterreur

Ponts à ajouter plus tard au tableau de 08 §0 (correspondance fermée seulement) :

De → versCorrespondance
bible → deckune entrée = une slide, layout fixé par le type d'entrée
bible → booktoutes les entrées character = une annexe
stories → toonune carte = une case : image → src, titre → :::caption, :::dialogue → bulle empilée

Avec le pont existant stories ⇄ motion (P11), une seule source donne la story 9:16, le webtoon et la vidéo verticale.

D7 — Images : Récit ne génère pas, il décrit, vérifie et trace

  • Prompt comme donnée. Le texte du prompt est dérivé de la bible par un gabarit déterministe : identité du style + identité du personnage (mot pour mot) + décor + cadrage + pose + action + avoid. Même bible, même prompt, octet pour octet (test).
  • Adaptateurs de fournisseur = gabarits de texte, déclarés dans la config (scenario.promptTemplates). Un seul gabarit livré : generic. Aucun SDK, aucune clé d'API dans Récit.
  • recit prompts build <story> écrit un fichier .txt par prompt et un prompts.json. L'auteur ou son agent génère ailleurs, puis recit assets register <image> --prompt <id> écrit le fichier de provenance.
  • Images de remplacement, pour que le niveau 0 rende tout sans IA : un cadre neutre au format de la scène, avec le nom du personnage, du décor et l'id du prompt, dans la palette de la bible. Si le bloc pixel (idée motion du backlog, plan voisin) existe, le remplaçant peut être un sprite pixel décrit dans la bible. En --strict, une image de remplacement dans un build de publication est une erreur.
  • Outils externes nommés : hatch-pet et imagegen (§2.2) sont des outils que l'auteur lance hors de Récit, comme tout générateur d'images. Ils ne sont jamais une dépendance, et aucun de leurs scripts n'est copié ; leurs requêtes et leurs planches sont des données du projet, enregistrées avec leur provenance (D12).
  • Contrôle de cohérence : au build, un asset dont le prompt a changé depuis son enregistrement (empreinte du prompt dans le fichier de provenance) donne un avertissement « image périmée ».

D8 — MCP : outils, prompts, ressources (dans @recit/mcp)

Aucun modèle appelé. Les schémas des outils viennent des mêmes définitions zod que le parseur (règle d'emaki), et coerceJson est conservé. Lot P7 : les deux ressources recit://guide/* seulement. P16 : describe_bible_schema, validate_bible, build_prompt, list_prompts, register_asset. Plus tard : build_bible, story_from_beats, les prompts MCP et l'Elicitation.

TypeNomRôle
outildescribe_bible_schemaschéma et clés de traits par type d'entrée
outilbuild_biblehandover tolérant (texte libre structuré) → bible validée. Tout trait non fourni par l'auteur est écrit avec inferred
outilvalidate_bible, check_scenariomêmes règles que la CLI, erreurs avec ligne
outilbuild_prompt(prompt_id) ou (character, set, shot, pose) → texte du prompt + références à joindre
outillist_promptsprompts d'un récit avec statut : asset présent, périmé ou manquant
outilregister_assetenregistre une image et écrit son fichier de provenance
outilstory_from_beatsgabarit de beats + bible + format → squelette de récit (scènes vides avec beat, cast, set), à écrire par l'hôte
promptbrand_discoveryguide l'hôte pour le brief de marque (idée hatch-pet) : sources citées, niveau de confiance, rien de copié
promptcharacter_bible, set_descriptiongabarits paramétrés de fiche
promptbeat_sheet(format, scenes, beats) → plan de scènes
ressourcerecit://guide/scenario, recit://guide/characterguides, source unique (comme guide.ts)
ressourcerecit://bible/{path}bible du projet, en lecture

Elicitation (plus tard, après vérification de la spécification MCP, §2.4) : quand l'hôte la prend en charge, build_bible demanderait à l'auteur les champs obligatoires manquants (nom, palette, voix). Sinon, l'outil renvoie la liste des champs manquants. Dans les deux cas, rien n'est inventé en silence.

D9 — Skills produit, depuis une seule source

Deux familles, à ne pas confondre avec les skills de développement (upstream-sync, recit-import) :

SkillGénéré depuisContenu
recit-scenariorecit://guide/scenariométhode : brief, bible, beats, récit, prompts, assets, rendu. Renvoie aux outils MCP et à la CLI
recit-characterrecit://guide/characterconstruire une bible de personnage cohérente et ses prompts
skill de personnage (broc/)la bible de l'auteur, par recit skills export --bible ./cast.mdSKILL.md (voix, règles, interdits), references/ (bible, décors, style), assets/ (référence canonique, provenance)
  • Un seul générateur pour tout Récit : recit skills export couvre tous les guides recit://guide/* (scenario, character, et pixel ou glossary si ces guides existent, plans 11 et 12) et, avec --bible, le skill d'un personnage.
  • Le générateur applique les règles de la spécification (nom, longueur, dossier) dans nos tests : pas d'outil externe ajouté.
  • Les guides restent la source ; les SKILL.md sont générés, jamais édités à la main (même principe que write-agents.mjs).
  • Un skill de personnage permet à un agent de jouer le personnage (écrire dans sa voix) sans Récit : c'est la part la plus standalone de l'outil.

D10 — Fountain

Plus tard. Tranché (24/10) : import et export seulement, par un petit parseur maison du sous-ensemble utile (en-têtes de scène, personnages, dialogues, didascalies, transitions), sans dépendance. Fountain ne devient pas une syntaxe source. recit convert story.fountain --to md --format toon et recit convert story.md --to fountain (une commande par besoin, règle B9 : pas de recit export fountain). Correspondance : en-tête de scène → set=, personnage → cast=, dialogue → :::dialogue. Ce qui n'a pas de correspondance (transitions) est conservé en :::notes. Si le sous-ensemble maison ne suffit pas, fountain-js (MIT, sans dépendance) est l'alternative, à inscrire dans NOTICE.md.

D11 — Site : un domaine, deux sections

OptionRecommandation
deux sites ai.recit.dev et scenario.recit.devnon : deux vitrines pour un même outil
un site ai.recit.dev, section /scenariooui, sur le modèle motion/video de 07 §3 : scenario.recit.dev (mot du backlog) redirige en 301 vers ai.recit.dev/scenario. « ai » couvre MCP, skills et scénario. Catégorie « site d'outil » de 07 §1 : aucun format, vitrine écrite en stories

Règle anti-doublon de 07 : aucune doc sur ai.recit.dev. Les pages « comment faire » vont dans docs.recit.dev/ai/… (MCP, skills) et docs.recit.dev/scenario/… (bible, beats, prompts, assets). La doc MCP existe déjà dans la carte de 07 (« CLI, MCP, API ») : elle y est complétée, pas déplacée.

D12 — Le kit de personnage de Broc (25/10, après pets.md)

Broc est l'entrée entry=character du gabarit lebrocoli.fr. Son kit est un dossier de données, sans code ni dépendance :

Code
examples/scenario-lebrocoli/cast/broc/ character.md # bible à une seule entrée (kind: bible), source Markdown character.json # jumeau JSON typé, même schéma, testé dans les deux sens reference.png # image de référence de l'utilisateur : source de vérité reference.png.json # provenance (kind: asset) ; auteur et licence donnés par l'utilisateur spritesheet.webp # planche hatch-pet importée telle quelle spritesheet.webp.json # provenance : tool hatch-pet, origin ai, references [reference.png] hatch-pet.request.md # la requête donnée à hatch-pet, gardée comme donnée

Pas de nouveau kind. character.json est une bible à une entrée : le schéma BibleSource de D3, défini en zod dans @recit/core/schema et publié en bible.json. Le seul ajout est un champ facultatif sheet de l'entrée character, avec son schéma zod SpriteSheet dans @recit/core/schema ; le type TypeScript en est dérivé (z.infer), jamais redéfini dans un format. Équivalence testée compile(character.md) == compile(character.json), comme toute bible.

MarkdownMarkdown
--- title: Broc kind: bible lang: fr bible: promptLang: en --- --- id=broc entry=character ## Broc Un brocoli vert souriant, au rendu 3D doux. :::identity Smiling green broccoli character, soft expressive 3D rendering, no clothing and no accessories. Same face, proportions, broccoli crown, colors, materials and 3D style as the canonical reference. ::: :::traits - species: broccoli ::: ::pose[Calm breathing and blinking]{id=idle} ::pose[Waving to greet]{id=waving} ::pose[Jump of joy]{id=jumping} :::avoid - clothing or accessories (no tuxedo, no cap) - any change of face, proportions or colors - text, letters or logos in the image ::: ::reference{src=./reference.png role=canonical} ::sheet{src=./spritesheet.webp layout=codex-pet-v1}
JSONJSON
{ "$schema": "https://recit.dev/schema/v1/bible.json", "kind": "bible", "version": 1, "meta": { "title": "Broc", "lang": "fr" }, "settings": { "promptLang": "en" }, "entries": [ { "id": "broc", "entry": "character", "name": "Broc", "summary": "Un brocoli vert souriant, au rendu 3D doux.", "identity": "Smiling green broccoli character, soft expressive 3D rendering, …", "traits": { "species": { "value": "broccoli" } }, "poses": [{ "id": "idle" }, { "id": "waving" }, { "id": "jumping" }], "expressions": [], "avoid": ["clothing or accessories (no tuxedo, no cap)", "any change of face, proportions or colors", "…"], "references": [{ "src": "./reference.png", "role": "canonical" }], "sheet": { "src": "./spritesheet.webp", "layout": "codex-pet-v1" } } ] }
TypeScriptTypeScript
// @recit/core/schema: layouts are data (interoperability facts), not code from hatch-pet. export const SpriteLayoutName = z.enum(["codex-pet-v1"]); export const SpriteSheet = z.object({ src: z.string(), // local path, relative to the bible layout: SpriteLayoutName, // fixes size, cell, rows, frames and durations }); export type SpriteSheet = z.infer<typeof SpriteSheet>;

Règles :

  • L'image de référence fait foi. :::identity ne décrit que ce que montre l'image, sans rien y ajouter ; :::avoid interdit tout nouvel accessoire. Si la description et l'image divergent, on corrige la description. Le texte d'identité ne dit pas le nom du modèle ni de l'outil.
  • Les poses sont les lignes de la planche. Une pose déclarée par ::pose doit exister dans le layout (sinon erreur avec ligne) ; une pose du layout non déclarée reste utilisable. Les id reprennent les noms de hatch-pet, sans traduction.
  • Un seul layout en v1 : codex-pet-v1. Le format v2 à 11 lignes n'a pas de spécification publique : il ne sera ajouté (codex-pet-v2) qu'avec une source vérifiable. Une planche d'une autre taille est une erreur explicite (« layout inconnu »), jamais une devinette.

Correspondance entre les lignes de hatch-pet et Récit (le layout codex-pet-v1 contient exactement ces chiffres). La lecture en boucle et les usages sont des choix de Récit, pas du skill :

LignePose (id)ImagesDurées (ms)LectureUsage motionUsage stories et beats
0idle6280, 110, 110, 140, 140, 320bouclepose par défaut d'un plancarte fixe ; image 0 en prefers-reduced-motion
1running-right8120 ×7, puis 220boucleentrée par la gauchetransition
2running-left8120 ×7, puis 220bouclesortie ou entrée par la droitetransition
3waving4140 ×3, puis 280une fois, tenuesalut, ouverture, appel à l'actionbeat hook
4jumping5140 ×4, puis 280une fois, tenuecélébrationbeat payoff
5failed8140 ×7, puis 240une fois, tenueerreur, déceptionbeat tension
6waiting6150 ×5, puis 260bouclequestion posée au publiccarte de question ou de sondage
7running6120 ×5, puis 220boucletravail en cours (pas une course)liste qui se révèle, chargement
8review6150 ×5, puis 280boucleexamen d'un chiffre, d'un textetextcard variant=stat ou citation

Un récit utilise Broc par les attributs de scène communs de D4 (cast=broc pose=waving). Sans pose=, le beat donne la pose par défaut de ce tableau, sinon idle. Le rendu (bloc sprite) est décrit dans 11-images.md D9.

Import d'une planche : une étape manuelle documentée, pas de commande. C'est le plus petit choix : une page docs.recit.dev/scenario/import-pet et un test de validation suffisent.

  1. Lancer hatch-pet hors de Récit (Codex ou ChatGPT), avec reference.png et la requête hatch-pet.request.md. Relire la planche contact et les GIF de hatch-pet : l'utilisateur valide les poses à ce moment-là.
  2. Copier spritesheet.webp depuis ~/.codex/pets/broc/ dans le kit. pet.json n'est pas copié : id, displayName et description sont déjà l'id, le name et le summary de l'entrée.
  3. recit assets register cast/broc/spritesheet.webp écrit la provenance (D7) : tool: "hatch-pet", model tel que l'hôte l'indique, origin: "ai" (mixed si retouchée), references: ["reference.png"], aiGenerated: true.
  4. Ajouter ::sheet{src=./spritesheet.webp layout=codex-pet-v1} à l'entrée.
  5. recit validate vérifie la taille exacte du layout (lue dans l'en-tête PNG ou WebP, sans sharp), les poses référencées par les récits et, en --strict, la provenance et la licence.

Une commande recit import pet <dossier> (étapes 2 à 4 en une fois) ne viendra que si des imports répétés en montrent le besoin.

Licences. hatch-pet et imagegen sont sous Apache-2.0, mais rien n'en est copié : ni texte ni script. Le layout codex-pet-v1 ne reprend que des faits d'interopérabilité (taille, ordre des lignes, nombre d'images, durées), réécrits, avec la source citée dans NOTICE.md (§5.2). La planche est une image générée : aiGenerated: true, mention IA (§5.1) et conditions d'usage des sorties du fournisseur d'images dans sa ligne NOTICE. Les poses générées ne sont probablement pas protégeables par le droit d'auteur (§2.7) ; l'image de référence l'est si elle a un auteur humain. Sa licence a été donnée le 25/10 : voir D13.

D13 — Image, licence, police et lieux (décisions du 25/10)

Cinq points tranchés le 25/10/2026, après la fourniture de l'image de référence. Ils ferment les questions laissées ouvertes par D12.

#PointDécision
1Image de référenceexamples/scenario-lebrocoli/cast/broc/reference.png, 1024×1024, fournie par l'utilisateur. Brocoli vert souriant, rendu 3D doux, T-pose, sans smoking ni casquette. L'image fait foi : la description de pets.md est corrigée d'après elle (§2.1), pas l'inverse
2Licence de l'image© vguerand, tous droits réservés — elle n'est pas couverte par la licence MIT du dépôt. Ligne NOTICE obligatoire, ajoutée en même temps que l'exemple (§5.2). La planche dérivée hérite de cette restriction
3Police de titreUnbounded (NT Type, Google Fonts, SIL OFL 1.1) remplace Monument Extended. Servie localement avec son OFL.txt, comme Lexend. Monument Extended n'entre jamais dans le dépôt
4lebrocoli.frl'utilisateur autorise l'usage du vrai domaine dans l'exemple : c'est le seul nom réel du dépôt (ailleurs, Lorem Ipsum). En revanche les lieux sont fictifs : aucun bar, salle ni adresse réelle
5Voix et 5 scénariosdélégués à l'assistant et écrits le 25/10 dans sites/plans/pages/annexes/broc/ (bible.md, scenario-1 à scenario-5). Tout ce qui n'est pas visible sur l'image reste inferred jusqu'à la relecture de l'utilisateur

Conséquence sur le NOTICE du dossier (§5.2) : la ligne « Police de titre de substitution (à choisir) » est remplacée par Unbounded, SIL OFL 1.1, et la ligne de l'image de référence porte désormais « © vguerand, all rights reserved » au lieu de « à confirmer ».

4. Packages, site, exemples et e2e

4.1 Packages

PackageGroupeStatutPubliéContenuDépendances
@recit/mcpdistribution✏️ P7ouilot P7 : ressources recit://guide/scenario et recit://guide/character (source unique). P16 : outils de D8@modelcontextprotocol/sdk, zod : inchangées
@recit/corefondations✏️ P16oui./schema : BibleSource, BibleEntry (étend Entry du plan 12), Trait, AssetProvenance, SpriteSheet (D12), kind: "bible" | "asset" (ajout compatible en v1). Noms d'attributs dans le registreinchangées
@recit/scenariofondations (packages/scenario)📅 P16ouiseulement si l'exemple du lot P7 en montre le besoin : parseur de bible, plugin remark des attributs communs, gabarit de prompt, gabarits de beats, provenance, composants CharacterSheet, SetCard, PromptCard, BeatSheet, ProvenanceBadge@recit/core, zod (catalogue), React 19 en peer. Aucune nouvelle dépendance
@recit/clidistribution✏️ P16ouirecit prompts build, recit assets register, recit skills export ; contrôles de scénario dans recit validateinchangées
@recit/site-kitoutils✏️ P16nonSiteId "ai", entrée dans SITES (port 3014)inchangées

Pourquoi une fondation et pas packages/formats/scenario : elle ne rend aucun format et sert à plusieurs (stories, toon, motion, docs), comme @recit/data et @recit/time. Elle ne dépend d'aucun format (tag nx scope:foundation). Règle commune (06, « Backlog ») : le cœur ne garde que les noms d'attributs (cast, beat, set, shot, pose, expression, prompt) dans son registre ; le plugin vit dans @recit/scenario. Sans elle, cast: dans un frontmatter donne une erreur claire (« installer @recit/scenario »).

Réutilisé tel quel : remark-directive et yaml (parsing), Localized<T> et la résolution des langues (09), le MCP d'emaki (coerceJson, erreurs par nœud, guide source unique), les règles de densité de @recit/core, @recit/paged/runner (Playwright) pour les captures, appelé par la CLI (@recit/scenario ne l'importe pas), le pont stories ⇄ motion, l'analyseur {k=v} du plan 12.

Écartés : tout SDK de génération d'images, satori/resvg, @contentauth/* (V1), fountain-js (sauf si le parseur maison, plus tard, ne suffit pas), tout service hébergé.

À reporter : @recit/scenario dans le glob des fondations de 03-packaging.md §1 et dans 03 §6, nom npm à réserver, README.md (« Règles du cœur ») règle 2, ligne Récit de NOTICE.md.

4.2 Site ai.recit.dev

DomaineRôleDossierContenuPhase
ai.recit.devsite d'outil : MCP, skills et scénaristesites/aihero = une story jouable dont la bible est dépliable à côté ; la même source en vidéo verticale ; galerie de bibles (fiches de personnages, décors) ; prompts dérivés à copier ; liste des outils MCP générée depuis @recit/mcp ; skills à télécharger ; gabaritsP16
AliasCiblePourquoi
scenario.recit.devai.recit.dev/scenariomot du backlog (règle commune de 07 §2)
SiteProjet VercelRacine du projetBuildOuverture
ai.recit.devrecit-aisites/ainx run ai:build. Les vidéos d'exemple sont rendues en CIP16

Port local : 3014, d'après la table d'attribution unique de 07-domaines.md §4 (components 3010, form 3011, directory 3012, maps 3013, ai 3014).

Composants @recit/site-kit utilisés :

ComposantRôleExemple sur ai.recit.dev
FormatHerodémo jouable + source dépliablela story « Lorem Night » et sa bible
SourceTogglerendu / Markdown / JSONajouter un quatrième onglet « bible » (évolution du composant, à valider)
LocaleDemomême récit en en et frtextes traduits, mêmes images
FormatGallerygaleriebibles et récits d'exemple
TemplateCardnpm create recit -- --template …scenario-lorem, scenario-lebrocoli
ExportPanelexports (composant unique de @recit/site-kit, lit exports.json)MP4 et PNG des stories (kind mp4 et png, origine story), skill (kind: "skill", origine tool) : variantes de ExportManifestSchema (@recit/core, 15-export-pdf.md §3.2), ajoutées en P16
BridgeCardpontsstories → motion
DocsLinksrenvoisdocs.recit.dev/ai/…, docs.recit.dev/scenario/…
SiteHeader, FormatFooteren-tête et pied communs—

4.3 Exemples et e2e

DossierContenuPhase
examples/scenario-loremlot P7 : bible Lorem en Markdown simple (un personnage, deux décors, un style, des prompts, hook-tension-payoff), trois micro-récits en motion (puis toon et stories quand ces formats existent), images de remplacement uniquement, sans package nouveau. En et fr. P16 : la même bible compilée et validéelot P7, puis P16
examples/scenario-lebrocolidossier unique du gabarit nommé par l'utilisateur : bible et kit de Broc (D12), traits non validés marqués inferred, décors, prompts, poses, micro-récits. Sections optionnelles des autres plans : sprite de Broc (plan 11, IM4), annuaire de lieux (plan 12), carte (plan 13), formulaire d'inscription (plan 10). En et frP16, seulement après accord
  • examples/scenario-lorem ne contient aucune image générée : les goldens sont stables et sans question de droits. En lot P7, la bible n'est pas compilée par Récit : elle est lue par l'auteur et par son agent via le guide. L'exemple sert à relever les champs vraiment utiles avant d'écrire le schéma (IA1).
  • examples/scenario-lebrocoli est la seule exception à la règle Lorem Ipsum du dépôt, avec un seul jeu de lignes NOTICE (§5.2). Il n'embarque l'image de référence et la planche de Broc qu'une fois leur licence confirmée. D'ici là, il utilise une image de remplacement. Aucune vignette gstatic, aucune police Monument Extended.
  • Nommage : scenario est un outil, pas un format ; la règle commune (06, « Backlog ») autorise examples/<bloc ou outil>-*.
  • e2e/scenario.e2e.ts (P16) : captures de la story et d'une frame motion issues de la même source ; fiche de personnage en clair et sombre, sur mobile ; erreur de référence inconnue (texte avec numéro de ligne) ; image périmée ; en et fr avec les mêmes images ; skill exporté conforme à la spécification ; serveur MCP testé par appels d'outils (prompt dérivé identique à l'octet près).

5. Sécurité, vie privée, licences

5.1 Principes

  • Récit n'appelle aucun modèle ni aucune API d'image. Il n'y a donc aucune clé à stocker. recit validate refuse une clé ou un jeton dans une bible, un récit ou recit.config.ts.
  • Pas de personne réelle. Une bible ne décrit pas une personne réelle identifiable sans son accord ; les exemples publics sont en Lorem Ipsum (sauf le gabarit lebrocoli.fr nommé par l'utilisateur). La discovery ne copie ni logo, ni slogan, ni texte d'une marque tierce : elle cite ses sources avec un niveau de confiance.
  • Traits inférés visibles. Un trait proposé par un agent porte inferred ; recit validate --strict bloque une publication qui en contient.
  • Provenance obligatoire en publication. Chaque image d'un build --strict a son fichier de provenance (origine, outil, modèle, date, auteur, licence).
  • Mention IA. Tranché le 24/10 (06, question 21) : une image aiGenerated: true porte la mention « généré par IA » dans ses métadonnées (fichier de provenance et métadonnées publiées) et dans son attribution visible, dans tous les formats publics. Les valeurs de scenario.aiLabel (credits | inline | off) sont à aligner sur ce défaut. La conformité à l'article 50 de l'AI Act n'est pas une question que ce plan tranche : la relecture juridique reste à faire.
  • C2PA. Les manifestes présents dans les images d'entrée ne sont pas retirés à l'optimisation. Lecture ou signature : plus tard, en option.
  • Vie privée. Le site ai.recit.dev ne charge aucun script tiers et n'envoie aucune donnée à un fournisseur d'IA. Le MCP tourne en local (stdio).

5.2 Lignes à prévoir dans NOTICE.md

« What comes from where » :

CheminOrigine
packages/scenarionouveau, Récit (P16). Idées de pipeline inspirées de openai/skills hatch-pet (Apache-2.0), aucun texte ni script repris ; si du texte est repris, crédit et licence Apache-2.0 ici
packages/mcp (outils scénario)étend le MCP importé d'emaki (crédit d'emaki déjà prévu)
packages/core (layout codex-pet-v1)faits d'interopérabilité (taille, ordre des lignes, images, durées) relevés dans openai/skills hatch-pet (Apache-2.0), réécrits ; aucun texte ni script repris
sites/ainouveau, Récit
examples/scenario-*nouveau, Récit

« Third-party assets » (| Item | Used in | License / terms |), jeu unique pour le gabarit lebrocoli.fr (aucun autre plan n'en ajoute) :

ItemUsed inLicense / terms
Image de référence de Broc (cast/broc/reference.png)examples/scenario-lebrocoli© vguerand, all rights reserved (fournie le 25/10, D13) — hors licence MIT du dépôt
Planche de Broc (cast/broc/spritesheet.webp)examples/scenario-lebrocoligénérée par hatch-pet et imagegen (OpenAI) depuis la référence ; aiGenerated: true ; conditions d'usage des sorties d'OpenAI ; publiée seulement avec la licence de la référence
Lexendexamples/scenario-lebrocoliSIL OFL 1.1
Unbounded (titres, D13)examples/scenario-lebrocoliSIL OFL 1.1 (NT Type) — remplace Monument Extended, exclue car non libre en usage commercial
Images générées des exemples (s'il y en a)examples/scenario-*une ligne par outil ou modèle utilisé, avec ses conditions d'usage des sorties
Fountain (syntaxe), plus tardpackages/scenariospécification ouverte ; fountain-js (MIT) seulement si adopté

6. Phases

Placement dans 06-roadmap.md (« Backlog : plans 10 à 14 ») : lot avancé en P7, puis P16 Scenario après la 1.0. Rien en P4 ni en P5. Lots IA0 à IA5, sous-tâches IAn.m (convention commune de 06). La doc et l'exemple viennent avant le schéma et le package.

IA0 — Guide, doc et exemple, sans package (S/M), lot avancé de P7

  • IA0.1 — Ressources recit://guide/scenario et recit://guide/character dans @recit/mcp (source unique, sur le modèle de guide.ts) : méthode brief → bible → beats → récit → prompts → assets, règle « aucun trait inventé ».
  • IA0.2 — Pages docs.recit.dev/ai/… (MCP, skills) et docs.recit.dev/scenario/… (bible, beats, prompts, provenance), sans promettre d'outil qui n'existe pas encore.
  • IA0.3 — examples/scenario-lorem (en et fr) : bible en Markdown simple, micro-récits en motion (et en toon dès que P7 le livre), images de remplacement.
  • IA0.4 — Relevé des champs réellement utilisés par l'exemple, qui sert d'entrée à IA1.

Sortie : un agent qui lit le guide écrit une bible et un micro-récit Lorem qui compile en motion, sans aucun trait inventé non marqué ; les pages de doc sont en ligne ; aucune dépendance ni package ajouté.

IA1 — Schémas, après l'exemple (S), P16

  • IA1.1 — BibleSource, BibleEntry (étend Entry du plan 12), Trait, AssetProvenance dans @recit/core/schema, kind: "bible" | "asset" comme ajout compatible en v1, JSON Schema publiés (bible.json, asset.json), limités aux champs relevés en IA0.4.
  • IA1.2 — Listes fermées : types d'entrée (entry=), clés de traits par type, rôles de référence.
  • IA1.3 — Tests de schéma sur des bibles Lorem valides et invalides.

Sortie : schémas publiés, exemples valides et invalides testés.

IA2 — @recit/scenario : bible, attributs, prompts (M), P16

  • IA2.1 — Parseur de bible (Markdown → BibleSource), erreurs avec numéro de ligne.
  • IA2.2 — Équivalence compile(md) == compile(toJson(md)) ; recit convert sur une bible.
  • IA2.3 — Plugin remark : cast:, beat, cast, set, shot, pose, expression, prompt, vérification des références.
  • IA2.4 — Gabarit de prompt generic, déterministe ; scenario.promptTemplates dans recit.config.ts ; recit prompts build.
  • IA2.5 — Provenance : recit assets register, empreinte du prompt, avertissement « image périmée ».
  • IA2.6 — Images de remplacement ; contrôles de scénario dans recit validate et --strict.
  • IA2.7 — Langues : cast.fr.md complet ou compagnon cast.fr.json, ligne de 09 §5.

Sortie : examples/scenario-lorem compile en stories et en motion, en et fr, sans aucune image générée ; même bible, même prompt à l'octet près ; toutes les erreurs ont un numéro de ligne.

IA3 — MCP et skills (M), P16

  • IA3.1 — Outils describe_bible_schema, validate_bible, build_prompt, list_prompts, register_asset dans @recit/mcp, schémas issus du parseur, coerceJson.
  • IA3.2 — Composants CharacterSheet, SetCard, PromptCard, BeatSheet, ProvenanceBadge, utilisables en MDX et via <StoryEmbed>.
  • IA3.3 — recit skills export : générateur unique de tous les guides recit://guide/*, et --bible pour le skill d'un personnage, validés contre les règles de la spécification Agent Skills.

Sortie : depuis un hôte MCP, une bible Lorem est validée, ses prompts listés et un asset enregistré, sans qu'aucun trait non fourni ne soit écrit sans inferred ; les skills exportés passent nos tests de conformité.

IA4 — Site ai.recit.dev (M), P16

  • IA4.1 — Gabarit npm create recit -- --template scenario-lorem.
  • IA4.2 — sites/ai (ai.recit.dev, site d'outil), projet recit-ai, alias scenario.recit.dev, entrée SITES (port 3014), liste des outils MCP générée.
  • IA4.3 — Tests : e2e/scenario.e2e.ts (captures multi-formats, clair et sombre, mobile, erreurs, langues), tests MCP, goldens.

Sortie : site en ligne en en et fr, gabarit installable, e2e verts, aucune doc sur ai.recit.dev.

IA5 — Gabarit lebrocoli.fr (M), P16, après accord de l'utilisateur

  • IA5.1 — Réponses aux questions communes de 06. Répondu le 25/10 (pets.md) : « Pet » = hatch-pet, nom Broc et description. Restent : licence et emplacement de l'image de référence, voix, police de substitution.
  • IA5.2 — Kit de Broc (D12) : character.md et son jumeau character.json, schéma SpriteSheet dans @recit/core/schema, page d'import manuel ; bible de Broc : traits du site, traits inférés marqués, validation par l'utilisateur.
  • IA5.3 — Décors, prompts, poses, trois micro-récits multi-formats ; sections optionnelles des plans 10 à 13 si elles sont retenues.
  • IA5.4 — Images : planche de Broc générée par hatch-pet hors de Récit et importée par l'étape manuelle de D12 ; images de scènes générées hors de Récit ; toutes enregistrées avec provenance ; lignes NOTICE.md.
  • IA5.5 — Gabarit scenario-lebrocoli, skill de personnage broc/ exporté.

Sortie : examples/scenario-lebrocoli passe recit validate --strict (aucun trait inféré, toutes les images avec provenance et licence), se joue sur ai.recit.dev en en et fr.

Plus tard

  • :::dialogue et son tableau fermé par format (D6), bulles empilées dans toon.
  • Ponts bible → deck, bible → book (back: [cast]), stories → toon.
  • Registre des assets en report.
  • Fountain en import et export seulement (D10, tranché).
  • build_bible, story_from_beats, prompts MCP (brand_discovery, character_bible, set_description, beat_sheet), Elicitation : après vérification de la spécification MCP.
  • Gabarit de beats save-the-cat.

7. Risques

RisqueParade
Traits inventés par un agent présentés comme des faitsinferred obligatoire, --strict en publication, liste des champs manquants
Images incohérentes d'une scène à l'autrebloc d'identité recopié mot pour mot, référence canonique, contrôle « image périmée ». Récit ne promet pas la cohérence : il la facilite
Dépendance cachée à un fournisseur d'IAaucun SDK, gabarits de texte seulement, niveau 0 testé en CI sans réseau
Droits sur la mascotte ou les images généréesprovenance obligatoire, exemple lebrocoli conditionné à l'accord, examples/scenario-lorem sans image générée
Le format des planches change (v2 à 11 lignes, nouvelle taille)layout nommé et versionné, taille vérifiée par recit validate, codex-pet-v2 seulement avec une source publique
Obligations AI Act mal interprétéeschamp aiGenerated, mention dans les métadonnées et l'attribution visible par défaut, relecture juridique demandée
Police de titre non libre embarquéeMonument Extended exclue, remplacée par Unbounded (SIL OFL 1.1, D13), ligne NOTICE avant merge
Un schéma conçu avant de savoir ce qui sertdoc et exemple d'abord (lot P7), schéma en P16 limité aux champs relevés
Un nouveau kind ou de nouveaux attributs alourdissent le cœurtout vit dans @recit/scenario ; le cœur ne connaît que les schémas et le registre des noms
Le site ai.recit.dev devient une seconde docrègle anti-doublon de 07, DocsLinks vers docs.recit.dev
Spécification MCP ou Agent Skills qui change ou est mal relevéefaits marqués « à vérifier », une seule source par guide, un seul générateur de skills

8. Questions ouvertes pour l'utilisateur

Les questions communes au backlog (« Pet », « le skill », « le projet basic », la mascotte, le nom et la voix du personnage, l'usage de lebrocoli.fr et ses décors, la police de titre, la mention IA, le domaine ai/scenario) sont regroupées une seule fois dans 06-roadmap.md, « Questions ouvertes ». « Pet », « le skill » et le nom du personnage y sont répondus depuis le 25/10 (pets.md, §2.2 et D12). Les questions propres à ce plan ont été tranchées le 24/10/2026, sans l'utilisateur et à sa demande (décisions réversibles) :

  1. Génération d'images : reste-t-elle toujours hors de Récit, ou veux-tu des adaptateurs optionnels (outil local, API) ? Tranché (24/10) : toujours hors de Récit ; les prompts sont des données, avec leur provenance. Pas d'adaptateur.
  2. « Le plus standalone possible » : la lecture en trois niveaux convient-elle, ou vises-tu un outil qui génère lui-même les images ? Tranché (24/10), par la réponse 1 : les trois niveaux, et Récit n'appelle jamais de modèle.
  3. Placement : lot avancé en P7, puis P16 Scenario : d'accord ? Les skills produit sortent-ils avec P16 ? Tranché (24/10) : oui pour l'ordre (06 question 14) ; les skills produit (recit skills export) sont livrés avec P16.
  4. Fountain : plus tard en import et export seulement, ou aussi comme syntaxe source, ou jamais ? Tranché (24/10) : plus tard, en import et export seulement.

À reporter dans les autres documents si ce plan est accepté

FichierCe qui change
02-architecture.mdmention de la bible comme source de référence (sans nouveau StoryFormat) ; attributs entry, cast, beat, set, shot, pose, expression, prompt dans le registre (§3)
03-packaging.mdfait : ligne @recit/scenario (📅 P16), nom à réserver. Reste : glob des fondations (§1)
06-roadmap.mdfait : lot P7 et P16 Scenario, décision datée du 24/10
07-domaines.mdfait : ai.recit.dev, alias scenario.recit.dev, projet recit-ai, port 3014
08-formats.mdplus tard : ponts bible → deck, bible → book, stories → toon ; bulles empilées dans toon ; back: [cast] dans book
09-langues-et-json.mdkind: "bible" et kind: "asset" (§2.2), ligne du §5, règle cast.fr.md complet ou cast.fr.json
NOTICE.mdlignes du §5.2