Nexus: autopilot, trabajo en paralelo y ejecuciones duraderas
Autopilot con puntos de control, trabajo paralelo supervisado, exportación de plan desde un enjambre y runtime duradero (create, start, launch, collect, verify, accept), adaptador Codex y límites.
Nexus es el orquestador de Core. Tiene cuatro roles: Scrum Master (sprints, historias, retrospectivas), Quick Flow (un cambio pequeño con el mínimo de ceremonia), Autopilot Controller (el pipeline de la idea a la entrega, con puntos de control) y Parallel Supervisor (varios agentes a la vez, sin colisiones). Debajo hay un runtime duradero, bmad-plus nexus, que guarda en disco grafos de tareas e intentos para que el trabajo sobreviva a una sesión cerrada y nada cuente como hecho hasta que lo digan comprobaciones independientes. Esta página es para quien quiere automatizar el trabajo de más de un agente y saber exactamente hasta dónde llega la automatización.
Nexus y el trabajo en paraleloCómo Nexus detecta tareas independientes, da a cada una su ámbito de escritura, registra resultados reales y ejecuta comprobaciones independientes antes de aceptar.Transcripción
Nexus coordina el trabajo de los demás roles. Busca las tareas independientes, las que no tocan ningún archivo compartido. Cada tarea recibe su propio ámbito de escritura, y esos ámbitos no pueden solaparse. Los agentes en paralelo los aporta tu herramienta anfitriona. Sin ellos, las tareas se ejecutan una tras otra. Nexus también puede lanzar un comando local planificado o un proceso de Codex CLI, bajo un supervisor en primer plano. Registra el resultado real y ejecuta comprobaciones independientes antes de aceptar nada. No hay ningún planificador en segundo plano, y los permisos del anfitrión siguen aplicándose. En autopilot, la misma secuencia va de la idea a la entrega, con los puntos de control que configures.
Di autopilot en el chat de tu herramienta de IA y luego describe el proyecto. Son instrucciones de chat, no comandos de terminal. Nexus examina la petición y el proyecto antes de elegir etapas: un cambio pequeño va directo a la implementación y la revisión, mientras que un contrato que falta o una incertidumbre de peso justifica una planificación más profunda. Para un proyecto que necesita el pipeline completo hay tres fases.
El pipeline de autopilot
Fase
Pasos
Punto de control
1. Discovery
Paso 0: el intake de cada pack que implique la petición. Luego Atlas (Analista): brainstorming e investigación del dominio; Atlas (PM): product brief y PRD; Sentinel (UX): especificación UX.
discovery: revisas el PRD y la especificación UX.
2. Build
Forge (Arquitecto): arquitectura; Nexus (Scrum Master): épicas, historias, plan de sprint; luego para cada historia, en paralelo si son independientes: implementar, probar, redactar los pasos de aceptación que una persona puede observar. Una comprobación fallida conserva sus evidencias y se repara dentro del límite de intentos de la tarea.
architecture: revisas la arquitectura. story: un aviso por historia terminada.
3. Ship
Revisión de código completa, revisión UX, documentación, receta de aceptación finalizada y entregada a una persona, resultados leídos y cada fallo clasificado, retrospectiva.
delivery: revisas el entregable final, con la ejecución citada.
Cada punto de control sigue el ajuste de _bmad/config.yaml: require_approval se detiene y espera, notify_only informa y continúa, auto continúa y lo registra. Con execution_mode: autopilot, el punto de control story pasa por defecto a notify_only. Una notificación externa (un mensaje a tu teléfono, por ejemplo) necesita un canal configurado y tu autorización: una instalación básica no tiene ningún emisor en segundo plano, así que ningún recordatorio se envía por sí solo.
La aceptación humana también encaja. Con uat.mode: advisory (por defecto, también cuando falta el bloque) la página se construye y se ofrece en cada entrega y nunca bloquea; gate hace que el punto de control de entrega espere a que bmad-plus uat gate pase; off no produce receta y el informe de entrega lo dice. Un pack también puede declarar un pipeline en el registro (pasos ordenados, cada uno con una puerta); autopilot ejecuta entonces ese pipeline para el trabajo del pack, tras su intake. Ningún pack declara uno en 0.23.0, así que es una capacidad del framework, no contenido entregado.
El estado de referencia vive en .bmad-plus/nexus/runs/. El archivo opcional .bmad-plus/orchestrator-state.yaml es solo un resumen de navegación; no puede demostrar que algo esté aceptado ni que un proceso se haya detenido.
No existe un ejecutable autopilot --resume. Para reanudar, inspecciona la ejecución duradera prevista y el estado real del anfitrión, y reconcilia un intento interrumpido antes de reintentar.
Fallo de prueba: se conservan las comprobaciones fallidas, la reparación se hace dentro del maxAttempts de la tarea y luego se vuelven a verificar los artefactos cambiados. Una declaración de terminado no puede hacer pasar una comprobación que falla.
Error de agente: se conservan el trabajo parcial y la identidad de su intento, y el informe dice qué sigue incierto. Las tareas dependientes esperan la aceptación.
Conflicto en trabajo paralelo: se deja de asignar trabajo que se solapa, se inspeccionan los propietarios, se reconcilian sus intentos y se conservan tus cambios antes de cualquier reintento.
Di parallel en el chat, o deja que autopilot lo llame cuando parallel_execution es true y se detectan tareas independientes. El Parallel Supervisor decide qué puede ejecutarse a la vez; el anfitrión decide si puede. El paralelismo real depende de tu herramienta: si no puede ejecutar subagentes, las tareas se ejecutan una tras otra.
Qué puede y qué no puede ejecutarse en paralelo
Paralelizable
Solo secuencial
Historias sin archivos compartidos
Historias que modifican los mismos archivos
Investigaciones independientes (mercado y técnica)
Una tarea cuya entrada es la salida de otra
Pruebas mientras se escribe la documentación
Decisiones de arquitectura antes de implementar
Cambios en módulos o paquetes separados
Revisión de código tras la implementación
Las seis acciones de supervisión
Acción
Cuándo
Qué ocurre
Launch
Se detectan tareas independientes
Iniciar sesiones de agentes en paralelo.
Monitor
De forma continua
Seguir el avance en la ejecución de Nexus.
Pause
Se detecta un conflicto
Detener al agente en conflicto.
Restart
Una vez resuelto el conflicto
Reconciliar el intento existente y sus efectos y reintentar dentro del límite registrado con una identidad de anfitrión nueva.
Reallocate
Un agente termina antes
Asignar la siguiente tarea de la cola.
Escalate
Se alcanza el límite de intentos o la reconciliación se bloquea
Informar de la situación sin resolver y de las evidencias; seguir con el trabajo independiente autorizado.
bmad-plus nexus conserva un grafo de tareas y sus intentos en .bmad-plus/nexus/runs/. Cada cambio normal toma un bloqueo exclusivo del proyecto y escribe un archivo de estado con suma de comprobación, mediante un archivo temporal volcado a disco y un renombrado atómico. La inspección es de solo lectura. Se mantienen separados tres resultados, y esa separación es el sentido mismo del runtime.
Ejecución, verificación, aceptación
Resultado
Quién lo establece
Qué significa
Ejecución
Un anfitrión identificado informa completed, failed, blocked o ambiguous; o un supervisor original en primer plano recoge el resultado real de su proceso hijo.
Una observación. No es una verificación independiente.
Verificación
Nexus ejecuta él mismo los comandos de comprobación del plan con arrays de argumentos literales y sin shell, registra códigos de salida y una salida acotada, y compara instantáneas de los artefactos y del ámbito de escritura antes y después.
El resultado supera las comprobaciones independientes, con recibos.
Aceptación
Una operación aparte y serializada vuelve a comprobar los artefactos actuales, los hashes de recursos y las evidencias de dependencias.
Se acepta el espacio de trabajo actual. No se hace ningún commit de Git, fusión, copia ni despliegue.
Las evidencias siguen siendo honestas con el tiempo. Una tarea aceptada cuenta como vigente solo mientras sus artefactos, recursos protegidos y cada dependencia transitiva sigan coincidiendo con lo verificado: cambiar un archivo aguas arriba invalida las evidencias de los dependientes, y un registro antiguo de «aceptada» no afirma que archivos editados después sigan pasando. Un plazo es una observación, no prueba de que el trabajo nunca ocurrió o de que un proceso terminó.
Un plan es un archivo JSON; la entrada estructurada pasa siempre por archivos para que el quoting del shell no pueda reinterpretar un array de comando. Este plan mínimo tiene una tarea cuyo resultado debe cumplir una comprobación que ya existe (checks/check-result.cjs) y cuyo código fuente queda fuera del ámbito de escritura del worker.
nexus-plan.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", ".agents/skills/agent-orchestrator/SKILL.md"],
"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 de una tarea
Campo
Significado
id, objective, acceptance
Identificador, qué producir y las condiciones que deben cumplirse.
dependsOn
Tareas que deben tener evidencias aceptadas vigentes antes de que esta empiece.
scope
Archivos o carpetas que la tarea puede escribir. Los scopes de todas las tareas son exclusivos y disjuntos dos a dos, incluso entre tareas secuenciales.
artifacts
Archivos que forman el resultado; se registran sus hashes.
resources
Cada instrucción y archivo de apoyo entregado al anfitrión, con hash de Nexus. Deben quedar fuera del ámbito de escritura de cualquier tarea. Nexus no puede dar fe de lo que no se declara.
checks
Hasta 30 por tarea: command (node o una ruta absoluta de ejecutable, cuyos bytes quedan ligados al plan), args, cwd, timeoutMs (de 10 a 300000). Los argumentos de archivo deben ser recursos declarados.
maxAttempts, deadlineMs, idempotent
Límite de intentos (como máximo 10), plazo, y si un reintento es seguro sin una observación específica.
authorizations
Texto que describe la autorización existente. Un worker no puede modificarla ni responder a una petición de aprobación.
execution
Contrato opcional para una tarea con proceso (ver más abajo). Sin él, la tarea pertenece al anfitrión.
Las rutas de un plan son portables, relativas al proyecto y usan /. Se rechazan las rutas absolutas, el recorrido hacia arriba, los flujos alternativos, los nombres reservados de Windows, los enlaces simbólicos o uniones, y las escrituras en .git o en el árbol de estado de Nexus. Las comprobaciones se ejecutan con un entorno restringido: solo se pueden copiar PATH, SYSTEMROOT, WINDIR, TEMP, TMP y TMPDIR (más unas variables de identidad y ruta no secretas en Windows), la configuración regional es C, la zona horaria es UTC, y NODE_OPTIONS, PYTHONPATH, los hooks de carga y las credenciales están ausentes. Es una restricción del entorno, no un sandbox del sistema operativo.
El flujo gestionado por el anfitrión: create, start, record, verify, accept#
El backend por defecto es el anfitrión: tu asistente hace el trabajo con sus propios medios e informa. Abajo, una ejecución real de una dispersión (fanout) exportada desde un enjambre (tres unidades de página; solo se recorre la primera). Crea los tres archivos del enjambre y host.json en un proyecto para reproducirla. El «worker» es un sustituto que escribe a mano el archivo de respuesta: el ejemplo muestra la contabilidad, no el trabajo de ningún modelo.
swarm/page-fanout.json (la definición del enjambre)
{
"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."
}
# 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}}
host.json (la identidad del worker y de su sesión)
Una tarea gestionada por el anfitrión, de la creación a la aceptación
$ npx bmad-plus swarm init --definition swarm/page-fanout.json --units swarm/units.jsonsite-pages-20261019-vwk0: fanout of 3 units, budget 26, approval not-needed.Units listed, no seed.Next: bmad-plus swarm briefs site-pages-20261019-vwk0$ npx bmad-plus swarm plan site-pages-20261019-vwk0 --out .bmad-plus/swarm/reports/site-pages-20261019-vwk0/plan.json/work/demo/app/.bmad-plus/swarm/reports/site-pages-20261019-vwk0/plan.json: 3 tasks, 10 in parallel.Next: bmad-plus nexus create --plan /work/demo/app/.bmad-plus/swarm/reports/site-pages-20261019-vwk0/plan.json$ npx bmad-plus nexus create --plan .bmad-plus/swarm/reports/site-pages-20261019-vwk0/plan.jsonNexus run site-pages-20261019-vwk0 — durable task coordinationabout: not started; verification=pending; acceptance=pendingpricing: not started; verification=pending; acceptance=pendingcontact: not started; verification=pending; acceptance=pendingUse inspect --json for recorded evidence and reconciliation observations.$ npx bmad-plus nexus start site-pages-20261019-vwk0 about --input host.jsonabout: running; verification=pending; acceptance=pending Attempt: a4ec0495-660b-487c-8c83-e82ada22a857; host: demo-worker/demo-session-1$ echo '{"id":"about","done":true,"words":120}' > .bmad-plus/swarm/runs/site-pages-20261019-vwk0/answers/about.json# El worker de sustitución escribe su archivo de respuesta a mano. Luego escribe rec.json (se muestra bajo este terminal) con el id de intento que imprime start.$ npx bmad-plus nexus record site-pages-20261019-vwk0 about --input rec.jsonabout: completed; verification=pending; acceptance=pending Attempt: a4ec0495-660b-487c-8c83-e82ada22a857; host: demo-worker/demo-session-1$ npx bmad-plus nexus verify site-pages-20261019-vwk0 aboutabout: completed; verification=passed; acceptance=pending$ npx bmad-plus nexus accept site-pages-20261019-vwk0 aboutabout: completed; verification=passed; acceptance=accepted$ npx bmad-plus nexus inspect site-pages-20261019-vwk0about: completed; verification=passed; acceptance=accepted Accept only after rechecking current artifacts and resources.pricing: not started; verification=pending; acceptance=pending Start when dependencies have current accepted evidence.# Cada comando nexus imprime además la línea de encabezado, las líneas pricing y contact y la indicación final; aquí solo se conservan las líneas que cambian.
npx bmad-plus swarm init --definition swarm/page-fanout.json --units swarm/units.json
npx bmad-plus swarm plan site-pages-20261019-vwk0 --out .bmad-plus/swarm/reports/site-pages-20261019-vwk0/plan.json
npx bmad-plus nexus create --plan .bmad-plus/swarm/reports/site-pages-20261019-vwk0/plan.json
npx bmad-plus nexus start site-pages-20261019-vwk0 about --input host.json
echo '{"id":"about","done":true,"words":120}' > .bmad-plus/swarm/runs/site-pages-20261019-vwk0/answers/about.json
npx bmad-plus nexus record site-pages-20261019-vwk0 about --input rec.json
npx bmad-plus nexus verify site-pages-20261019-vwk0 about
npx bmad-plus nexus accept site-pages-20261019-vwk0 about
npx bmad-plus nexus inspect site-pages-20261019-vwk0
Salida capturada de una ejecución real. Fuente: bmad-plus 0.23.0, 2026-10-19
rec.json (lo que informa el anfitrión; el id de intento se copia de start)
{
"attemptId": "a4ec0495-660b-487c-8c83-e82ada22a857",
"backend": { "kind": "host", "id": "demo-worker", "sessionId": "demo-session-1" },
"outcome": "completed",
"exitCode": 0,
"summary": "The demo host reports the about page is written."
}
record necesita el id exacto del intento y el mismo backend y sesión. Los otros resultados son failed, blocked (la petición sigue visible y conserva su capacidad) y ambiguous (entonces se rechazan los acuses ordinarios; reconcilia explícitamente). verify sale con 1 cuando la verificación no pasó, y accept rechaza una tarea sin una verificación superada elegible. El código de salida de un worker o una frase que diga «hecho» nunca sustituye un recibo de comprobación.
Registra una petición. Un intento del anfitrión no señaliza ningún PID ni terminal; el anfitrión solo detiene su propia operación. La capacidad sigue retenida hasta la reconciliación.
nexus reconcile RUN TASK
El intento, outcome (completed, failed o cancelled), ownerStopped: true, retrySafe, summary
Cierra un intento incierto con una observación de operador. Es una observación, nunca evidencia independiente de que el propietario se detuvo.
nexus retry RUN TASK
Una identidad de anfitrión nueva
Inicia un intento nuevo tras la reconciliación. Consume maxAttempts; una sesión nueva no reinicia el límite. Las tareas no idempotentes también necesitan retrySafe: true.
nexus recover-lock
El hash exacto del bloqueo que da inspect, ownerStopped: true, una note no vacía
Retira un bloqueo de escritura interrumpido después de que inspeccionaste a su propietario. Un escritor local vivo impide la retirada. Nunca automático.
El backend de procesos opcional y el adaptador Codex#
Una tarea puede llevar un objeto execution en vez de pertenecer al anfitrión. Es una definición aportada por el operador, nunca un comando deducido del texto de la tarea. nexus launch RUN TASK permanece entonces en primer plano hasta que acaba la operación que posee; un terminal, un anfitrión de código o un runner de CI lo mantiene vivo. El registro de la tarea se guarda antes de lanzar el proceso: liga un id de intento nuevo a una sesión de supervisor nueva, a la definición exacta y a los hashes de sus entradas protegidas. El supervisor conserva stdout y stderr acotados, la salida o la señal reales y un recibo con suma de comprobación. launch deja pendiente la recogida incluso tras una salida limpia: nexus collect RUN TASK --input attempt.json (el attemptId exacto y el objeto backend completo) la cierra, y rechaza un recibo ajeno, repetido o tardío. El estado 0 de launch significa solo que el recibo del proceso dice completed; no significa aceptación.
Una tarea con el adaptador de comando genérico (objeto execution)
El ejecutable se resuelve a un archivo regular y su SHA-256 queda fijado en el plan. Los argumentos son arrays literales, pasados sin shell, sin sobrescribir el entorno y sin instantánea de credenciales.
Las entradas de texto son de 256 KiB cada una como máximo y el conjunto completo de 1 MiB. Las instrucciones se anteponen a la entrada estándar con sus rutas relativas.
Una salida a cero es finalización genérica; un código distinto de cero listado en blockedExitCodes es bloqueado. Esa lista es una convención de tu envoltorio, nunca una política de aprobación.
El adaptador Codex construye -a never exec --json --color never --sandbox MODE --skip-git-repo-check --ignore-user-config -; model es opcional y solo añade --model MODEL. sandbox es read-only (por defecto) o workspace-write; no se acepta ningún otro flag, ninguna omisión de aprobación ni cadena de shell. Solo HOME, USERPROFILE, HOMEDRIVE, HOMEPATH y CODEX_HOME pueden heredarse más allá del entorno mínimo, y los recibos listan nombres de variables, no valores.
La finalización de Codex exige una salida a cero, una identidad thread.started y un evento turn.completed sin error terminal. Solo los códigos de error explícitos approval_required pasan a bloqueado; los demás errores del proveedor siguen siendo fallos.
La cancelación está ligada a la identidad devuelta. Solo el supervisor original puede señalizar al proceso hijo directo que creó; nada mata un PID guardado ni adopta un terminal antiguo. Un plazo, una salida excesiva o un supervisor perdido producen un resultado ambiguo y retienen la capacidad hasta la reconciliación.
Evidencia honesta: el contrato de flags se comprobó con Codex CLI 0.153.4. Una llamada autorizada el 2026-09-11 produjo un hilo y un evento terminal reales, pero el anfitrión rechazó como solo lectura la edición de archivo pedida; Nexus recogió el recibo, el verificador independiente falló y se rechazó la aceptación. Eso muestra el cableado y la contención del fallo en ese anfitrión; allí no se estableció que Codex escriba archivos con éxito.
Archivos por instantánea de ámbito; tamaño de un archivo instantaneado
10000; 16 MiB
Archivos de entrada JSON
Como máximo 1 MiB, archivos regulares
Sin demonio, sin planificador, sin bucle desatendido. Cada lanzamiento es explícito y retiene una plaza de capacidad; la capacidad no es un presupuesto de dinero.
Sin sandbox del sistema operativo. Los workers comparten el proyecto y el usuario del sistema con Nexus y pueden ignorar los scopes declarados; las sumas de comprobación detectan cambios accidentales, no son firmas. Protege el plan y el verificador, y usa un proyecto aislado o una política del anfitrión cuando importe.
Sin commit de Git, fusión ni despliegue. Aceptación significa «el espacio de trabajo actual superó las comprobaciones independientes», nada más.
Ninguna afirmación sobre la calidad de un modelo. Un recibo no es evidencia de que un modelo mejorara en nada.
Un tiempo de verificación agotado solo señaliza al hijo directo y registra un resultado ambiguo, porque no se demuestra la ausencia de descendientes o de efectos externos. Los programas de comprobación deben ser comandos acotados en primer plano.
Dejar que Nexus lleve un proyecto pequeño con puntos de control#
Úsalo al comienzo de un proyecto, con execution_mode en manual o en hybrid para conservar las aprobaciones.
En tu asistente de IA
autopilot. El proyecto: una API pequeña que permite a autónomos enviar presupuestos y convertirlos en facturas. Empieza por el intake de cualquier pack implicado. Detente en el punto de control del PRD y en el de la arquitectura y espera mi aprobación. Mantén cada historia pequeña, verifica cada una con sus criterios de aceptación antes de la siguiente y dime al final qué sigue incierto.
Lo que deberías obtener Primero se ejecuta Discovery (brief, PRD, especificación UX) y se detiene en el punto de control discovery con algo que puedes leer. Tras tu aprobación Forge escribe la arquitectura y Nexus vuelve a detenerse. Luego se implementan y prueban las historias una a una; con los puntos de control por defecto, cada historia terminada espera además tu aprobación (story), salvo que lo ajustes a notify_only, y la entrega final se detiene para tu revisión (delivery). Una comprobación fallida se repara dentro del límite de intentos en lugar de darla por buena. El informe final indica qué se verificó y qué sigue abierto.
Dividir el trabajo aprobado en tareas independientes#
Úsalo cuando ya existan las historias. El anfitrión debe admitir subagentes para un paralelismo real; si no, las tareas se ejecutan en secuencia.
En tu asistente de IA
parallel. Toma las historias aprobadas y divídelas en tareas que no toquen los mismos archivos. Para cada tarea da un ámbito de escritura exclusivo, los archivos que puede leer y una comprobación que yo pueda ejecutar. Registra el plan con bmad-plus nexus create, ejecuta juntas solo las tareas independientes y enséñame nexus inspect tras cada oleada. No aceptes una tarea antes de que nexus verify haya pasado.
Lo que deberías obtener Un nexus-plan.json con ámbitos disjuntos y comprobaciones independientes, una ejecución de Nexus listada por nexus inspect (cada tarea not started; verification=pending; acceptance=pending) y después una línea de estado por tarea según avanza el trabajo. Una tarea cuya comprobación falla muestra verification=failed y no se puede aceptar; un conflicto pausa la tarea en colisión en vez de sobrescribirla.