Files
fn_registry/dev/issues/0085-registry-call-standardization-and-usage-tracking.md
T
egutierrez 20f72edb5a feat(metabase): auto-commit con 17 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 18:40:22 +02:00

10 KiB

id, title, status, priority, created, related
id title status priority created related
0085 Estandarizar llamadas a funciones del registry desde Claude + app de monitorizacion de uso pending high 2026-05-13
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".