# nexus

> Exécutions de tâches durables : un plan de tâches à périmètres d’écriture disjoints, des tentatives récupérables après une interruption, une vérification indépendante et une acceptation distincte.

Canonical: https://bmad-plus.rochetta.fr/fr/docs/reference/cli-nexus/
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/) › nexus

Quand plusieurs tâches doivent être faites et que vous voulez la preuve que chacune l’a été, l’agent Nexus peut les garder dans une exécution durable. La commande `nexus` est le registre de cette exécution. Vous décrivez les tâches dans un plan JSON ; chaque tâche possède un dossier ou un fichier qu’elle peut écrire (son périmètre) et une liste de commandes de contrôle qui décident si son résultat est acceptable. Le registre consigne qui a essayé quoi (une tentative), conserve l’état malgré les pannes, lance lui-même les contrôles, et ne laisse accepter la tâche qu’ensuite. Un worker qui dit « terminé » n’est jamais une preuve : les contrôles le sont. Cette page s’adresse à qui pilote Nexus à la main, depuis la CI, ou veut savoir ce que fait l’agent en coulisses.

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

**Dans le terminal de votre projet**

```sh
npx bmad-plus nexus create --plan <file> [--json] [-d <path>]
npx bmad-plus nexus inspect [run] [--json] [-d <path>]
npx bmad-plus nexus recover-lock --input <file> [--json] [-d <path>]
npx bmad-plus nexus <start|launch|collect|record|reconcile|verify|retry|cancel|accept> <run> <task> [--input <file>] [--json] [-d <path>]
```

**Options de nexus**

| Option | Argument | Défaut | Ce qu’elle fait |
| --- | --- | --- | --- |
| `-d, --directory <path>` | dossier | dossier courant | Le projet qui contient l’exécution. |
| `--plan <file>` | fichier JSON | aucun | Le plan de tâches. Seul `create` le prend. |
| `--input <file>` | fichier JSON | aucun | Identité de l’hôte, observation ou demande de reprise pour une action qui modifie une tâche, ou observation du verrou pour `recover-lock`. Fichier ordinaire de 1 Mio au plus, objet JSON. |
| `--json` | - | désactivé | Affiche l’état durable et les preuves en JSON au lieu du résumé court. |

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

**Actions de Nexus**

| Action | Arguments | Fichier d’entrée | Ce qu’elle fait |
| --- | --- | --- | --- |
| `create` | `--plan FILE` | non (il utilise `--plan`) | Valide le plan et crée l’exécution. Refuse un identifiant d’exécution existant. |
| `inspect` | `[RUN]` | interdit | Lecture seule. Sans identifiant, liste les exécutions et l’état du verrou. Avec un identifiant, montre tâches, tentatives, preuves et observations. |
| `recover-lock` | - | obligatoire | Retire explicitement un verrou d’écriture abandonné, après que vous avez confirmé que son propriétaire s’est arrêté. |
| `start` | `RUN TASK` | obligatoire | Ouvre une tentative pour une tâche portée par l’hôte, liée à un identifiant d’hôte et une session exacts. |
| `launch` | `RUN TASK` | facultatif | Lance au premier plan le backend processus de la tâche et attend. Avec `{"retry":true}`, crée une nouvelle tentative. |
| `collect` | `RUN TASK` | obligatoire | Prend le reçu d’une tentative de processus lancée (identifiant de tentative et backend exacts). |
| `record` | `RUN TASK` | obligatoire | Un hôte rapporte le résultat de sa tentative : `completed`, `failed`, `blocked` ou `ambiguous`. |
| `reconcile` | `RUN TASK` | obligatoire | Règle une tentative interrompue ou annulée en `completed`, `failed` ou `cancelled`, une fois ses effets vérifiés. |
| `verify` | `RUN TASK` | interdit | Lance les commandes de contrôle du plan et consigne de vrais reçus. |
| `retry` | `RUN TASK` | obligatoire | Ouvre une nouvelle tentative après un échec réconcilié, dans la limite du budget de tentatives. |
| `cancel` | `RUN TASK` | obligatoire | Consigne une demande d’annulation avec un motif. Ne signale aucun processus de l’hôte. |
| `accept` | `RUN TASK` | interdit | Accepte l’espace de travail courant pour la tâche, après avoir revérifié les preuves. |

