29 — 1.0 : le premier contrat stable de Récit
Statut : proposé · Phase : P12 · Mis à jour : 02/11/2026.
Ce plan détaille la phase P12 de 06 · Feuille de route. La 1.0 n'ajoute pas de fonction : elle transforme ce qui existe en contrat. Après elle, un projet écrit pour Récit 1.x continue de compiler, de se valider et de se construire avec toute version 1.y, et une rupture s'appelle 2.0. Le plan dit ce qui entre dans ce contrat (§2), comment on le mesure (§3), ce qui reste à faire pour le tenir (§4), en lots exécutables par des agents (§5), puis les risques et les questions pour l'utilisateur.
Il vient après l'alpha (22 · Alpha publique) et les six formats de P6 à P11 (08 · Formats). Il ne s'exécute pas avant eux, mais ses outils de mesure (lots V1 et V2) gagnent à exister plus tôt : chaque phase de format sait alors ce qu'elle change.
0. Pourquoi une 1.0, et pourquoi pas tout de suite
- Pour un utilisateur, la 1.0 est une promesse : la syntaxe d'une story, ses clés de front
matter, le jumeau JSON,
recit.config.ts, les commandes et les exports ne cassent plus sans changement de majeure. C'est ce qui permet d'écrire des decks, des films et des sites qu'on garde des années. - Pour Récit, c'est un coût : chaque nom publié devient permanent jusqu'à la 2.0. On ne fige
donc que ce qui a servi : la 1.0 attend que les neuf formats de la vision aient été écrits, lus et
convertis entre eux, parce que le modèle
Storyet le schémav1doivent les porter tous. - La règle B1 rend l'attente moins chère : un nouveau format ou un nouveau
kindest un ajout compatible env1(06-roadmap, backlog). Les formats d'après la 1.0 (form, directory, atlas, scenario, P13 à P16) entrent en mineure, sans toucher au contrat.
1. État réel au 02/11/2026
Vérifié dans le code. Rien n'est encore publié : l'alpha est l'objet du plan 22.
| Sujet | État |
|---|---|
| Versions | Tous les packages en 0.0.0 ; 17 version plans en attente donneront 0.1.0-alpha.0. Groupe fixed, tags recit@{version} |
| Formats faits | deck, motion, docs : packages, sites (presentation, motion, docs), exemples (deck-*, motion-hello, motion-saas, site-embed, site-i18n bilingue), pages de doc (sites/docs/pages/formats/deck/, motion.mdx) |
| Formats à venir | report, toon, book, roadmap, calendar, stories : squelettes privés (src/index.ts = export {}), comme @recit/data, @recit/time et @recit/paged |
Schéma JSON v1 | 12 fichiers générés dans packages/core/schema/v1 (par json-schema.spec.ts, RECIT_UPDATE_SCHEMAS=1), $id en https://recit.dev/schema/v1/…. Ceux des six formats à venir sont des coquilles d'environ 3,3 ko. Non servis sur recit.dev (lot AL8 du plan 22) |
recit migrate | N'existe pas : aucune commande, aucun migrateStorySource dans packages/cli ni packages/core (09 · Langues et JSON §2 le prévoit) |
| Alias dépréciés | Toujours présents (compileDeck, presentation.config.*, PresentationEmbed…) ; retirés avant l'alpha si la question 2 du plan 22 est acceptée, sinon ici |
| Surface publique | Aucun test ne la mesure. published-packages.spec.ts vérifie la forme des manifestes, publint les cartes exports, mais un export qui disparaît ne fait échouer aucun test |
| Ponts entre formats | Un seul fait : deck → motion (P4). Les autres ponts de 08 · Formats §0 arrivent avec leur format |
| Règles de version | check-version-plans.js refuse patch, minor, major en 0.x ; à 1.0.0-rc.N il accepte major sans preid, qui donne 1.0.0. Rien n'y dit encore ce qui exige une majeure après la 1.0 |
| Frontières | Une violation tolérée : @recit/site-stories → @recit/cli (ST-5, TOLERATED de check-package-boundaries.js) |
Studio, play.recit.dev | @recit/studio est un squelette privé ; aucun projet Vercel pour play |
| Politique de sécurité | Pas de SECURITY.md |
| Remotion | Dépendance dure de @recit/motion-render seul ; question 5 de la feuille de route (licence) ouverte |
2. Ce que la 1.0 promet : la liste des contrats
Un contrat est ce qu'un utilisateur écrit ou importe. Tout ce qui n'est pas dans cette liste peut changer en mineure, et la page « Stability » de la doc le dit.
| N° | Contrat | Mesuré par (§3) |
|---|---|---|
| C1 | La syntaxe Markdown de chaque format : séparateurs et attributs de scène, directives (:::notes, :::step…), clés de front matter, réglages à plat | corpus d'exemples (V3) |
| C2 | Le schéma JSON v1 : story.json, un fichier par format, sidecar.json, config.json ; le jumeau kind: "story" et le sidecar kind: "sidecar" | schémas figés et corpus (V3) |
| C3 | recit.config.ts : chaque clé, ses défauts, ses diagnostics | config.json figé (V3) |
| C4 | La CLI : commandes, options, codes de sortie, fichiers produits | instantané de --help et tests (V2) |
| C5 | Les exports JS des packages publiés : entrées de la carte exports, noms exportés, types publics | test de surface publique (V2) |
| C6 | Les outils MCP : noms, schémas d'entrée, ressources recit://… | instantané de describe_format (V2) |
| C7 | Les jetons CSS de @recit/theme (variables) et les classes sémantiques que la doc donne aux auteurs (slide-* de deck.css) | liste figée (V2), question 6 |
Hors contrat, dit explicitement : les noms de classes des modules CSS (générés), la structure HTML
rendue, le format des film.json (artefact de build, jamais le twin), le contenu des messages de
diagnostic (leur code, lui, fait partie de C3), l'API interne des plugins du framework de sites si
la question 3 le décide.
3. Décisions proposées
| N° | Décision proposée | Pourquoi |
|---|---|---|
| D1 | Chemin de version : une préversion 0.N.0-alpha.0 par phase (P5 → 0.1, P6 → 0.2… P11 → 0.7), puis une série 1.0.0-rc.N (plan premajor, preid rc), puis 1.0.0 (plan major, preid vide) sous le dist-tag latest | check-version-plans.js accepte déjà ce chemin ; la série rc laisse le temps de trouver ce qui casse sans rien promettre |
| D2 | Un test de surface publique : pour chaque package de release.projects, la carte exports, les noms exportés à l'exécution (import du dist) et les types exportés (API du compilateur TypeScript, déjà au catalogue), écrits dans un instantané JSON versionné. Toute différence fait échouer pnpm test ; la mise à jour est explicite (RECIT_UPDATE_API=1) et la sortie dit si elle retire (majeure) ou ajoute (mineure) | Un export qui disparaît est aujourd'hui invisible. Aucune dépendance nouvelle (pas d'api-extractor) |
| D3 | Gel du schéma v1 à 1.0.0-rc.0 : les fichiers de packages/core/schema/v1 deviennent la référence ; un test refuse toute modification qui ne soit pas un ajout compatible (propriété optionnelle, valeur d'énumération, format ou kind nouveaux sous B1). Tous les exemples et les stories des sites restent valides contre la version figée | C'est la seule promesse qu'un outil tiers lit directement |
| D4 | recit migrate livré à la 1.0 avec une seule migration réelle, v1 → v1 (identité, normalisation), et la mécanique pour v2 : lecture de version, chaîne migrateStorySource, rapport par fichier, --dry-run | La feuille de route l'exige ; l'écrire avant d'en avoir besoin évite de l'écrire sous la pression d'une 2.0 |
| D5 | Politique de dépréciation : un nom déprécié l'est en mineure, avec un diagnostic deprecated qui nomme son remplaçant ; il disparaît à la majeure suivante, jamais avant. Aucun alias ne passe la 1.0 : ceux qui restent sont retirés dans 1.0.0-rc.0 | Les alias accumulés en 0.x ne doivent pas devenir des contrats par inertie |
| D6 | Règles de version après la 1.0 : patch, minor et major redeviennent permis ; un plan qui retire ou renomme un élément de C1 à C7 est en major, et le test de surface (D2) le rappelle. Les préversions de la ligne suivante passent sous next | Les règles d'aujourd'hui sont écrites pour la 0.x ; elles doivent dire ce qui arrive ensuite |
| D7 | Les neuf formats de la 1.0 (deck, motion, docs, report, toon, book, roadmap, calendar, stories) remplissent chacun la liste de contrôle de §4.2 | Critère de P12 dans la feuille de route ; question 1 |
| D8 | Les ponts de 08 · Formats §0 sont chacun testés par une conversion d'un exemple réel et documentés sur une page « Bridges » ; un pont non fermé est une erreur explicite, jamais une devinette | Critère de P12, et règle d'emaki reprise |
| D9 | Une seule ligne maintenue : seul le dernier majeur reçoit des correctifs, pas de branche de maintenance ; Node : la plage d'engines (>=22.22.0) est testée en CI sur la plus basse et la plus récente version paire | Un seul mainteneur ; une promesse de support qu'on ne peut pas tenir est pire que pas de promesse. Question 5 |
| D10 | Dépôt et sécurité : SECURITY.md (signalement privé par GitHub), règle « Require a pull request » sur main avec une GitHub App autorisée pour le commit de release (SETUP.md §5), provenance npm sur chaque version | Un projet 1.0 dit comment signaler une faille |
| D11 | play.recit.dev n'est pas une condition de la 1.0 : il arrive quand @recit/studio est prêt, en mineure | La feuille de route le met au conditionnel ; question 7 |
| D12 | La violation tolérée ST-5 (site-stories → cli) est résolue avant 1.0.0-rc.0 : la lecture de fichiers part dans @recit/core/node (03-packaging.md §8). TOLERATED est vide à la 1.0 | Une dépendance inversée figée dans un contrat 1.x ne se corrige plus qu'en 2.0 |
4. Ce qui reste
4.1 Les cases de P12, mises en face des lots
| Case de P12 (feuille de route) | Lot |
|---|---|
API publique de Story, recit.config.ts, CLI, @recit/site-stories stable | V1, V2 |
| Alias dépréciés retirés | V5 |
| Ponts entre formats documentés et testés | V6 |
| Neuf formats : page, site, deux exemples dont un bilingue, schéma publié | V7 |
Schéma v1 figé, recit migrate prêt | V3, V4 |
play.recit.dev si le studio est prêt | hors plan (D11) |
4.2 La liste de contrôle d'un format, pour la 1.0
Pour chacun des neuf formats :
- package publié dans
release.projects, forme vérifiée (published-packages.spec.ts,publint), budgetsize-limits'il a un runtime navigateur ; - page de doc sur docs.recit.dev (syntaxe, réglages, exports), et site de format en ligne (07 · Domaines) ;
- au moins deux exemples dans
examples/, dont un bilingue, en Lorem Ipsum, chacun avec son jumeau couvert parsource-conversion.spec.ts; - schéma
v1/<format>.jsonréel (plus une coquille), servi surrecit.dev/schema/v1/; - un spec e2e de son site, des stories pour ses composants (plan 21), axe sans erreur ;
- ses ponts (§3, D8) testés.
5. Lots
Règles de 20 · Multi-agents §3 : un lot, un agent, ses fichiers ; relire avant
d'écrire ; jamais de git ; une note ### V1-n — <titre> — <date> dans le journal ; BROWSER=none.
nx.json, AGENTS.md, CONTRIBUTING.md et SETUP.md appartiennent au coordinateur. Chaque lot
qui touche un package publié ajoute un version plan (prerelease pendant la série rc).
V1 et V2 peuvent partir dès la fin de l'alpha : ils mesurent sans rien figer. V3 à V9 attendent la fin de P11.
V1 — L'inventaire des contrats (S)
Fichiers : sites/docs/pages/documentation/reference/stability.mdx (nouveau, en brouillon), la note
de journal. Lecture seule partout ailleurs.
- 1.1 — Pour C1 à C7, la liste exhaustive tirée du code (exports, commandes, clés de config, directives, outils MCP, jetons), avec le fichier source de chaque élément.
- 1.2 — Ce qui est hors contrat, écrit (§2).
Vérification : pnpm exec nx run docs:build ; pnpm check.
V2 — Le test de surface publique (M)
Fichiers : scripts/public-api.js (nouveau), scripts/__tests__/public-api.spec.ts,
scripts/public-api.snapshot.json, la note de journal.
- 2.1 — Instantané de C4, C5, C6, C7 pour chaque package de
release.projects(D2). - 2.2 — Une différence échoue avec la liste des retraits et des ajouts ;
RECIT_UPDATE_API=1réécrit l'instantané. - 2.3 — Le message dit le bump attendu : retrait ou renommage →
majoraprès la 1.0 (preminoren 0.x).
Vérification : pnpm exec vitest run scripts/__tests__/public-api.spec.ts ;
pnpm exec nx run-many -t build puis pnpm test ; pnpm check.
V3 — Le gel du schéma v1 (M)
Dépend de : V7 (les six schémas réels). Fichiers :
packages/core/src/__tests__/json-schema.spec.ts,
packages/core/src/__tests__/schema-compat.spec.ts (nouveau), un version plan.
- 3.1 — Comparaison de chaque schéma généré à sa version figée : seuls les ajouts compatibles passent (D3), le reste échoue en nommant le chemin JSON.
- 3.2 — Corpus : chaque story de
examples/et desites/*/stories, et son jumeau, valides contre la version figée. - 3.3 — Règle B1 : un format ou un
kindinconnu donne l'erreur « installez @recit/… », pas une erreur de schéma.
Vérification : pnpm exec vitest run packages/core ; pnpm test ; pnpm check.
V4 — recit migrate (M)
Fichiers : packages/core/src/schema/migrate.ts (nouveau), packages/cli/src/commands/migrate.ts
(nouveau), leurs tests, la page CLI de référence, un version plan.
- 4.1 —
migrateStorySource(source) → { source, changes },v1 → v1(D4). - 4.2 —
recit migrate [fichiers…] [--dry-run]: rapport par fichier, code de sortie non nul si un fichier ne se migre pas, jamais d'écriture en--dry-run. - 4.3 — Test : tout le corpus de V3 passe par
migratesans changement.
Vérification : pnpm test:related sur les fichiers ; pnpm -F @recit/cli typecheck ; pnpm test ;
pnpm check.
V5 — Dépréciations et alias (S/M)
Fichiers : les sources des alias qui restent (si le plan 22 ne les a pas retirés), le module de
diagnostics de @recit/core (code deprecated), leurs tests, un version plan.
- 5.1 — Diagnostic
deprecatedavec le nom du remplaçant (D5). - 5.2 — Plus aucun alias dans le code ;
grepdes anciens noms vide.
Vérification : pnpm exec nx run-many -t build typecheck ; pnpm test ; pnpm check.
V6 — Les ponts entre formats (M/L, un agent par pont si besoin)
Fichiers : un test de conversion par pont dans le package du format d'arrivée,
sites/docs/pages/formats/bridges.mdx (nouveau).
- 6.1 — Chaque ligne de 08 · Formats §0 : un exemple réel converti, le résultat validé par le schéma du format d'arrivée.
- 6.2 — Un cas non fermé par pont, qui donne l'erreur explicite attendue.
Vérification : pnpm test ; pnpm exec nx run docs:build ; pnpm check.
V7 — La revue des neuf formats (M par format, agents en parallèle)
Un agent par format, la liste de §4.2 comme brief. Chacun ne touche que son package, ses exemples, son site et sa page de doc ; il signale le reste au coordinateur.
Vérification par format : pnpm exec nx run <format>:build et typecheck ;
pnpm exec vitest run packages/formats/<format> ; pnpm test:stories sur ses stories ;
pnpm test:e2e:host e2e/site-<site>.spec.ts.
V8 — Les règles de version 1.x et la sécurité (S)
Fichiers : scripts/check-version-plans.js, scripts/__tests__/check-version-plans.spec.ts,
SECURITY.md (nouveau), une matrice Node dans .github/workflows/build.yaml. Demande au
coordinateur : CONTRIBUTING.md §5, SETUP.md §5 et §6.
- 8.1 — Tests du chemin complet de D1 :
0.7.0-alpha.3+premajor(rc) →1.0.0-rc.0;prerelease→1.0.0-rc.1;majorsanspreid→1.0.0; après1.0.0,patch,minoretmajoracceptés. - 8.2 — Matrice Node : plus basse version d'
engineset dernière version paire (D9).
Vérification : pnpm exec vitest run scripts/__tests__ ; pnpm check.
V9 — La série rc, puis la 1.0 (coordinateur, puis humain)
- 9.1 —
1.0.0-rc.0:pnpm verify,pnpm test:e2e:linuxcomplet, test de fumée du plan 22 (scripts/pack-smoke.js), dry run relu ; arrêt et remise à l'utilisateur. - 9.2 — Publication de chaque
rcsur le feu vert explicite de l'utilisateur, sousnext. - 9.3 — Après au moins une
rcsans correctif de contrat :1.0.0, planmajor,preidvide, dist-taglatest, sur le feu vert de l'utilisateur. - 9.4 — Page « Stability » publiée (V1), guide de migration 0.x → 1.0, annonce sur recit.dev.
5.1 Ordre
| Moment | Lots | Condition |
|---|---|---|
| Après l'alpha | V1, V2 | plan 22 terminé |
| Pendant P6 à P11 | V7 (au fil des formats) | chaque format le fait à sa sortie |
| Après P11 | V3, V4, V5, V6, V8, D12 | les neuf formats faits |
| Fin | V9 | tous vérifiés, porte e2e verte, feu vert |
6. Critères de sortie de P12
1.0.0est sur npm souslatestpour chaque package publié, avec la provenance, sur le feu vert de l'utilisateur.- Les neuf formats remplissent §4.2.
- Le test de surface (V2) et le gel du schéma (V3) sont dans
pnpm testet verts. recit migrate --dry-runpasse sur tout le corpus sans changement.TOLERATEDest vide ; aucun alias dans le code.- La page « Stability » liste C1 à C7 et la politique de dépréciation et de support.
7. Risques
| Risque | Parade |
|---|---|
| Figer trop tôt un schéma que les formats suivants veulent changer | gel à 1.0.0-rc.0 seulement, après P11 ; B1 pour tout ajout ultérieur |
| Neuf formats repoussent la 1.0 de plusieurs mois | V1 et V2 dès l'alpha ; question 1 (une 1.0 plus courte, formats en mineure) |
| Le test de surface devient du bruit qu'on met à jour sans lire | la sortie classe retraits et ajouts, et donne le bump attendu ; la revue de diff lit l'instantané |
| Un correctif urgent sur 1.x après le début de 2.0 | D9 l'assume : pas de branche de maintenance ; à revoir si des utilisateurs le demandent |
| La licence de Remotion bloque un usage commercial du format motion | dépendance limitée à motion-render ; question 4 tranchée avant rc.0 |
| Le framework de sites publié (plan 22, D2) fige son API de plugins | hors contrat si la question 3 le décide, et dit sur la page « Stability » |
8. Questions ouvertes
- Neuf formats pour la 1.0 (feuille de route, proposé), ou une 1.0 plus tôt sur
deck,motionetdocs, les six autres arrivant en mineures 1.x grâce à la règle B1 ? La seconde option publie un contrat plus petit plus tôt, mais fige le modèleStoryavant que report, book et calendar l'aient éprouvé. - Série
1.0.0-rc.Navant la 1.0 (proposé), ou passage direct d'une0.N.0-alphaà1.0.0? - Le framework de sites dans le contrat : si
@recit/siteest publié (plan 22, question 1), son API de plugins fait-elle partie de C5, ou reste-t-elle hors contrat en 1.x (proposé) ? - Remotion : la licence convient-elle à l'usage prévu (question 5 de la feuille de route) ?
Sinon,
motion-rendersort de la 1.0 et reste en préversion. - Support : seul le dernier majeur reçoit des correctifs (proposé), ou une période de recouvrement (par exemple six mois) après la sortie d'une 2.0 ?
- Classes sémantiques de
deck.css(slide-card…) : contrat C7 (proposé, parce que la doc les donne aux auteurs pourtheme.customCss), ou détail interne ? play.recit.devhors des conditions de la 1.0 (proposé, D11) ?