# Capability: registry

Auditoria y monitorizacion del propio registry (issue 0085/0086/0087). Cubre: detectar codigo copiado sin import (`audit_copied_code`), funciones huerfanas (`find_unused_functions`), drift entre imports y `uses_functions` declarado, drift `pc_locations` BD vs disco, drift de capability groups (`audit_capability_groups`), telemetria de llamadas (call_monitor `function_stats`), y generacion automatica de proposals (`generate_proposals_from_telemetry`).

## Funciones

| ID | Firma | Que hace |
|---|---|---|
| `audit_copied_code_go_infra` | `func AuditCopiedCode(registryRoot string) ([]CopiedCodeEntry, error)` | Audita apps en busca de cuerpos de funcion copiados del registry sin import. Calcula fingerprint normalizado (strip comments + whitespace) por funcion del registry y por funcion declarada en apps/, projects/*/apps/. Reporta matches exactos. MVP: exact_copy con sha256 truncado. Issue 0085k. |
| `audit_registry_paths_bash_pipelines` | `audit_registry_paths([output_file: string]) -> void` | Audita file_path de todas las functions y types en registry.db, verifica que cada ruta apunte a un archivo existente en disco, y genera un txt con las rutas rotas para que agentes puedan corregirlas. |
| `find_unused_functions_go_infra` | `func FindUnusedFunctions(registryRoot string) ([]UnusedFunction, error)` | Abre registry.db y retorna todas las funciones que no son referenciadas por ninguna otra funcion, app ni analisis. Util para detectar candidatas a deprecar o eliminar (fn doctor unused). |
| `full_git_pull_bash_pipelines` | `full_git_pull() -> stdout: tabla resumen` | Pull automatico de fn_registry + todos los sub-repos locales + submodules + fn sync. Descubre repos locales, stashea dirty trees antes de pullear, hace pull --ff-only, actualiza submodulos del repo principal, pulla ~/.password-store, regenera registry.db con fn index y ejecuta fn sync. |
| `full_git_push_bash_pipelines` | `full_git_push(commit_message?: string) -> stdout: tabla resumen` | Push automatico de fn_registry + todos los sub-repos + fn sync. Descubre repos, escanea secrets (aborta si detecta), auto-inicializa apps/analyses sin .git via ensure_repo_synced, auto-commitea dirty trees, pushea solo repos adelantados, pushea ~/.password-store sin commitear, y ejecuta fn sync. |
| `generate_proposals_from_telemetry_go_infra` | `func GenerateProposalsFromTelemetry(registryRoot string) ([]ProposalDraft, error)` | Genera proposals automaticas para registry.db.proposals a partir de telemetria de call_monitor.operations.db. Aplica 4 reglas MVP: copy_detected, orphan, bug, wrapper_skip. IDs deterministas (sha1 truncado) garantizan idempotencia. Cierra la fase MEJORAR del bucle reactivo. Issue 0085h. |
| `parser_registry_py_core` | `class ParserRegistry: register(name: str, parser: BaseParser) -> None; unregister(name: str) -> None; get_parser(name: str) -> BaseParser \| None; get_parser_for_file(path: str) -> BaseParser \| None; async parse(source: str, **kwargs) -> ParseResult; list_parsers() -> list[str]; list_supported_extensions() -> list[str]` | Registry extensible que despacha parsing de archivos al parser correcto basado en extension. Patron plugin: registrar parsers por nombre y extensiones, resolver automaticamente. Mantiene estado mutable (mapa extension→parser). Singleton global disponible via get_registry(). |
| `proposal_from_failure_go_infra` | `func ProposalFromFailure(registryDB string, appID string, results []CheckResult, executionID string) ([]string, error)` | Crea una fila en la tabla proposals de registry.db por cada CheckResult con Status=fail. Usa kind=new_function para fallos criticos y kind=improve_function para warnings. Retorna los IDs de proposals creados. Parte del bucle reactivo: conecta los resultados de e2e_run_checks con la etapa MEJORAR. |
| `registry_telemetry_py_infra` | `install() -> bool` | 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. |
| `setup_registry_api_bash_infra` | `setup_registry_api(ssh_host: string, api_token: string, basic_auth_user: string, basic_auth_pass: string) -> json` | Deploy completo de registry_api en VPS con Docker + Traefik (Coolify proxy). Sincroniza el repo via rsync, genera el hash bcrypt para basicAuth, sube el traefik-dynamic.yml, crea el .env con el token, hace docker compose build+up y verifica el health check. |
| `sql_workbench_cpp_core` | `void fn::sql_workbench(const char* id, sqlite3* db, fn::SqlWorkbenchState& state, ImVec2 size); bool fn::sql_workbench_run_query(sqlite3*, const char*, fn::SqlWorkbenchState&); void fn::sql_workbench_load_schema(sqlite3*, fn::SqlWorkbenchState&); void fn::sql_workbench_destroy(fn::SqlWorkbenchState&)` | Workbench SQL embebido en ImGui: editor con highlighting (text_editor + CodeLang::SQL), tabla de resultados (table_view), sidebar de schema (sqlite_master) e historial. Ejecuta queries contra una sqlite3* del caller (no abre/cierra la DB). |
| `tag_unused_pending_py_pipelines` | `python tag_unused_pending.py` | Etiqueta cada funcion del registry sin consumidor con el tag `pendiente-usar` (issue 0062). Lee `fn doctor unused --json`, modifica el frontmatter YAML del .md de cada funcion, y deja la indicacion para correr `fn index`. Idempotente: tambien retira el tag de funciones que han vuelto a usarse. |
| `telemetry_prelude_bash_infra` | `source telemetry_prelude.sh` | 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. |
| `validate_registry_paths_bash_shell` | `validate_registry_paths(db_path: string, table: string, root_dir: string) -> tsv_stdout` | Consulta registry.db y verifica que cada file_path apunte a un archivo existente en disco. Imprime a stdout las rutas rotas en formato TSV (id, file_path, domain, tabla). |
| `vault_aggregate_index_go_infra` | `func VaultAggregateIndex(repoRoot string) (AggregateReport, error)` | Agrega los índices de todos los vaults del registry en la tabla vault_files de registry.db. Lee cada vault_index.db (via VaultIndexOpen) y reemplaza las filas de forma atómica. Idempotente: re-ejecutar limpia y reescribe sin duplicar. |
| `write_analysis_md_bash_infra` | `write_analysis_md(analysis_dir: string, name: string, description: string, tags_csv: string) -> string` | Genera un archivo analysis.md con frontmatter valido para el registry. Calcula dir_path relativo a FN_REGISTRY_ROOT (o lo deduce buscando registry.db hacia arriba). Acepta tags como CSV. |
| `write_jupyter_registry_kernel_bash_infra` | `write_jupyter_registry_kernel([project_dir: string]) -> string` | Genera un script de startup de IPython que autoconfigura FN_REGISTRY_ROOT, sys.path a python/functions del registry, y helpers fn_query/fn_search/fn_code para consultar registry.db desde notebooks. |


## Ejemplo canonico

### Auditoria completa pre-merge

```bash
./fn doctor                                  # todos los checks
./fn doctor uses-functions --json | jq .
./fn doctor unused --json | jq '.[] | select(.calls_90d == 0)'
./fn doctor copied-code --json | jq '.[] | select(.kind == "exact_copy")'
./fn doctor capabilities --json
```

### Telemetria del agente (issue 0085)

```bash
cd projects/fn_monitoring/apps/call_monitor

./call_monitor copied-code            # popula tabla copied_code
./call_monitor snapshot               # snapshot a function_versions
./call_monitor propose                # crea proposals automaticas desde function_stats
```

### Detectar candidatos a capability group

```bash
./fn run propose_capability_groups --min-count 10 --max-domains 4
# Promociona uno: ./fn run propose_capability_groups --apply mantine
```

## Fronteras

- **NO modifica codigo del registry** automaticamente. Solo audita + abre proposals.
- **NO sincroniza** entre PCs. Para eso usar `fn sync` (grupo `git` cubre push/pull).
- **NO ejecuta tests**. Solo audita schema, hash, y telemetria.
- Funciones runtime de apps compiladas (Go/C++): quedan **fuera** de la telemetria salvo via `./fn run` o e2e_checks. Ver issue 0085 "Que se escapa del monitor".
