Completa el sistema E2E con Playwright (cierra issue 0022 completo):
- Tests para assistant-bot y asistente-2
- Script run.sh de orquestacion completa
- Documentacion en e2e/README.md
- Seccion E2E en CLAUDE.md
Cierra 0022c (tests de agentes + docs) y el issue padre 0022
(Tests E2E con Playwright) ya que todos los sub-issues estan completados:
- 0022a: infraestructura base
- 0022b: auth fixtures y helpers
- 0022c: tests de agentes, run.sh, documentacion
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- e2e/README.md: guia completa de instalacion, configuracion,
ejecucion y debug de tests E2E
- .gitignore: agrega e2e/playwright-report/
- CLAUDE.md: agrega seccion E2E tests y dev-scripts/e2e en estructura
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Completa el placeholder de 0022a con el flujo completo:
1. Verifica agentes corriendo (via ps.sh)
2. Levanta Element Web si no esta activo
3. Ejecuta npx playwright test
4. Genera reporte HTML en caso de fallos
5. Teardown de Element Web
6. Retorna exit code de Playwright
Soporte --headed para debug local con DISPLAY.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests de cada agente via Element Web + Playwright:
- assistant-bot: saludo DM, pregunta, !help, !ping, E2EE check
- asistente-2: saludo, !tools, tool use (que hora es?), !help, E2EE check
Assertions flexibles para respuestas LLM (no-deterministicas),
estrictas para commands deterministicos (!help, !ping).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Integra fixtures de autenticacion para Element Web (login + cross-signing
con recovery key), helpers de interaccion con rooms Matrix (goToRoom,
sendMessage, waitForBotReply, assertNoDecryptionErrors) y smoke tests
de validacion de sesion E2EE.
Implementa el issue 0022b — fixtures de Playwright para
autenticacion en Element Web y helpers de interaccion con rooms.
- element-auth.ts: flujo completo de login + cross-signing con
recovery key, preparado para cachear sesion via storageState
- global-setup.ts: ejecuta login una vez antes de todos los tests,
reutiliza sesion cacheada si tiene menos de 12 horas
- matrix-room.ts: helpers goToRoom, sendMessage, waitForBotReply,
getLastMessage, assertNoDecryptionErrors (detecta "Unable to decrypt")
- login.spec.ts: 3 smoke tests validando sesion, E2EE y navegacion
- playwright.config.ts: configurado storageState para inyectar sesion
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Proyecto Node.js independiente en e2e/ con Playwright + Chromium headless.
Incluye setup-element.sh para descargar y servir Element Web localmente
(puerto 8090 por defecto, 8080 ocupado por Docker).
Scripts de instalacion y placeholder para ejecucion de tests.
Cierra issue 0022a.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Issue multi-issue desglosado en 3 sub-issues:
- 0022a: infraestructura base (Docker, Playwright config, CI)
- 0022b: auth fixtures y helpers (login, E2EE, utilidades Matrix)
- 0022c: tests de agentes + documentacion
Incluye actualizacion del README con issue 21 (completado) y todos
los sub-issues de 0022 registrados como pendientes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nuevo comando slash que automatiza la creacion de issues en dev/issues/.
Sigue estrictamente la regla create_issue.md, evalua el tamaño del issue
para desglosar en sub-issues con feature flags si es necesario, y registra
todo en el README automaticamente.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dos problemas corregidos:
1. Detección de threads con E2EE: después de desencriptar un evento,
evt.Content.Raw puede no contener m.relates_to. Se añade fallback
usando el contenido tipado (evt.Content.Parsed) que es más robusto
tras la desencriptación de mautrix.
2. Notificaciones de tools fuera del thread: la notificación "🔨 tool"
se enviaba con SendMarkdown directo a la sala, ignorando el contexto
de thread. Ahora usa sendReply que respeta ThreadID.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Añadir tipo de rama quick/<slug> a los comandos /git-branch y /git-push
para cambios pequeños que no están asociados a un issue existente.
Antes, /git-push en master siempre inventaba un número de issue inexistente.
Ahora pregunta al usuario si el cambio tiene issue asociado o no.
No se modifican los flujos de ramas issue/ ni feature flags.
Actualiza el template de new-agent.sh para que agentes nuevos se creen
con matrix.threads.enabled: true por defecto. Tambien documenta la
seccion threads en create_agent.md para que la guia de creacion
incluya la configuracion de threads como opcion personalizable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Añade la seccion matrix.threads con enabled: true a los 3 agentes
existentes (assistant-bot, asistente-2, meteorologo). Esto activa
el soporte de threads implementado en issue 0012, permitiendo que
los bots respondan dentro de threads cuando reciben mensajes en uno.
auto_thread queda en false para no cambiar el comportamiento actual.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests unitarios:
- runner_test.go: verifica ruteo correcto de ReplyAction segun
ThreadID (plain markdown, reply, thread, thread sin fallback, nil reply)
- thread_test.go: extraccion de ThreadID desde m.relates_to raw
(thread, reply sin thread, plain, m.replace, thread sin event_id)
- thread_relates_test.go: estructura JSON de RelatesTo.SetThread
cumple la spec de Matrix (rel_type, event_id, is_falling_back, m.in_reply_to)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implementa el soporte completo de threads de Matrix:
- Listener extrae ThreadID de m.relates_to con rel_type=m.thread
- Client.SendThreadMarkdown envia mensajes como parte de un thread
usando SetThread de mautrix con fallback m.in_reply_to
- Runner detecta ThreadID en ReplyAction y rutea a SendThreadMarkdown
- MatrixSender interfaz actualizada con SendThreadMarkdown
- runtime.go propaga ThreadID en todas las respuestas (comandos, LLM, RBAC)
- sendReply helper centraliza la logica de envio con/sin thread
- Auto-thread: si matrix.threads.auto_thread=true, crea thread nuevo
para cada conversacion que no esta ya en un thread
- Memoria por thread: usa ThreadID como clave de window cuando el mensaje
esta en un thread, permitiendo conversaciones paralelas independientes
- Config: matrix.threads.enabled y matrix.threads.auto_thread en ThreadsCfg
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Todas las tareas del issue implementadas: default seguro con tmpdir,
configuracion de agentes existentes, tests unitarios y documentacion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- docs/security.md: nueva seccion 6 sobre aislamiento del provider
claude-code, comportamiento del working_dir y checklist actualizado
- CLAUDE.md: añadir claude_code.working_dir a la seccion de seguridad
- create_agent.md: recomendar siempre configurar working_dir cuando
se usa el provider claude-code
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extraer la logica de resolucion de working_dir a una funcion
resolveWorkDir() separada para hacerla testeable. Tres tests cubren:
- WorkingDir vacio → crea tmpdir con prefijo claude-agent-*
- WorkingDir configurado → crea el directorio y lo usa
- WorkingDir ya existente → lo usa sin error
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Setear working_dir a /tmp/claude-agents/<agent-id> en assistant-bot
y asistente-2, evitando que claude -p herede el CWD del launcher
(raiz del repo). El directorio se crea automaticamente al arrancar
gracias al MkdirAll añadido en el commit anterior.
Se mantiene bypassPermissions ya que el aislamiento real viene del
working_dir — sin acceso al repo, el bypass no expone codigo fuente.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cuando WorkingDir esta vacio, se crea un directorio temporal aislado
en lugar de heredar el CWD del launcher (raiz del repo). Esto evita
que el subproceso claude -p tenga acceso de lectura/escritura al
codigo fuente del proyecto.
Si WorkingDir tiene valor, se asegura que el directorio exista
creandolo con MkdirAll. Se loguea WARN cuando se usa el tmpdir
para que el operador lo note y configure explicitamente.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Issue para evitar que el subproceso claude -p tenga acceso al repositorio
del proyecto. Incluye default seguro con tmpdir, configuracion de agentes
existentes, tests y documentacion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Completa el issue 0019 (prompt injection hardening) con:
- storage.base_path configurable para aislar datos de runtime
- Seccion de seguridad anti-injection en todos los system prompts
- Template reutilizable en .claude/templates/security-prompt.md
- Documentacion completa en docs/security.md
- Actualizacion de CLAUDE.md, create_agent.md y create_tool.md
- Feature flag prompt-injection-hardening activado
- Issue 0019 cerrado y movido a completed
Todas las fases del issue 0019 (prompt injection hardening) completadas
a traves de 4 sub-issues (0019a, 0019b, 0019c, 0019d).
- Activa feature flag prompt-injection-hardening en feature_flags.json
- Mueve issue a dev/issues/completed/
- Actualiza README con estado completado
- Marca todas las tareas pendientes como completadas en el issue
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cambios en documentacion para completar fase 7 del issue 0019:
- CLAUDE.md: nueva seccion Seguridad con resumen de protecciones
- create_agent.md: requisito obligatorio de seccion anti-injection en
system prompts + item en checklist de verificacion
- create_tool.md: nueva seccion Seguridad con requisitos para tools
que hacen I/O (deny-by-default, path traversal, SSRF, command
injection, rate limiting)
- docs/security.md: documentacion completa de las 5 capas de defensa
(sanitizacion, prompt hardening, tool validation, rate limiting,
filesystem isolation) con ejemplos de configuracion
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Crea template reutilizable en .claude/templates/security-prompt.md y
aplica seccion de seguridad obligatoria a todos los system prompts:
- assistant-bot/prompts/assistant-system.md
- asistente-2/prompts/system.md
- meteorologo/prompts/system.md
Las instrucciones cubren:
- Rechazo de acciones fuera del rol
- Proteccion del system prompt (no revelar)
- Rechazo de comandos destructivos
- Validacion de coherencia contextual de tool calls
- Resistencia a redefinicion de identidad
- Prohibicion de generar contenido para ataques
Tareas 3.1, 3.2, 3.3 del issue 0019.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Añade BasePath a StorageCfg y resolveDataBase() en runtime.go para
centralizar la resolucion del directorio base de datos del agente.
Prioridad: config storage.base_path > $AGENTS_DATA_DIR/<id> > agents/<id>/data
Esto permite mover los datos de runtime fuera del arbol del proyecto,
evitando que herramientas de desarrollo lean bases de datos, logs o
crypto stores por accidente.
Los paths de memory.db y knowledge.db ahora usan el base resuelto.
Los configs existentes no se rompen (fallback al path original).
Tareas 1.1 y 1.2 del issue 0019.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rate limiting de tool calls por room usando sliding window en el registry.
Config via security.tool_rate_limit en YAML. Loguea tool_rate_limited
al exceder el limite. Tests unitarios y de integracion incluidos.
Sub-issue 0019c del hardening contra prompt injection.
Marca como completadas las tareas de fase 4 (rate limiting) y 6.5
(tests de rate limiting) en el desglose multi-issue.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests unitarios para tools/ratelimit.go:
- Allow dentro del limite, denegacion al exceder
- Keys independientes (rooms distintas no interfieren)
- Expiracion de ventana temporal
- Cleanup de entries expiradas vs activas
Tests de integracion para Registry.ExecuteForRoom:
- Rate limiting activo bloquea tras exceder limite
- Sin rate limiter todas las llamadas pasan
Parte de issue 0019c (tarea 6.5).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Añade rate limiting de tool calls por room usando sliding window:
- tools/ratelimit.go: RateLimiter con sliding window per key (room),
Allow() para verificar/registrar llamadas, Cleanup() para limpiar
entries expiradas
- tools/registry.go: SetRateLimiter() y ExecuteForRoom() que verifica
el rate limit antes de ejecutar, logueando tool_rate_limited si excede
- internal/config/schema.go: ToolRateLimitCfg en SecurityCfg con
enabled, max_calls_per_min y cleanup_interval_s
- agents/runtime.go: inicializa rate limiter desde config y arranca
goroutine de cleanup periodico
- agents/commands.go: usa ExecuteForRoom en !tool command
Config YAML:
security:
tool_rate_limit:
enabled: true
max_calls_per_min: 10
Parte de issue 0019c (prompt injection hardening — rate limiting).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nuevo comando slash que ejecuta de punta a punta el flujo de
implementacion y cierre de un issue, siguiendo estrictamente la
regla fix_issue.md. Incluye:
- Resolucion del issue por numero o slug
- Lectura del issue y extraccion de tareas
- Creacion de rama con /git-branch
- Planificacion con TodoWrite
- Implementacion con compilacion frecuente
- Tests obligatorios antes de cerrar
- Evaluacion de feature flags si aplica
- Cierre del issue (mover a completed/, actualizar README)
- Integracion a master con /git-push
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Marcar como completado: fase 2 (sanitizacion de input) y tarea 6.1
(tests de pkg/sanitize). Actualizar tabla de desglose multi-issue.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
17 test functions cubriendo:
- Deteccion de delimitadores de sistema (<|system|>, [INST], XML tags)
- Override de instrucciones (EN/ES)
- Redefinicion de identidad (you are now / ahora eres)
- Exfiltracion de prompt (EN/ES)
- Jailbreak (developer mode, DAN)
- Evasion base64
- Modos: warn, strip, reject
- Filtro por severidad minima
- Patrones deshabilitados
- False positives: 9 mensajes legitimos verifican 0 warnings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- agents/runtime.go: campo sanitizeOpts en Agent, sanitizeInput() que
llama a sanitize.Sanitize() y loguea warnings. Integrado en
executeActions() y handleTaskEvent() antes de enviar al LLM.
En modo reject, responde al usuario y corta el flujo.
- internal/config/schema.go: nuevo tipo SanitizeCfg dentro de SecurityCfg
con campos enabled, mode, min_severity, disabled_patterns.
Protegido por feature flag prompt-injection-hardening (OFF).
Se activa por agente via security.sanitize.enabled en config.yaml.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nuevo paquete puro (sin I/O) que detecta patrones de prompt injection
en mensajes de usuario antes de enviarlos al LLM.
- patterns.go: 15 patrones en ingles y español (delimitadores de sistema,
override de instrucciones, exfiltracion de prompt, jailbreak, evasion base64)
- sanitize.go: funcion Sanitize() con 3 modos (warn, strip, reject),
filtro por severidad minima y patrones deshabilitables
- Tipos: Pattern, Severity, Mode, Options, Warning, Result
Todo puro: string in → Result out. Los side effects (logging, rechazo)
ocurren en el caller (runtime.go).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Se condensa el archivo principal de contexto eliminando redundancia
con las reglas detalladas que ya viven en .claude/rules/*.md.
Cambios:
- Eliminar secciones duplicadas (dev-scripts, env vars, dependencias,
extensiones pendientes) que ya están documentadas en otros archivos
- Mantener los dos pilares (FP + TBD) como secciones principales
- Condensar estructura de directorios, agentes, build y preferencias
- Referenciar .claude/rules/index.md para guías detalladas
No se pierde información: todo lo eliminado existe en rules/, MEMORY.md,
o README.md. El archivo queda más enfocado y dentro de límites razonables
para el contexto de LLMs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>