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.
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.
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.
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.
{
"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).
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.
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.
É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.
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.
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
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);
}
Créer, démarrer, enregistrer, vérifier et accepter une exécution
$ npx bmad-plus nexus create --plan nexus-plan.jsonNexus run example — durable task coordinationresult: not started; verification=pending; acceptance=pendingUse inspect --json for recorded evidence and reconciliation observations.$ npx bmad-plus nexus start example result --input host.jsonNexus run example — durable task coordinationresult: running; verification=pending; acceptance=pending Attempt: c3bbafd1-62ef-4b8b-ac72-0d9b09932427; host: my-assistant/session-1Use inspect --json for recorded evidence and reconciliation observations.$ npx bmad-plus nexus record example result --input rec.jsonNexus run example — durable task coordinationresult: completed; verification=pending; acceptance=pending Attempt: c3bbafd1-62ef-4b8b-ac72-0d9b09932427; host: my-assistant/session-1Use inspect --json for recorded evidence and reconciliation observations.$ npx bmad-plus nexus verify example resultNexus run example — durable task coordinationresult: completed; verification=passed; acceptance=pending Attempt: c3bbafd1-62ef-4b8b-ac72-0d9b09932427; host: my-assistant/session-1Use inspect --json for recorded evidence and reconciliation observations.$ npx bmad-plus nexus accept example resultNexus run example — durable task coordinationresult: completed; verification=passed; acceptance=accepted Attempt: c3bbafd1-62ef-4b8b-ac72-0d9b09932427; host: my-assistant/session-1Use inspect --json for recorded evidence and reconciliation observations.$ npx bmad-plus nexus inspect exampleNexus run example — durable task coordinationresult: 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.
npx bmad-plus nexus create --plan nexus-plan.json
npx bmad-plus nexus start example result --input host.json
npx bmad-plus nexus record example result --input rec.json
npx bmad-plus nexus verify example result
npx bmad-plus nexus accept example result
npx bmad-plus nexus inspect example
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":"..."}.
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.
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.
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
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.
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
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 obtenirinspect 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.