# 0037 — Agente que crea otros agentes y bots via Matrix

**Estado:** pendiente

## Objetivo

Crear un agente especializado ("creator-bot") que reciba peticiones en lenguaje natural via Matrix para crear nuevos agentes o robots. El usuario describe lo que necesita (ej: "crea un bot que monitoree servidores con SSH") y creator-bot ejecuta todo el pipeline automaticamente: scaffold, build, registro Matrix, configuracion, personalización del system prompt y reinicio del launcher.

## Contexto

- El proyecto ya tiene `dev-scripts/agent/create-full.sh` que ejecuta el pipeline completo de scaffold + build + register + verify E2EE. Funciona bien desde la terminal.
- Existen dos skills de Claude Code (`/create-agent` y `/create-bot`) que automatizan la creacion via el CLI de Claude, pero solo funcionan dentro de una sesion de Claude Code.
- El provider `claude-code` ya esta implementado (`shell/llm/claude_code.go`) y soporta `allowed_tools`, `add_dirs`, `permission_mode` y `working_dir`.
- No hay forma de crear agentes desde Matrix sin acceso SSH al servidor. Este issue cierra esa brecha: un usuario admin envia un mensaje y el agente lo resuelve end-to-end.
- La infraestructura de seguridad (grupos de usuarios, permisos por agente, ACLs en `security/`) permite restringir el acceso a este agente privilegiado.

## Arquitectura

### Provider y acceso

El creator-bot usa `provider: claude-code` con `working_dir` apuntando a la raiz del proyecto. Esto es una excepcion deliberada a la regla de sandbox (`working_dir` fuera del repo) porque el agente necesita acceso de lectura y escritura al arbol completo para crear archivos de agentes, editar el launcher y ejecutar scripts.

```
Usuario envia "crea un robot que responda !saludo"
  → Matrix event → listener
  → Rules: DM/mention → ActionKindLLM
  → claude-code provider recibe el mensaje + system prompt
  → claude -p ejecuta:
      1. Analiza la peticion (tipo, nombre, descripcion, tools)
      2. ./dev-scripts/agent/create-full.sh <id> "Name"
      3. Personaliza config.yaml, agent.go, prompts/system.md
      4. go build -tags goolm ./...
      5. ./dev-scripts/server/restart.sh
      6. Verifica logs del nuevo agente
  → Responde al usuario con resultado
```

**Pure core / impure shell:**
- `agents/creator-bot/agent.go` — PURO: reglas simples (DM/mention → LLM), sin side effects
- Toda la logica de creacion ocurre dentro del subprocess `claude -p` (impuro por naturaleza)
- No se anade nada a `pkg/` — el creator-bot es composicion pura de infraestructura existente

### Archivos afectados

```
agents/creator-bot/              NEW — directorio del agente
agents/creator-bot/agent.go      NEW — reglas puras (DM/mention → LLM)
agents/creator-bot/config.yaml   NEW — provider claude-code, working_dir al repo, ACL admin-only
agents/creator-bot/prompts/system.md  NEW — guia completa de creacion de agentes
cmd/launcher/main.go             MOD — blank import de creator-bot
security/permissions.yaml        MOD — policy restrictiva para creator-bot (solo admins)
security/agent-groups.yaml       MOD — grupo para agentes privilegiados
```

## Tareas

### Fase 1 — Scaffold y configuracion basica

- [ ] **1.1** Ejecutar `./dev-scripts/agent/create-full.sh creator-bot "Creator Bot"` para scaffold completo (registro Matrix, E2EE, env vars)
- [ ] **1.2** Configurar `agents/creator-bot/config.yaml`:
  - `agent.type: agent`
  - `agent.description: "Agente que crea otros agentes y robots via Matrix"`
  - `llm.primary.provider: claude-code`
  - `llm.primary.claude_code.working_dir: "/home/ubuntu/CodeProyects/agents_and_robots"` (raiz del proyecto)
  - `llm.primary.claude_code.permission_mode: bypassPermissions`
  - `llm.primary.claude_code.allowed_tools: [Bash, Read, Edit, Write, Glob, Grep]`
  - `llm.primary.claude_code.add_dirs` con las rutas de referencia (ver Fase 2)
- [ ] **1.3** Escribir `agents/creator-bot/agent.go` con reglas simples:
  - DM o mencion → `ActionKindLLM`
  - Package name: `creator` (strip hyphens + strip `_bot`)
  - `agents.Register("creator-bot", Rules)` en `init()`
- [ ] **1.4** Verificar blank import en `cmd/launcher/main.go`:
  ```go
  _ "github.com/enmanuel/agents/agents/creator-bot"
  ```
