# 20 — Exécution multi-agent

**Statut : accepté · Phase : transverse · Mis à jour : 29/10/2026.**

Décidé le 29/10/2026. Les plans de Récit s'exécutent par **plusieurs agents en parallèle sur le même
arbre de travail**, une session coordinatrice en tête. Cette page fixe ce que l'outillage permet,
les limites mesurées le 29/10 (dix-sept lots du plan 18, deux lots du plan 19, trois inventaires,
trois plans écrits dans la journée), les rôles, le protocole, et le découpage le plus parallèle
possible des vagues restantes du plan 19. Elle vaut pour tout plan à venir.

## 1. Ce que l'outillage permet

| Moyen                               | Usage                                                                                                                                                 | Coût et limite                                                                                                   |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Agents lancés en parallèle          | Un appel par lot dans la même réponse ; chacun tourne en arrière-plan et notifie à la fin ; le coordinateur continue pendant ce temps                 | Jusqu'à cinq simultanés le 29/10 ; pas de maximum technique, la limite est le budget (§2)                        |
| Agent **fork**                      | Hérite de tout le contexte de la session (plans lus, inventaires, rapports des lots précédents) ; le bon choix quand le lot dépend de ce contexte     | Cher : 150 000 à 500 000 jetons par lot ; chaque fork repart avec un contexte de plusieurs centaines de milliers |
| Agent **frais** (`general-purpose`) | Ne connaît que son brief : la page du plan, le skill, les notes du journal ; le bon choix pour un lot que le plan spécifie seul (STY0b, STY0c, STY0d) | Moins cher, plus prévisible ; le brief doit être complet (§3.3)                                                  |
| Agent **Explore**                   | Lecture seule, balayage large, rapport chiffré avec pointeurs de fichiers : les trois inventaires du plan 19                                          | 90 000 à 100 000 jetons chacun, 3 à 6 minutes                                                                    |
| Reprise après coupure               | Un agent coupé par la limite d'usage garde son contexte ; un message le relance là où il était, en lui rappelant l'état des fichiers                  | Trois coupures le 29/10, aucune perte ; une minute de reprise                                                    |
| `Workflow`                          | Pipeline déterministe (phases, `parallel`, `pipeline`, reprise par identifiant de run) pour une vague entière                                         | Même coût par agent ; utile quand les vagues sont écrites d'avance, moins souple en cas de coupure               |
| Skills                              | Un skill par règle durable : `mantine-style` (la loi du plan 19), `e2e-baselines` (captures et galerie)                                               | Chargé par l'agent qui en a besoin ; c'est le lieu des conventions, pas le brief                                 |

## 2. Les limites réelles, mesurées

| Limite                                    | Mesure du 29/10                                                                                                                                 | Règle qui en découle                                                                                                                                                                                                                                                                                                     |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Budget d'usage par fenêtre de cinq heures | Trois coupures, chaque fois avec trois ou quatre forks lourds en parallèle ; remise à zéro à heure fixe                                         | Trois agents lourds **ou** deux lourds et trois frais à la fois ; lancer les forks en début de fenêtre ; reprendre sans relancer                                                                                                                                                                                         |
| Un seul conteneur e2e                     | 7 à 8 minutes par passage complet (copie 1 s, installation 30 s, construction 2 min, tests 5 min) ; le conteneur copie l'arbre entier           | Le coordinateur lance l'e2e à la fin d'une vague, sur un arbre stable ; un agent ne lance que la spec de sa surface ; le conteneur est libre quand `docker ps --filter ancestor=mcr.microsoft.com/playwright:v1.64.1-noble` ne rend rien (jamais `pgrep -f e2e-linux` dans une boucle d'attente : il se trouve lui-même) |
| Verrou Cargo                              | Deux `tauri build` dans le même `target` : le bundler AppImage vide le dossier de l'autre, le binaire change de nom (APP9, APP10)               | Un `RECIT_APP_TARGET_DIR` par lot natif, ou un seul lot natif à la fois                                                                                                                                                                                                                                                  |
| `dist/` vidé par `tsdown`                 | Une reconstruction concurrente d'un paquet a fait échouer deux `recit app build` et un build de site (APP7, APP11a)                             | Un seul lot reconstruit un paquet partagé à la fois ; les autres lisent le cache nx                                                                                                                                                                                                                                      |
| Manifeste et lockfile                     | Deux `pnpm install` concurrents se disputent `pnpm-lock.yaml` ; un catalogue incomplet casse `pnpm` pour tout le dépôt le temps d'un lot (APP4) | Un seul propriétaire du catalogue et du lockfile par vague ; les autres ajoutent leur dépendance en dernier, après `pgrep`                                                                                                                                                                                               |
| Processeur et mémoire                     | 8 cœurs, 31 Go : quatre builds Vite simultanés passent ; au-delà, les temps doublent                                                            | Quatre agents qui construisent en même temps, pas plus ; les agents de documentation ne comptent pas                                                                                                                                                                                                                     |
| Fichiers partagés                         | `journal.md` (quinze notes en un jour), `index.mdx`, `package.json`, `biome.jsonc`, `AGENTS.md` (`CLAUDE.md` est un lien symbolique vers lui)   | Ajout seulement, relecture juste avant, jamais de réécriture ; `AGENTS.md` seul, jamais `CLAUDE.md`                                                                                                                                                                                                                      |
| Navigateur de l'utilisateur               | VS Code Remote renvoie toute ouverture d'URL vers le poste de l'utilisateur : neuf onglets par passage Playwright local                         | `BROWSER=none` dans le shell de tout agent ; les `webServer` de Playwright le posent                                                                                                                                                                                                                                     |
| Processus orphelins                       | Une coupure laisse tourner Xvfb, serveurs de dev, binaires de test                                                                              | Le message de reprise liste les processus à tuer ; `pgrep` avant tout lancement                                                                                                                                                                                                                                          |
| Contexte du coordinateur                  | Chaque rapport entre dans la session ; au-delà de quelques centaines de milliers de jetons, la session est résumée                              | Rapports sous 50 lignes ; le journal porte le détail ; la mémoire porte ce qui survit à la session                                                                                                                                                                                                                       |

