# 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/<NNNN>-<slug>  ← 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/effects/         Runner: []Action → side effects
shell/bus/             comunicacion inter-agente
agents/runtime.go      Agent{}: ensambla core + shell
agents/<id>/           agent.go (reglas puras) + config.yaml + prompts/system.md
tools/                 tool registry + tool implementations (subpackages)
internal/config/       schema.go + loader.go
cmd/launcher/          entrypoint principal (rulesRegistry)
cmd/agentctl/          CLI de gestion
dev-scripts/server/    start, stop, restart, ps, logs, dashboard
dev-scripts/agent/     new, register, verify, avatar, remove, list
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`
