From 9a9b8764003283e044f0df7ebfe712f026b2cf4f Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sun, 7 Jun 2026 19:32:47 +0200 Subject: [PATCH] =?UTF-8?q?feat(commands):=20/orquestador=20=E2=80=94=20mo?= =?UTF-8?q?do=20de=20coordinacion=20de=20Claudes=20secundarios=20en=20kitt?= =?UTF-8?q?y?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nuevo slash command que codifica el modo orquestador: el Claude principal descompone una tarea grande y lanza Claudes secundarios interactivos, cada uno en su propia terminal kitty con un prompt autonomo inyectado y aislamiento git impuesto (worktree / sub-repo / scope disjunto). El humano habla solo con el orquestador, ve a los secundarios en sus terminales y puede saltar a cualquiera. El cuerpo cubre los 8 pasos del ciclo (descomponer, lanzar, aislar, prompt, seguir, no pkill, integrar, kitty vs Agent tool), la plantilla del comando de lanzamiento, la tabla de seguimiento de la flota, las reglas de aislamiento, los anti-patrones y un ejemplo end-to-end. Referencia las funciones del registry launch_claude_agent_kitty_bash_infra, list_claude_agents_bash_infra y reboot_all_claudes_bash_infra (grupo orchestration). Deja explicita la diferencia con fn-orquestador / autopilot (Agent tool en sandbox no-interactivo). Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/commands/orquestador.md | 279 ++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 .claude/commands/orquestador.md diff --git a/.claude/commands/orquestador.md b/.claude/commands/orquestador.md new file mode 100644 index 00000000..a8d392c1 --- /dev/null +++ b/.claude/commands/orquestador.md @@ -0,0 +1,279 @@ +--- +name: orquestador +description: "Modo orquestador: el Claude principal NO hace el trabajo pesado — descompone la tarea y lanza Claudes SECUNDARIOS interactivos, cada uno en su propia terminal kitty con un prompt autonomo y aislamiento git impuesto. El humano habla solo con el orquestador, ve a los secundarios en sus kitties y puede saltar a cualquiera. El orquestador sigue la flota, lee sus reports 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 kitty, 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`. No hay hook: el modo se sostiene por estas instrucciones +mientras estén en contexto. Si el comportamiento se diluye tras muchos turnos, el humano puede +re-invocar `/orquestador` para reanclarlo. + +Al entrar, responde con una sola línea de confirmación y queda a la espera de la tarea grande: + +``` +MODO ORQUESTADOR activo. 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 **kitty** | Lanza un sub-agente via el **Agent tool** (no interactivo) | +| Visibilidad | El humano **ve y habla** con cada secundario en su kitty | 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/` gestionado por el propio `fn-orquestador` | +| Gobierno | El humano coordina via el orquestador; iteración en vivo | Bucle autónomo CONSTRUIR→EJECUTAR→...→MEJORAR hasta converger, PR draft | +| Regla de referencia | esta página | `.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. Si el humano quiere fan-out autónomo y barato sin mirar, +usa el Agent tool o `/autopilot`; si quiere una flota de Claudes interactivos que él supervisa, +usa 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; el +frontend vs el backend; documentación vs código. Si dos piezas comparten archivos, o las fusionas +en un secundario, o las serializas (una después de otra), o las das scopes de archivos disjuntos. + +### 2. Lanzar cada secundario + +Comando canónico de lanzamiento (memoria `lanzar-agentes-skip-permissions`), **siempre** con +`--dangerously-skip-permissions` porque los secundarios trabajan autónomos y desatendidos y los +prompts de permiso en cada Bash los atascarían: + +```bash +setsid nohup kitty --title " · " --directory \ + zsh -ic 'claude --dangerously-skip-permissions "$(cat /tmp/orq_.md)"; exec zsh' \ + >/tmp/orq__kitty.log 2>&1 & disown +``` + +`setsid nohup ... & disown` hace que la kitty sobreviva al cierre de la terminal padre. El +`zsh -ic '...; exec zsh'` deja una shell interactiva viva cuando el claude termina, para que el +humano siga en esa terminal. El log de `/tmp/orq__kitty.log` es donde se ve el arranque. + +**Prefiere la función del registry** en vez de teclear el one-liner a mano (registry-first, +queda en telemetría): + +```bash +./fn run launch_claude_agent_kitty " · " /tmp/orq_.md +``` + +- `launch_claude_agent_kitty_bash_infra(title, directory, prompt_file)` — lanza el secundario con + el comando canónico exacto y devuelve el log donde se ve el arranque. Valida que el dir y el + prompt_file existan y que kitty esté instalado. + +### 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 del 06/06/2026: los commits de un agente acabaron en la rama del otro y su propia rama +quedó vacía). Por eso **cada secundario trabaja en un espacio aislado**, y el orquestador elige +cuál y se lo **impone** en el prompt del secundario: + +| Opción | Cómo | Cuándo | +|---|---|---| +| **(a) Sub-repo Gitea propio** | El secundario trabaja dentro de `apps//`, `analysis//`, `projects/