<a id="three-outcomes"></a>
## Exécution, vérification, acceptation

Nexus garde trois questions séparées. Exécution : le worker a-t-il terminé ? Un hôte le rapporte avec `record`, ou le superviseur au premier plan recueille la vraie sortie du processus qu’il a lancé. Vérification : le travail passe-t-il les contrôles du plan ? Nexus les lance lui-même, avec des arguments littéraux et sans shell, et compare les artefacts déclarés et tout le périmètre d’écriture avant et après. Acceptation : l’espace de travail actuel est-il toujours celui qui a réussi ? `accept` revérifie les empreintes des artefacts, les ressources protégées et l’état accepté de chaque dépendance. Un contrôle en échec empêche l’acceptation même si le worker a réussi. Nexus ne fait jamais de commit, de fusion, de copie de fichiers ni de déploiement.

<a id="plan"></a>
## Le fichier de plan

**Un plan minimal à une tâche**

```json
{
  "id": "example",
  "maxParallel": 1,
  "config": { "language": "English" },
  "tasks": [
    {
      "id": "result",
      "objective": "Produce the requested result in work/result.txt.",
      "acceptance": ["The result satisfies the independent check."],
      "dependsOn": [],
      "scope": ["work"],
      "artifacts": ["work/result.txt"],
      "resources": ["checks/check-result.cjs"],
      "checks": [
        {
          "id": "result-content",
          "command": "node",
          "args": ["checks/check-result.cjs"],
          "cwd": ".",
          "timeoutMs": 30000
        }
      ],
      "maxAttempts": 2,
      "deadlineMs": 3600000,
      "idempotent": true,
      "authorizations": ["Edit work/ and run the listed local check."]
    }
  ]
}
```

**Champs du plan et leurs règles**

| Champ | Règle |
| --- | --- |
| `id` | Identifiant d’exécution : 1 à 64 lettres minuscules, chiffres, `_` ou `-`. Même règle pour les identifiants de tâche. |
| `maxParallel` | Entre 1 et 32 tentatives actives à la fois. |
| `config` | Réglages primitifs non secrets uniquement. Les clés qui ressemblent à des secrets sont refusées. |
| `tasks` | 1 à 200 tâches. Identifiants uniques ; les dépendances doivent exister et ne pas former de cycle. |
| `objective`, `acceptance` | Ce que la tâche doit produire et les énoncés que le résultat doit satisfaire. |
| `dependsOn` | Identifiants des tâches qui doivent être acceptées d’abord. |
| `scope` | Fichiers ou dossiers que le worker peut écrire. Les périmètres de tâches différentes doivent être disjoints, même quand l’une dépend de l’autre. Jamais `.git` ni l’état propre de Nexus. |
| `artifacts` | Fichiers qui doivent exister dans le périmètre de la tâche lors de la vérification. |
| `resources` | Fichiers protégés : le vérificateur et chaque fichier d’instructions donné au worker. Ils sont hachés et doivent se trouver hors de tout périmètre. |
| `checks` | 1 à 30 par tâche. `command` vaut `node` ou un chemin absolu d’exécutable ; `args` est un tableau littéral ; chaque argument fichier doit être une ressource déclarée ; `timeoutMs` de 10 à 300000. |
| `maxAttempts` | 1 à 10. Les tours de vérification sont bornés par cette valeur aussi. |
| `deadlineMs` | 100 à 86400000. Une échéance est une observation, pas la preuve que le travail s’est arrêté. |
| `idempotent` | Booléen. Une tâche non idempotente exige une réconciliation explicite `retrySafe: true` avant une reprise. |
| `authorizations` | Énoncés de ce qui a été autorisé. Les workers ne peuvent pas les modifier. |
| `execution` | Facultatif. Choisit un backend processus au lieu d’un hôte (voir plus bas). |

