--- name: telemetry_prelude lang: bash domain: infra version: 0.1.0 purity: impure kind: function description: "Prelude bash que envuelve cada funcion del registry definida en el shell con un wrapper que mide duration y registra cada llamada en call_monitor.operations.db. Activable con FN_TELEMETRY=1. Issue 0085c." tags: [telemetry, monitoring, registry, bash-wrapper, pendiente-usar] signature: "source telemetry_prelude.sh" error_type: "error_go_core" returns_optional: false params: - name: FN_TELEMETRY (env) desc: "Si vale '1', el prelude auto-envuelve cada funcion bash conocida del registry. Si no, return 0 inmediato sin hacer nada." - name: FN_REGISTRY_ROOT (env) desc: "Override de la raiz. Si no se setea, se descubre walking up desde cwd buscando registry.db." - name: CLAUDE_SESSION_ID (env) desc: "ID de sesion Claude Code persistido en cada fila de calls." output: "Sin output. Side effect: cada funcion del registry sourceada queda reemplazada por un wrapper con telemetria. Idempotente." uses_functions: [] uses_types: [] imports: - sqlite3 (CLI) - date (coreutils) - find (coreutils) example: | # Auto-wrap export FN_TELEMETRY=1 source bash/functions/infra/android_screenshot.sh # define android_screenshot() source bash/functions/infra/telemetry_prelude.sh # envuelve android_screenshot android_screenshot /tmp/out.png # registrado en calls como android_screenshot_bash_infra file_path: "bash/functions/infra/telemetry_prelude.sh" tested: false notes: | Mecanismo: `declare -f ` extrae el cuerpo de la funcion. Se renombra a `_fn_t_orig_` via eval. La funcion original queda reemplazada por un wrapper que mide `date +%s%3N` antes/despues, ejecuta `_fn_t_orig_`, captura exit code, y llama `_fn_t_log function_id duration_ms success error_class`. function_id heuristic: `{name}_bash_{domain}` donde `name`=basename del .sh y `domain`=basename del directorio padre. Coincide con convencion del registry. Fail-safe: si la BD no existe, sqlite3 falta, o INSERT falla, el wrapper ignora silenciosamente y retorna el exit code del original. NUNCA aborta ni modifica el comportamiento de la funcion envuelta. Idempotente: marca cada wrapper con `_FN_T_WRAPPED_=1` y no re-envuelve. Sourcear el prelude N veces es seguro. Limitacion: el wrapper requiere que las funciones del registry ya esten sourceadas antes de cargarse este prelude. Si la app sourcea una funcion DESPUES del prelude, esa funcion NO queda envuelta automaticamente — hay que llamar `_fn_t_autowrap` manualmente o usar `_fn_t_wrap `. ---