# CLAUDE.md — Contexto del proyecto agents_and_robots

## Qué es este proyecto

Monorepo en Go para gestionar bots Matrix. Cada bot es un agente autónomo con personalidad, reglas de decisión y acceso a herramientas (LLM, SSH, HTTP, MCP). Los bots se comunican entre sí y con humanos a través de Matrix (mautrix-go).

**Homeserver activo:** `https://matrix-af2f3d.organic-machine.com`
**Server name:** `matrix-af2f3d.organic-machine.com`

## Filosofía de diseño — LA REGLA MÁS IMPORTANTE

El proyecto usa el patrón **pure core / impure shell** estrictamente:

```
pkg/      → PURE: solo tipos, funciones puras, cero side effects
shell/    → IMPURE: todo I/O, red, filesystem, procesos
agents/   → composición: reglas puras + ensamblado con shell en runtime.go
```

**Nunca** añadir side effects (I/O, red, llamadas a APIs) dentro de `pkg/`.
**Siempre** que el core necesite "hacer algo", produce un `[]decision.Action` (datos puros) que el shell interpreta.

El flujo es siempre:
```
Matrix event → Parse (pure) → Evaluate rules (pure) → []Action (pure data)
            → Runner.Execute (impure) → efectos reales
```

## Módulo Go

`github.com/enmanuel/agents`

## Estructura de directorios

```
pkg/decision/     → motor de reglas puro (Evaluate, Rule, MatchFunc, Action)
pkg/llm/          → tipos de LLM puros (CompleteFunc, CompletionRequest, Route)
pkg/tools/        → specs declarativas de herramientas (SSHCommandSpec, etc.)
pkg/message/      → parse y format de mensajes Matrix (puros)
pkg/personality/  → tipos de personalidad (Personality, Tone, etc.)

shell/llm/        → clientes LLM reales (anthropic.go, openai.go, factory.go)
shell/matrix/     → cliente Matrix mautrix-go (client.go, listener.go)
shell/ssh/        → ejecutor SSH real (executor.go)
shell/effects/    → Runner que interpreta []Action → side effects
shell/bus/        → comunicación inter-agente via Go channels
shell/protocols/  → adaptadores MCP (mcp.go)

agents/runtime.go      → Agent{}: ensambla core + shell, maneja eventos
agents/assistant-bot/  → reglas puras + config del assistant-bot

internal/config/schema.go  → tipos completos del YAML de configuración
internal/config/loader.go  → Load() con expand env vars, LoadMeta() sin validación
cmd/launcher/main.go       → inicia agentes, tiene rulesRegistry
cmd/agentctl/main.go       → CLI de gestión (list, start, stop, remove)
cmd/register/main.go       → registra bots en Synapse via admin API
dev-scripts/               → scripts bash para operaciones del día a día
dev-scripts/server/        → gestión del launcher (start, stop, restart, ps, logs, dashboard)
dev-scripts/agent/         → gestión de agentes (new, register, verify, avatar, remove, list)
```

## Políticas para LLMs

Las políticas guían cómo ejecutar tareas específicas respetando la arquitectura del proyecto.
Ver índice completo en `.claude/policies/index.md`.

| Política | Cuándo aplicarla |
|----------|------------------|
| `.claude/policies/create_agent.md` | Al crear un nuevo bot/agente Matrix |
| `.claude/policies/create_tool.md` | Al añadir una nueva tool para function calling |
| `.claude/policies/create_command.md` | Al añadir un comando directo (!xxx) a un agente |

Documentación detallada para humanos en `docs/creating-agents.md`.

## Agentes existentes

| ID             | Estado    | LLM     | Descripción                              |
|----------------|-----------|---------|------------------------------------------|
| assistant-bot  | activo    | GPT-4o  | Asistente general, responde DMs          |
| asistente-2    | activo    | GPT-4o  | Asistente con tools (current_time)       |

## Dependencias clave

```
maunium.net/go/mautrix v0.21.1     → Matrix client
github.com/sashabaranov/go-openai  → OpenAI + Ollama-compatible
github.com/mark3labs/mcp-go        → MCP protocol server/client
golang.org/x/crypto/ssh            → SSH execution
github.com/spf13/cobra             → CLI
gopkg.in/yaml.v3                   → Config parsing
```

## Configuración de agentes

Cada agente vive en `agents/<id>/`:
- `config.yaml` — configuración completa (ver schema en `internal/config/schema.go`)
- `agent.go` — reglas puras que implementan `Rules() []decision.Rule`
- `prompts/system.md` — system prompt del LLM
- `data/` — datos de runtime (SQLite, crypto, logs) — en .gitignore

