feat(metabase): auto-commit con 17 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
---
|
||||
id: 0085
|
||||
title: Estandarizar llamadas a funciones del registry desde Claude + app de monitorizacion de uso
|
||||
status: pending
|
||||
priority: high
|
||||
created: 2026-05-13
|
||||
related: [0068, 0069]
|
||||
---
|
||||
|
||||
## Contexto
|
||||
|
||||
Claude actualmente invoca funciones del registry de formas heterogeneas y sin trazabilidad:
|
||||
|
||||
| Patron de invocacion | Frecuencia esta sesion (meta_bigq) | Trazabilidad |
|
||||
|---|---|---|
|
||||
| Heredoc Python inline (`python/.venv/bin/python3 - <<'PYEOF' ... PYEOF`) | ~15 veces | ninguna (queda en transcript) |
|
||||
| Bash inline con `sqlite3 registry.db "..."` | 1 (violando regla MCP-first) | ninguna |
|
||||
| `./fn run <id>` CLI | 0 | log en stdout, no persistido |
|
||||
| `mcp__registry__fn_run` MCP tool | 0 | mensaje tool-result |
|
||||
| `mcp__registry__fn_search/show/code` | 0 (deberia haber sido obligatorio) | ninguna |
|
||||
| Imports directos `from metabase import ...` en heredoc | en cada heredoc | ninguna |
|
||||
| `client._http.request(...)` directo saltando funciones del registry | varias veces (para PUT custom como result_metadata) | ninguna |
|
||||
|
||||
Consecuencias:
|
||||
- **No sabemos que funciones del registry usa Claude realmente**. Hay ~1200 funciones indexadas pero solo unas pocas se usan en cada sesion. Imposible decidir cuales deprecar, cuales mejorar, cuales son criticas.
|
||||
- **Cada sesion reinventa boilerplate**. Patrones repetitivos (refresh `result_metadata`, dispatch `dimension` vs `variable` mapping, batch param config) se reescriben inline. Si se extraen como funciones del registry nadie lo nota porque no hay metricas de "esto se repite mucho".
|
||||
- **CLAUDE.md tiene reglas (MCP-first, registry-first) que se violan silenciosamente**. Sin telemetria, la regla es aspiracional.
|
||||
- **No hay datos para que el bucle reactivo mejore el registry**. El analizador/mejorador deberian saber "esta funcion se uso 50 veces, esta 0 veces, esta fallo 8 veces" — info que ahora mismo no existe.
|
||||
|
||||
## Objetivo
|
||||
|
||||
1. **Estandarizar** como Claude invoca funciones del registry (un patron canonico por caso de uso).
|
||||
2. **Instrumentar** todas las invocaciones para que dejen rastro en una BD local.
|
||||
3. **App `claude_call_monitor`** (TUI o web) que muestra uso por funcion, latencia, errores, patrones repetidos, violaciones de reglas.
|
||||
4. **Feedback al registry**: marcar funciones "huerfanas", proponer extracciones cuando un mismo bloque inline se repite N veces, sugerir helpers nuevos.
|
||||
|
||||
## Diseno
|
||||
|
||||
### Fase 1 — Estandarizacion de invocaciones
|
||||
|
||||
Tres patrones canonicos. Cada uno con su tool de entrada y formato de log.
|
||||
|
||||
| Caso de uso | Patron canonico | Cuando usar |
|
||||
|---|---|---|
|
||||
| **Inspeccion del registry** (buscar, leer, ver dependencias) | `mcp__registry__fn_search/show/code/uses` | SIEMPRE. Reemplaza `sqlite3 registry.db "..."` inline. CLAUDE.md ya lo exige; ahora se hace cumplir via lint del log |
|
||||
| **Ejecucion de pipeline/funcion 1-shot** | `mcp__registry__fn_run <id> [args]` o `./fn run <id> [args]` | Cuando hay UNA funcion/pipeline a lanzar con sus args. Salida estructurada |
|
||||
| **Composicion ad-hoc multi-funcion** | Heredoc Python via Bash, importando del registry | Cuando hay logica intermedia (loops, conditionals, dispatch). Esta sesion casi todo el trabajo cae aqui |
|
||||
|
||||
Para composiciones que se repiten: extraer a `python/functions/pipelines/` o a una funcion del registry. Decision basada en datos del monitor (ver fase 3).
|
||||
|
||||
### Fase 2 — Instrumentacion
|
||||
|
||||
Hook + libreria que captura cada invocacion. Stack propuesto:
|
||||
|
||||
**2a. Hook en Bash tool**: parsea cada comando Bash. Si contiene heredoc Python `python/.venv/bin/python3` o invoca `./fn run` o `mcp__registry__fn_*`, captura:
|
||||
- timestamp_start, timestamp_end, duration_ms
|
||||
- session_id (del log de Claude Code)
|
||||
- tool_used (Bash heredoc / fn_run / mcp_fn_X / mcp_fn_search / sqlite_direct / etc.)
|
||||
- functions_imported (parse `from <pkg> import <names>`)
|
||||
- functions_called (mejor esfuerzo: regex sobre el codigo del heredoc + para fn_run el id explicito)
|
||||
- success / exit_code / error_snippet
|
||||
- patron_detected (refresh_metadata, build_mappings, etc — clasificadores configurables)
|
||||
|
||||
Implementacion: hook `PostToolUse` en `~/.claude/settings.json` que llama a un binario Go que escribe en `~/.claude/projects/<proj>/call_monitor.db` (SQLite).
|
||||
|
||||
**2b. Wrapper Python**: `from registry_telemetry import wrap` que parchea las funciones del paquete `metabase`/`bigquery`/etc al importarse en heredoc. Cada llamada se loguea (function_id, args_hash, duration, success). Solo se activa si env var `FN_TELEMETRY=1` (no romper otros usos).
|
||||
|
||||
**2c. Hook directo en MCP `registry`**: si el server MCP esta bajo nuestro control, anadir logging en cada tool call (mas confiable que parsear bash).
|
||||
|
||||
Las 3 fuentes se cruzan: si una sesion tiene Bash heredoc usando `metabase_get_dashboard` pero no aparece en MCP logs, es violacion (deberia haber usado `mcp__registry__fn_show` para inspeccionar antes).
|
||||
|
||||
### Fase 3 — App `claude_call_monitor`
|
||||
|
||||
App standalone en `apps/claude_call_monitor/` o `projects/fn_monitoring/apps/claude_call_monitor/`. Stack:
|
||||
- Backend Go (sirve datos de `call_monitor.db` + agregados)
|
||||
- Frontend React + Mantine (consume `@fn_library`) o TUI con `cpp/framework` ImGui — segun preferencia
|
||||
|
||||
Vistas minimas:
|
||||
|
||||
1. **Top funciones por uso** — tabla rankada: `function_id, calls_24h, calls_7d, mean_duration_ms, error_rate, last_used_at`. Filtros por dominio/lang/purity.
|
||||
2. **Funciones huerfanas** — listado de funciones del registry con `calls_30d = 0`. Cruzado con `fn doctor unused` para distinguir "nunca usada" vs "no usada por Claude pero si por humanos".
|
||||
3. **Patrones repetidos** — clusterizacion de heredocs Python por similitud. Detecta cuando un bloque inline se repite N veces → proposal automatico para extraer a funcion.
|
||||
4. **Violaciones de regla** — usos de `sqlite3 registry.db` directo, uso de `Centros_ISO_Limpio` cuando deberia ser via card snippet, etc. Reglas configurables en YAML.
|
||||
5. **Sesion view** — timeline de una sesion (Claude Code session_id) con todas las llamadas, errores, duraciones. Util para post-mortem.
|
||||
6. **Health score** — score 0-100 por sesion: ratio de invocaciones canonicas vs ad-hoc, errores, repeticiones. Telemetria para mejorar prompts del agente.
|
||||
|
||||
### Fase 4 — Feedback al registry
|
||||
|
||||
Hooks de salida del monitor:
|
||||
|
||||
- **Proposals automaticas**: cuando un patron inline se repite >5 veces en distintas sesiones, se crea proposal `new_function` en `registry.db` con evidencia (lista de session_ids + snippet representativo). El humano (o `fn-mejorador`) decide si aprobar.
|
||||
- **Deprecation candidates**: funciones con `calls_90d = 0` y sin `uses_functions` upstream → proposal `deprecate_function`.
|
||||
- **Performance regressions**: funciones cuyo `mean_duration_ms` crece >50% entre semanas → flag al humano.
|
||||
|
||||
## Implementacion por pasos
|
||||
|
||||
| Paso | Tarea | Sub-issue |
|
||||
|---|---|---|
|
||||
| 1 | Migracion `call_monitor.db` schema (`calls`, `sessions`, `patterns`, `violations`) | 0085a |
|
||||
| 2 | Hook Bash `PostToolUse` que parsea comandos y escribe a `calls` | 0085b |
|
||||
| 3 | Wrapper Python opcional con `FN_TELEMETRY=1` | 0085c |
|
||||
| 4 | App `claude_call_monitor` skeleton (Go API + frontend) | 0085d |
|
||||
| 5 | Vistas: top usage, huerfanas, sesiones | 0085e |
|
||||
| 6 | Clusterizacion de heredocs + deteccion de patrones | 0085f |
|
||||
| 7 | Reglas de violacion configurables (YAML) | 0085g |
|
||||
| 8 | Pipeline `fn-monitor proposal` que crea proposals automaticas en `registry.db` desde patrones detectados | 0085h |
|
||||
| 9 | `e2e_checks` para la propia app del monitor | 0085i |
|
||||
| 10 | Documentacion en CLAUDE.md: patrones canonicos + como leer el monitor | 0085j |
|
||||
|
||||
## Criterios de exito
|
||||
|
||||
- Todas las invocaciones de funciones del registry desde Claude quedan registradas (>95% cobertura medida cruzando 3 fuentes).
|
||||
- App `claude_call_monitor` muestra top-20 funciones usadas por Claude en los ultimos 7 dias con metricas reales.
|
||||
- Se detectan al menos 5 patrones repetidos como candidatos a extraccion (con evidencia trazable).
|
||||
- Se identifican >50 funciones huerfanas para decision (deprecar/promover/dejar).
|
||||
- CLAUDE.md tiene seccion "Como llamar a funciones del registry" con los 3 patrones canonicos + tabla "cuando usar cual".
|
||||
- El bucle reactivo (0068) tiene un nuevo input: assertions sobre uso de funciones → proposals.
|
||||
|
||||
## Anti-patrones a prohibir explicitamente
|
||||
|
||||
| Patron | Por que | Alternativa |
|
||||
|---|---|---|
|
||||
| `sqlite3 registry.db "SELECT ..."` para inspeccionar funciones | Salta MCP, no hay logging, FTS5 gotchas | `mcp__registry__fn_search "..."` |
|
||||
| `python -c "import metabase; print(dir(metabase))"` para descubrir helpers | Salta el registry como fuente de verdad | `mcp__registry__fn_search "metabase"` + `mcp__registry__fn_show <id>` |
|
||||
| Heredoc que reescribe logica que ya existe como funcion | Reinvento + perdida de capitalizacion | Primero `fn_search`, luego importar |
|
||||
| `client._http.request(...)` directo cuando hay un wrapper del registry | Salta validacion y telemetria del wrapper | Usar la funcion del registry; si falta una, delegar a `fn-constructor` |
|
||||
| Crear scripts en `temp/` o paths sueltos cuando es composicion repetida | Codigo se pierde, no se monitoriza | Si patron se repite → pipeline en `python/functions/pipelines/` |
|
||||
|
||||
## Stakeholders
|
||||
|
||||
- **Usuario humano (Lucas / Emanuel)**: revisa proposals automaticas, prioriza extracciones, decide deprecaciones.
|
||||
- **Claude (agente principal)**: lee CLAUDE.md actualizado, usa patrones canonicos, recibe feedback de monitor en CLAUDE.md (top huerfanas, top errores).
|
||||
- **fn-mejorador (fase 5 bucle reactivo)**: consume `call_monitor.db` para generar proposals con evidencia real de uso.
|
||||
- **fn-orquestador (issue 0069)**: usa health score del monitor como criterio adicional de exito.
|
||||
|
||||
## Notas
|
||||
|
||||
- Esta issue no requiere refactorizar las 1200 funciones existentes — solo capturar como se invocan.
|
||||
- El monitor empieza pasivo (solo loguea). En una fase posterior puede bloquear violaciones criticas (ej. `sqlite3 registry.db` directo aborta con mensaje + sugerencia).
|
||||
- Datos sensibles: el `args_hash` se guarda pero los valores concretos NO. Para queries SQL que contienen secretos por accidente, mantener allowlist de redaccion.
|
||||
- Compatible con el patron de `task_runs` del issue 0069 — comparten el concepto de "ejecucion trazable".
|
||||
Reference in New Issue
Block a user