## 3. Rôles et protocole

### 3.1 Les rôles

- **Le coordinateur** (la session principale) : découpe en lots, écrit les briefs, tient la porte
  entre deux vagues (vérifications, `pnpm check`, e2e, galerie), relit les plans, écrit le bilan du
  journal et la mémoire. Il ne code que les raccords entre lots (une ligne de navigation, une
  exclusion biome, un câblage oublié) : tout le reste est délégué.
- **L'agent de lot** : un lot, ses fichiers, sa vérification, sa note au journal, un rapport court.
  Il ne modifie jamais un fichier qu'il ne possède pas : il le demande dans son rapport.
- **L'agent d'inventaire** : lecture seule avant tout plan qui touche beaucoup de fichiers ; trois
  en parallèle, un par zone, pour le plan 19.
- **L'agent relecteur** : un plan est relu deux fois par son rédacteur et une fois par le
  coordinateur, contre le code et les inventaires, avant d'être exécuté.
- **L'utilisateur** : commits de contrôle (« Claude limit », « screenshot before migration »), la
  branche, les réponses aux questions ouvertes, la revue de la galerie servie quand il le veut.

### 3.2 La porte entre deux vagues

1. Chaque lot de la vague a rapporté, avec ses commandes de vérification passées.
2. Le coordinateur fait les raccords signalés par les rapports et relance `pnpm check`.
3. `pnpm test:e2e:linux` dans le conteneur, sur l'arbre stable, deux fois (règle du skill
   `e2e-baselines`) ; les specs de la surface touchée suffisent entre deux vagues, la suite entière
   à la fin.