<a id="backends"></a>
## Backends : hôte ou processus

Par défaut, une tâche appartient à l’hôte : votre assistant fait le travail avec ses propres outils et dit à Nexus le résultat avec `record`. Nexus vérifie ensuite. Ajouter un objet `execution` à une tâche en fait une tâche de processus : `launch` démarre le programme au premier plan, l’attend et conserve un reçu à somme de contrôle de ce qui s’est réellement passé. Il existe deux adaptateurs.

**Adaptateurs d’exécution**

| Adaptateur | Champs | Remarques |
| --- | --- | --- |
| `command` | `command`, `args`, `cwd`, `input`, `resources`, `blockedExitCodes`, `outputLimitBytes` | Vous fournissez la commande ; elle n’est jamais déduite du texte de la tâche. L’exécutable est figé par SHA-256. Une sortie 0 signifie terminé ; un code listé dans `blockedExitCodes` signifie bloqué. Pas de shell, pas de surcharge d’environnement. |
| `codex-exec` | `command` (chemin absolu du `codex` installé), `input`, `instructions`, `sandbox`, `model` facultatif | Lance la CLI Codex installée sans interaction. `sandbox` vaut `read-only` (défaut) ou `workspace-write`. L’achèvement exige une sortie 0 plus les événements de démarrage de fil et de fin de tour ; seule une erreur explicite `approval_required` devient bloquée. |

> **Attention · Pas un bac à sable** Les workers partagent votre projet et votre utilisateur système. Ils peuvent ignorer leur périmètre déclaré ; les sommes de contrôle détectent un changement accidentel mais ne sont pas des signatures. Il n’y a ni démon, ni planificateur, ni supervision d’arbre de processus : chaque `launch` est une commande au premier plan. `workspace-write` est une demande à l’hôte Codex installé, pas un bac à sable Nexus. Utilisez un projet isolé ou une politique d’hôte quand le worker n’est pas de confiance.

<a id="limits"></a>
## Limites

**Bornes prises en charge**

| Borne | Valeur |
| --- | --- |
| Tâches par exécution | 200 |
| Tentatives actives par exécution | 32 |
| Tentatives par tâche | 10 |
| Contrôles par tâche | 30 |
| Durée par contrôle | 10 à 300000 ms |
| Sortie capturée par contrôle | 64 Kio |
| Fichiers dans un instantané de périmètre | 10000, chacun de 16 Mio au plus |
| Fichier d’état d’une exécution | 16 Mio |
| Fichiers d’entrée et de plan | 1 Mio, fichier ordinaire, pas de lien symbolique |

<a id="reads-writes"></a>
## Ce qu’elle lit et écrit

- État : `.bmad-plus/nexus/runs/<run-id>.json`, une enveloppe à somme de contrôle écrite par un fichier temporaire vidé sur disque puis un renommage atomique.
- Verrous : `.bmad-plus/nexus/writer.lock` (une modification à la fois) et, pendant une récupération exceptionnelle, `.bmad-plus/nexus/recovery.lock`. Un verrou retiré est archivé sous `.bmad-plus/nexus/lock-recovery/`.
- `inspect` n’écrit rien et continue de fonctionner pendant une vérification. Toutes les autres actions sauf `create` modifient une exécution existante ; `create` la crée.
- Lit votre plan et vos fichiers d’entrée, les ressources et artefacts déclarés, et prend un instantané des périmètres d’écriture. La vérification lance vos commandes de contrôle ; `launch` lance le processus de la tâche. Ce sont les seuls processus que Nexus démarre, et seulement quand vous les invoquez.
- Les commandes de contrôle reçoivent un environnement minimal (`PATH`, `SYSTEMROOT`, `WINDIR`, `TEMP`, `TMP`, `TMPDIR`, plus la langue fixée à `C` et le fuseau `UTC`). Identifiants et `NODE_OPTIONS` ne sont pas transmis. Ne mettez aucun secret dans les arguments ni dans la sortie.

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