- [ ] **1.5** Compilar y verificar: `go build -tags goolm ./...`

### Fase 2 — System prompt y knowledge

- [ ] **2.1** Escribir `agents/creator-bot/prompts/system.md` completo. Debe incluir:
  - **Identidad**: "Eres Creator Bot, un agente especializado en crear otros agentes y robots para Matrix"
  - **Flujo de trabajo completo**:
    1. Entender la peticion del usuario (tipo agent/robot, nombre, descripcion, tools necesarias)
    2. Elegir tipo (Agent vs Robot) segun la decision tree de `create_agent.md`
    3. Ejecutar `./dev-scripts/agent/create-full.sh <id> "Display Name"`
    4. Personalizar `config.yaml` (provider, tools, personality, etc.)
    5. Escribir `prompts/system.md` del nuevo agente con instrucciones de seguridad
    6. Personalizar `agent.go` si se necesitan reglas especificas
    7. Compilar: `go build -tags goolm ./...`
    8. Reiniciar launcher: `./dev-scripts/server/restart.sh`
    9. Verificar que el nuevo agente arranca (revisar logs)
    10. Confirmar al usuario con resumen del agente creado
  - **Decision tree Agent vs Robot**: reproducir la tabla de `create_agent.md`
  - **Referencia de config YAML**: secciones clave del schema (agent, llm, personality, tools, matrix, security)
  - **Guia de system prompts**: como escribir buenos prompts para agentes, con ejemplo
  - **Seccion de seguridad anti-injection** (obligatoria, copiar de template)
  - **Reglas criticas**:
    - Siempre compilar con `-tags goolm` despues de modificar Go
    - `agent.id` debe coincidir con nombre del directorio
    - Nunca commitear tokens ni passwords
    - Incluir seccion de seguridad en todo system prompt creado
    - Env vars siguen la convencion: `MATRIX_TOKEN_<NORMALIZED_ID>`
- [ ] **2.2** Configurar `add_dirs` en config.yaml para dar acceso a las referencias:
  ```yaml
  claude_code:
    add_dirs:
      - ".claude/rules"
      - "agents/_template"
      - "agents/_template_robot"
      - "agents/assistant-bot"
      - "agents/asistente-2"
      - "internal/config"
  ```
- [ ] **2.3** Test manual: enviar "crea un robot que responda !saludo con Hola mundo" y verificar que:
  - Ejecuta `create-full.sh` correctamente
  - Crea los archivos del robot con config `type: robot`
  - El comando `!saludo` esta registrado
  - Compila sin errores
  - Reinicia el launcher
  - El nuevo robot aparece en los logs como running

### Fase 3 — Seguridad y restriccion de acceso

- [ ] **3.1** Crear grupo de agentes privilegiados en `security/agent-groups.yaml`:
  ```yaml
  privileged:
    - creator-bot
  ```
- [ ] **3.2** Agregar policy restrictiva en `security/permissions.yaml`:
  ```yaml
  - agent_group: privileged
    permissions:
      - user_group: admins
        actions: ["*"]
  ```
  Esto asegura que solo los admins puedan interactuar con creator-bot.
- [ ] **3.3** Verificar que un usuario no-admin recibe "permiso denegado" al escribir a creator-bot

### Fase 4 — Gestion del servidor

- [ ] **4.1** Asegurar que el system prompt incluye instrucciones para ejecutar `./dev-scripts/server/restart.sh` despues de crear un agente
- [ ] **4.2** Incluir verificacion post-reinicio: el creator-bot debe revisar `run/launcher.log` para confirmar que el nuevo agente arranco con los mensajes esperados (`"e2ee ready"`, `"agent running"`)
- [ ] **4.3** Si el reinicio falla o el agente no arranca, reportar el error al usuario con los logs relevantes

### Fase 5 — Tests y documentacion

- [ ] **5.1** Test E2E en `e2e/tests/creator-bot.spec.ts`:
  - Login como admin
  - Enviar peticion de creacion de un robot simple
  - Verificar que creator-bot responde con confirmacion
  - (Opcional) Verificar que el robot creado responde en su room
- [ ] **5.2** Test de acceso denegado: login como usuario no-admin, verificar que creator-bot rechaza la peticion
- [ ] **5.3** Documentar en el system prompt del creator-bot los casos de error comunes y como reportarlos al usuario

## Ejemplo de uso

### Crear un robot simple

