merge: quick/issue-0035-observability — restaurar comandos Claude + issue 0035

Restaura los 4 comandos de .claude/commands/ eliminados por error
y añade el issue 0035 para observabilidad activa (audit trail + !metrics).
This commit is contained in:
2026-04-09 00:46:48 +00:00
6 changed files with 671 additions and 0 deletions
+154
View File
@@ -0,0 +1,154 @@
# Command: create issue
Crea un issue nuevo en `dev/issues/` siguiendo **estrictamente** la regla `create_issue.md`. Si el issue es grande, lo desglosa automaticamente en sub-issues con feature flags.
## Inputs
Se necesitan los datos del issue. Si no se proporcionan, preguntar.
- `titulo`: titulo corto y descriptivo (ej: "Hot reload de configuracion")
- `descripcion`: objetivo/descripcion de lo que se quiere lograr
- `dependencias` (opcional): issues de los que depende (ej: "Requiere issue 0010")
## Flujo obligatorio
### 1. Determinar el numero del issue
Buscar el numero mas alto en `dev/issues/` y `dev/issues/completed/` y usar el siguiente.
Formato: 4 digitos con ceros a la izquierda (`0023`, `0024`, etc.).
```bash
ls dev/issues/ dev/issues/completed/ | grep -oP '^\d{4}' | sort -rn | head -1
```
### 2. Generar slug
A partir del titulo:
- Lowercase
- Palabras separadas por guiones
- Conciso (2-4 palabras)
- Ejemplo: "Hot reload de configuracion" → `hot-reload`
### 3. Evaluar tamano del issue
Antes de escribir el issue, analizar el alcance y determinar si cabe en **una sola rama corta (horas)**.
**Criterios para desglosar en sub-issues:**
- Toca mas de 2 capas del patron (pkg/ + shell/ + agents/ + tools/)
- Requiere mas de ~3 fases de implementacion
- El usuario lo indica explicitamente
- La descripcion implica multiples componentes independientes
**Si es un issue simple** (cabe en una rama):
- Crear un solo archivo `dev/issues/<NNNN>-<slug>.md`
- Seguir directo al paso 4
**Si es un issue grande** (necesita desglose):
- Crear el issue principal `dev/issues/<NNNN>-<slug>.md` con seccion `## Desglose multi-issue`
- Crear cada sub-issue como `dev/issues/<NNNN><letra>-<sub-slug>.md` (ej: `0023a-types`, `0023b-client`)
- Cada sub-issue es autocontenido: debe compilar, pasar tests, no romper master
- Agregar feature flag en la descripcion del issue principal
- Registrar todos los sub-issues en `dev/issues/README.md`
### 4. Crear el issue desde el template
Copiar `.claude/templates/issue.md` y rellenar **todas** las secciones:
- **Objetivo**: 1-3 frases claras
- **Contexto**: que existe, que falta, dependencias
- **Arquitectura**: archivos afectados (marcar `NEW` los nuevos). Explicar que va en `pkg/` (puro) vs `shell/` (impuro)
- **Tareas**: fases con tareas numeradas (`1.1`, `1.2`, etc.). Cada tarea concreta y verificable. Siempre incluir fase de tests y fase de cleanup/docs
- **Ejemplo de uso**: flujo concreto
- **Decisiones de diseno**: justificaciones clave
- **Prerequisitos**: que debe existir antes
- **Riesgos**: problemas potenciales y mitigacion
### 5. Para issues multi-issue — contenido adicional
En el issue principal, agregar despues de las tareas:
```markdown
## Desglose multi-issue
Este issue se implementa en sub-issues independientes, cada uno en su propia rama.
| Sub-issue | Rama | Alcance | Estado |
|-----------|------|---------|--------|
| <NNNN>a-<slug> | issue/<NNNN>a-<slug> | <que cubre> | pendiente |
| <NNNN>b-<slug> | issue/<NNNN>b-<slug> | <que cubre> | pendiente |
| ...
### Feature flag
Nombre: `<nombre-del-flag>`
Se activa en el ultimo sub-issue cuando todo esta integrado.
### Progreso por tarea
- [ ] **1.1** <tarea> — sub-issue <NNNN>a
- [ ] **1.2** <tarea> — sub-issue <NNNN>a
- [ ] **2.1** <tarea> — sub-issue <NNNN>b
...
```
Cada sub-issue individual debe tener su propio archivo con:
- Objetivo especifico del sub-issue
- Tareas que le corresponden del issue principal
- Nota de que es parte de un issue mayor
### 6. Registrar feature flag (solo multi-issue)
Actualizar `dev/feature_flags.json`:
```json
{
"<nombre-del-flag>": {
"enabled": false,
"issue": "<NNNN>",
"description": "<descripcion breve>",
"added": "<YYYY-MM-DD>"
}
}
```
### 7. Actualizar el indice
En `dev/issues/README.md`, agregar filas al final de la tabla.
**Issue simple:**
```markdown
| <N> | <Titulo> | [<NNNN>-<slug>.md](<NNNN>-<slug>.md) | pendiente |
```
**Issue multi-issue (agregar fila por cada sub-issue tambien):**
```markdown
| <N> | <Titulo> | [<NNNN>-<slug>.md](<NNNN>-<slug>.md) | pendiente |
| <N>a | <Titulo> (parte a) | [<NNNN>a-<slug>.md](<NNNN>a-<slug>.md) | pendiente |
| <N>b | <Titulo> (parte b) | [<NNNN>b-<slug>.md](<NNNN>b-<slug>.md) | pendiente |
```
### 8. Verificar
- [ ] Archivo(s) creado(s) en `dev/issues/`
- [ ] Todas las secciones del template rellenadas
- [ ] Fila(s) agregada(s) en `dev/issues/README.md`
- [ ] Numero de issue es consecutivo (sin saltos ni duplicados)
- [ ] Si es multi-issue: sub-issues creados, feature flag en `dev/feature_flags.json`, seccion de desglose en issue principal
### 9. Reportar al usuario
Mostrar resumen:
- Numero y titulo del issue
- Si fue desglosado: listar sub-issues con su alcance
- Recordar: usar `/fix-issue <NNNN>` (o `/fix-issue <NNNN>a`, `<NNNN>b`, etc.) para implementar
## Reglas criticas
- Seguir `create_issue.md` de forma estricta
- **Patron pure core / impure shell**: toda feature debe explicar que va en `pkg/` vs `shell/`
- **Tareas atomicas**: cada tarea debe ser implementable de forma independiente
- **Numeracion continua**: nunca reusar numeros
- **Estado**: issues nuevos siempre `pendiente`
- **Issues grandes**: desglosar en sub-issues con feature flags, nunca dejar una rama abierta por dias
- **Feature flag != WIP**: un flag protege codigo terminado y testeado, no codigo a medias
- **No commitear**: este comando solo crea archivos en `dev/issues/`. No hace commits ni crea ramas
+96
View File
@@ -0,0 +1,96 @@
# Command: fix issue
Ejecuta de punta a punta el flujo de implementacion/cierre de un issue siguiendo **estrictamente** la regla `fix_issue.md`.
## Inputs
Se necesita el issue objetivo. Si no se proporciona, preguntar.
- `issue`: numero o nombre (ej: `0010` o `0010-access-control`)
## Flujo obligatorio
1. Resolver el issue objetivo:
- Si viene solo numero (`0010`), buscar `dev/issues/0010-*.md`.
- Si viene slug completo (`0010-access-control`), usar `dev/issues/0010-access-control.md`.
- Si no existe en `dev/issues/`, **STOP** e informar al usuario.
- Si ya esta en `dev/issues/completed/`, **STOP** e informar al usuario.
2. Leer completo el issue y extraer:
- objetivo
- tareas/fases
- arquitectura y limites (pure core / impure shell)
3. Crear rama de trabajo (inline, sin invocar `/git-branch`):
Verificar la rama actual:
```bash
git branch --show-current
```
- Si ya estamos en `issue/<NNNN>-<slug>` que coincide con el issue → continuar directamente a paso 4.
- Si estamos en `master` o cualquier otra rama → crear la rama:
```bash
git checkout master
git pull --rebase
git checkout -b issue/<NNNN>-<slug>
```
Nunca trabajar directamente en `master`.
4. Planificar con `TodoWrite`:
- Crear plan basado en las tareas del issue.
- Respetar el orden de fases.
- Incluir siempre una tarea de tests.
5. Implementar el issue completo:
- Ejecutar tareas en orden.
- Respetar pure core / impure shell (`pkg/` puro, `shell/` impuro).
- Compilar frecuentemente: `go build -tags goolm ./...`.
- Marcar progreso en `TodoWrite` al completar cada bloque.
6. Tests obligatorios:
```bash
go test -tags goolm ./...
```
- Si falla, corregir antes de continuar.
- No cerrar el issue sin tests pasando.
7. Feature flags (si aplica):
- Evaluar si es feature multi-issue o despliegue gradual.
- Si aplica, actualizar `dev/feature_flags.json` en el commit correspondiente.
- No usar flags para esconder codigo incompleto.
8. Cerrar el issue al terminar:
```bash
mv dev/issues/<NNNN>-<slug>.md dev/issues/completed/
```
Actualizar `dev/issues/README.md`:
- Link a `completed/<NNNN>-<slug>.md`
- Estado a `completado`
9. Integrar/publicar con `/git-push`:
```text
/git-push
```
## Reglas criticas
- Seguir `fix_issue.md` de forma estricta.
- No saltear tareas del issue.
- No hacer commits WIP.
- Commits atomicos por bloque logico (`feat:`, `fix:`, `test:`, `docs:`, `refactor:`, `chore:`).
- Siempre usar `-tags goolm` en build/test.
+86
View File
@@ -0,0 +1,86 @@
# Command: git branch (TBD)
Crea una rama de trabajo. **Nunca trabajar directamente en master.**
Soporta dos tipos de rama:
- `issue/<NNNN>-<slug>` — para implementar un issue existente de `dev/issues/`
- `quick/<slug>` — para cambios pequeños sin issue asociado (fixes, config, docs, etc.)
## Inputs
Preguntar al usuario si el cambio esta asociado a un issue o no.
### Si es un issue:
- `issue_number`: numero de 4 digitos (e.g. `0020`)
- `slug`: nombre corto separado por guiones (e.g. `hot-reload`)
### Si es un cambio rapido (sin issue):
- `slug`: nombre corto descriptivo separado por guiones (e.g. `fix-typo-readme`)
## Flujo obligatorio
1. Verificar que estamos en master y limpio:
```bash
git branch --show-current
git status --short
```
Si no estamos en master, cambiar primero:
```bash
git checkout master
```
Si hay cambios sin commitear, **avisar al usuario** y no continuar hasta resolver.
2. Actualizar master desde remoto:
```bash
git pull --rebase
```
3. Crear la rama y cambiar a ella:
**Para issues:**
```bash
git checkout -b issue/<issue_number>-<slug>
```
Ejemplo: `git checkout -b issue/0013-hot-reload`
**Para cambios rapidos:**
```bash
git checkout -b quick/<slug>
```
Ejemplo: `git checkout -b quick/fix-typo-readme`
4. Confirmar al usuario:
```
Rama `<nombre-rama>` creada desde master actualizado.
Puedes empezar a trabajar. Cuando termines, usa `/git-push` para integrar a master.
```
## Convenciones
- **Formato de rama issue**: `issue/<NNNN>-<slug>` (siempre 4 digitos)
- **Formato de rama quick**: `quick/<slug>` (sin numero)
- **Ramas cortas**: idealmente horas, no dias
- **Una rama por issue**: no mezclar issues en la misma rama
- **Nunca pushear la rama al remoto**: el push se hace desde master despues del merge
- **No rebase interactivo**: si los commits son limpios desde el inicio, no reescribir historia
- **No commits WIP**: cada commit en la rama debe ser atomico y con mensaje real (ver convencion en `/git-push`)
## Features multi-issue
Para features que no caben en una sola rama, usar sub-issues con sufijo letra:
```
issue/0015a-telegram-types
issue/0015b-telegram-client
issue/0015c-telegram-listener
issue/0015d-telegram-enable
```
Cada sub-rama sigue el mismo flujo: crear → implementar → merge --no-ff → delete.
El codigo parcial se protege con **feature flags** en `dev/feature_flags.json` (no con commits WIP).
+157
View File
@@ -0,0 +1,157 @@
# Command: git push
Integra cambios a master y publica. Soporta ramas `issue/*` y `quick/*`.
## Flujo obligatorio
### 1. Verificar rama actual y estado
```bash
git branch --show-current
git status --short
```
#### Si estamos en una rama `issue/*` o `quick/*`
Continuar directamente al paso 2.
#### Si estamos en `master` con cambios pendientes
Crear una rama automaticamente antes de continuar:
1. Preguntar al usuario: **¿Este cambio esta asociado a un issue existente?**
2. **Si es un issue**: pedir el numero y slug, crear rama `issue/<NNNN>-<slug>`.
3. **Si NO es un issue**: pedir un slug descriptivo, crear rama `quick/<slug>`.
```bash
# Para issues:
git checkout -b issue/<NNNN>-<slug>
# Para cambios rapidos:
git checkout -b quick/<slug>
```
4. Continuar al paso 2 con los cambios ya en la rama nueva.
**IMPORTANTE**: No inventar numeros de issue. Solo usar `issue/` si el issue existe en `dev/issues/`.
#### Si estamos en `master` sin cambios
**STOP**: no hay nada que publicar.
### 2. Revisar cambios y crear commits por bloque
```bash
git status --short
git diff --stat
git diff
```
Crear commits **atomicos por bloque logico**. Cada commit agrupa cambios de la misma naturaleza:
```bash
git add <archivos_del_bloque_1>
git commit -m "<tipo>: <resumen breve>" -m "Descripcion larga en espanol explicando que cambia, por que se hizo, impacto esperado y alcance del bloque."
git add <archivos_del_bloque_2>
git commit -m "<tipo>: <resumen breve>" -m "Descripcion larga en espanol."
```
**Reglas criticas de commits:**
- **No WIP**: nunca commitear "wip", "tmp", "fix fix" ni codigo a medias. Cada commit debe ser atomico y completo.
- **No mezclar tipos**: no combinar `feat:` + `test:` en un mismo commit. Separar por bloque logico.
- **No squash**: los commits individuales se preservan en master via `--no-ff`. Usar `git log --first-parent master` para ver solo merge commits.
- **No rebase interactivo**: si los commits ya son limpios, no reescribir historia.
### 3. Ejecutar tests
**Obligatorio antes de mergear.** Si el proyecto tiene tests, ejecutarlos:
```bash
go test -tags goolm ./...
```
- Si los tests **fallan****STOP**: corregir antes de continuar. No mergear codigo roto.
- Si los tests **pasan** → continuar al paso 4.
- Si no hay tests aplicables (e.g. solo cambios de docs/config) → indicar al usuario y continuar.
### 4. Evaluar feature flags
Feature flags se usan cuando el issue es **parte de una feature multi-issue** o el cambio tiene riesgo y necesita poder desactivarse. **Feature flag ≠ WIP** — un flag protege codigo terminado y testeado, no codigo a medias.
Si se modifico `dev/feature_flags.json` o si los cambios son parte de una feature que se despliega en fases:
1. Verificar que `dev/feature_flags.json` existe y esta actualizado.
2. Confirmar que el flag correspondiente tiene el estado correcto (`enabled: true/false`).
3. Incluir el archivo en el commit correspondiente (no crear commit separado solo para flags).
Si el issue es autocontenido (se completa en esta rama), no necesita flag. Saltar este paso.
### 5. Actualizar master y hacer merge --no-ff
```bash
git checkout master
git pull --rebase
git merge --no-ff <rama> -m "merge: <rama> — <titulo breve>"
```
El merge commit debe tener formato:
- Titulo: `merge: <rama> — <descripcion corta>`
- Cuerpo (opcional): resumen de lo que entra
Ejemplos:
- `merge: issue/0021-threads-default-config — habilitar threads en agentes`
- `merge: quick/fix-typo-readme — corregir typo en README`
Si hay conflictos durante el merge:
1. Resolver los conflictos
2. `git add` los archivos resueltos
3. `git commit` (sin -m, para mantener el mensaje de merge)
### 6. Push a remoto
```bash
git push
```
### 7. Limpiar rama local
```bash
git branch -d <rama>
```
### 8. Confirmar al usuario
```
Rama `<rama>` integrada a master y publicada.
Rama local eliminada.
```
## Convencion de commits
- `feat:` nueva funcionalidad
- `fix:` correccion de error
- `refactor:` cambio estructural sin cambio funcional
- `docs:` documentacion
- `chore:` mantenimiento
- `test:` tests nuevos o modificados
- `merge:` commit de merge (generado por --no-ff)
## Regla de mensajes
- El titulo (`-m` corto) debe resumir el bloque.
- El cuerpo (`-m` largo) debe estar en espanol y explicar:
- que se cambio,
- por que se cambio,
- que impacto tiene,
- que no se toco.
## Checklist rapido
- [ ] Todos los cambios estan commiteados en una rama `issue/*` o `quick/*`.
- [ ] Se separaron cambios distintos en commits diferentes.
- [ ] Cada commit tiene descripcion larga en espanol.
- [ ] Tests ejecutados y pasando (o no aplican).
- [ ] Feature flags evaluados (o no aplican).
- [ ] `git merge --no-ff` ejecutado desde master.
- [ ] `git push` ejecutado correctamente.
- [ ] Rama local eliminada.
+177
View File
@@ -0,0 +1,177 @@
# 0035 — Observabilidad activa: audit trail + comando !metrics
**Estado:** pendiente
## Objetivo
Activar la infraestructura de auditoría (`AuditCfg`) que ya está definida en `internal/config/schema.go` pero nunca implementada, y añadir un comando `!metrics` que agregue datos del log del día actual. Ambas features usan infraestructura existente (JSONL logs, config schema, command system) sin dependencias nuevas.
## Contexto
- `AuditCfg` lleva definida desde el schema original pero el código nunca la consume: no hay writer, no hay emisión de eventos, no hay integración con el runtime.
- Los logs JSONL ya contienen métricas útiles (`duration_ms`, `tokens_used`, `tool_exec_*`, `command_received`) pero no hay forma de consultarlas sin parsear archivos manualmente.
- `shell/logger/query.go` ya tiene helpers para leer y filtrar logs por fecha/campo.
- El command system (`!status`, `!info`) ya existe y es extensible via built-in.
## Arquitectura
### Fase 1: Audit trail
```
shell/audit/ NEW — audit event writer (archivo JSONL + opcionalmente room Matrix)
shell/audit/writer.go NEW — AuditWriter: escribe eventos a archivo y/o room
```
Integración en el runtime existente:
```
agents/handler.go MOD — emitir eventos audit en puntos clave
agents/runtime.go MOD — inicializar AuditWriter si cfg.Security.Audit.Enabled
tools/registry.go MOD — emitir evento audit en tool_exec
```
**Pure core / impure shell:**
- No se añade nada a `pkg/` — los eventos audit son side effects puros (escritura a archivo/Matrix)
- `shell/audit/` es 100% impuro: escribe a disco y opcionalmente envía mensajes Matrix
### Fase 2: Comando !metrics
```
agents/commands.go MOD — añadir cmdMetrics como built-in
pkg/command/builtins.go MOD — añadir spec de !metrics
```
El comando lee los JSONL del día actual usando `shell/logger/query.go` (ya existente) y calcula agregados en memoria. No persiste nada, no crea tablas, no necesita SQLite.
## Tareas
### Fase 1 — Audit trail
- [ ] **1.1** Crear `shell/audit/writer.go` con `AuditWriter` struct:
- Constructor `New(cfg AuditCfg, matrixSender func(roomID, msg string), logger *slog.Logger) *AuditWriter`
- Método `Emit(event AuditEvent)` que escribe a `LogFile` (JSONL append) y opcionalmente envía a `LogToRoom` (room Matrix)
- `AuditEvent` struct: `{ Time, AgentID, EventType, SenderID, RoomID, Detail string }`
- Filtrado por `Include` (lista de event types a auditar; vacío = todos)
- Event types iniciales: `command_exec`, `tool_exec`, `llm_request`, `llm_error`, `message_received`
- [ ] **1.2** Crear `shell/audit/writer_test.go`:
- Test de escritura a archivo (verificar formato JSONL)
- Test de filtrado por `Include` (solo emite los tipos configurados)
- Test con `LogFile` vacío (no escribe a archivo, solo room)
- Test con `LogToRoom` vacío (solo escribe a archivo)
- [ ] **1.3** Integrar `AuditWriter` en `agents/runtime.go`:
- En `New()`: si `cfg.Security.Audit.Enabled`, crear `AuditWriter` y guardarlo en el struct `Agent`
- Pasar `matrixSender` como closure que usa el cliente Matrix del agente
- Si audit no está habilitado, `AuditWriter` es nil (los call sites hacen nil-check)
- [ ] **1.4** Emitir eventos en los puntos clave:
- `agents/handler.go``message_received` (sender, room, is_dm)
- `agents/handler.go``command_exec` (command name, sender)
- `tools/registry.go``tool_exec` (tool name, duration, success/error)
- `shell/llm/``llm_request` (provider, model, tokens) y `llm_error` (provider, error)
### Fase 2 — Comando !metrics
- [ ] **2.1** Añadir spec en `pkg/command/builtins.go`:
```go
{Name: "metrics", Description: "Métricas agregadas del día actual", Usage: "!metrics"}
```
- [ ] **2.2** Implementar `cmdMetrics` en `agents/commands.go`:
- Leer logs del día actual con `logger.ReadDayLogs(logDir, agentID, time.Now())`
- Calcular: total mensajes recibidos, comandos ejecutados, llamadas LLM (count + tokens totales + latencia media), llamadas a tools (count + errores), errores totales
- Formatear como markdown table para Matrix
- Ejemplo de output:
```
**Métricas de hoy (2026-04-09):**
| Métrica | Valor |
|---------|-------|
| Mensajes recibidos | 42 |
| Comandos ejecutados | 15 |
| Llamadas LLM | 27 |
| Tokens totales | 45,230 |
| Latencia LLM media | 1,250 ms |
| Tool calls | 8 |
| Tool errors | 1 |
| Errores totales | 2 |
| Uptime | 6h 30m |
```
- [ ] **2.3** El handler necesita acceso al `logDir` del agente — pasar via config o campo en Agent struct (ya existe `a.cfg` con el agent ID, solo falta saber el baseDir de logs)
### Fase 3 — Tests y cleanup
- [ ] **3.1** Tests para `cmdMetrics`: crear logs JSONL de ejemplo en tmpdir, verificar que los agregados son correctos
- [ ] **3.2** Test de integración: `AuditWriter` + handler emite eventos reales a archivo temporal
- [ ] **3.3** Documentar en `docs/security.md` la sección de audit trail (config YAML de ejemplo)
## Ejemplo de uso
### Audit trail
Config en `agents/asistente-2/config.yaml`:
```yaml
security:
audit:
enabled: true
log_file: "logs/asistente-2/audit.jsonl"
log_to_room: "!audit-room:matrix-af2f3d.organic-machine.com"
include:
- command_exec
- tool_exec
- llm_error
```
Resultado en `audit.jsonl`:
```json
{"time":"2026-04-09T10:30:00Z","agent_id":"asistente-2","event":"command_exec","sender":"@user:matrix","room":"!abc:matrix","detail":"!status"}
{"time":"2026-04-09T10:30:05Z","agent_id":"asistente-2","event":"tool_exec","sender":"@user:matrix","room":"!abc:matrix","detail":"http_get duration=350ms ok"}
```
### Comando !metrics
```
Usuario: !metrics
Bot:
**Métricas de hoy (2026-04-09):**
| Métrica | Valor |
|---------|-------|
| Mensajes recibidos | 42 |
| Comandos ejecutados | 15 |
| Llamadas LLM | 27 |
| Tokens totales | 45,230 |
| Latencia LLM media | 1,250 ms |
| Tool calls | 8 |
| Tool errors | 1 |
| Errores totales | 2 |
| Uptime | 6h 30m |
```
## Decisiones de diseño
1. **Audit separado de logs normales**: los logs de runtime son para debugging (alto volumen, retención corta). El audit trail es para compliance/revisión (eventos selectivos, retención configurable independiente).
2. **Sin SQLite para métricas**: el comando `!metrics` calcula en memoria leyendo JSONL del día. Con los volúmenes actuales (~cientos de eventos/día por agente), esto es instantáneo. Si escala, se puede cachear o migrar a SQLite en un issue futuro.
3. **AuditWriter acepta matrixSender como función**: evita acoplar `shell/audit/` con el cliente Matrix directamente. Sigue el patrón de inyección de dependencias del proyecto.
4. **Include como allowlist**: lista vacía = auditar todo. Esto es deny-by-default invertido (opt-in por tipo de evento) para evitar audit logs gigantes.
## Prerequisitos
Ninguno. Todo usa infraestructura existente:
- `AuditCfg` en `internal/config/schema.go`
- `shell/logger/query.go` para leer JSONL
- `pkg/command/builtins.go` para registrar `!metrics`
- `agents/commands.go` para implementar el handler
## Riesgos
| Riesgo | Mitigación |
|--------|------------|
| Audit file crece sin límite | Usar el mismo `DailyRotatingWriter` de `shell/logger/` o rotación externa (logrotate) |
| `LogToRoom` falla (room no existe) | Log warning y continuar — audit a archivo no debe fallar por Matrix |
| `!metrics` lento con logs muy grandes | Los JSONL se rotan a 50MB max. Un día normal tiene KB-pocos MB. Aceptable. |
| Audit de `message_received` loguea contenido sensible | El `Detail` solo incluye metadata (sender, room, is_dm), nunca el body del mensaje |
+1
View File
@@ -45,3 +45,4 @@ afectados y notas de implementacion.
| 32 | E2E: verificar skill /create-agent | [0032-e2e-create-agent-skill.md](0032-e2e-create-agent-skill.md) | pendiente |
| 33 | Comandos de robots sin prefijo ! | [0033-bot-commands-no-prefix.md](0033-bot-commands-no-prefix.md) | pendiente |
| 34 | E2E: verificar skill /create-bot | [0034-e2e-create-bot-skill.md](0034-e2e-create-bot-skill.md) | pendiente |
| 35 | Audit trail + comando !metrics | [0035-audit-trail-metrics.md](0035-audit-trail-metrics.md) | pendiente |