**Codes de sortie de nexus**

| Code | Signification |
| --- | --- |
| 0 | L’action a réussi. |
| 1 | `verify` n’a pas réussi ; `launch` ne s’est pas terminé en `completed` ; `collect` ne s’est pas terminé en `completed` ; ou toute erreur. Un code non nul sur `launch` ou `collect` dit ce que le processus a fait, jamais que la tâche est acceptable. |

<a id="real-output"></a>
## Lire la sortie

Le parcours complet le plus court demande trois petits fichiers à côté de `nexus-plan.json`. Le vérificateur est celui que le plan déclare comme ressource ; `host.json` est l’identité que votre assistant donne à `start` ; `rec.json` est le résultat qu’il rapporte à `record`, avec l’identifiant de tentative qu’a affiché `start`.

**checks/check-result.cjs, le vérificateur**

```text
const fs = require("node:fs");
const text = fs.readFileSync("work/result.txt", "utf8");
if (!text.includes("done")) {
  console.error("work/result.txt must contain done");
  process.exit(1);
}
```

**host.json, donné à start**

```json
{ "backend": { "kind": "host", "id": "my-assistant", "sessionId": "session-1" } }
```

**rec.json, donné à record (l’identifiant de tentative est celui qu’a affiché start)**

```json
{
  "attemptId": "c3bbafd1-62ef-4b8b-ac72-0d9b09932427",
  "backend": { "kind": "host", "id": "my-assistant", "sessionId": "session-1" },
  "outcome": "completed",
  "summary": "Wrote work/result.txt."
}
```

**Créer, démarrer, enregistrer, vérifier et accepter une exécution**

```text
$ npx bmad-plus nexus create --plan nexus-plan.json
Nexus run example — durable task coordination
result: not started; verification=pending; acceptance=pending
Use inspect --json for recorded evidence and reconciliation observations.
$ npx bmad-plus nexus start example result --input host.json
Nexus run example — durable task coordination
result: running; verification=pending; acceptance=pending
  Attempt: c3bbafd1-62ef-4b8b-ac72-0d9b09932427; host: my-assistant/session-1
Use inspect --json for recorded evidence and reconciliation observations.
$ npx bmad-plus nexus record example result --input rec.json
Nexus run example — durable task coordination
result: completed; verification=pending; acceptance=pending
  Attempt: c3bbafd1-62ef-4b8b-ac72-0d9b09932427; host: my-assistant/session-1
Use inspect --json for recorded evidence and reconciliation observations.
$ npx bmad-plus nexus verify example result
Nexus run example — durable task coordination
result: completed; verification=passed; acceptance=pending
  Attempt: c3bbafd1-62ef-4b8b-ac72-0d9b09932427; host: my-assistant/session-1
Use inspect --json for recorded evidence and reconciliation observations.
$ npx bmad-plus nexus accept example result
Nexus run example — durable task coordination
result: completed; verification=passed; acceptance=accepted
  Attempt: c3bbafd1-62ef-4b8b-ac72-0d9b09932427; host: my-assistant/session-1
Use inspect --json for recorded evidence and reconciliation observations.
$ npx bmad-plus nexus inspect example
Nexus run example — durable task coordination
result: completed; verification=passed; acceptance=accepted
  Attempt: c3bbafd1-62ef-4b8b-ac72-0d9b09932427; host: my-assistant/session-1
  Accept only after rechecking current artifacts and resources.
Use inspect --json for recorded evidence and reconciliation observations.
# Les mots après « acceptance= » et les lignes d’indice supplémentaires dépendent de l’état de l’exécution ; lisez-les avec inspect --json.
```

Sortie capturée lors d’une exécution réelle. Source: Rejoué avec le paquet 0.23.0 dans un projet Git jetable ; l’identifiant de tentative change à chaque exécution

