---
name: registry_telemetry
lang: py
domain: infra
version: 0.1.0
purity: impure
kind: function
description: "Telemetria de invocaciones del registry desde Python. Patchea via sys.meta_path los paquetes del registry (core, finance, metabase, etc.) y registra cada llamada en call_monitor.operations.db. Activable con FN_TELEMETRY=1. Issue 0085c."
tags: [telemetry, monitoring, registry, import-hook, pendiente-usar]
signature: "install() -> bool"
error_type: "error_go_core"
returns_optional: false
params:
  - name: FN_TELEMETRY (env)
    desc: "Si vale '1', install() registra el meta_path finder y envuelve cada modulo del registry al importarse. Si no, no-op."
  - name: FN_REGISTRY_ROOT (env)
    desc: "Override de la raiz del registry. Si no se setea, se descubre walking up desde el archivo del modulo."
  - name: CLAUDE_SESSION_ID (env)
    desc: "ID de sesion Claude Code, persistido en cada fila de calls. Vacio si no se setea."
output: "True si el finder se instalo, False si FN_TELEMETRY != '1' o si ya estaba instalado."
uses_functions: []
uses_types: []
imports:
  - functools
  - importlib.abc
  - importlib.util
  - sqlite3
  - sys
  - time
example: |
  # Activacion en heredoc o app
  import os
  os.environ["FN_TELEMETRY"] = "1"
  import sys, os.path as p
  sys.path.insert(0, p.join(os.environ["FN_REGISTRY_ROOT"], "python", "functions"))
  import infra.registry_telemetry  # auto-install al importarse
  from core import filter_list, map_list  # automaticamente envueltos
  filter_list(lambda x: x > 0, [1, -2, 3])  # registrado en calls
file_path: "python/functions/infra/registry_telemetry.py"
tested: false
notes: |
  Patron: meta_path importer (PEP 451). Cuando el agente importa `core`, `finance`, etc.,
  el finder intercepta la carga del modulo, deja que el loader real ejecute, y luego
  envuelve cada callable definido en el modulo con un decorator que mide duration
  y registra en calls (con tool_used='python_wrapper').

  Fail-safe: si la BD no existe, INSERT falla, o cualquier excepcion ocurre durante
  el wrap, se ignora silenciosamente. NUNCA rompe el codigo cliente.

  function_id heuristic: `{name}_py_{domain}` donde domain = nombre del paquete
  top-level (`core`, `finance`, etc.). Coincide con convencion del registry
  siempre que el paquete top-level se llame igual que el dominio.

  Privacidad: solo function_id, duration_ms, success, error_class, type_name del error.
  NUNCA args, kwargs, return values. error_snippet truncado a 240 chars.
---
