# CLAUDE.md — agents_and_robots Monorepo Go para bots Matrix autonomos. Modulo: `github.com/enmanuel/agents`. **Homeserver:** `https://matrix-af2f3d.organic-machine.com` | **Server name:** `matrix-af2f3d.organic-machine.com` ## Los dos pilares — SIEMPRE APLICAR ### 1. Functional PRogramming: Pure core / Impure shell ``` pkg/ → PURO: tipos, funciones puras, cero side effects shell/ → IMPURO: todo I/O (Matrix, LLM, SSH, filesystem) agents/ → composicion: reglas puras + ensamblado con shell tools/ → Def (puro) + Exec (impuro) ``` **Nunca** side effects en `pkg/`. El core produce `[]decision.Action` (datos puros), el shell los interpreta. ``` Matrix event → Parse (pure) → Evaluate rules (pure) → []Action (pure data) → Runner.Execute (impure) → efectos reales ``` ### 2. TBD: Trunk-based development **master** es el unico branch estable. Nunca trabajar directamente en master. ``` master ← siempre deployable ↑ └── issue/- ← rama efimera (horas) commits atomicos (feat:, fix:, test:, docs:, refactor:, chore:) merge --no-ff → master → push → delete branch ``` - `/git-branch` — crea rama desde master - `/git-push` — tests → merge --no-ff → push → elimina rama - Commits atomicos por bloque logico, titulo corto + cuerpo en espanol - No WIP, no squash, no rebase -i **Feature flags** (solo para features multi-issue): codigo completo y testeado, mergeado pero desactivado. Flag != WIP. Archivo: `dev/feature_flags.json`. ## Estructura ``` pkg/decision/ motor de reglas puro pkg/llm/ tipos LLM puros pkg/message/ parse/format mensajes pkg/personality/ tipos de personalidad shell/llm/ clientes LLM (anthropic, openai) shell/matrix/ cliente Matrix (mautrix-go) shell/ssh/ ejecutor SSH shell/mcp/ cliente y servidor MCP (Model Context Protocol) shell/effects/ Runner: []Action → side effects shell/bus/ comunicacion inter-agente agents/runtime.go Agent{}: ensambla core + shell agents// agent.go (reglas puras) + config.yaml + prompts/system.md tools/ tool registry + tool implementations (subpackages) tools/mcptools/ bridge: convierte MCP tools → tools.Tool internal/config/ schema.go + loader.go security/ grupos de usuarios/agentes + politicas de permisos (YAMLs) cmd/launcher/ entrypoint principal (rulesRegistry) cmd/agentctl/ CLI de gestion crons/ catálogo de automatizaciones nombradas (schedule.yaml + prompts) knowledges/ base de conocimiento compartida entre agentes (*.md + SQLite FTS5) dev-scripts/server/ start, stop, restart, ps, logs, dashboard dev-scripts/agent/ new, register, verify, avatar, remove, list dev-scripts/cron/ new, list, apply — gestión de automatizaciones cron dev-scripts/e2e/ install, run — E2E tests con Playwright e2e/ proyecto Node.js con Playwright (tests, fixtures, Element Web) ``` ## E2E Tests Tests end-to-end con Playwright contra Element Web + homeserver real. Proyecto Node.js separado en `e2e/`. ```bash ./dev-scripts/e2e/install.sh # instalar dependencias cp e2e/.env.example e2e/.env # configurar credenciales ./dev-scripts/e2e/run.sh # ejecutar tests (headless) ./dev-scripts/e2e/run.sh --headed # con browser visible ``` - **Fixtures**: `e2e/fixtures/` — login E2EE (`element-auth.ts`), helpers de room (`matrix-room.ts`) - **Tests**: `e2e/tests/` — login, assistant-bot, asistente-2 - **Assertions flexibles** para respuestas LLM (no-deterministicas), estrictas para commands (`!help`, `!ping`) - Documentacion completa: `e2e/README.md` ## Reglas operativas Guias detalladas en `.claude/rules/index.md`: | Regla | Cuando | |-------|--------| | `create_agent.md` | Crear nuevo bot/agente | | `create_tool.md` | Añadir tool para function calling | | `create_command.md` | Añadir comando !xxx | | `create_issue.md` | Crear issue en dev/issues/ | | `fix_issue.md` | Implementar un issue existente | ## Agentes | ID | LLM | Descripcion | |----|-----|-------------| | assistant-bot | GPT-4o | Asistente general, DMs | | asistente-2 | GPT-4o | Asistente con tools | ## Build - Go 1.23.5 (`/usr/local/go/bin`), siempre compilar con `-tags goolm` - CGO_ENABLED=0 (pure-Go SQLite via modernc, shim en `cmd/launcher/sqlite.go`) - Secrets via env vars (`.env.example`), nunca commitear `.env` ## Seguridad Protecciones contra prompt injection y abuso de tools (issue 0019): - **`pkg/sanitize/`** — deteccion pura de patrones de injection en mensajes entrantes - **Tools deny-by-default** — allowlist vacia = todo denegado (file, ssh, http, matrix) - **Path traversal** — EvalSymlinks + prefix validation en `tools/file/` - **SSRF** — bloqueo de IPs privadas en `tools/http/` - **SSH** — AllowedCommands allowlist + validacion de sintaxis shell en `tools/ssh/` - **Rate limiting** — por room en `tools/registry.go` via `security.tool_rate_limit` - **System prompts** — seccion anti-injection obligatoria (template en `.claude/templates/security-prompt.md`) - **`storage.base_path`** — permite aislar datos de runtime fuera del arbol del proyecto - **`claude_code.working_dir`** — aislamiento del subproceso `claude -p` fuera del repo (default: tmpdir) Config YAML relevante: `security.sanitize.*`, `security.tool_rate_limit.*`, `storage.base_path`, `claude_code.working_dir` Documentacion completa: `docs/security.md` ## Preferencias - Espanol en configs/comentarios de dominio, ingles en codigo Go - FP estricto, sin abstraccion prematura - Trunk-based, Gitea como remote - Arquitectura propia, sin frameworks de agentes externos - Issues en `dev/issues/`, docs internas en `dev/README.md`