Dispatch reclama tareas automaticas y las lanza con el runtime configurado.
ops-center.service: API y UI.ops-dispatch-launcher.service: launcher de tareas.Validar:
dispatch_enabledUn health no es suficiente si solo confirma que hay heartbeat. Tambien debe detectar desalineaciones entre plantilla, workspace, agente, modelo, proveedor y worker.
Interpretacion de /api/dispatch/health:
ok=true significa que no hay blockers de los workers activos ni warnings de cola.blockers solo debe incluir agentes anunciados por workers frescos. Un agente activo en catalogo pero no anunciado por ningun worker no bloquea dispatch.opencode puede estar sano con mode=task_scoped aunque el OAuth local este caducado, siempre que haya credenciales OPS activas y un worker fresco con ALLOW_TASK_SCOPED_CREDENTIAL_AUTH=true.local_reason es diagnostico del host local; no es blocker si ready=true.OpenCode es el runtime preferente del workspace interno mientras este configurado y autenticado.
Hermes es valido si se configura explicitamente en tarea, plantilla, perfil o workspace. Hermes no debe usarse como fallback silencioso.
Los fallbacks deben:
Los modelos y proveedores cambian rapido. La UI puede sugerir modelos conocidos, pero dispatch debe admitir cualquier modelo que el runtime configurado soporte.
Orden recomendado para OpenCode:
workspace en OPS para el agente opencode y proveedor real (openai, minimax, openrouter, etc.).El launcher resuelve credenciales antes de seleccionar runtime. Si una tarea trae una credencial de workspace valida, puede ejecutar OpenCode aunque el OAuth local este caducado.
Variables soportadas por OpenCode en el worker o por credenciales inyectadas:
OPENAI_API_KEYANTHROPIC_API_KEYMINIMAX_API_KEYGOOGLE_API_KEYGEMINI_API_KEYOPENROUTER_API_KEYXAI_API_KEYOPENCODE_API_KEYALLOW_TASK_SCOPED_CREDENTIAL_AUTH=true permite que un worker anuncie un runtime cuando el binario existe y la autenticacion puede venir de la tarea. Si la tarea no tiene credencial ni existe auth global/local, el launcher falla de forma visible y deja blocker; no cambia a Hermes ni a otro proveedor.
No todas las tareas tienen que pasar por el worker del VPS. Si una tarea necesita credenciales locales, repos abiertos o supervision estrecha, puede reclamarse desde la aplicacion de escritorio.
Regla operativa:
Antes de lanzar o reclamar una tarea de IA, revisa que tenga bloque Instrucciones para agente en la descripcion o en contexto. Ese bloque debe incluir agente/modelo preferente, contexto operativo, criterio de terminado, donde registrar y que hacer si se bloquea.
El contrato estructurado vive en execution_contract:
tasks.execution_contract para overrides por tarea.task_templates.execution_contract para recurrentes.metadata.execution_contract en workspace/profile como fuente heredable.El dispatcher recibe el contrato efectivo como JSON dentro del prompt. El preflight solo bloquea dispatch cuando el contrato efectivo incluye preflight_required=true, require_preflight=true o required=true; esto evita romper tareas antiguas mientras permite tareas estrictas.
Cuando una tarea pertenece a un proyecto ejecutable, el agente que la cree o la desglose debe rellenar execution_contract con el contexto minimo para que otro agente pueda continuar sin preguntar lo basico. No se usa una columna separada tipo context_json: la fuente oficial es execution_contract, porque ya se hereda desde workspace, perfil, plantilla y tarea.
Copia este bloque cuando pidas a un agente que cree o divida tareas para ejecucion autonoma:
Cuando crees o dividas tareas OPS para ejecucion autonoma, rellena `execution_contract` en cada tarea que vaya a ejecutar un agente.
No uses `context_json`. La fuente oficial es `execution_contract`.
Estructura base:
{
"preflight_required": true,
"preferred_agent_slug": "opencode",
"preferred_model": "openai/gpt-5.4",
"project_path": "/ruta/absoluta/al/proyecto",
"working_folder": "src",
"depends_on": [ID_TAREA_PREVIA],
"deliverables": [
"ruta/del/archivo-a-crear-o-modificar"
],
"verify_commands": [
"comando seguro de verificacion"
],
"acceptance_criteria": [
"Condicion observable para considerar la tarea terminada"
],
"blocked_fallback": "Si falta ruta, credencial, repo o decision funcional, dejar la tarea en waiting con una pregunta concreta."
}
Reglas:
1. Si una tarea B necesita que A termine antes, B debe incluir `"depends_on": [A]`.
2. No confies en score, orden visual o posicion en cola para definir dependencias.
3. Si la tarea toca codigo, incluye `project_path` y, si aplica, `working_folder`.
4. `working_folder` puede ser relativo a `project_path` o una ruta absoluta.
5. Incluye `deliverables` con archivos, rutas o artefactos esperados.
6. Incluye `verify_commands` solo con comandos seguros de verificacion.
7. No pongas comandos destructivos en `verify_commands`.
8. Si falta informacion real, no inventes rutas ni dependencias: deja la tarea en `waiting` y pregunta.
9. Mantén `execution_contract` corto y operativo. La explicacion larga va en descripcion o contexto.
10. Cada tarea debe poder entenderse aislada: titulo, descripcion, proyecto, contrato, criterio de aceptacion y fallback.
Estructura recomendada:
{
"preflight_required": true,
"preferred_agent_slug": "opencode",
"preferred_model": "openai/gpt-5.4",
"project_path": "/Volumes/Disco SSD/Desarrollo/clientes/cliente/proyecto",
"working_folder": "src",
"depends_on": [1011],
"deliverables": [
"src/Models/Expediente.php",
"src/Controllers/ExpedienteController.php"
],
"verify_commands": [
"php -l src/Models/Expediente.php",
"php -l src/Controllers/ExpedienteController.php"
],
"acceptance_criteria": [
"El modelo existe y no rompe carga/autoload.",
"El controlador compila sin errores de sintaxis.",
"La tarea deja evidencia de comandos ejecutados."
],
"blocked_fallback": "Si falta repo, credencial o decision funcional, dejar la tarea en waiting con pregunta concreta."
}
Campos que el dispatcher/launcher ya entiende:
depends_on: lista de IDs de tareas que deben estar done o archived antes de ejecutar. Si alguna sigue abierta, el dispatcher no selecciona ni reclama la tarea.project_path: ruta absoluta del proyecto en el worker que ejecutara la tarea.working_folder: subcarpeta relativa dentro de project_path, o ruta absoluta si aplica. El launcher la usa como cwd real.deliverables: archivos, rutas o artefactos que la tarea debe producir o modificar.verify_commands: comandos concretos de verificacion que el agente debe ejecutar cuando proceda.runtime_timeout_ms o runtime_timeout_minutes: limite de ejecucion para tareas largas. Si expira, el launcher deja la tarea en waiting con timed_out=true, rutas de logs parciales y una pista de reanudacion.resume_hint o timeout_resume_hint: instruccion breve para reintentar, dividir o revisar salida parcial tras timeout.Campos de calidad recomendados:
acceptance_criteria: condiciones observables para considerar la tarea terminada.required_outputs: evidencias obligatorias que deben aparecer en la respuesta final.completion_checklist: checklist que el agente debe completar en contexto/comentario.human_gate_policy: required si hay datos sensibles, despliegue, borrado, pagos, usuarios o credenciales.blocked_fallback: que debe hacer el agente cuando no pueda continuar.Reglas para agentes que creen o dividan tareas:
depends_on en las posteriores. No confiar solo en score o posicion en cola.project_path y, si procede, working_folder.waiting o pedir aclaracion.verify_commands; dejarlo como paso con Human Gate.execution_contract corto y operativo. La explicacion larga va en descripcion, plan o contexto.Estados visibles:
inboxnextdoingwaitingreviewdonearchivedEstados tecnicos:
queueddispatchingSolo dispatch encola una tarea. Mover a doing no ejecuta automatismo.
El scheduler crea instancias desde task_templates.
human/manual crea en inbox.interactive/auto crea en queued.done ni archived, no duplica.execution_contract.allow_overlapping_instances=true, solo evita duplicados de la misma ventana planificada y permite que el siguiente ciclo nazca aunque quede trabajo anterior en review.Salvo que la plantilla permita solape, si una instancia recurrente queda en review, waiting, next o doing, puede bloquear la siguiente ocurrencia. Hay que cerrarla, archivarla o relanzarla de forma consciente.
El scheduler abre o reabre alertas de sistema cuando una recurrente falla por RRULE invalida, error de scheduler o instancia activa bloqueante. Si el fallo requiere correccion de plantilla, crea o reutiliza una tarea scheduler-watchdog con tag recurring-watchdog.
Cuando una tarea automatizable esta bloqueada por falta de input:
Respuesta requerida;Responder y ejecutar para continuar automatico;Responder y desbloquear si solo se quiere quitar el bloqueo;Dispatch now para lanzar manualmente tareas automatizables en next.Solo guardar nota conserva contexto, pero no desbloquea ni ejecuta. Comentar en una tarea no debe interpretarse mentalmente como ejecutar. Reencolar significa llamar a dispatch y pasar a queued.