# Arquitectura del sistema --- ## Dos bases de datos, dos propósitos | | Registry (esta BBDD) | Operacional (por proyecto) | |---|---|---| | **Qué almacena** | Lo que sabes hacer | Lo que has hecho y cómo fluye | | **Naturaleza** | Conocimiento estático | Conocimiento dinámico | | **Cuándo cambia** | Solo al añadir código | En cada proyecto activo | | **Scope** | Compartida entre todos los proyectos | Local a cada proyecto | | **Tablas** | `functions`, `types` | `entities`, `relations` | --- ## Registry — estructura de directorios ``` fn-registry/ functions/ core/ filter_slice.go filter_slice.md finance/ parse_ohlcv.go parse_ohlcv.md io/ fetch_ticks.go fetch_ticks.md pipelines/ tick_to_ohlcv.go tick_to_ohlcv.md components/ DataTable.tsx DataTable.md types/ core/ result.go result.md finance/ ohlcv.go ohlcv.md registry.db ← SQLite, solo índice FTS. Regenerable siempre. fn ← binario CLI ``` Los archivos `.go` / `.tsx` son la **fuente de verdad del código**. Los archivos `.md` son la **fuente de verdad de la documentación**. `registry.db` es solo el índice — si se borra, `fn index` lo regenera en segundos. --- ## CLI — comandos ```bash fn search "filter predicate sin mutar" # búsqueda FTS sobre nombre, descripción, tags, signature fn search -k function -p pure "slice" # filtrar por kind y purity fn search -l go -d finance "ohlcv" # filtrar por lang y domain fn search -k component "tabla datos" # buscar componentes React fn add # abre $EDITOR con template según kind fn show filter_slice_go_core # imprime entrada completa fn index # regenera registry.db desde los .md fn list # lista todas las entradas fn list -d finance # lista por dominio fn list -k pipeline # lista solo pipelines ``` --- ## Operacional — tablas por proyecto Cada proyecto tiene su propia BBDD operacional que referencia IDs del registry. ### Entities Instancias concretas de tipos registrados dentro de un contexto de ejecución. | Campo | Tipo | Descripción | |---|---|---| | `id` | string | Identificador único | | `name` | string | Nombre semántico (`ticks_btcusdt`) | | `type_ref` | string | Referencia al `types.id` del registry | | `description` | text | Qué representa en este dominio concreto | | `tags` | []string | Etiquetas | ### Relations Cómo las entidades se conectan a través de funciones o pipelines. | Campo | Tipo | Descripción | |---|---|---| | `id` | string | Identificador único | | `from_entity` | string | Entidad origen | | `to_entity` | string | Entidad destino | | `via` | string | `functions.id` que transforma | | `description` | text | Qué ocurre en esta transformación | | `purity` | enum | `pure` \| `impure` | --- ## El agente y el registry El agente consulta el registry para: 1. **Descubrir** qué funciones y tipos existen en un dominio 2. **Razonar** sobre composabilidad comparando `returns` con `uses_types` 3. **Priorizar** funciones puras para el núcleo del pipeline 4. **Aislar** impuras en los bordes 5. **Verificar** que los contratos no están rotos comparando `version` El agente consulta la operacional para: 1. Entender qué entidades fluyen en este proyecto concreto 2. Ver qué transformaciones ya están modeladas 3. Detectar patrones de uso frecuentes --- ## Capa diagnostica: `fn doctor` Sobre el modelo registry+operations existe el comando `fn doctor` (read-only) que reporta estado del sistema: - `artefacts` — salud por artefacto (git/venv/manifest/upstream). - `services` — apps tag `service` + systemctl + puerto. - `sync` — drift `pc_locations` BD vs disco del PC actual. - `uses-functions` — drift entre imports reales en codigo de apps y `uses_functions` declarado en `app.md`. - `unused` — funciones del registry sin consumidores. Cada subcomando es wrapper fino sobre una funcion del registry (`functions/infra/{artefact_doctor,services_status,pc_locations_drift,audit_uses_functions,find_unused_functions}.go`). La logica vive en el registry; el CLI solo formatea. `--json` produce salida estructurada para agentes. Detalle en `.claude/rules/fn_doctor.md`. Util tras deploys, `fn sync`, `git pull` masivos o como gate antes de evaluar metricas del bucle reactivo. --- ## Mejoras incorporadas al schema v1.0 | Problema | Solución | |---|---| | IDs frágiles con colisiones | Formato `{name}_{lang}_{domain}` + UUID interno | | `lang` libre fragmenta el índice | Enum controlado, normalizado al indexar | | Sin versionado | Campo `version` semver en functions y types | | `file_path` absoluta se rompe al mover | Siempre relativa a la raíz del registry | | Sin contexto de dominio | Campo `domain` obligatorio | | Sin trazabilidad temporal | `created_at` / `updated_at` automáticos | | `signature` ambigua en lenguajes dinámicos | Convención formal definida para Python/SQL | | Pura que devuelve opcional mal modelada | Regla: modelar como tipo suma, no `returns_optional: true` |