```
Usuario: Crea un robot que responda al comando !hora con la hora actual

Creator Bot: Entendido. Voy a crear un robot llamado "hora-bot" que responde al comando !hora.

[Ejecutando pipeline...]

1. Scaffold completado: agents/hora-bot/
2. Configurado como robot (type: robot, sin LLM)
3. Comando !hora registrado con respuesta dinamica
4. Build exitoso
5. Launcher reiniciado

El robot "hora-bot" esta activo. Puedes invitarlo a un room y usar !hora para obtener la hora actual.

Resumen:
- ID: hora-bot
- Tipo: Robot (command-only)
- Comandos: !hora, !help, !ping
- Room: invitalo desde Element
```

### Crear un agente con tools

```
Usuario: Necesito un agente experto en Docker que pueda ejecutar comandos SSH en mis servidores

Creator Bot: Voy a crear un agente con LLM y herramientas SSH habilitadas.

[Ejecutando pipeline...]

1. Scaffold completado: agents/docker-expert/
2. Configurado como agent (type: agent, provider: openai, model: gpt-4o)
3. Tools habilitadas: ssh_command con targets configurables
4. System prompt escrito con expertise en Docker, docker-compose, Dockerfile best practices
5. Seccion de seguridad incluida en el prompt
6. Build exitoso
7. Launcher reiniciado
8. Verificado: "docker-expert" aparece en logs como running

El agente "docker-expert" esta activo. Configuracion SSH pendiente:
- Editar agents/docker-expert/config.yaml para agregar los SSH targets permitidos
- Agregar las SSH keys necesarias

Quieres que configure los targets SSH ahora?
```

## Decisiones de diseno

1. **Provider claude-code en vez de LLM regular**: la creacion de agentes requiere acceso al filesystem, ejecucion de scripts y edicion de archivos. Un LLM regular con tools no tiene la capacidad de ejecutar pipelines complejos de forma autonoma. claude-code puede usar Bash, Read, Edit, Write directamente.

2. **working_dir = raiz del proyecto**: excepcion necesaria a la regla de sandbox. El creator-bot necesita:
   - Leer templates y reglas existentes
   - Ejecutar `create-full.sh` que opera sobre el arbol del proyecto
   - Editar `cmd/launcher/main.go` para agregar blank imports
   - Ejecutar `go build` y `restart.sh`
   Sin acceso al repo, nada de esto es posible.

3. **ACL admin-only**: dado que el agente tiene acceso de escritura completo al repo, es critico restringirlo a usuarios de confianza. Se usa el sistema de permisos existente (`security/permissions.yaml`) con un grupo de agentes "privileged".

4. **Sin codigo nuevo en pkg/**: el creator-bot es pura composicion de infraestructura existente (scripts, templates, config schema, security). Las reglas en `agent.go` son triviales (DM/mention → LLM). Toda la inteligencia esta en el system prompt que guia al subprocess claude -p.

5. **Reinicio del launcher**: despues de crear un agente, el launcher debe reiniciarse para cargarlo. Esto afecta temporalmente a todos los agentes en ejecucion. Es aceptable porque el reinicio es rapido (~2-3 segundos) y la creacion de agentes es una operacion infrecuente.

## Prerequisitos

- Provider `claude-code` funcional (`shell/llm/claude_code.go`) -- ya implementado
- Scripts de creacion (`dev-scripts/agent/create-full.sh`) -- ya implementados
- Sistema de permisos (`security/`) -- ya implementado (issue 0024)
- Templates de agente (`agents/_template/`, `agents/_template_robot/`) -- ya existen

## Riesgos

| Riesgo | Probabilidad | Mitigacion |
|--------|-------------|------------|
| creator-bot tiene write access al repo completo | Alta (by design) | ACL admin-only via `security/permissions.yaml`; el agente solo se configura para usuarios de maxima confianza |
| Script `create-full.sh` falla a mitad de ejecucion | Media | El system prompt debe instruir al creator-bot a reportar errores con logs y sugerir pasos de recovery manual |
| Reinicio del launcher afecta todos los agentes | Baja impacto | El reinicio es rapido (~2-3s); los agentes reconectan automaticamente al sync de Matrix |
| claude -p genera codigo incorrecto para el nuevo agente | Media | El system prompt incluye las convenciones y el creator-bot debe compilar (`go build`) antes de reiniciar; si falla, corrige y reintenta |
| Agente creado tiene configuracion insegura | Baja | El system prompt obliga a incluir seccion de seguridad anti-injection en todo prompt generado; las tools son deny-by-default |
| Doble ejecucion accidental (usuario repite la peticion) | Baja | El creator-bot debe verificar si ya existe un agente con el ID solicitado antes de ejecutar el pipeline |