El `config.yaml` soporta variables de entorno con `${VAR}` y `$VAR`. El loader usa `os.ExpandEnv`.

Secciones principales del config: `agent`, `personality`, `llm`, `tools`, `matrix`, `agents` (peers), `ssh`, `security`, `schedules`, `observability`, `resilience`, `storage`.

## Cómo añadir un nuevo bot

Guía rápida (detalle completo en `docs/creating-agents.md`, policy en `.claude/policies/create_agent.md`):

1. Crear scaffold: `./dev-scripts/agent/new-agent.sh <id> "Display Name"` o manual en `agents/<id>/`
2. Crear `agent.go` (reglas puras), `config.yaml`, `prompts/system.md`
3. Registrar en `cmd/launcher/main.go` → import + `rulesRegistry`
4. Registrar en Matrix: `./dev-scripts/agent/register.sh <id> "Display Name"`
5. Avatar y nombre: `./dev-scripts/agent/avatar.sh <id> static/<imagen>.jpg`
6. Verificación E2EE: `go run -tags goolm ./cmd/verify --homeserver ... --username <id> --password ... --token ...`
7. Arrancar: `./dev-scripts/server/start.sh <id>`

## Dev-scripts disponibles

```bash
# === server/ — gestión del launcher ===
./dev-scripts/server/start.sh            # iniciar el launcher
./dev-scripts/server/stop.sh             # detener el launcher
./dev-scripts/server/restart.sh          # reiniciar el launcher
./dev-scripts/server/ps.sh              # procesos con detalle (PID, mem, CPU, uptime)
./dev-scripts/server/logs.sh [lines]    # tail -f de logs
./dev-scripts/server/dashboard.sh       # TUI interactiva

# Gestión unificada (wrapper)
./dev-scripts/server/server.sh start     # iniciar
./dev-scripts/server/server.sh stop      # detener
./dev-scripts/server/server.sh restart   # reiniciar
./dev-scripts/server/server.sh status    # resumen general del servidor
./dev-scripts/server/server.sh ps        # procesos con detalle
./dev-scripts/server/server.sh logs      # tail -f de logs
./dev-scripts/server/server.sh kill      # SIGKILL forzado (emergencia)

# === agent/ — gestión de agentes ===
./dev-scripts/agent/list.sh              # ver todos los bots y estado
./dev-scripts/agent/new-agent.sh <id> [name]  # scaffold completo
./dev-scripts/agent/register.sh <id> [name]   # registrar bot en Matrix
./dev-scripts/agent/verify.sh [agent-id]      # verificación E2EE
./dev-scripts/agent/avatar.sh <id> <img>      # subir avatar
./dev-scripts/agent/reset-password.sh <id>    # resetear password
./dev-scripts/agent/remove.sh <agent-id>      # deshabilitar (sin borrar datos)
```

PID files: `run/<id>.pid` | Log files: `run/<id>.log`

## Gestión de procesos

Los bots corren como procesos independientes lanzados por `agentctl` o `dev-scripts/server/start.sh`.
Cada proceso escribe su PID en `run/<id>.pid` y su log en `run/<id>.log`.
`is_running()` usa `kill -0 <pid>` para verificar sin matar el proceso.

## Variables de entorno críticas

```bash
MATRIX_HOMESERVER         # URL del servidor Matrix
MATRIX_SERVER_NAME        # nombre del servidor (parte después de :)
MATRIX_ADMIN_TOKEN        # token admin para registrar bots (cmd/register)
MATRIX_TOKEN_<BOT>        # access token de cada bot
OPENAI_API_KEY            # OpenAI
ANTHROPIC_API_KEY         # Anthropic/Claude
```

Nunca commitear `.env`. Plantilla en `.env.example`.

## Preferencias del usuario

- **Idioma**: español en configs/comentarios de dominio, inglés en código Go
- **Estilo**: FP estricto (pure core / impure shell), sin abstracción prematura
- **Desarrollo**: trunk-based, Gitea como remote
- **Go version**: 1.23.5 en `/usr/local/go/bin`
- **No usar** frameworks de agentes externos — arquitectura propia

## Próximas extensiones naturales

- Scheduling: cron runner en `shell/` para `ScheduleCfg`
- Conversation history: mantener `[]Message` por room en memoria/SQLite
- RBAC real: conectar `SecurityCfg.Roles` al listener
- E2EE: habilitar `encryption.enabled: true` con crypto store de mautrix
- MCP: exponer tools de los agentes como MCP server en el puerto configurado
- A2A: agent card HTTP endpoint para comunicación con agentes externos