/...` — cada uno tiene su `.git` independiente (regla `apps_subrepo.md`) | Cuando las sub-tareas caen en apps/analyses/projects distintos. Es el aislamiento natural del monorepo. | +| **(b) git worktree** | `git worktree add /tmp/ -b master` y el secundario hace TODO ahí. Worktrees comparten objetos pero **no** HEAD/índice | Cuando 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 `, **nunca** `git add -A` | Último recurso, solo si los scopes están garantizados disjuntos y no hay `git checkout` de rama 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 ``. + +### 4. El prompt de cada secundario + +Lo escribes tú en `/tmp/orq_.md` antes de lanzar. El secundario **no ve este historial**; +el prompt debe ser **autocontenido**. Incluye SIEMPRE: + +1. **Objetivo claro** — qué construir/arreglar, acotado y verificable. +2. **Dónde trabaja** — el dir aislado exacto (worktree, sub-repo o dir), por path absoluto. +3. **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 con `git add` + de paths específicos, nunca `git add -A`; si es worktree, push de la rama al terminar, sin + merge a master (lo integra el orquestador). +4. **Qué entrega y dónde** — un **report** en `reports/` (o `projects/

/reports/`) con + evidencia ejecutable (comandos + salida cruda), siguiendo `.claude/rules/reports.md` y + `.claude/rules/dod_quality.md`. Reports son artefacto local gitignored: se escriben, no se + commitean. +5. **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`). +6. **La coletilla**: *"reporta tu progreso en esta terminal"* — para que el humano que mire la + kitty vea el estado sin abrir el report. + +Mira `/tmp/unibus_agent_*.md` como ejemplos reales de prompts de secundario que imponen +aislamiento (cada uno fija sub-repo, rama, flags de build, DoD y dónde reportar). + +### 5. Seguir la flota + +Mantén una **tabla de agentes vivos** y actualízala en cada turno. La fuente de verdad del +mapeo PID→sessionId→cwd son los archivos `~/.claude/sessions/.json` (memoria +`claude-session-pid-mapping`). Usa la función del registry para listarla: + +```bash +./fn run list_claude_agents # tabla: PID, STATUS, ETIME, KITTY, SELF, SESSION_ID, CWD +./fn run list_claude_agents --json # para parsear y decidir +``` + +- `list_claude_agents_bash_infra([--json] [--exclude-current])` — cruza `pgrep -x claude` con los + `sessions/.json` (con validación anti-PID-reciclado), marca tu propia sesión como `SELF`, + y reporta cwd + sessionId de cada secundario (para retomar con `claude --resume `). + +Tu tabla de seguimiento, una fila por secundario: + +| slug | título kitty | PID | cwd / dir aislado | rama | log | report | estado | +|---|---|---|---|---|---|---|---| +| docs | fn_registry · docs | 3637133 | /tmp/orq_docs_wt | orq/docs | /tmp/orq_docs_kitty.log | reports/00NN-…-docs.md | en curso | + +Cuando un secundario parezca terminado, confirma: ¿pusheó la rama? ¿escribió el report? Lee el +report (`reports/`), revisa los commits de su rama (`git -C

