El doc hablaba de "tope de fan-out para no explotar la flota" sin numero. Se fija un maximo DURO: 6 ejecutores role=executor activos simultaneos por orquestador. Al alcanzarlo, el orquestador no lanza mas: encola las sub-tareas restantes hasta que un slot se libere (ejecutor verificado met + kill_fleet_agent). Justificacion: ya hubo el caso de 30 agentes que no cerraban nada y, al competir todos por el mismo rate-limit compartido, hubo que desactivar goal_refine. Mas ejecutores no es mas throughput; el cuello de botella es el rate-limit compartido y los DoD que nadie cierra. Escrito en el splitter + regla dura de orchestration.md (detalle + justificacion) y en las reglas duras del command (numero + encolado, puntero al detalle). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
20 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
hay perfil fleet ($FLEET_SOCKET, lo normal), o kitty fuera de él. NUNCA como sub-agente del Agent
tool (ver paso 8). Empieza por el bloque de flota tmux cuando estás en un perfil fleet; kitty es
el fallback para secundarios que deban vivir fuera de la flota.
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.
En la flota tmux (PREFERIDO en perfil fleet)
Si estás dentro de un perfil FleetView ($FLEET_SOCKET seteada), 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:
./fn run spawn_fleet_agent --socket "$FLEET_SOCKET" --session "$FLEET_SESSION" \
--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_infracrea 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 la flota (kitty fallback)
./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 fuera de un perfil fleet.
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.
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:
- En perfil fleet (
$FLEET_SOCKET, lo normal) →spawn_fleet_agent(window de la flota tmux). - Fuera de un perfil fleet → kitty con
launch_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 (window de la flota si hay $FLEET_SOCKET; aquí kitty fallback). Tras conocer su
# sessionId, escribe su DoD-contrato con set_dod_contract.
./fn run launch_claude_agent_kitty "kanban · health endpoint" ~/fn_registry/apps/kanban /tmp/orq_health.md
./fn run launch_claude_agent_kitty "fn_registry · doc deploy" /tmp/orq_capdoc /tmp/orq_capdoc.md
# 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.