Lancer `verify` juste après `create` est refusé, car rien n’a encore été enregistré : `Nexus: Nexus: Verification requires completed, unaccepted, reconciled work.` Démarrez et enregistrez d’abord, comme ci-dessus. Notez le préfixe doublé : les messages propres au moteur commencent déjà par `Nexus:`, et la commande ajoute le sien.

Chaque ligne de tâche se lit `<task>: <execution>; verification=<status>; acceptance=<state>`, suivie de la dernière tentative avec son backend. `inspect --json` ajoute, par tâche, `resourcesCurrent`, `evidenceEligible`, `stale`, `staleReason` et `overdue` : un ancien enregistrement accepté ne peut donc pas prétendre que des fichiers modifiés depuis passent encore. En mode JSON, les erreurs sont affichées sous la forme `{"schemaVersion":1,"status":"error","error":"..."}`.

<a id="recovery"></a>
## Interruptions, annulation, reprises

- Une tentative interrompue ou déconnectée garde sa capacité jusqu’à ce que `reconcile` la règle. L’observation exige `ownerStopped: true`, une déclaration de votre part que vous avez vérifié, pas de la télémétrie. Pour une tâche non `idempotent`, une reprise exige aussi `retrySafe: true`.
- `cancel` ne fait que consigner une demande. Pour une tâche d’hôte, l’hôte arrête son propre travail ; pour une tâche de processus, seul le superviseur d’origine au premier plan peut envoyer un signal au processus fils qu’il a créé. Nexus ne tue jamais un PID enregistré.
- `retry` (ou `launch` avec `{"retry":true}`) ouvre une nouvelle tentative et consomme `maxAttempts`. Une nouvelle session de backend ne remet pas la limite à zéro.
- Une vérification qui dépasse son délai est consignée comme ambiguë, car des descendants du contrôle pourraient encore avoir des effets. Inspectez avant de reprendre.
- `recover-lock` prend l’empreinte exacte du verrou donnée par `inspect`, `ownerStopped: true` et une `note` non vide. Un écrivain local vivant le bloque. L’âge seul n’autorise jamais le retrait.

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

Les erreurs sont affichées sous la forme `Nexus: <message>` sur le flux d’erreur. Les messages propres au moteur commencent déjà par `Nexus:`, si bien que la plupart des erreurs montrent le préfixe deux fois (`Nexus: Nexus: Run ID must use ...`).

**Erreurs de nexus**

| Message | Cause | Que faire |
| --- | --- | --- |
| `Use nexus create --plan FILE, inspect RUN, or start\|launch\|collect\|record\|reconcile\|verify\|retry\|cancel\|accept RUN TASK.` | Action inconnue ou identifiants d’exécution/tâche manquants. | Vérifiez la synopsis. |
| `--plan requires a JSON file.` / `--input requires a JSON file.` | L’option manque pour une action qui en a besoin. | Ajoutez le fichier ; voir le tableau des actions. |
| `--input must name a regular JSON file no larger than 1 MiB.` | Pas un fichier ordinaire, un lien symbolique, ou trop gros. | Utilisez un simple fichier JSON. |
| `verify executes its recorded contract and takes no input file.` | `--input` donné à `verify` ou `accept`. | Retirez `--input`. |
| `Overlapping exclusive write scopes: <a> and <b>` | Deux tâches partagent un chemin dans leurs périmètres. | Rendez les périmètres disjoints. |
| `Verifier/resource lies in a worker write scope: <file>` | Un fichier protégé se trouve dans le périmètre d’une tâche. | Déplacez le vérificateur hors de tout périmètre. |
| `Run already exists; inspect it instead.` | `create` avec un identifiant d’exécution existant. | Utilisez `inspect`, ou un nouvel identifiant de plan. |
| `Stale or missing attempt identity.` / `Backend handle/session does not own this attempt.` | L’entrée désigne une autre tentative, un autre identifiant ou une autre session. | Copiez l’identifiant de tentative et le backend exacts renvoyés par `start` ou `launch`. |
| `Protected verifier or agent resource changed since the plan was created.` | Une ressource déclarée a été modifiée après `create`. | Restaurez-la, ou créez une nouvelle exécution depuis un plan mis à jour. |
| `Dependency has not been accepted: <task>` | Une dépendance n’est pas encore acceptée. | Vérifiez et acceptez d’abord la dépendance. |
| `Run capacity is occupied until active work is reconciled.` | Des tentatives actives ou interrompues remplissent `maxParallel`. | Collectez, enregistrez ou réconciliez-les. |
| `Another mutation owns writer.lock; inspect before explicit recovery.` | Une autre commande tourne, ou l’une a été tuée. | Attendez ; si elle a été tuée, utilisez `inspect` puis `recover-lock`. |
| `Corrupt or foreign run state; original bytes were preserved.` | Le fichier d’exécution ne correspond pas à sa somme de contrôle. | Restaurez le fichier depuis une sauvegarde ; rien n’est réparé automatiquement. |
| `Current attempt has no eligible passed verification.` | `accept` avant un `verify` réussi. | Lancez `verify` ; corrigez le travail s’il échoue. |
| `Stale evidence: checked artifacts or write scope changed.` | Des fichiers ont changé après la vérification. | Vérifiez de nouveau. |

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

