Ejecuciones de tareas duraderas: un plan de tareas con alcances de escritura disjuntos, intentos recuperables tras una interrupción, verificación independiente y una aceptación aparte.
Cuando hay que hacer varias tareas y quieres la prueba de que cada una se hizo, el agente Nexus puede mantenerlas en una ejecución duradera. El comando nexus es el libro de registro de esa ejecución. Describes las tareas en un plan JSON; cada tarea posee una carpeta o archivo que puede escribir (su alcance) y una lista de comandos de comprobación que deciden si su resultado es aceptable. El registro anota quién intentó qué (un intento), conserva el estado ante caídas, ejecuta él mismo las comprobaciones y solo entonces te deja aceptar la tarea. Que un worker diga «hecho» nunca es una prueba: las comprobaciones sí. Esta página es para quien maneja Nexus a mano, desde CI, o quiere saber qué hace el agente por dentro.
Identidad del host, observación o petición de reintento para una acción que modifica una tarea, u observación del bloqueo para recover-lock. Archivo normal de 1 MiB como máximo, objeto JSON.
--json
-
desactivado
Imprime el estado duradero y las evidencias en JSON en vez del resumen corto.
Nexus mantiene separadas tres preguntas. Ejecución: ¿terminó el worker? Un host lo informa con record, o el supervisor en primer plano recoge la salida real del proceso que lanzó. Verificación: ¿pasa el trabajo las comprobaciones del plan? Nexus las ejecuta él mismo, con argumentos literales y sin shell, y compara los artefactos declarados y todo el alcance de escritura antes y después. Aceptación: ¿sigue siendo el espacio de trabajo actual el que pasó? accept vuelve a comprobar las huellas de los artefactos, los recursos protegidos y el estado aceptado de cada dependencia. Una comprobación fallida impide la aceptación aunque el worker haya tenido éxito. Nexus nunca hace commit, fusión, copia de archivos ni despliegue.
{
"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."]
}
]
}
Campos del plan y sus reglas
Campo
Regla
id
Id de ejecución: de 1 a 64 letras minúsculas, dígitos, _ o -. Misma regla para los ids de tarea.
maxParallel
Entre 1 y 32 intentos activos a la vez.
config
Solo ajustes primitivos no secretos. Se rechazan las claves que parecen secretos.
tasks
De 1 a 200 tareas. Ids únicos; las dependencias deben existir y no formar ciclos.
objective, acceptance
Lo que la tarea debe producir y los enunciados que el resultado debe cumplir.
dependsOn
Ids de las tareas que deben aceptarse antes.
scope
Archivos o carpetas que el worker puede escribir. Los alcances de tareas distintas deben ser disjuntos, incluso si una depende de otra. Nunca .git ni el estado propio de Nexus.
artifacts
Archivos que deben existir dentro del alcance de la tarea al verificarla.
resources
Archivos protegidos: el verificador y cada archivo de instrucciones entregado al worker. Se les calcula la huella y deben estar fuera de todo alcance.
checks
De 1 a 30 por tarea. command es node o una ruta absoluta de ejecutable; args es un array literal; cada argumento de archivo debe ser un recurso declarado; timeoutMs de 10 a 300000.
maxAttempts
De 1 a 10. Las rondas de verificación también se limitan con él.
deadlineMs
De 100 a 86400000. Un plazo es una observación, no la prueba de que el trabajo se detuvo.
idempotent
Booleano. Una tarea no idempotente exige una reconciliación explícita con retrySafe: true antes de reintentar.
authorizations
Enunciados de lo que se autorizó. Los workers no pueden editarlos.
execution
Opcional. Elige un backend de proceso en lugar de un host (ver abajo).
Por defecto una tarea es del host: tu asistente hace el trabajo con sus propias herramientas y comunica el resultado a Nexus con record. Después Nexus verifica. Añadir un objeto execution a una tarea la convierte en una tarea de proceso: launch arranca el programa en primer plano, lo espera y guarda un recibo con suma de comprobación de lo que realmente ocurrió. Hay dos adaptadores.
Tú aportas el comando; nunca se deduce del texto de la tarea. El ejecutable queda fijado por SHA-256. Salida 0 significa completado; un código listado en blockedExitCodes significa bloqueado. Sin shell, sin sobrescribir el entorno.
codex-exec
command (ruta absoluta del codex instalado), input, instructions, sandbox, model opcional
Ejecuta la CLI de Codex instalada sin interacción. sandbox es read-only (por defecto) o workspace-write. Completar exige salida 0 más los eventos de inicio de hilo y fin de turno; solo un error explícito approval_required pasa a bloqueado.
Advertencia· No es un sandbox
Los workers comparten tu proyecto y tu usuario del sistema. Pueden ignorar su alcance declarado; las sumas de comprobación detectan un cambio accidental pero no son firmas. No hay demonio, ni planificador, ni supervisión del árbol de procesos: cada launch es un comando en primer plano. workspace-write es una petición al host Codex instalado, no un sandbox de Nexus. Usa un proyecto aislado o una política del host cuando el worker no sea de confianza.
Estado: .bmad-plus/nexus/runs/<run-id>.json, un sobre con suma de comprobación escrito mediante un archivo temporal volcado a disco y un renombrado atómico.
Bloqueos: .bmad-plus/nexus/writer.lock (una modificación a la vez) y, durante una recuperación excepcional, .bmad-plus/nexus/recovery.lock. Un bloqueo retirado se archiva en .bmad-plus/nexus/lock-recovery/.
inspect no escribe nada y sigue funcionando mientras corre una verificación. Todas las demás acciones salvo create modifican una ejecución existente; create la crea.
Lee tu plan y tus archivos de entrada, los recursos y artefactos declarados, y toma una instantánea de los alcances de escritura. La verificación ejecuta tus comandos de comprobación; launch ejecuta el proceso de la tarea. Son los únicos procesos que Nexus inicia, y solo cuando los invocas.
Los comandos de comprobación reciben un entorno mínimo (PATH, SYSTEMROOT, WINDIR, TEMP, TMP, TMPDIR más el idioma fijado en C y la zona UTC). No se reenvían credenciales ni NODE_OPTIONS. No pongas ningún secreto en los argumentos ni en la salida.
verify no pasó; launch no terminó en completed; collect no terminó en completed; o cualquier error. Un código distinto de cero en launch o collect dice lo que hizo el proceso, nunca que la tarea sea aceptable.
El recorrido completo más corto necesita tres archivos pequeños junto a nexus-plan.json. El verificador es el que el plan declara como recurso; host.json es la identidad que tu asistente da a start; rec.json es el resultado que informa a record, con el id de intento que imprimió start.
checks/check-result.cjs, el verificador
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);
}
Crear, iniciar, registrar, verificar y aceptar una ejecución
$ 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.# Las palabras tras «acceptance=» y las líneas de pista adicionales dependen del estado de la ejecución; léelas con 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
Salida capturada de una ejecución real. Fuente: Reproducido con el paquete 0.23.0 en un proyecto Git desechable; el id de intento cambia en cada ejecución
Ejecutar verify justo después de create se rechaza, porque todavía no se ha registrado nada: Nexus: Nexus: Verification requires completed, unaccepted, reconciled work. Inicia y registra primero, como arriba. Fíjate en el prefijo duplicado: los mensajes propios del motor ya empiezan por Nexus:, y el comando añade el suyo.
Cada línea de tarea se lee <task>: <execution>; verification=<status>; acceptance=<state>, seguida del último intento con su backend. inspect --json añade, por tarea, resourcesCurrent, evidenceEligible, stale, staleReason y overdue, de modo que un registro aceptado antiguo no puede afirmar que archivos editados después sigan pasando. En modo JSON, los errores se imprimen como {"schemaVersion":1,"status":"error","error":"..."}.
Un intento interrumpido o desconectado conserva su capacidad hasta que reconcile lo cierra. La observación exige ownerStopped: true, una declaración tuya de que lo comprobaste, no telemetría. Para una tarea no idempotent, el reintento exige además retrySafe: true.
cancel solo registra una petición. En una tarea del host, el host detiene su propio trabajo; en una tarea de proceso, solo el supervisor original en primer plano puede enviar señales al proceso hijo que creó. Nexus nunca mata un PID guardado.
retry (o launch con {"retry":true}) abre un intento nuevo y consume maxAttempts. Una sesión de backend nueva no reinicia el límite.
Una verificación que agota el tiempo se registra como ambigua, porque descendientes de la comprobación aún podrían tener efectos. Inspecciona antes de reintentar.
recover-lock toma la huella exacta del bloqueo que da inspect, ownerStopped: true y una note no vacía. Un escritor local vivo lo bloquea. La antigüedad por sí sola nunca autoriza la retirada.
Los errores se imprimen como Nexus: <message> en el flujo de error. Los mensajes propios del motor ya empiezan por Nexus:, así que la mayoría de los errores muestran el prefijo dos veces (Nexus: Nexus: Run ID must use ...).
Errores de nexus
Mensaje
Causa
Qué hacer
Use nexus create --plan FILE, inspect RUN, or start|launch|collect|record|reconcile|verify|retry|cancel|accept RUN TASK.
Acción desconocida o faltan ids de ejecución/tarea.
Revisa la sinopsis.
--plan requires a JSON file. / --input requires a JSON file.
Falta la opción en una acción que la necesita.
Añade el archivo; consulta la tabla de acciones.
--input must name a regular JSON file no larger than 1 MiB.
No es un archivo normal, es un enlace simbólico, o es demasiado grande.
Usa un archivo JSON simple.
verify executes its recorded contract and takes no input file.
Se dio --input a verify o accept.
Quita --input.
Overlapping exclusive write scopes: <a> and <b>
Dos tareas comparten una ruta en sus alcances.
Haz los alcances disjuntos.
Verifier/resource lies in a worker write scope: <file>
Un archivo protegido está dentro del alcance de una tarea.
Mueve el verificador fuera de todo alcance.
Run already exists; inspect it instead.
create con un id de ejecución existente.
Usa inspect, o un id de plan nuevo.
Stale or missing attempt identity. / Backend handle/session does not own this attempt.
La entrada nombra otro intento, identificador o sesión.
Copia el id de intento y el backend exactos que devolvió start o launch.
Protected verifier or agent resource changed since the plan was created.
Un recurso declarado se editó tras create.
Restáuralo, o crea una ejecución nueva con un plan actualizado.
Dependency has not been accepted: <task>
Una dependencia aún no está aceptada.
Verifica y acepta primero la dependencia.
Run capacity is occupied until active work is reconciled.
Intentos activos o interrumpidos llenan maxParallel.
Recógelos, regístralos o reconcílialos.
Another mutation owns writer.lock; inspect before explicit recovery.
Otro comando está en marcha, o uno fue matado.
Espera; si lo mataron, usa inspect y luego recover-lock.
Corrupt or foreign run state; original bytes were preserved.
El archivo de ejecución no coincide con su suma de comprobación.
Restaura el archivo desde una copia; nada se repara automáticamente.
Current attempt has no eligible passed verification.
accept antes de un verify superado.
Ejecuta verify; corrige el trabajo si falla.
Stale evidence: checked artifacts or write scope changed.
Tres cambios independientes tocan carpetas distintas. Quieres que cada uno se verifique con una comprobación que escribiste tú, no con la palabra del worker.
En tu asistente de IA
Nexus, divide el trabajo aprobado en tareas independientes, cada una con su carpeta de escritura y un comando de comprobación que yo pueda ejecutar. Crea una ejecución duradera con `bmad-plus nexus create`, inicia un intento por tarea y no aceptes nada hasta que `bmad-plus nexus verify` haya pasado para ella.
Lo que deberías obtener Nexus escribe un plan con alcances disjuntos y ejecuta create, que rechaza alcances que se solapan o un verificador dentro de un alcance. Para cada tarea el host hace el trabajo y registra el resultado; verify ejecuta tu comprobación y guarda su recibo; accept solo tiene éxito si las evidencias están al día. Una tarea cuya comprobación falla sigue sin aceptar y puede reintentarse dentro de maxAttempts.
La máquina se reinició mientras corría una tarea. No estás seguro de si el worker aún tiene archivos abiertos.
En tu asistente de IA
Nexus, inspecciona la ejecución `release-prep` con `bmad-plus nexus inspect release-prep --json`. Dime qué intentos están sin resolver y qué debo comprobar antes de que los reconcilies. No reintentes nada por tu cuenta.
Lo que deberías obtenerinspect es de solo lectura e informa de cada intento con su backend, el resultado registrado y las observaciones (stale, overdue). Los intentos sin resolver conservan su capacidad. Cuando has comprobado los efectos y confirmas que el propietario se detuvo, reconcile registra completed, failed o cancelled; solo entonces un reintento puede abrir un intento nuevo. Si quedó un bloqueo de escritura, inspect sin id de ejecución muestra su huella para recover-lock.