# bmad-plus swarm

> Tirer, briefer, vérifier, classer et compter un essaim de sous-agents dans un budget : panel, jury ou fanout. Options, arborescence, approbation au code 2, règles d’honnêteté, sortie réelle, erreurs.

Canonical: https://bmad-plus.rochetta.fr/fr/docs/reference/cli-swarm/
Language: fr
BMAD+ version: 0.23.1
Documentation reviewed: 2026-10-19
Author: Laurent Rochetta
License: MIT

Documentation BMAD+ › [Référence](https://bmad-plus.rochetta.fr/fr/docs/reference/) › bmad-plus swarm

Un essaim, ce sont de nombreux sous-agents qui font chacun une fois le même type de travail : trente acheteurs simulés qui lisent un argumentaire, trois jurés qui tiennent chacun un angle, un rédacteur par page. `bmad-plus swarm` tient la comptabilité autour de cela. Il tire les unités, écrit un brief par sous-agent, vérifie chaque fichier de réponse, classe une réponse qu’un sous-agent s’est contenté d’afficher et compte les réponses valides. Il n’appelle jamais de modèle, n’ouvre aucune connexion réseau et ne lance aucun processus : votre assistant (l’assistant hôte) lance les sous-agents, la commande ne fait que lire et écrire des fichiers sous `.bmad-plus/swarm/`. À utiliser quand on demande un panel, un jury ou un éclatement en unités indépendantes. La version 0.23.0 ne livre aucune définition d’essaim dans ses packs ; c’est vous ou un pack qui fournit le fichier de définition.

<a id="synopsis"></a>
## Synopsis

**Dans le terminal de votre projet**

```sh
npx bmad-plus swarm init --definition FILE [--profile FILE | --units FILE] [--context NAME=FILE]... [--n N] [--seed N] [--approved]
npx bmad-plus swarm briefs RUN [--wave N]
npx bmad-plus swarm check RUN
npx bmad-plus swarm save RUN UNIT --input FILE
npx bmad-plus swarm tally RUN [--out FILE]
npx bmad-plus swarm inspect RUN
npx bmad-plus swarm plan RUN [--out FILE]
```

**Options de bmad-plus swarm**

| Option | Argument | Défaut | Effet |
| --- | --- | --- | --- |
| `<action>` | `init`, `briefs`, `check`, `save`, `tally`, `inspect`, `plan` | obligatoire | L’étape à exécuter. |
| `[run]`, `[unit]` | id d’exécution, id d’unité | aucun | Id d’exécution comme `buyer-panel-20261018-oqu7` (toutes les actions sauf `init`) ; id d’unité comme `B002` (`save` uniquement). |
| `-d, --directory <path>` | chemin | dossier courant | Dossier du projet. |
| `--definition <file>` | chemin | aucun | Définition de l’essaim, JSON relatif au projet. `init` uniquement ; obligatoire. |
| `--profile <file>` | chemin | aucun | Profil du panel, JSON relatif au projet. `init` ; obligatoire pour un panel, refusé pour les autres types. |
| `--units <file>` | chemin | aucun | Unités du fanout, JSON relatif au projet. `init` ; obligatoire pour un fanout, refusé pour les autres types. |
| `--context <name=file>` | NOM=FICHIER | aucun | Fichier de contexte repris tel quel dans chaque brief. Répétable. Chaque nom déclaré par la définition est obligatoire ; un nom non déclaré est refusé. |
| `--n <count>` | entier de 1 à 1000 | aucun | Nombre d’unités à tirer pour un panel. Refusé pour un jury ou un fanout. |
| `--seed <number>` | entier de 0 à 2147483647 | tirée une fois, puis enregistrée | Graine du tirage. Panel uniquement. Même profil, même `--n`, même graine : mêmes cartes. |
| `--approved` | aucun | désactivé | Enregistre qu’un humain a accepté de dépasser le budget. Ne le passez jamais de votre propre chef. |
| `--wave <count>` | entier de 1 à 1000 | vague configurée (10) | Sous-agents lancés ensemble. `briefs` uniquement. |
| `--input <file>` | chemin | aucun | Réponse qu’un sous-agent a affichée. `save` uniquement ; obligatoire ; hors de `.bmad-plus/` ; 1 Mio au plus. |
| `--out <file>` | chemin | dans l’exécution | Fichier de sortie de `tally` et `plan`. Doit se trouver sous `.bmad-plus/swarm/` (voir Lectures, écritures et limites). |
| `--json` | aucun | désactivé | Sortie lisible par machine, avec `schemaVersion: 1` et un champ `status`. |

<a id="kinds"></a>
## Les trois types d’essaim

**Types, fixés par le fichier de définition**

| Type | Les unités viennent de | Usage typique | Décompte |
| --- | --- | --- | --- |
| `panel` | Un profil : des dimensions avec des parts, tirées par quotas exacts et sous graine (`--profile`, `--n`, `--seed`). | Acheteurs, lecteurs ou utilisateurs simulés qui lisent un argumentaire. | Taux par groupe, effectifs, citations, nombres. |
| `jury` | La définition elle-même : des unités listées une à une, chacune avec un `lens`. | Une lecture contradictoire d’un argumentaire, d’une page ou d’un plan. | Effectifs et citations par angle. |
| `fanout` | Un fichier d’unités (`--units`) : chaque unité a son propre `scope` d’écriture, disjoint des autres. | Pages à rédiger, modules à documenter : du travail indépendant en parallèle. | Taux et nombres ; exportable en plan Nexus durable avec `plan`. |

Un panel et un jury tournent comme des sous-agents de session : l’hôte les lance, attend, puis lit leurs fichiers. Un fanout peut tourner de la même façon, ou être exporté avec `plan` quand le travail doit survivre à la session, exige un contrôle indépendant par unité ou modifie le dépôt (voir `bmad-plus nexus`). Le fichier de définition (JSON) nomme le type, le gabarit de brief, les champs de réponse (`boolean`, `integer`, `number`, `string`, `enum`, `list`), le décompte et une phrase de `disclosure` de 1 à 500 caractères.

<a id="budget"></a>
## Budget, vagues et approbation

Trois réglages du bloc `swarm` de `_bmad/config.yaml` bornent une exécution. Un fichier ou un bloc absent signifie les valeurs par défaut ci-dessous ; toute autre valeur est refusée. `init` compare le nombre d’unités au budget : une exécution plus grand est créé à l’état `needs-approval`, n’écrit aucun brief et se termine par le code 2. L’assistant doit alors vous demander, en une phrase chiffrée, et seulement après un oui relancer `init` avec `--approved` et la graine affichée par le refus.

**Le bloc swarm de _bmad/config.yaml**

| Clé | Défaut | Valeurs admises | Effet |
| --- | --- | --- | --- |
| `budget` | 26 | entier de 1 à 1000 | Sous-agents qu’une exécution peut employer avant que l’hôte doive vous demander. |
| `wave` | 10 | entier de 1 à 1000 | Sous-agents lancés ensemble ; `briefs` regroupe les unités en attente par vagues de cette taille (remplaçable par `--wave`). |
| `media_credits` | `ask` | exactement `ask` | La génération payante d’images, de vidéo ou d’audio n’est jamais couverte par un budget : l’hôte demande avant chaque exécution de ce genre. |

> **Attention · L’approbation appartient à une personne** `--approved` est enregistré dans l’exécution comme `approval: user`. La compétence swarm ne l’autorise qu’après un oui humain, quel que soit le nombre d’unités. Une exécution n’est jamais approuvé sur le seul jugement de l’assistant.

<a id="actions"></a>
## Les sept actions

**Ce que chaque action lit et écrit**

| Action | Lit | Écrit | Sortie |
| --- | --- | --- | --- |
| `init` | Définition, gabarit, profil ou unités, contextes, `_bmad/config.yaml`. | L’arborescence de l’exécution (entrées figées et `run.json`). | 0 prêt, 2 approbation requise, 1 refusé. |
| `briefs RUN` | L’arborescence de l’exécution et les réponses. | Un brief pour chaque unité sans réponse valide ; le dossier `answers/`. | 0, ou 2 si l’exécution demande une approbation. |
| `check RUN` | L’arborescence de l’exécution et les réponses. | Rien. | 0 complet, 1 incomplet. |
| `save RUN UNIT --input F` | L’arborescence de l’exécution et le fichier de réponse. | `answers/<unit>.json`. | 0 classé, 1 refusé. |
| `tally RUN [--out F]` | L’arborescence de l’exécution et les réponses. | `tally.json` et `tally.md` (ou `--out`). | 0, ou 2 si l’exécution demande une approbation. |
| `inspect RUN` | L’arborescence de l’exécution, les réponses, les briefs. | Rien. | 0. |
| `plan RUN [--out F]` | L’arborescence de l’exécution (fanout uniquement). | Tous les briefs, `checks/`, `nexus-plan.json` (ou `--out`). | 0 planifié, 2 approbation requise, 1 pas un fanout. |

Ordre habituel : `init`, puis `briefs`, l’hôte lance un sous-agent par brief avec exactement la consigne « Read the brief and follow it exactly; it is your whole instruction », puis `check`. Relancez `briefs` une fois pour donner une seconde chance aux unités manquantes (il ne rend que les unités sans réponse valide), classez avec `save` toute réponse affichée, puis `tally`. Une unité toujours manquante après la seconde vague reste manquante et est nommée dans le décompte. `inspect` résume une exécution à tout moment sans rien écrire.

<a id="run-tree"></a>
## L’arborescence d’une exécution

**Créée dans votre projet par init**

```text
.bmad-plus/swarm/runs/<definition-id>-<yyyymmdd>-<4 chars>/
  run.json            inputs hashes, n, seed, wave, budget, approval, status
  definition.json     the normalized definition, frozen
  template.md         the brief template, frozen
  cards.json          the dealt or listed units
  context/<name>.md   each context file, frozen
  briefs/<unit>.md    written by briefs (and plan)
  answers/<unit>.json written by the sub-agent, or filed by save
  tally.json, tally.md
  checks/answer.cjs, checks/swarm-validate.cjs, nexus-plan.json   (fanout, written by plan)
```

Le suffixe de 4 caractères est aléatoire et un dossier existant n’est jamais réutilisé. Les entrées sont figées à `init` : modifier ensuite un contexte ou la définition ne change rien pour cette exécution. États : `needs-approval` (terminal), `ready`, `briefed`, `tallied`. Un décompte peut être relancé, et `briefs` peut l’être après un décompte. Les rapports demandés avec `--out` vont sous `.bmad-plus/swarm/reports/<run id>/`.

<a id="honesty"></a>
## Règles d’honnêteté

- Des unités simulées ne sont pas des personnes. Le décompte s’ouvre sur la mention de transparence (`disclosure`) de la définition, avant tout chiffre. Les taux d’un panel sont une borne haute à confirmer avec de vraies personnes, jamais une mesure.
- Les citations sont simulées : présentez-les comme ce qu’a écrit une unité simulée, jamais comme un témoignage ou un entretien.
- Le modérateur ne répond jamais à la place d’une unité : pas de fichier de réponse écrit à la main, pas de « correction » d’une réponse invalide. `save` se contente d’extraire et de valider ce qu’un sous-agent a affiché.
- Les briefs ne sont jamais modifiés. Un changement va dans le gabarit ou la définition, puis dans une nouvelle exécution.
- Même graine, mêmes cartes : une comparaison avant/après de deux argumentaires relance le même profil avec le même `--n` et la même `--seed`, de sorte que seul le contexte a changé.
- Le runtime ne filtre rien : valeurs des cartes, entrées des réservoirs et fichiers de contexte arrivent mot pour mot au sous-agent. Lisez un contexte avant de le passer ; il est copié dans chaque brief, secrets et consignes compris.
- Une réponse valide est une réponse bien formée. Rien ne prouve qu’un sous-agent a lu son brief ni qu’il a dit vrai.

<a id="reads-writes"></a>
## Lectures, écritures et limites

- N’écrit que sous `.bmad-plus/swarm/`. `--out` pour `tally` et `plan` doit rester dans `.bmad-plus/swarm/reports/<run id>/` ou dans l’arborescence de l’exécution, jamais par-dessus `answers/`, `briefs/`, `context/`, `checks/`, `run.json`, `cards.json`, `definition.json`, `template.md`, `nexus-plan.json`, `tally.json` ou `tally.md`.
- Chaque chemin que vous nommez (`--definition`, `--profile`, `--units`, `--context`, `--input`) est relatif au projet avec des `/` ; chemins absolus, antislashs, `..`, `.git` et tout passage par un lien symbolique sont refusés. Ces fichiers ne peuvent pas venir de `.bmad-plus/`.
- Limites : 1 à 1000 unités par exécution ; budget et vague de 1 à 1000 ; graine de 0 à 2147483647 ; entrées de 16 Mio au plus ; réponse affichée pour `save` de 1 Mio au plus ; 50 champs de réponse au plus ; 20 contextes par définition au plus ; 5 champs `groupBy` au plus.
- Les ids d’unité sont des lettres, chiffres, `_` ou `-` (64 caractères au plus ; en minuscules pour un fanout). Les ids d’un panel tiré sont le préfixe plus la position complétée à au moins trois chiffres (`B001`).
- Les fichiers sont écrits via un fichier temporaire puis renommés. Aucun réseau, aucun processus enfant, aucun `eval`.

<a id="exit-codes"></a>
## Codes de sortie

**Codes de sortie de bmad-plus swarm**

| Code | Signification |
| --- | --- |
| 0 | L’action a réussi ; pour `check`, chaque unité a une réponse valide. |
| 1 | `check` a trouvé des unités manquantes ou invalides (état `incomplete`), ou une erreur quelconque (affichée `Swarm: <message>`). |
| 2 | État `needs-approval` : l’exécution a plus d’unités que le budget et pas de `--approved`. Demandez à une personne, puis relancez `init --approved --seed <seed>`. `briefs`, `save`, `tally` et `plan` sur une telle exécution sortent aussi avec 2 et n’écrivent rien. |

<a id="sample-files"></a>
## Les fichiers d’exemple

Les transcriptions et les exemples ci-dessous utilisent les fichiers imprimés ici. Ils se trouvent dans le dépôt, sous `tests/fixtures/swarm/`, et ne font pas partie du paquet npm : ils sont donc donnés en entier. Créez-les sous `swarm/` dans votre projet et les commandes reproduisent les transcriptions, à l’exception des identifiants d’exécution (une date et un suffixe aléatoire). Les six premiers appartiennent au panel d’acheteurs ; les trois derniers appartiennent à l’exemple de fanout en fin de page.

**swarm/buyer-panel.json, la définition du panel**

```json
{
  "schemaVersion": 1,
  "id": "buyer-panel",
  "kind": "panel",
  "pack": "marketfit",
  "title": "Simulated buyers see the pitch",
  "units": { "source": "profile", "idPrefix": "B" },
  "brief": { "template": "briefs/buyer.md", "context": ["pitch"] },
  "answer": {
    "required": ["id", "buys", "reason_code", "reason"],
    "fields": {
      "buys": { "type": "boolean" },
      "reason_code": { "type": "enum", "values": ["price", "habit", "need", "trust", "other"] },
      "reason": { "type": "string", "max": 600 },
      "price_floor": { "type": "number", "min": 0 },
      "visits_per_week": { "type": "integer", "min": 0, "max": 14 },
      "would_tell": { "type": "list", "maxItems": 3 }
    }
  },
  "tally": {
    "rate": "buys",
    "groupBy": ["segment", "behaviour"],
    "counts": ["reason_code"],
    "quotes": { "reason": 2 },
    "numbers": ["price_floor"]
  },
  "disclosure": "Simulated units are not people. Read rates as an upper bound and confirm with real ones."
}
```

**swarm/profile.json, le profil dont sont tirées les 30 fiches d’acheteurs**

```json
{
  "schemaVersion": 1,
  "subject": "Orbit espresso bar",
  "target": "Urban professionals who buy coffee most days",
  "dimensions": [
    {
      "name": "segment",
      "values": [
        { "value": "early career", "share": 0.45, "ranges": { "income": [38000, 85000] } },
        { "value": "mid career", "share": 0.4, "ranges": { "income": [85000, 150000] } },
        { "value": "high earner", "share": 0.15, "ranges": { "income": [150000, 210000] } }
      ]
    },
    {
      "name": "behaviour",
      "values": [
        { "value": "daily regular", "share": 0.2, "note": "same drink, same place, most mornings" },
        { "value": "explorer", "share": 0.5 },
        { "value": "occasional", "share": 0.3, "note": "a treat, not a routine" }
      ]
    }
  ],
  "ranges": { "age": [24, 38], "walk_minutes": [1.5, 12] },
  "pools": {
    "objection": ["too steep for a drink", "my place is closer", "I do not know the brand"],
    "habit": ["you pass the street on the way to work", "you order the same thing every day"]
  }
}
```

**swarm/pitch.md, le texte que lisent les acheteurs**

```md
Orbit opens at 7, two streets from the station. A flat white is 4.20, the loyalty card gives
the tenth one free, and the bar keeps your usual order under your name.
```

**swarm/briefs/buyer.md, le gabarit de brief (chaque repère entre doubles accolades est rempli pour chaque unité)**

```md
# You are unit {{unit.id}} of run {{run.id}}

You are one simulated buyer. Stay inside this card for the whole task.

- Segment: {{card.segment}}, income {{card.income}}
- Behaviour: {{card.behaviour}} ({{card.behaviour_note}})
- Age {{card.age}}, {{card.walk_minutes}} minutes on foot from the bar
- Your first objection: {{card.objection}}
- Your habit: {{card.habit}}

## The pitch

{{context.pitch}}

## Your answer

Write a JSON object to `{{answer.path}}` with the fields `id` (exactly "{{unit.id}}"), `buys`,
`reason_code` (price, habit, need, trust or other), `reason` (your own words, 600 characters at
most) and, when you have one, `price_floor`.

{{disclosure}}
```

**swarm/reply-ok.json, une réponse valide pour l’unité B001**

```json
{ "id": "B001", "buys": true, "reason_code": "habit", "reason": "The loyalty card and my usual order under my name suit my mornings." }
```

**swarm/reply-bad.txt, une réponse que le validateur refuse (buys doit valoir true ou false)**

```json
{ "id": "B002", "buys": "maybe", "reason_code": "price", "reason": "Too steep for a drink." }
```

**swarm/units.json, les trois pages de l’exemple de fanout**

```json
{
  "schemaVersion": 1,
  "units": [
    { "id": "about", "scope": "site/about", "title": "About us", "tone": "warm" },
    { "id": "pricing", "scope": ["site/pricing", "site/data/prices.json"], "title": "Pricing", "tone": "plain" },
    { "id": "contact", "scope": "site/contact", "title": "Contact", "tone": "short" }
  ]
}
```

**swarm/page-fanout.json, la définition du fanout**

```json
{
  "schemaVersion": 1,
  "id": "site-pages",
  "kind": "fanout",
  "title": "One sub-agent per page of the site",
  "units": { "source": "input" },
  "brief": { "template": "briefs/page.md", "context": [] },
  "answer": {
    "required": ["id", "done", "words"],
    "fields": {
      "done": { "type": "boolean" },
      "words": { "type": "integer", "min": 0 },
      "note": { "type": "string", "max": 200 }
    }
  },
  "tally": { "rate": "done", "numbers": ["words"] },
  "disclosure": "Each page was written by a separate sub-agent from the same brief; read them together before publishing."
}
```

**swarm/briefs/page.md, le gabarit de brief du fanout**

```md
# Page {{unit.id}}

Write the page "{{card.title}}" under `{{card.scope}}`, {{card.tone}} in tone. Touch nothing
outside that folder.

When the page is written, write a JSON object to `{{answer.path}}` with `id` ("{{unit.id}}"),
`done`, `words` (the word count) and an optional `note`.

{{disclosure}}
```

<a id="real-output"></a>
## Sortie réelle

Ces transcriptions viennent de la recette humaine de 0.23.0 : un panel de 30 acheteurs simulés dans une application de démonstration, face au budget par défaut de 26. Les lignes `npm notice` et l’invite du shell sont retirées. La définition (`swarm/buyer-panel.json`) et le profil sont les fixtures de test du dépôt, copiées dans l’application de démonstration.

**30 unités face à un budget de 26 : refusé (code de sortie 2)**

```text
$ npx bmad-plus swarm init --definition swarm/buyer-panel.json --profile swarm/profile.json --context pitch=swarm/pitch.md --n 30 --seed 7 --directory .\demo-app
buyer-panel-20261018-ungp: needs approval. The run needs 30 sub-agents and the budget is 26: ask the user, then re-run init with --approved --seed 7.
```

Sortie capturée lors d’une exécution réelle. Source: Capturé pendant la recette d’acceptation de la 0.23.0, le 2026-10-18 (étape 6)

**Après un oui humain : --approved avec la même graine**

```text
$ npx bmad-plus swarm init --definition swarm/buyer-panel.json --profile swarm/profile.json --context pitch=swarm/pitch.md --n 30 --seed 7 --approved --directory .\demo-app
buyer-panel-20261018-oqu7: panel of 30 units, budget 26, approval user.
Seed 7 (same seed, same cards).
Next: bmad-plus swarm briefs buyer-panel-20261018-oqu7
```

Sortie capturée lors d’une exécution réelle. Source: Capturé pendant la recette d’acceptation de la 0.23.0, le 2026-10-18 (étape 6)

**Briefs, par vagues de 10**

```text
$ npx bmad-plus swarm briefs buyer-panel-20261018-oqu7 --directory .\demo-app
buyer-panel-20261018-oqu7: 30 of 30 units need a sub-agent, in waves of 10.
Wave 1:
  B001  C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\briefs\B001.md
  B002  C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\briefs\B002.md
  B003  C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\briefs\B003.md
  B004  C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\briefs\B004.md
  B005  C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\briefs\B005.md
  B006  C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\briefs\B006.md
  B007  C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\briefs\B007.md
  B008  C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\briefs\B008.md
  B009  C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\briefs\B009.md
  B010  C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\briefs\B010.md
# Les vagues 2 (B011 à B020) et 3 (B021 à B030) suivent au même format ; elles sont omises ici.
Each sub-agent: Read the brief and follow it exactly; it is your whole instruction.
Disclosure: Simulated units are not people. Read rates as an upper bound and confirm with real ones.
```

Sortie capturée lors d’une exécution réelle. Source: Capturé pendant la recette d’acceptation de la 0.23.0, le 2026-10-18 (étape 6; vagues 2 et 3 abrégées)

**Une réponse valide, une réponse refusée, le décompte**

```text
$ npx bmad-plus swarm save buyer-panel-20261018-oqu7 B001 --input swarm/reply-ok.json --directory .\demo-app
buyer-panel-20261018-oqu7: answer of B001 filed at C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\answers\B001.json
$ npx bmad-plus swarm check buyer-panel-20261018-oqu7 --directory .\demo-app
buyer-panel-20261018-oqu7: 1 of 30 valid answers.
  B002  missing: no answer file
  B003  missing: no answer file
# B004 à B030 sont listées de la même façon (27 lignes de plus).
$ npx bmad-plus swarm save buyer-panel-20261018-oqu7 B002 --input swarm/reply-bad.txt --directory .\demo-app
Swarm: Reply of unit B002 refused: field "buys" must be true or false.
$ npx bmad-plus swarm tally buyer-panel-20261018-oqu7 --directory .\demo-app
C:\Users\you\demo-app\.bmad-plus\swarm\runs\buyer-panel-20261018-oqu7\tally.md
1 of 30 units counted; 29 skipped.
Disclosure: Simulated units are not people. Read rates as an upper bound and confirm with real ones.
```

Sortie capturée lors d’une exécution réelle. Source: Capturé pendant la recette d’acceptation de la 0.23.0, le 2026-10-18 (étape 6; les 27 autres lignes manquantes de check sont abrégées ; la première commande (classement de B001) a été rejouée ensuite avec le même paquet ; la mention de transparence (Disclosure) est celle que la même exécution a affichée depuis les briefs)

Comment le lire : le premier `init` a créé une exécution refusée (`...-ungp`) et rien d’autre ; l’exécution approuvée est une autre exécution (`...-oqu7`) avec son propre suffixe aléatoire. Seule B001 avait répondu : le décompte honnête compte 1 unité et nomme 29 unités ignorées ; la mention de transparence vient en premier, et c’est aussi la première ligne de `tally.md`. La réponse refusée n’a rien écrit pour B002.

<a id="errors"></a>
## Erreurs et que faire

**Messages affichés par bmad-plus swarm**

| Message | Cause | Que faire |
| --- | --- | --- |
| `<run>: needs approval. The run needs N sub-agents and the budget is B: ask the user, then re-run init with --approved --seed S.` (code 2) | Plus d’unités que `swarm.budget` et pas de `--approved`. | Demandez à une personne, en une phrase chiffrée. Après un oui, relancez `init` avec `--approved --seed S`. Ou baissez `--n`, ou relevez `swarm.budget` dans `_bmad/config.yaml`. |
| `Swarm: Use swarm init --definition FILE [--profile FILE \| --units FILE] …` | Action inconnue, ou id d’exécution ou d’unité manquant ou mal placé. | Vérifiez la synopsis : `save` prend une exécution et une unité, les autres actions après `init` ne prennent qu’une exécution. |
| `Swarm: init needs --definition FILE.` | `init` sans définition. | Passez `--definition`. |
| `Swarm: A panel needs --profile FILE.` / `A panel needs --n, the number of units to deal.` / `A panel takes --profile, not --units.` | Panel lancé sans ses entrées. | Ajoutez `--profile` et `--n` ; ne passez pas `--units`. |
| `Swarm: Only a panel takes --profile.` / `A jury has as many units as it lists; --n does not apply.` / `A seed only applies to a dealt panel.` / `A fanout needs --units FILE.` | Options qui ne correspondent pas au type nommé dans la définition. | Retirez l’option, ou utilisez la bonne définition. |
| `Swarm: The definition needs --context NAME=FILE.` / `Context "x" is not declared by the definition.` / `A context is written NAME=FILE: …` | Un contexte déclaré manque, un contexte en trop a été passé, ou la forme est mauvaise. | Passez exactement les contextes que déclare la définition, sous la forme `--context name=path`. |
| `Swarm: _bmad/config.yaml: swarm.media_credits must be "ask".` / `…swarm.budget must be an integer from 1 to 1000.` / `…swarm has an unknown key "x".` | Le bloc `swarm` contient une valeur ou une clé que le runtime refuse. | Corrigez le bloc, ou supprimez-le pour retrouver les valeurs par défaut (26, 10, `ask`). |
| `Swarm: Definition does not exist: …` / `…is not valid JSON: …` / `…exceeds N bytes` / `…is not a regular file` | Le fichier d’entrée est absent, mal formé, trop gros ou n’est pas un fichier. | Corrigez le chemin ou le JSON. |
| `Swarm: … may not reach .git` / `… may not come from the BMAD+ state tree` / `… refused: … (…)` | Le chemin vise `.git`, `.bmad-plus/`, sort du projet ou passe par un lien. | Utilisez un chemin relatif au projet avec des `/`, hors de `.bmad-plus/`. |
| `Swarm: Tally groupBy field "f" is absent from unit U.` | Une carte n’a pas un champ sur lequel le décompte groupe. | Ajoutez le champ au profil, à la liste ou au fichier d’unités, ou retirez-le de `tally.groupBy`. |
| `Swarm: A run id reads <definition>-<yyyymmdd>-<4 characters>.` / `Run record is not usable: …` | Mauvais id d’exécution, ou arborescence d’exécution abîmée. | Copiez l’id affiché par `init` ; si l’arborescence a été modifiée, démarrez une nouvelle exécution. |
| `Swarm: Reply of unit U refused: …` / `No JSON object found in the reply filed for unit U.` | La réponse affichée ne contient pas d’objet JSON, ou ne respecte pas le contrat de réponse (mauvais type, champ manquant, mauvais id). | Rien n’a été écrit. Redemandez au sous-agent (relancez `briefs`) ou laissez l’unité manquante. N’écrivez pas la réponse vous-même. |
| `Swarm: Unit U already has a valid answer; it is kept.` / `Unknown unit U in run R.` | `save` sur une unité déjà répondue, ou absente de l’exécution. | Utilisez `check` pour voir quelles unités sont ouvertes. |
| `Swarm: save needs --input FILE, the reply the sub-agent printed.` | `save` sans `--input`. | Enregistrez la réponse dans un fichier du projet hors de `.bmad-plus/` et passez-le. |
| `Swarm: --out must stay under … or …` / `--out may not write inside …` / `--out may not replace the run file …` | `--out` vise un endroit où `tally` ou `plan` n’ont pas le droit d’écrire. | Utilisez un chemin sous `.bmad-plus/swarm/reports/<run id>/`. |
| `Swarm: Only a fanout exports a Nexus plan; run R is a panel.` | `plan` sur un panel ou un jury. | N’utilisez `plan` qu’avec un fanout. |

<a id="examples"></a>
## Exemples

<a id="example-cli-swarm-buyer-panel"></a>
### Un panel d’acheteurs simulés dans un budget

Vous avez une définition d’essaim, un profil et un fichier d’argumentaire. Le budget par défaut est de 26 sous-agents ; vous en demandez 30.

**Dans votre assistant IA**

```text
Lance le panel d’acheteurs de swarm/buyer-panel.json avec le profil swarm/profile.json et mon argumentaire dans swarm/pitch.md. Prends 30 acheteurs simulés et la graine 7.
```

**Ce que vous devriez obtenir** L’assistant lance `swarm init`. Trente unités dépassent le budget de 26 : la commande sort avec le code 2 et n’écrit aucun brief ; l’assistant vous dit « 30 sous-agents pour un budget de 26 » et vous demande. Après votre oui, il relance `init` avec `--approved --seed 7`, obtient un id d’exécution, lance `briefs` (trois vagues de 10), démarre un sous-agent par brief avec la consigne fixe, puis lance `check`, donne une seconde chance aux unités manquantes et termine par `tally`. Son compte rendu s’ouvre sur la mention de transparence, dit combien d’unités ont été comptées et combien ignorées, et présente les taux comme une borne haute.

<a id="example-cli-swarm-before-after"></a>
### Comparer deux versions d’un argumentaire

Le même panel, lancé deux fois avec la même graine, ne diffère que par le fichier d’argumentaire.

**Dans votre assistant IA**

```text
Lance le panel d’acheteurs sur swarm/pitch-v1.md, puis à nouveau sur swarm/pitch-v2.md, avec le même profil, 24 acheteurs et la graine 7. Compare les deux décomptes.
```

**Ce que vous devriez obtenir** Vingt-quatre unités tiennent dans le budget par défaut de 26 : aucun des deux `init` ne demande d’approbation. Comme le profil, `--n` et `--seed` sont identiques, les deux exécutions tirent les mêmes 24 cartes ; seul `{{context.pitch}}` diffère dans les briefs. Chaque exécution a son id et son `tally.md`. La comparaison est présentée comme un écart entre deux bornes hautes simulées, mention de transparence en tête, et non comme une variation de conversion mesurée.

<a id="example-cli-swarm-fanout-plan"></a>
### Un rédacteur par page, vérifié par Nexus

Une définition de fanout et un fichier d’unités donnent à chaque page son propre périmètre d’écriture. Le travail doit survivre à la session : il est exporté en plan durable.

**Dans votre assistant IA**

```text
Rédige les trois pages listées dans swarm/units.json avec un sous-agent par page, avec swarm/page-fanout.json. Exporte-le en plan Nexus pour que chaque page soit vérifiée avant que je l’accepte.
```

**Ce que vous devriez obtenir** L’assistant lance `swarm init` avec `--definition` et `--units`, puis `swarm plan RUN`. Le plan contient une tâche par unité : son périmètre plus son fichier de réponse, son brief et les fichiers figés comme ressources, un contrôle `node checks/answer.cjs --unit=<unit>`, `maxAttempts` à 2, et `maxParallel` égal à la vague configurée plafonnée à 32. `plan` affiche le chemin du plan et `Next: bmad-plus nexus create --plan <path>`. Ensuite Nexus démarre, vérifie et accepte chaque tâche ; une unité dont le fichier de réponse est mal formé échoue à son contrôle et est rejouée, pas acceptée.

**Voir aussi**

- [bmad-plus nexus : exécuter un plan de fanout exporté](https://bmad-plus.rochetta.fr/fr/docs/reference/cli-nexus/)
- [bmad-plus intake : les questions posées avant un essaim](https://bmad-plus.rochetta.fr/fr/docs/reference/cli-intake/)
- [config.yaml : le bloc swarm](https://bmad-plus.rochetta.fr/fr/docs/reference/config-yaml/#swarm-block)
- [Structure du projet : .bmad-plus/swarm/](https://bmad-plus.rochetta.fr/fr/docs/reference/project-layout/)
- [Dépannage](https://bmad-plus.rochetta.fr/fr/docs/faq/troubleshooting/)

[Documentation BMAD+](https://bmad-plus.rochetta.fr/fr/docs/) · [Référence](https://bmad-plus.rochetta.fr/fr/docs/reference/)

[Code sur GitHub](https://github.com/lrochetta/BMAD-PLUS)