4. La galerie (`node scripts/screenshot-gallery.js`, `--serve <port>` pour l'utilisateur) : chaque
   différence est voulue ou corrigée ; les références acceptées sont régénérées par
   `pnpm test:e2e:update:linux <spec>` et listées au journal avec la raison.
5. La vague suivante part. Le tableau d'état de la page du plan est mis à jour.

### 3.2 bis La boucle courte des agents (30/10)

Mesuré à la vague 4 : `pnpm check` dure environ 10 s, mais le conteneur e2e coûte 2 s de copie, 28 s
d'installation, **2 min de build de tous les sites** quelle que soit la spec, puis jusqu'à 5 min de
tests, et un seul tourne à la fois : huit agents qui le lançaient chacun faisaient la queue et
reconstruisaient tout. La règle depuis :

- un agent ne lance **jamais** le conteneur : il travaille avec `pnpm check`,
  `pnpm test:related <fichiers>`, `pnpm test:stories <stories>`, le build et le typecheck de son
  projet, et `pnpm test:e2e:host <spec>` (Playwright sur la machine, projet `chromium`, sans
  captures) pour le comportement ;
- les captures sont jugées **à la porte**, par le coordinateur seul : `pnpm test:e2e:linux` une fois
  pour toute la vague, la galerie, puis les références acceptées ;
- un agent qui pense avoir changé un rendu le dit dans son rapport, avec la page ; la porte vérifie.

Allègements du 30/10 (lot INFRA), mesurés sur `pnpm test:e2e:linux e2e/site-docs.spec.ts` avec
d'autres agents au travail :

| Phase        | Avant                             | Après                               |
| ------------ | --------------------------------- | ----------------------------------- |
| copie        | 2 s                               | 1 s de nettoyage + 2 s              |
| installation | 35 à 47 s à chaque passage        | 2 s si la lockfile n'a pas changé   |
| build        | tous les projets, plus de 3,5 min | `docs` et ses 14 dépendances, 2 min |
| tests        | non atteints (build en échec)     | 2,5 à 2,7 min (106 tests)           |

- avec des specs, le conteneur ne construit et Playwright ne sert que leurs projets
  (`scripts/e2e-projects.js`, variable `E2E_PROJECTS`) ; sans spec, tout, comme la CI ;
- `node_modules` Linux reste dans le volume `recit-e2e-work`, le reste est recopié de l'arbre et
  `pnpm install --frozen-lockfile` tourne toujours ; un second passage simultané s'arrête net ;
- le conteneur est plafonné à `E2E_CPUS=6` et `E2E_MEMORY=12g`, quatre workers Playwright ;
- les hooks git restent courts : au commit Biome, oxfmt et les deux compteurs (quelques secondes),
  au push `pnpm check`, le typecheck des projets touchés et `pnpm test:related` (une à deux
  minutes), jamais Docker ; `LEFTHOOK=0` ou `--no-verify` les sautent.

### 3.3 Le brief type

Dix éléments, toujours dans cet ordre, pour un agent frais comme pour un fork : l'objectif et le
numéro du lot ; les sections du plan et le skill à lire d'abord ; les fichiers possédés, liste
exhaustive ; les agents concurrents et leurs fichiers ; les faits de la machine (chaînes installées,
caches, `BROWSER=none`, ce qui est déjà construit) ; les livrables numérotés comme dans le plan ;
les commandes de vérification à coller dans le journal ; le titre de la note de journal ; la forme
du rapport (langue, longueur, ce qu'il doit contenir pour les lots suivants) ; les interdits (git,
branche, worktree, `pnpm fix`, oxfmt global, `CLAUDE.md`).

### 3.4 La coupure de limite d'usage

Quand la limite coupe une vague : le coordinateur note l'heure de remise à zéro, relit `git status`
et `pgrep`, puis renvoie à chaque agent un message de reprise qui dit ce qui est sur le disque, ce
qui tourne encore, et ce que les autres agents ont livré entre-temps. Un agent relancé repart de son
contexte, pas de zéro. Rien n'est relancé en double.

## 4. Le découpage le plus parallèle du plan 19

Le plan 19 §10.1 prévoit sept vagues et dix-sept lots. Le 29/10, STY0 tournait seul en vague 1 alors
que quatre de ses six items ne partagent aucun fichier : le découpage ci-dessous les sépare, et fait
de même pour STY5 et STY6.3. Les dépendances de fichiers de §10 du plan 19 restent la seule
contrainte ; chaque ligne nomme le type d'agent qui convient.

| Vague | Agents en parallèle                                                                                                                                                                                                                                                                                                              | Condition d'entrée                                      | Lourds / frais |
| ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | -------------- |
| 0     | STY1 (captures avant), STY10.1 (skill) — **faits**                                                                                                                                                                                                                                                                               | la branche                                              | 2 / 0          |
| 1     | **STY0a** socle du site (`packages/site`, catalogue, lockfile) · **STY0b** modules dans un paquet publié (`packages/components`, `scripts/build-css-modules.js`) · **STY0c** module dans un deck par esbuild (`packages/cli/src/bundle`, `examples/deck-mdx`) · **STY0d** compteur (`scripts/check-style-rule.*`) — **en cours** | le « avant » généré                                     | 1 / 3          |
| 2     | **STY2** thème et mode de couleur (`packages/site`) · **STY6.1** outillage des paquets publiés et CLI sans Tailwind · **STY7a** modules statiques des blocs motion (`styles.ts` → `blocks.module.css`, `ThemeVars`, sans toucher l'outillage ni la couche d'animation)                                                           | STY0a à STY0d vérifiés, e2e `site-docs` et galerie vide | 1 / 2          |
| 3     | **STY3a** actions et texte · **STY3b** surcouches · **STY3c** code · **STY6.2** `@recit/components` · **STY7b** couche d'animation, `render.tsx`, goldens                                                                                                                                                                        | STY2 et STY6.1 vérifiés, galerie                        | 3 / 2          |
| 4     | **STY4a** pages et mise en page · **STY4b** navigation et plugins · **STY6.3a** `@recit/deck` · **STY6.3b** `site-kit`, `site-stories`, client motion de la CLI · **STY8** sites et exemples                                                                                                                                     | STY3a-c et STY6.2 vérifiés, galerie                     | 2 / 3          |
| 5     | **STY5a** typographie (`Typography`, `Heading`, `MdxComponents`, module) · **STY5b** démontage de `main.css` et variables de `Layout.module.css`                                                                                                                                                                                 | STY4a-b vérifiés                                        | 2 / 0          |
| 5'    | **STY5c** retrait de Tailwind, de `cn.ts` et des dépendances, mesure des bundles                                                                                                                                                                                                                                                 | STY5a-b vérifiés, galerie vide                          | 1 / 0          |
| 6     | **STY9** bascule finale · **STY10.2** docs, CONTRIBUTING, NOTICE                                                                                                                                                                                                                                                                 | STY5c, STY6.3a-b, STY7b, STY8 vérifiés                  | 1 / 1          |

Vingt-trois agents au lieu de dix-sept, huit portes au lieu de sept, et jamais plus de cinq agents à
la fois, dont trois lourds au plus. Les lots « frais » ont dans leur brief la page du plan, le skill
et les notes du journal des lots dont ils dépendent : c'est ce qui les rend possibles. Le plan 21
(tests et Storybook) s'intercale sur les mêmes surfaces : ses lots qui touchent
`sites/storybook/.storybook/*` et `packages/components` passent après STY6.1 et STY6.2, ou dans leur
vague avec des fichiers distincts (ses propres `*.stories.tsx` et specs).

## 5. Budget et rythme

- Une vague de quatre à cinq lots coûte entre un et deux millions de jetons d'agents et une heure à
  une heure et demie de travail, porte comprise. Les sept vagues restantes du plan 19 tiennent en
  une à deux journées de calendrier selon les coupures.
- Un fork par vague au plus là où le contexte de la session compte (le thème, la bascule) ; tout le
  reste en agents frais. Les inventaires et les relectures en agents frais ou Explore.
- Le coordinateur garde son contexte pour les portes : il ne lit pas les transcriptions des agents,
  seulement leurs rapports ; les gros fichiers (un plan de mille lignes) sont lus par sections.

## 6. Ce que l'utilisateur voit

- `sites/plans/pages/journal.md` : une note par lot, un bilan par jour, toujours à la fin.
- Le tableau d'état en tête du §5 ou §10 de chaque plan (18 : fait ; 19 : à tenir à jour par vague).
- `git status` : rien n'est commité par un agent ; les commits de contrôle sont les siens.
- La galerie servie : `node scripts/screenshot-gallery.js --serve 4390`, à ouvrir depuis son poste.
- La mémoire de session (hors dépôt) garde l'état de la machine et les règles apprises.

## 7. Risques

| Risque                                                         | Parade                                                                                                |
| -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| Deux agents sur le même fichier malgré le découpage            | La liste des fichiers possédés est exhaustive ; un fichier manquant se demande ; le diff git est relu |
| Un rapport confiant mais faux                                  | Chaque lot colle ses commandes et leurs sorties au journal ; la porte rejoue les vérifications clés   |
| La session coordinatrice résumée au milieu d'une vague         | Le journal et la mémoire suffisent pour reprendre ; les agents notifient quelle que soit la session   |
| Un agent qui contourne un interdit (git, branche, `CLAUDE.md`) | Rappel dans chaque brief ; `git status` et `ls -la CLAUDE.md` à la porte                              |
| Vagues plus parallèles, donc plus de coupures de limite        | Trois lourds au plus ; les frais pour le reste ; reprise systématique                                 |

## 8. Questions ouvertes

1. Faire tourner des vagues la nuit, sans porte humaine ? Proposé : oui pour les lots, non pour la
   fusion ; la galerie attend le matin.
2. Passer les vagues sous `Workflow` (pipeline écrit d'avance) ? Proposé : non tant que les coupures
   de limite demandent une reprise manuelle ; à revoir si elles disparaissent.
3. Autoriser un agent à committer à la fin de son lot sur `feature/*` ? Proposé : non, les commits
   de contrôle restent à l'utilisateur (règle globale).
