Files
fn_registry/.claude/rules/registry_calls.md
T
egutierrez 47fac22230 chore: auto-commit (799 archivos)
- .claude/CLAUDE.md
- .claude/commands/subagentes.md
- .claude/rules/INDEX.md
- .mcp.json
- bash/functions/cybersecurity/analyze_dns.md
- bash/functions/cybersecurity/audit_http_headers.md
- bash/functions/cybersecurity/audit_ssh_config.md
- bash/functions/cybersecurity/check_firewall.md
- bash/functions/cybersecurity/detect_suspicious_users.md
- bash/functions/cybersecurity/encrypt_file.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 00:28:20 +02:00

8.3 KiB

Como invocar funciones del registry — patrones canonicos

Toda invocacion del agente al registry sigue uno de tres patrones. Cualquier otro patron es antipatron auditable. Las invocaciones se loguean en projects/fn_monitoring/apps/call_monitor/operations.db (issue 0085) para alimentar el bucle reactivo.

Patrones canonicos

Caso Patron Cuando
Inspeccionar (buscar, leer codigo, ver dependencias, listar dominios, leer proposals) mcp__registry__fn_search / fn_show / fn_code / fn_uses / fn_list_domains / fn_proposal SIEMPRE para descubrimiento, lectura de codigo, exploracion.
Ejecutar UNA funcion/pipeline con sus args mcp__registry__fn_run <id> [args] (preferido) o ./fn run <id> [args] (fallback CLI) ID conocido + args planos. Despacho automatico por lenguaje.
Componer ad-hoc multi-funcion con logica intermedia Heredoc python/.venv/bin/python3 - <<'PYEOF' ... PYEOF IMPORTANDO funciones del registry Solo si hay loops/conditionals/dispatch entre N funciones. Las funciones del registry se importan, no se reescriben.

Antipatrones prohibidos (audit-targeted)

Patron Razon Sustituir por
sqlite3 registry.db "SELECT ..." para buscar funciones/tipos Salta MCP, FTS5 gotchas, sin trazabilidad mcp__registry__fn_search
sqlite3 registry.db "SELECT ... FROM proposals" Mismo problema mcp__registry__fn_proposal
python -c "import metabase; dir(metabase)" para descubrir helpers Fuente de verdad = registry, no __init__.py mcp__registry__fn_search "metabase" + mcp__registry__fn_show <id>
Heredoc que reescribe logica que ya existe como funcion del registry Reinvento + perdida de capitalizacion Buscar primero; si falta, delegar a fn-constructor (no escribir inline)
client._http.request(...) saltando wrapper del registry Salta validacion del wrapper y telemetria Usar wrapper; si firma incompleta, fn proposal add --kind improve_function
Scripts en temp/ para composiciones que se repiten >2 veces Codigo perdido + sin monitoreo Pipeline en python/functions/pipelines/ o bash/functions/pipelines/
from <pkg> import * en heredoc Imposible identificar funciones usadas Imports explicitos from <domain> import <name1>, <name2>

Excepciones autorizadas para sqlite3 directo

Casos donde el MCP no aplica y sqlite3 registry.db es legitimo:

  • Introspeccion de schema: .schema, .tables, PRAGMA table_info(...), PRAGMA index_list(...).
  • Agregaciones: COUNT(*), GROUP BY, SUM(...), AVG(...).
  • JOINs custom entre tablas que el MCP no expone (functions JOIN unit_tests ON ...).
  • Columnas que el MCP no devuelve (rare; preferir proponer ampliacion del MCP).

El hook PreToolUse (.claude/scripts/hook_registry_mcp.sh) ya deja pasar estas excepciones y solo avisa cuando ve sqlite3 registry.db "SELECT ..." plano.

Verificacion previa — fn doctor

Antes de empezar trabajo no trivial sobre el registry, ejecutar fn doctor para confirmar que el ecosistema esta sano:

  • Artefactos OK (sin git_not_initialized, venv_broken_path, etc.).
  • Services activos cuando se necesiten (sqlite_api, registry_api, registry_mcp).
  • Sin drift pc_locations vs disco.
  • Sin drift uses_functions vs imports reales.

Si fn doctor reporta service inactive para registry_mcp.service, el MCP estara siendo invocado en modo stdio por Claude Code (normal); el systemd unit solo aplica al modo HTTP. Si el binario no responde, rebuild: cd apps/registry_mcp && CGO_ENABLED=1 go build -tags fts5 -o registry_mcp ..