log --oneline`). + +### 6. NUNCA `pkill`/`killall` sobre claude + +Un `pkill claude` o `killall claude` **te mata a ti mismo** (el orquestador) junto con la flota. +Para parar un secundario: + +- **Kill por PID exacto** del secundario (lo tienes en la tabla / `list_claude_agents`): + `kill ` (o `kill ` para cerrar su ventana). Verifica que NO es tu `SELF`. +- **`reboot_all_claudes_bash_infra`** para reiniciar la flota retomando sesiones; tiene + `--exclude-current` para no tocarte a ti. Es dry-run por defecto; `--go` para ejecutar. + +### 7. Integrar + +Cuando un secundario termina (rama pusheada + report verde): + +1. **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 kitty, o tú le mandas otro prompt). +2. **Mergea si procede** desde el **working tree principal** (ahí suele estar `master` + checked-out): `git -C ~/fn_registry merge --no-ff ` para apps con TBD, o el flujo que + corresponda al sub-repo. Para funciones nuevas del registry padre, sus archivos viajan en la + rama y el merge los lleva a master. +3. **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. kitty vs Agent tool — cuándo cada uno + +- **kitty (este modo)**: trabajo **largo e interactivo** que el humano quiere **ver** y poder + **retomar** — implementar una feature de horas, depurar en vivo, una sesión que evoluciona. +- **Agent tool directo**: fan-out **acotado y no interactivo** — buscar en el codebase, crear + una función con `fn-constructor`, auditar N apps con `fn-recopilador`. Más barato, sin + terminal, sin supervisión humana. Para esto NO lances kitty: usa `Agent(...)` y ya. + +Regla práctica: si el humano va a querer hablar con ello o mirarlo trabajar → kitty. Si es una +sub-tarea que devuelve un resultado y se acabó → Agent tool. + +## Reglas duras del modo + +- **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? +- **Cada secundario, su aislamiento.** Nunca lances dos secundarios sobre el mismo working tree + sin worktrees/sub-repos/scopes disjuntos. Es la causa nº1 de commits perdidos. +- **El prompt del secundario lleva SIEMPRE las reglas de aislamiento.** Un prompt sin "trabaja + aquí, no toques aquello, commitea así" es un secundario que contaminará otro repo. +- **Nunca `git add -A` en un secundario** salvo que su dir aislado sea exclusivamente suyo + (worktree/sub-repo). En scope compartido, paths específicos. +- **Nunca `pkill`/`killall claude`.** Kill por PID exacto o `reboot_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 por PID exacto / `reboot_all_claudes --exclude-current` | +| 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 ` | +| Lanzar kitty para un fan-out trivial | Caro y sin supervisión que aporte | Agent tool directo (`fn-constructor`, `Explore`, …) | +| 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` | + +## Funciones del registry que usa este modo (grupo `orchestration`) + +| Función | Para qué | +|---|---| +| `launch_claude_agent_kitty_bash_infra` | Lanzar un secundario en kitty con prompt autónomo + `--dangerously-skip-permissions` | +| `list_claude_agents_bash_infra` | Listar la flota de Claudes vivos (PID, sessionId, cwd, status, kitty) para seguirla | +| `reboot_all_claudes_bash_infra` | Reiniciar/parar la flota retomando sesiones; `--exclude-current` para no tocarte | + +## 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. + +```bash +# 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 (worktree del padre; 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): +# /tmp/orq_health.md → "trabaja en apps/kanban (sub-repo propio), rama issue/health, +# commits atómicos de tus paths, push al terminar, report en reports/. No toques el +# repo padre. Reporta tu progreso en esta terminal." +# /tmp/orq_capdoc.md → "trabaja SOLO en /tmp/orq_capdoc (worktree), rama orq/cap-deploy, +# toca solo docs/capabilities/deploy.md, git add de ese path, push al terminar, report +# en reports/. No toques ~/fn_registry. Reporta tu progreso en esta terminal." + +# 4. Lanzar ambos secundarios (cada uno su kitty, su dir aislado): +./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 la flota (cada turno): +./fn run list_claude_agents +# → tabla con los 2 secundarios vivos (PID, cwd, sessionId, status) + tu SELF. +# Lee /tmp/orq_*_kitty.log para el arranque; cuando terminen, lee sus reports/. + +# 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. Tarea grande hecha. +``` + +## 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 kitty +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 por PID exacto, nunca `pkill`. + +## Relación con otras reglas + +- `.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 de `git init` antes de limpiar un + worktree con una app nueva dentro. +- `.claude/rules/reports.md` + `.claude/rules/dod_quality.md` — qué entrega cada secundario: + report con evidencia ejecutable + gaps. +- `.claude/rules/delegation.md` + `.claude/rules/registry_calls.md` — los secundarios siguen + registry-first y delegan a `fn-constructor` igual que tú. +- Memorias: `lanzar-agentes-skip-permissions`, `multi-agent-git-race-same-repo`, + `claude-session-pid-mapping`, `prefiere-kitty-terminal`.