fa2d4a3177
- app.md - call_monitor - main.go - operations.db - operations.db-shm - operations.db-wal - daemon.go Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
171 lines
6.8 KiB
Markdown
171 lines
6.8 KiB
Markdown
---
|
|
name: call_monitor
|
|
lang: go
|
|
domain: infra
|
|
version: 0.1.0
|
|
description: "Telemetria de invocaciones del agente al fn_registry. Persiste eventos (calls, code_writes, test_runs, e2e_runs_fn, violations, patterns, sessions) en su propia operations.db. Vista agregada function_stats por function_id alimenta el bucle reactivo (proposals automaticas). Issue 0085."
|
|
tags: [service, telemetry, monitoring, registry, sqlite]
|
|
uses_functions:
|
|
- sqlite_open_go_infra
|
|
- sqlite_apply_migrations_go_infra
|
|
- audit_copied_code_go_infra
|
|
- generate_proposals_from_telemetry_go_infra
|
|
uses_types: []
|
|
framework: "stdlib"
|
|
entry_point: "main.go"
|
|
dir_path: "projects/fn_monitoring/apps/call_monitor"
|
|
repo_url: ""
|
|
service:
|
|
port: null
|
|
health_endpoint: null
|
|
health_timeout_s: 3
|
|
systemd_unit: call_monitor.service
|
|
systemd_scope: user
|
|
restart_policy: always
|
|
runtime: systemd-user
|
|
pc_targets:
|
|
- aurgi-pc
|
|
- home-wsl
|
|
is_local_only: true
|
|
# Runtime: subcomando `daemon` mantiene loop cada `--interval` (default 5m)
|
|
# llamando snapshot + sequences --detect --propose. Ver daemon.go.
|
|
e2e_checks:
|
|
- id: build
|
|
cmd: "CGO_ENABLED=1 go build -tags fts5 -o call_monitor ."
|
|
timeout_s: 60
|
|
- id: init
|
|
cmd: "./call_monitor init --db /tmp/call_monitor_e2e.db"
|
|
expect_stdout_contains: "ready"
|
|
- id: status_empty
|
|
cmd: "./call_monitor status --db /tmp/call_monitor_e2e.db"
|
|
expect_stdout_contains: "no calls recorded yet"
|
|
- id: schema_view
|
|
cmd: "sqlite3 /tmp/call_monitor_e2e.db 'SELECT COUNT(*) FROM function_stats;'"
|
|
expect_stdout_contains: "0"
|
|
---
|
|
|
|
## Arquitectura
|
|
|
|
App Go bajo modulo `fn-registry` (sin `go.mod` propio). Estructura:
|
|
|
|
```
|
|
projects/fn_monitoring/apps/call_monitor/
|
|
app.md
|
|
main.go # CLI: init, status
|
|
db.go # openDB + apply migrations + queries
|
|
migrations/
|
|
001_init.sql # 7 tablas event-log
|
|
002_function_stats_view.sql # vista agregada por function_id
|
|
operations.db # creada al primer init (gitignored)
|
|
```
|
|
|
|
Reusa `infra.SQLiteOpen` + `infra.ApplyMigrations` del registry (mismo patron que `apps/kanban/backend/db.go`).
|
|
|
|
## Tablas event-log (append-only)
|
|
|
|
| Tabla | Captura |
|
|
|---|---|
|
|
| `sessions` | Sesion Claude Code: session_id, cwd, started_at, ended_at, health_score, mcp_ratio |
|
|
| `calls` | Cada invocacion al registry (heredoc/mcp/fn_run): function_id, tool_used, duration_ms, success, error_class, args_hash |
|
|
| `code_writes` | Edit/Write sobre archivo del registry: function_id, file_path, lines_added/removed |
|
|
| `test_runs` | Unit tests: function_id, test_id, passed, duration_ms, output_snippet |
|
|
| `e2e_runs_fn` | E2E checks de apps que dependen: function_id, app_id, check_id, passed |
|
|
| `violations` | Antipatrones (sqlite3 inline, import *, heredoc reinvento): rule_id, function_id, severity |
|
|
| `patterns` | Heredocs clusterizados por similitud: pattern_hash, occurrences, session_ids[] |
|
|
| `function_versions` | Historial de versiones por function_id. source = `index` (poblado por `call_monitor snapshot` tras `fn index`), `edit_hook` (poblado por hook PostToolUse), `copy_detected` (futura fase 0085k) |
|
|
|
|
Datos sensibles: solo `args_hash`, NUNCA argumentos concretos.
|
|
|
|
## Vista `function_stats`
|
|
|
|
Rollup por `function_id` con:
|
|
|
|
- **Uso**: calls_total, calls_24h/7d/30d/90d, last_used_at
|
|
- **Errores**: errors_total, error_rate, last_error_ts
|
|
- **Performance**: mean_duration_ms (p95 pendiente — requires window functions o sub-query)
|
|
- **Codigo**: writes_count, last_write_at
|
|
- **Tests**: tests_total, tests_failed, test_fail_rate, last_test_failed_at
|
|
- **E2E**: e2e_total, e2e_failed, e2e_fail_rate, consumer_apps_count
|
|
- **Salud**: violations_caused
|
|
|
|
Vista O(N) sobre tablas event-log. Si performance degrada en >100k filas, materializar como TABLE refrescada por cron.
|
|
|
|
## Uso
|
|
|
|
```bash
|
|
# Build
|
|
cd projects/fn_monitoring/apps/call_monitor
|
|
CGO_ENABLED=1 go build -tags fts5 -o call_monitor .
|
|
|
|
# Crear/abrir BD (aplica migraciones idempotentemente)
|
|
./call_monitor init
|
|
|
|
# Resumen actual
|
|
./call_monitor status --top 20
|
|
|
|
# Snapshot versions desde registry.db (idempotente, ejecutar tras cada fn index)
|
|
./call_monitor snapshot
|
|
./call_monitor snapshot --registry /home/lucas/fn_registry/registry.db
|
|
|
|
# BD personalizada
|
|
./call_monitor init --db /tmp/test.db
|
|
./call_monitor status --db /tmp/test.db
|
|
```
|
|
|
|
## Integracion con el resto
|
|
|
|
| Componente | Como interactua |
|
|
|---|---|
|
|
| Hook `PostToolUse` (0085b) | Parsea cada Bash + cada mcp__registry__* y hace `INSERT INTO calls/...` directo sobre operations.db |
|
|
| Wrapper Python `registry_telemetry` (0085c) | Patcha imports al activar `FN_TELEMETRY=1`, registra calls del heredoc |
|
|
| `registry_dashboard` (UI) | Lee via `sqlite_api`: nuevo datasource `ops:call_monitor`. Tab "Claude usage" con top funciones, huerfanas, patrones |
|
|
| `fn-mejorador` (fase 5 bucle reactivo) | Consulta `function_stats` + `patterns` + `violations` para generar proposals con evidencia trazable |
|
|
| `fn-orquestador` (issue 0069) | Usa `sessions.health_score` como criterio de exito adicional |
|
|
|
|
## Roadmap
|
|
|
|
- 0085a (este paso): schema + skeleton ✓
|
|
- 0085b: hook PostToolUse Bash que insert en `calls`/`code_writes`/`violations`
|
|
- 0085c: wrapper Python con `FN_TELEMETRY=1`
|
|
- 0085d: anadir datasource a `sqlite_api` + tabs en `registry_dashboard`
|
|
- 0085e..h: clusterizacion, proposals automaticas, gating
|
|
- p95 en mean_duration_ms via percentile calc o ext.
|
|
|
|
## Automation (systemd user timer)
|
|
|
|
`sequences --detect --propose --report` corre cada 6h via systemd user timer (00:00, 06:00, 12:00, 18:00). Detecta secuencias A→B(→C) repetidas en `calls` y genera proposals `new_pipeline` en `registry.db` (idempotente — dedupea contra proposals existentes).
|
|
|
|
Unit files versionados en `systemd/` para sincronizar entre PCs. Activacion en un PC nuevo:
|
|
|
|
```bash
|
|
cp systemd/call_monitor_sequences.* ~/.config/systemd/user/
|
|
systemctl --user daemon-reload
|
|
systemctl --user enable --now call_monitor_sequences.timer
|
|
```
|
|
|
|
Verificar:
|
|
|
|
```bash
|
|
systemctl --user list-timers call_monitor_sequences.timer
|
|
systemctl --user status call_monitor_sequences.service
|
|
journalctl --user -u call_monitor_sequences.service -n 30 --no-pager
|
|
```
|
|
|
|
Para correr manualmente fuera del schedule: `systemctl --user start call_monitor_sequences.service`.
|
|
|
|
## Notas
|
|
|
|
- BD vive **junto al binario** (`<exe_dir>/operations.db`) por defecto, no en el cwd del agente. Hook puede pasar `--db` explicito si conviene.
|
|
- `operations.db` gitignored — telemetria es local por PC, no se sincroniza.
|
|
- Sin `repo_url`: aun no se ha hecho `gitea_create_repo`. Se inicializara con `/full-git-push` cuando este la fase 0085b lista para evitar repos vacios.
|
|
|
|
|
|
## Capability growth log
|
|
|
|
Una linea por bump SemVer. Bump-type segun `.claude/commands/version.md`:
|
|
- `major`: breaking observable (CLI args, schema BBDD propia, formato wire).
|
|
- `minor`: feature aditiva (nuevo panel, endpoint, opcion).
|
|
- `patch`: bugfix sin cambio observable.
|
|
|
|
- v0.1.0 (2026-05-18) — baseline.
|