Tools MCP disponibles

Tool Lectura/escritura Gating
fn_search read siempre on
fn_show read siempre on
fn_code read siempre on
fn_uses read siempre on
fn_list_domains read siempre on
fn_proposal read siempre on
fn_doctor read siempre on
fn_run execute (mutating side-effects) requiere --enable-run
fn_create_function write requiere --enable-write

Heredoc Python — convenciones obligatorias

Cuando el caso 3 (composicion) sea inevitable:

  1. Imports explicitos desde paquetes del registry. Nunca import *.
  2. No reescribir la firma de una funcion del registry — importarla.
  3. Args via env vars o stdin JSON, nunca interpolacion shell directa (inyeccion).
  4. Output a stdout JSON cuando vaya a ser consumido por el siguiente paso.
  5. Si el heredoc supera ~30 lineas, extraer a python/functions/pipelines/. El monitor avisara automaticamente cuando un patron similar se repita >5 veces.

Trazabilidad — bucle reactivo

Cada evento alimenta a call_monitor.db (event-log append-only) y se rollupea en una vista function_stats con contadores por funcion del registry. Tablas event-log:

Tabla Captura
calls Cada invocacion (heredoc/mcp/fn_run): function_id, tool_used, duration_ms, success, error_class, args_hash
code_writes Cada Edit/Write sobre archivo del registry: function_id, session_id, lines_added/removed
test_runs Cada go test/pytest que toca codigo del registry: function_id, test_id, passed, duration_ms
e2e_runs_fn Cada check e2e_checks de app que usa la funcion: function_id, app_id, check_id, passed
violations Antipatron detectado: rule_id, session_id, command_snippet, severity
patterns Heredocs clusterizados: pattern_hash, session_ids[], occurrences, representative_snippet
sessions session_id, cwd, started_at, ended_at, health_score, mcp_ratio

Vista agregada function_stats por function_id:

  • Uso: calls_total, calls_24h/7d/30d/90d, last_used_at
  • Errores: errors_total, error_rate, last_error_class, last_error_ts
  • Performance: mean_duration_ms, p95_duration_ms
  • 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

Assertions derivadas → proposals automaticas:

Regla Threshold Proposal
Huerfana absoluta calls_90d=0 AND writes_count=0 deprecate_function
Bug prioritario error_rate>0.1 AND calls_7d>5 improve_function (bug)
Regresion performance p95_24h > 1.5 * p95_30d improve_function (perf)
Test flaky test_fail_rate>0.1 AND tests_total>10 improve_function (flaky)
Wrapper saltado violations_caused>3 improve_function (API gap)
Patron inline sin funcion patterns.occurrences>5 AND no match FTS new_function con snippet
Blast radius alto e2e_fail_rate>0 AND consumer_apps_count>=3 improve_function (critical)

Datos sensibles: solo args_hash, NUNCA valores concretos. Snippets de error redactados via allowlist.

Capas de monitorizacion (issue 0085)

Cobertura por capa, no todas activas a la vez:

# Capa Activacion Cobertura
1 Hook PostToolUse Bash siempre (settings.local.json) mcp, fn_cli_run, edit_registry, violations
2 Wrapper Python registry_telemetry FN_TELEMETRY=1 env var heredocs + notebooks Jupyter
3 Wrapper Bash telemetry_prelude.sh source explicito o FN_TELEMETRY=1 heredoc bash + apps bash
4 Interceptor en fn run siempre (binario Go) duration/error real de invocacion CLI
5 fn doctor copied-code comando manual / cron drift estatico: codigo copiado en apps
6 function_versions + snapshot poblado por fn index + edit-hook historial de versiones
7-8 Build-tag Go / macro C++ opt-in por app runtime de app (futuro)

Boundary: monitorizamos al agente y a invocaciones canonicas. Runtime de apps Go/C++ compiladas queda fuera. Compensar con tests + e2e_checks (issue 0068).

Que NO se monitoriza

  • Funcion Go/C++ llamada internamente por app ya compilada.
  • Funcion ejecutada por systemd timer / cron / Dagu sin pasar por fn run.
  • Sub-agente (Agent tool) — sus tools no propagan a hook del padre.
  • Service de produccion recibiendo HTTP.

Implicacion: una funcion con calls_90d=0 puede ser huerfana real O usada en runtime invisible. Antes de proponer deprecate_function, cruzar con consumer_apps_count > 0 (e2e) o con fn doctor uses-functions (declaraciones estaticas).