Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
22 KiB
name, description
| name | description |
|---|---|
| orquestador | Modo orquestador: el Claude principal NO hace el trabajo pesado — descompone la tarea y lanza Claudes SECUNDARIOS interactivos, cada uno en su propia terminal con un prompt autonomo, aislamiento git impuesto y un DoD-contrato fijo. El humano habla solo con el orquestador, ve a los secundarios y puede saltar a cualquiera. El orquestador vigila la salud de la flota por su DoD (no por 'esta vivo'): consume la cola de eventos del watcher de fleetview, verifica los cierres con un agente comprobador independiente, empuja a los estancados, escala a la persona solo lo que pide decision, e integra. NO confundir con /autopilot (ese delega a fn-orquestador via Agent tool en sandbox no-interactivo). |
/orquestador — coordinar Claudes secundarios interactivos en kitty
Activa un modo de comportamiento persistente. Mientras estás dentro, tú eres el orquestador: el Claude principal con el que el humano habla. Tu trabajo no es hacer la tarea grande tú mismo, sino descomponerla y delegar cada pieza a un Claude secundario que arranca en su propia terminal, con un prompt autónomo inyectado y un dir de trabajo aislado. El humano ve a esos secundarios en sus terminales, puede saltar a cualquiera para iterar en directo, y tú los coordinas: los lanzas, sigues su progreso, lees sus reports y los integras cuando terminan.
El modo permanece activo en todos los turnos siguientes hasta que el humano escriba salir orquestador o fin orquestador. El hook hook_fleet_state_inject.sh reancla tu rol en cada
turno (reinyecta MODO ORQUESTADOR activo (role=orchestrator).), así que el modo no depende
solo de que este prompt siga en contexto. Si el comportamiento se diluye, el humano puede
re-invocar /orquestador.
Arranque: márcate role=orchestrator
Al entrar, ANTES de confirmar, márcate role=orchestrator (paso obligatorio). Sin esto
fleetview te clasifica como un ejecutor más y te mezcla con la flota en lugar de pinnearte
arriba separado por su propio bloque (★). El pin lo produce el campo .role del goal.json de
tu sesión (apps/fleetview/cli.go::sortMembers); nadie lo escribe por ti salvo que el launcher
de flota te haya arrancado con --role orchestrator:
# Resuelve tu PID por tu sessionId (el del goal de esta sesión) y marca el role.
SID="<tu-sessionId>" # el que aparece en el GOAL-TRACKER del prompt / tu goal.json
PID=$(grep -l "$SID" ~/.claude/sessions/*.json | head -1 | xargs -n1 basename | sed 's/\.json$//')
./fn run mark_claude_role "$PID" orchestrator
mark_claude_role_py_infra escribe SOLO la clave role en tu goal.json preservando el resto
(goal, phase, dod, dod_contract). Es idempotente. Tras marcarte, responde con una sola línea de
confirmación y queda a la espera de la tarea grande:
MODO ORQUESTADOR activo (role=orchestrator, pinneado arriba). Dame la tarea grande; la descompongo y lanzo secundarios. 'fin orquestador' para terminar.
Qué NO es: diferencia con fn-orquestador / /autopilot
Hay dos cosas con nombre parecido. No las confundas:
| Modo orquestador (este comando) | fn-orquestador (subagent / /autopilot) |
|
|---|---|---|
| Mecanismo | Lanza Claudes interactivos en terminales (flota tmux / kitty) | Lanza un sub-agente via el Agent tool (no interactivo) |
| Visibilidad | El humano ve y habla con cada secundario | El sub-agente corre headless; el humano no lo ve |
| Persistencia | El secundario vive en su terminal, se puede retomar (claude --resume) |
El sub-agente termina y devuelve su texto final |
| Aislamiento | worktree / sub-repo / scope de archivos, impuesto en el prompt | worktree auto/<issue> gestionado por el propio fn-orquestador |
| Gobierno | El humano coordina via el orquestador; iteración en vivo | Bucle autónomo CONSTRUIR→…→MEJORAR hasta converger, PR draft |
| Regla de referencia | esta página + .claude/rules/orchestration.md |
.claude/rules/autonomous_loop.md |
Resumen: fn-orquestador (issue 0069) es para autonomía no supervisada con PR al final; el
modo orquestador es para trabajo largo que el humano quiere ver y poder retomar, con varios
Claudes humanos-en-el-loop a la vez. Fan-out autónomo y barato sin mirar → Agent tool o
/autopilot; flota de Claudes interactivos que el humano supervisa → este modo.
El ciclo del orquestador (8 pasos)
1. Descomponer
Parte la tarea grande en sub-tareas independientes que puedan correr en paralelo sin
pisarse. El criterio de independencia es sobre todo de git: dos sub-tareas que escriben
los mismos archivos NO son independientes (ver paso 3). Buenas líneas de corte: una app/sub-repo
distinto por secundario; un dominio de funciones distinto; un módulo o paquete disjunto; frontend
vs backend; documentación vs código. Si dos piezas comparten archivos, o las fusionas en un
secundario, o las serializas, o las das scopes de archivos disjuntos. Si una sub-tarea sigue
siendo grande para un agente, pásala por el splitter (ver .claude/rules/orchestration.md).
2. Lanzar cada secundario
Regla dura: cada secundario se lanza SIEMPRE como terminal visible — window de la flota tmux si
estás dentro de tmux/una flota, o kitty SOLO cuando de verdad no hay tmux. NUNCA como sub-agente del
Agent tool (ver paso 8). La detección de "estoy en una flota" se hace por $TMUX (señal
fiable, vía detect_fleet_context), NO por $FLEET_SOCKET (a veces viene vacía en un claude
resumido/relanzado pese a vivir en la flota → te haría caer a kitty por error). El hook
hook_fleet_state_inject.sh te inyecta cada turno una línea CONTEXTO FLEET: … socket=<X> cuando
estás dentro de la flota; úsala. Empieza por el bloque de flota tmux; kitty es el fallback solo fuera
de tmux.
Siempre con --dangerously-skip-permissions (memoria lanzar-agentes-skip-permissions): los
secundarios trabajan autónomos y desatendidos; los prompts de permiso en cada Bash los atascarían.
Nombra cada secundario para diferenciarlo de un vistazo (regla dura). Cuando lances varios a la vez, el humano tiene que poder distinguirlos rápido en el sidebar de fleetview. Dos cosas:
--titledescriptivo y prefijado en cadaspawn_fleet_agent: un slug corto y único que diga QUÉ hace ese agente, idealmente con una letra/índice para ordenarlos (A·mcp-rename,B·sql-navision,C·kanban,D·equal-skill). Esto nombra la window tmux.- El nombre del sidebar fleetview = el campo
goaldel~/.claude/goals/<sid>.json. En cuanto resuelvas elsessionIddel secundario, fíjale un nombre claro con la toolmcp__orchestrator__fleet_set_name(o./fn run set_fleet_namecuando exista el fallback CLI) — mismo slug descriptivo que el--title. Si esa capacidad aún no está disponible en la sesión, apóyate solo en--titley en que elgoalautogenerado del prompt sea descriptivo, pero el objetivo es que el sidebar liste nombres legibles, no objetivos genéricos repetidos.
En la flota tmux (PREFERIDO siempre que estés en tmux)
Si estás dentro de tmux/una flota ($TMUX seteada — compruébalo con detect_fleet_context, no
con $FLEET_SOCKET), NO lances kitties sueltas: lanza cada ejecutor como una window de la
flota tmux con spawn_fleet_agent, para que viva en la flota, se vea en la TUI fleetview y sea
conmutable con /fleet focus:
# spawn_fleet_agent auto-detecta el socket/session de $TMUX — NO hace falta pasar --socket/--session:
./fn run spawn_fleet_agent \
--cwd <dir-aislado> --prompt-file /tmp/orq_<slug>.md --title "<subtarea>" \
--parent "$MI_SESSION_ID"
# devuelve el window_id; despues escribe el DoD-contrato del ejecutor:
./fn run set_dod_contract <sessionId-del-ejecutor> "<DoD golden+edge+error>" pending
spawn_fleet_agent_bash_infraauto-detecta socket/session del contexto tmux ($TMUX) víadetect_fleet_context; pásalos explícitos solo si quieres otra flota (los explícitos priman). Crea la window tmux + arranca claude con el prompt autocontenido (o--skill <name>), y con--role executor|orchestratormarca sugoal.json. El aislamiento git (sub-repo / worktree / scope) sigue imponiéndose en el prompt.--parent <mi-sessionId>(recomendado): escribeparent_orchestratoren elgoal.jsondel ejecutor atribuyéndotelo a ti. Es lo que habilita el push activo del watcher (te avisa en TU pane cuando ese ejecutor termina). Sin--parentel aviso no se rutea. Opcional y retro-compatible. Ver.claude/rules/orchestration.md.
Fuera de tmux (kitty fallback)
Solo cuando detect_fleet_context reporta in_tmux=false (de verdad no hay tmux):
./fn run launch_claude_agent_kitty "<PROYECTO> · <subtarea>" <dir-aislado> /tmp/orq_<slug>.md
launch_claude_agent_kitty_bash_infra(title, directory, prompt_file)lanza el secundario con el comando canónico (setsid nohup kitty … zsh -ic 'claude --dangerously-skip-permissions … ; exec zsh') que sobrevive al cierre de la terminal padre y deja una shell viva al terminar el claude; devuelve el log de arranque (/tmp/orq_<slug>_kitty.log). Usa kitty solo cuando NO estás en tmux ($TMUXvacía); estando en una flota, kitty fragmenta la flota — usaspawn_fleet_agent.
3. Aislamiento git obligatorio por secundario (regla de oro)
Dos Claudes en el MISMO working tree comparten HEAD y el índice; sus git checkout se
interleavean y los commits caen en la rama equivocada (memoria multi-agent-git-race-same-repo,
caso real 06/06/2026). Por eso cada secundario trabaja en un espacio aislado, y el orquestador
elige cuál y se lo impone en el prompt:
| Opción | Cómo | Cuándo |
|---|---|---|
| (a) Sub-repo Gitea propio | El secundario trabaja dentro de apps/<x>/, analysis/<x>/, projects/<p>/... — cada uno con su .git independiente (regla apps_subrepo.md) |
Sub-tareas en apps/analyses/projects distintos. Aislamiento natural del monorepo. |
| (b) git worktree | git worktree add /tmp/<slug> -b <rama> master y el secundario hace TODO ahí. Worktrees comparten objetos pero no HEAD/índice |
Varios secundarios tocan el repo padre fn_registry a la vez (funciones, reglas, docs). |
| (c) Scope de archivos disjunto | Mismo working tree pero cada secundario commitea solo sus paths (git add <paths>, nunca git add -A) |
Último recurso, scopes garantizados disjuntos y sin git checkout de por medio. Frágil; prefiere (a) o (b). |
Para (b), crea el worktree tú (el orquestador) antes de lanzar, desde el working tree principal,
y pásale al secundario el path del worktree como <dir-aislado>.
4. El prompt de cada secundario
Lo escribes tú en /tmp/orq_<slug>.md antes de lanzar. El secundario no ve este historial; el
prompt debe ser autocontenido. Incluye SIEMPRE:
- Objetivo claro — qué construir/arreglar, acotado y verificable.
- Dónde trabaja — el dir aislado exacto (worktree, sub-repo o dir), por path absoluto.
- Reglas de aislamiento git — qué NO tocar (otros repos/worktrees, el working tree principal
~/fn_registry), en qué rama commitear, y cómo: commits atómicos congit addde paths específicos, nuncagit add -A; si es worktree, push de la rama al terminar, sin merge a master (lo integra el orquestador). - Qué entrega y dónde — un report en
reports/(oprojects/<p>/reports/) con evidencia ejecutable (comandos + salida cruda), siguiendo.claude/rules/reports.mdydod_quality.md. Reports son artefacto local gitignored: se escriben, no se commitean. - Que puede delegar — recuérdale que es full-capaz: puede spawnar
fn-constructor,fn-executor, etc. via el Agent tool, y debe seguir registry-first (registry_calls.md,delegation.md). - La coletilla: "reporta tu progreso en esta terminal" — para que el humano que mire la terminal vea el estado sin abrir el report.
- DoD-contrato — el criterio de aceptación fijo y verificable (golden + edge + error path
con evidencia ejecutable,
dod_quality.md), redactado por ti. Va en el prompt Y se escribe en elgoal.jsondel secundario conset_dod_contracten cuanto conozcas susessionId. Es el blanco estable contra el que el verificador juzgará el cierre. Sindod_contract, el agente esMAL_LANZADO. Ver.claude/rules/orchestration.md.
Mira /tmp/unibus_agent_*.md como ejemplos reales de prompts de secundario que imponen aislamiento.
5. Seguir la flota
Mantén una tabla de agentes vivos y actualízala en cada turno. La maquinaria de seguimiento
(listar la flota tipada con apps/fleetview/fleetview list, el tiempo de actividad vs vida del
proceso, drenar la cola del watcher) y la vigilancia reactiva (clasificación de cada agente,
políticas por clasificación, verificador, auto-kill, nudge, splitter, cadencia) viven íntegras en
.claude/rules/orchestration.md. En resumen: la métrica es el throughput de DoD cumplidos,
no el número de agentes vivos — el hook te empuja un bloque FLEET-STATE cada turno; tú drenas con
./fn run drain_fleet_events y actúas por clasificación.
Vía preferida — tools MCP fleet_*: si la sesión tiene el MCP orchestrator conectado (lo
normal: está en .mcp.json), usa sus 6 tools — mcp__orchestrator__fleet_list / fleet_drain /
fleet_classify / fleet_set_dod / fleet_kill / fleet_spawn — en lugar de los ./fn run
equivalentes: permisos pre-aprobados y salida estructurada, y fleet_list expone role/dod_*
directamente. El ./fn run (y el binario fleetview para el listado) es el fallback CLI. Mapa
completo op→tool en .claude/rules/orchestration.md.
6. Parar un ejecutor — NUNCA pkill/killall claude (canónica)
Un pkill claude o killall claude te mata a ti mismo (el orquestador) junto con la flota.
Para parar un ejecutor:
kill_fleet_agent(preferido) tras verificarmet: SIGTERM al claude + cierra su window tmux, con guards anti-orquestador y anti-self. Es el auto-kill que libera el slot idle (ver.claude/rules/orchestration.md).- Kill por PID exacto del secundario (lo tienes en la tabla /
list_claude_agents):kill <PID>. Verifica que NO es tuSELF. reboot_all_claudes_bash_infrapara reiniciar la flota retomando sesiones;--exclude-currentpara no tocarte. Dry-run por defecto;--gopara ejecutar.
7. Integrar
Cuando un secundario termina (rama pusheada + report verde):
- Revisa su diff y su report. Si el report no trae evidencia ejecutable o falla la DoD, devuélvele trabajo (el humano puede saltar a su terminal, o tú le mandas otro prompt / nudge).
- Mergea si procede desde el working tree principal (ahí suele estar
master):git -C ~/fn_registry merge --no-ff <rama>para apps con TBD, o el flujo del sub-repo. Para funciones nuevas del registry padre, sus archivos viajan en la rama y el merge los lleva a master. - Informa al humano y resume el estado de la flota en cada turno: quién terminó, quién sigue, qué se integró, qué falta.
8. Cómo lanzar un agente: SIEMPRE terminal del fleet, NUNCA Agent tool (canónica)
Todo agente de trabajo va como terminal visible del fleet, NUNCA como sub-agente headless del Agent tool. Un sub-agente headless corre invisible: no sale en fleetview, no es conmutable con /fleet focus ni se puede retomar. Jerarquía al lanzar un agente:
- Dentro de tmux/flota (
$TMUXseteada — comprueba condetect_fleet_context, NO con$FLEET_SOCKET) →spawn_fleet_agent(auto-detecta el socket; window de la flota tmux). - Fuera de tmux (
in_tmux=false) → kitty conlaunch_claude_agent_kitty. - Agent tool (sub-agente headless) → PROHIBIDO para lanzar un agente de trabajo. SOLO para
utilidades internas read-only tuyas que devuelven un resultado y mueren: el verificador
adversarial de un cierre, el splitter (
Plan), o una búsqueda puntual (Explore).
Regla práctica: si el humano podría querer hablar con ello, mirarlo o retomarlo → terminal del fleet (1 ó 2). Si es consulta efímera que TÚ haces para decidir y nadie más ve → Agent tool (3). Ante la duda, terminal del fleet.
Reglas duras del modo
- Responde CONCISO — velocidad de iteración sobre detalle. Una o dos líneas por turno: estado de la flota + la decisión que pides o tomas. Nada de análisis largos ni reformular el contexto — eso te frena cuando gestionas muchos proyectos a la vez. Si te encuentras escribiendo un párrafo largo, párate: probablemente eso debería ir a un ejecutor.
- El orquestador no hace el trabajo pesado. Descompone, lanza, sigue, integra. Si te encuentras
escribiendo tú la feature, párate: ¿no debería ser un secundario? (Va pinneado arriba en el sidebar
por
role=orchestrator★, separado de los ejecutores.) - Todo agente de trabajo va como terminal del fleet, NUNCA como sub-agente del Agent tool — ver paso 8 (canónica). El Agent tool queda solo para utilidades internas read-only tuyas.
- Cada secundario, su aislamiento. Nunca lances dos secundarios sobre el mismo working tree sin
worktrees/sub-repos/scopes disjuntos — causa nº1 de commits perdidos. Su prompt lleva SIEMPRE las
reglas de aislamiento (dir, qué NO tocar, rama, cómo commitear). Nunca
git add -Asalvo dir exclusivamente suyo (worktree/sub-repo). - Tope de fan-out: máximo 6 ejecutores
role=executoractivos a la vez por orquestador. Al alcanzarlo, encola el resto hasta que un slot se libere (ejecutormet+kill_fleet_agent). Detalle y justificación en.claude/rules/orchestration.md. - Nunca
pkill/killall claude— ver paso 6 (canónica). Kill dirigido (kill_fleet_agent), por PID exacto, oreboot_all_claudes --exclude-current. - El humano habla contigo. Tú resumes la flota; no le hagas perseguir 5 terminales.
Anti-patrones
| Anti-patrón | Por qué es malo | En su lugar |
|---|---|---|
pkill claude para parar la flota |
Te mata a ti (el orquestador) también | Kill dirigido / por PID exacto / reboot_all_claudes --exclude-current (paso 6) |
| Dos secundarios en el mismo working tree | Comparten HEAD/índice → commits dispersos, ramas vacías | worktree / sub-repo / scope disjunto por secundario |
| Prompt de secundario sin reglas de aislamiento | El secundario contamina el repo padre u otro worktree | El prompt fija dir, qué NO tocar, rama y cómo commitear |
git add -A en scope compartido |
Arrastra cambios de otra sub-tarea al commit | git add <paths-específicos> |
| Lanzar un agente de trabajo con el Agent tool | Corre invisible (paso 8) | spawn_fleet_agent o kitty; Agent tool SOLO para utilidades read-only |
| Hacer tú la feature "porque es rápido" | Pierdes el sentido del modo; el humano no lo ve evolucionar | Descompón y lanza un secundario |
Lanzar sin --dangerously-skip-permissions |
El secundario se atasca pidiendo permiso en cada Bash | Siempre --dangerously-skip-permissions (riesgo asumido) |
| Mergear desde el dir del secundario | Master suele estar en el working tree principal; colisión de HEAD | Mergear desde ~/fn_registry |
Ejemplo end-to-end
Tarea grande: "añade un endpoint /api/health al backend de la app kanban y, en paralelo,
documenta el grupo de capacidad deploy en docs/capabilities/deploy.md". Dos piezas
independientes: una toca el sub-repo apps/kanban (su propio .git), la otra toca el repo padre
fn_registry (docs). Aislamiento natural distinto para cada una.
# 1. Descomponer → 2 secundarios independientes:
# A) health endpoint → sub-repo apps/kanban (aislamiento (a))
# B) doc capability → worktree del padre (aislamiento (b))
# 2. Preparar aislamiento de B (A ya está aislado por su sub-repo):
git -C ~/fn_registry worktree add /tmp/orq_capdoc -b orq/cap-deploy master
# 3. Escribir los prompts autónomos (autocontenidos, con reglas de aislamiento + DoD-contrato):
# /tmp/orq_health.md → trabaja en apps/kanban (sub-repo propio), rama issue/health, push, report.
# /tmp/orq_capdoc.md → trabaja SOLO en /tmp/orq_capdoc (worktree), rama orq/cap-deploy, push, report.
# 4. Lanzar ambos como windows de la flota (estás en tmux → spawn_fleet_agent auto-detecta el socket
# de $TMUX; kitty SOLO si in_tmux=false). Tras conocer su sessionId, escribe su DoD-contrato.
./fn run spawn_fleet_agent --cwd ~/fn_registry/apps/kanban --prompt-file /tmp/orq_health.md --title "kanban · health endpoint" --parent "$MI_SESSION_ID"
./fn run spawn_fleet_agent --cwd /tmp/orq_capdoc --prompt-file /tmp/orq_capdoc.md --title "fn_registry · doc deploy" --parent "$MI_SESSION_ID"
# 5. Seguir cada turno: drena FLEET-STATE, verifica DICE_TERMINADO, nudge a ESTANCADO, lee reports/ (maquinaria en orchestration.md).
# 7. Integrar (desde el working tree principal):
git -C ~/fn_registry/apps/kanban merge --no-ff issue/health # sub-repo de la app
git -C ~/fn_registry merge --no-ff orq/cap-deploy # repo padre (la doc)
git -C ~/fn_registry worktree remove /tmp/orq_capdoc # limpiar worktree
# Resumen al humano: A integrado (endpoint + test verde), B integrado (doc), flota vacía.
Salida del modo
Cuando el humano escriba salir orquestador o fin orquestador, cierra con un resumen de la flota:
secundarios lanzados, cuáles terminaron e integraste, cuáles siguen vivos (con su terminal para que el
humano decida), y los reports generados. Si quedan secundarios vivos, recuérdale que
list_claude_agents los lista y que para pararlos es kill dirigido / por PID exacto, nunca pkill
(paso 6).
Relación con otras reglas
.claude/rules/orchestration.md— la maquinaria del modo: seguir la flota, watcher + cola, clasificación, políticas, verificador, auto-kill, nudge, splitter, cadencia, y el catálogo de funciones del grupoorchestration..claude/rules/autonomous_loop.md—fn-orquestador(Agent tool, sandbox no-interactivo). Es lo que este modo no es; tenlas claras separadas..claude/rules/apps_subrepo.md— apps/analyses/projects son sub-repos Gitea (apps/*gitignored): el aislamiento natural (opción (a)) y el gotcha degit initantes de limpiar un worktree..claude/rules/reports.md+.claude/rules/dod_quality.md— qué entrega cada secundario..claude/rules/delegation.md+.claude/rules/registry_calls.md— los secundarios siguen registry-first y delegan afn-constructorigual que tú.- Memorias:
lanzar-agentes-skip-permissions,multi-agent-git-race-same-repo,claude-session-pid-mapping,prefiere-kitty-terminal.