<a id="example-cli-nexus-split-and-prove"></a>
### Découper le travail et prouver chaque partie

Trois changements indépendants touchent des dossiers différents. Vous voulez que chacun soit vérifié par un contrôle que vous avez écrit, et non sur la parole du worker.

**Dans votre assistant IA**

```text
Nexus, découpe le travail approuvé en tâches indépendantes, chacune avec son dossier d’écriture et une commande de contrôle que je peux lancer. Crée une exécution durable avec `bmad-plus nexus create`, démarre une tentative par tâche et n’accepte rien tant que `bmad-plus nexus verify` n’a pas réussi pour elle.
```

**Ce que vous devriez obtenir** Nexus écrit un plan à périmètres disjoints et lance `create`, qui refuse les périmètres qui se chevauchent ou un vérificateur placé dans un périmètre. Pour chaque tâche, l’hôte fait le travail et consigne le résultat ; `verify` lance votre contrôle et conserve son reçu ; `accept` ne réussit que si les preuves sont à jour. Une tâche dont le contrôle échoue reste non acceptée et peut être reprise dans la limite de `maxAttempts`.

<a id="example-cli-nexus-recover-after-crash"></a>
### Reprendre après une panne

La machine a redémarré pendant qu’une tâche tournait. Vous ne savez pas si le worker tient encore des fichiers ouverts.

**Dans votre assistant IA**

```text
Nexus, inspecte l’exécution `release-prep` avec `bmad-plus nexus inspect release-prep --json`. Dis-moi quelles tentatives sont non résolues et ce que je dois vérifier avant que tu les réconcilies. Ne reprends rien de ta propre initiative.
```

**Ce que vous devriez obtenir** `inspect` est en lecture seule et indique chaque tentative avec son backend, le résultat consigné et les observations (`stale`, `overdue`). Les tentatives non résolues gardent leur capacité. Une fois les effets vérifiés et l’arrêt du propriétaire confirmé, `reconcile` consigne `completed`, `failed` ou `cancelled` ; ensuite seulement une reprise peut ouvrir une nouvelle tentative. Si un verrou d’écriture est resté, `inspect` sans identifiant d’exécution montre son empreinte pour `recover-lock`.

**Voir aussi**

- [La CLI en un coup d’œil et les codes de sortie](https://bmad-plus.rochetta.fr/fr/docs/reference/cli-overview/)
- [swarm : exporter un fanout comme plan Nexus](https://bmad-plus.rochetta.fr/fr/docs/reference/cli-swarm/)
- [uat : la porte d’acceptation utilisée comme contrôle](https://bmad-plus.rochetta.fr/fr/docs/reference/cli-uat/)
- [Arborescence du projet](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)
