From 1e4ffba40eecd2e0b6e2443709ea94f00de932e8 Mon Sep 17 00:00:00 2001 From: Egutierrez Date: Sat, 28 Mar 2026 01:59:14 +0100 Subject: [PATCH] docs: schema de documentacion v1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Añade la especificacion completa del registry: - README con overview de tablas y kinds - Schema de functions (atomicas, pipelines, components) - Schema de types (algebraicos: product y sum) - Reglas de integridad y referencias cruzadas - Arquitectura del sistema (registry vs operacional) Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/README.md | 29 ++++++++++ docs/architecture.md | 133 +++++++++++++++++++++++++++++++++++++++++++ docs/functions.md | 95 +++++++++++++++++++++++++++++++ docs/integrity.md | 68 ++++++++++++++++++++++ docs/types.md | 78 +++++++++++++++++++++++++ 5 files changed, 403 insertions(+) create mode 100644 docs/README.md create mode 100644 docs/architecture.md create mode 100644 docs/functions.md create mode 100644 docs/integrity.md create mode 100644 docs/types.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..344bd58c --- /dev/null +++ b/docs/README.md @@ -0,0 +1,29 @@ +# fn-registry — Schema de documentación + +Registry personal de código con búsqueda FTS. Diseñado para composición funcional y agentes. + +## Archivos + +- `functions.md` — Schema de la tabla functions (incluye pipelines y componentes React) +- `types.md` — Schema de la tabla types +- `integrity.md` — Reglas de integridad y referencias cruzadas +- `architecture.md` — Visión general del sistema + +## Tablas + +| Tabla | Descripción | +|---|---| +| `functions` | Funciones atómicas, pipelines y componentes React | +| `types` | Tipos algebraicos (product / sum) | + +## kind: valores posibles + +| Valor | Descripción | +|---|---| +| `function` | Función atómica pura o impura | +| `pipeline` | Composición de funciones, siempre impura | +| `component` | Componente React, extiende el schema base | + +--- + +*fn-registry schema v1.0* diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 00000000..2b44d945 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,133 @@ +# 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 + +--- + +## 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` | diff --git a/docs/functions.md b/docs/functions.md new file mode 100644 index 00000000..afdee4f5 --- /dev/null +++ b/docs/functions.md @@ -0,0 +1,95 @@ +# Tabla: functions + +Almacena funciones atómicas, pipelines y componentes React. Un pipeline es una función de `kind: pipeline`, siempre impura, que orquesta otras funciones del registry. Un componente es `kind: component` con campos adicionales para su API visual. Los tres comparten el mismo schema base. + +--- + +## Campos base + +| Campo | Tipo | Descripción | Notas / Restricciones | +|---|---|---|---| +| `id` | string | Identificador único generado. | Formato: `{name}_{lang}_{domain}` ej: `filter_slice_go_core`. UUID interno + slug legible. | +| `name` | string | Nombre de la función, pipeline o componente. | Obligatorio. Sin espacios, snake_case. | +| `kind` | enum | Clasificación del ejecutable. | `function` \| `pipeline` \| `component` | +| `lang` | enum | Lenguaje de implementación. | `go` \| `python` \| `sql` \| `typescript` \| ... (enum controlado, normalizado al indexar) | +| `domain` | string | Namespace o área de dominio. | Ej: `finance`, `dsp`, `core`, `io`. Evita colisiones de ID y filtra ruido en búsqueda. | +| `version` | string | Versión semántica de la función. | Semver: `1.0.0`. Permite detectar contratos rotos en `uses_functions`. | +| `purity` | enum | Indica si la función tiene side effects. | `pure` \| `impure` | +| `signature` | string | Firma completa incluyendo parámetros y tipos de retorno. | Para lenguajes sin tipos formales (Python sin hints), usar convención: `fn(xs: []T, pred: T→bool) → []T`. Para `kind: component`, es la interfaz de props en TypeScript/JSX. | +| `description` | text | Qué hace, por qué existe y cuándo usarla. | Obligatorio. | +| `tags` | []string | Etiquetas libres para búsqueda. | Dominio, patrón, utilidad. Ej: `[slice, functional, generic]` | +| `uses_functions` | []string | IDs de funciones del registry que esta función invoca. | Referencias validadas. `kind: pipeline` → no puede estar vacío. | +| `uses_types` | []string | IDs de tipos del registry que recibe como parámetros. | Referencias validadas contra tabla `types`. | +| `returns` | []string | IDs de tipos del registry que emite como resultado. | Referencias validadas. Vacío en `kind: component` — usar `emits`. | +| `returns_optional` | bool | Si el valor de retorno puede estar ausente. | Siempre `false` en puras. `true` en impuras que pueden no devolver valor. | +| `error_type` | string | ID del tipo de error que puede emitir. | Obligatorio en impuras. Referencia validada contra tabla `types`. | +| `imports` | []string | Dependencias externas fuera del registry. | Paquetes, módulos. Ej: `[github.com/shopspring/decimal]` | +| `example` | text | Ejemplo concreto de uso con inputs y outputs esperados. | Preferiblemente compilable. | +| `tested` | bool | Si existe al menos un test para esta función. | `true` → `test_file_path` obligatorio. | +| `tests` | []string | Lista de nombres o descripciones de los tests aplicados. | Vacío si `tested: false`. | +| `test_file_path` | string | Ruta relativa al archivo de test. | Relativa a la raíz del registry. Obligatoria si `tested: true`. | +| `file_path` | string | Ruta relativa al archivo de implementación. | Relativa a la raíz del registry. No rutas absolutas. | +| `created_at` | datetime | Fecha de creación de la entrada. | ISO 8601. Generado automáticamente. | +| `updated_at` | datetime | Fecha de última modificación. | ISO 8601. Actualizado automáticamente al indexar. | + +--- + +## Campos adicionales — kind: component + +Estos campos se añaden únicamente cuando `kind: component`. El resto del schema base aplica igual. + +| Campo | Tipo | Descripción | Notas / Restricciones | +|---|---|---|---| +| `props` | []PropDef | API de entrada del componente. | Cada prop: `{ name, type, required, description }`. Equivale a los parámetros de una función. | +| `emits` | []string | Eventos que el componente lanza hacia arriba. | Ej: `[onClick, onChange, onSubmit]`. No son `returns` — son comunicación hacia el padre. | +| `has_state` | bool | Si el componente gestiona estado interno. | `true` → `purity: impure` automáticamente. `false` → puede ser `pure`. | +| `framework` | enum | Framework de UI en el que está implementado. | `react` (único valor registrado actualmente). Obligatorio en `kind: component`. | +| `variant` | []string | Variantes visuales o de comportamiento disponibles. | Ej: `[primary, ghost, danger, disabled]`. Útil para el agente al buscar una variante concreta. | + +### Equivalencias function → component + +| Concepto en functions | Equivalente en kind: component | +|---|---| +| parámetros de función | `props` — API de entrada con nombre, tipo y opcionalidad | +| `returns` | `emits` — eventos hacia el padre. `returns` queda vacío. | +| `purity: impure` | `has_state: true` → impure automáticamente | +| `signature` | Interfaz de props en TypeScript/JSX | +| `uses_types` | Tipos del registry usados en props o emits | + +### Ejemplo de signature para un componente React + +```tsx +DataTable(props: { data: T[]; columns: ColumnDef[]; onRowClick?: (row: T) => void }): JSX.Element +``` + +--- + +## Reglas de integridad + +### Reglas base + +| Condición | Regla | +|---|---| +| `kind: pipeline` | `purity` siempre `impure`. `uses_functions` no puede estar vacío. | +| `purity: pure` | `returns_optional` siempre `false`. `error_type` vacío. Una pura que devuelve opcional debe modelarse como tipo suma, no como `returns_optional: true`. | +| `purity: impure` | `error_type` obligatorio. Toda impura declara explícitamente qué puede salir mal. | +| `tested: true` | `test_file_path` obligatorio. `tests` no puede estar vacío. | +| `tested: false` | `tests` vacío. `test_file_path` vacío. | +| `uses_functions[]` | Todos los IDs deben existir en la tabla `functions`. Sin referencias huérfanas. | +| `uses_types[]` | Todos los IDs deben existir en la tabla `types`. Sin referencias huérfanas. | +| `returns[]` | Todos los IDs deben existir en la tabla `types`. | +| `error_type` | Debe existir en la tabla `types` si informado. | +| `file_path` | Relativa a raíz del registry. Nunca absoluta. | +| `lang` | Debe pertenecer al enum controlado de lenguajes registrados. | +| `id` | Único global. Formato: `{name}_{lang}_{domain}`. Colisiones rechazadas. | + +### Reglas adicionales — kind: component + +| Condición | Regla | +|---|---| +| `kind: component` | `framework` obligatorio. | +| `kind: component` | `returns` vacío. Los outputs se expresan mediante `emits`. | +| `kind: component` | `signature` es la interfaz de props en formato TypeScript/JSX. | +| `has_state: false` + sin side effects | `purity: pure` válido. | +| `has_state: true` | `purity: impure` automáticamente. | +| `kind: component` | `uses_types` puede referenciar tipos del registry usados en props o emits. | diff --git a/docs/integrity.md b/docs/integrity.md new file mode 100644 index 00000000..cd0517ea --- /dev/null +++ b/docs/integrity.md @@ -0,0 +1,68 @@ +# Referencias cruzadas entre tablas + +Todas las referencias son validadas al indexar. Una referencia a un ID inexistente es rechazada. El grafo de dependencias es siempre consistente. + +--- + +## Mapa de referencias + +| Campo origen | → | Campo destino | +|---|---|---| +| `functions.uses_functions[]` | → | `functions.id` | +| `functions.uses_types[]` | → | `types.id` | +| `functions.returns[]` | → | `types.id` | +| `functions.error_type` | → | `types.id` | +| `types.uses_types[]` | → | `types.id` | + +--- + +## Jerarquía de composición + +``` +types/ → contratos de datos + product: OHLCV, Tick, Order... + sum: Result, OrderResult, ParseError... + +functions/ + pure/ → transformaciones atómicas sin side effects + filter_slice + clamp + map_ohlcv + + impure/ → bordes del sistema (IO, red, tiempo, estado) + fetch_ticks + write_csv + get_bitcoin_price + + pipeline/ → composiciones orquestadas, siempre impuras + tick_to_ohlcv + build_market_feed + + component/ → UI React, pura si sin estado, impura si con estado + DataTable + PriceChart + OrderForm +``` + +**Regla arquitectónica fundamental:** +- Las funciones **puras** nunca dependen de funciones **impuras** +- Los **pipelines** son el único lugar donde se orquesta IO +- Los **tipos** no tienen purity — son solo forma +- El agente compone puras libremente e **aísla** impuras en los bordes + +--- + +## Grafo de dependencias + +El grafo completo vive en las referencias cruzadas. Para cualquier función o pipeline el agente puede recorrer: + +``` +pipeline.uses_functions + → function.uses_functions (recursivo) + → function.uses_types + → type.uses_types (recursivo) + → function.returns + → function.error_type +``` + +Esto permite al agente saber exactamente qué necesita para componer cualquier pipeline antes de escribir una sola línea de código. diff --git a/docs/types.md b/docs/types.md new file mode 100644 index 00000000..275405d5 --- /dev/null +++ b/docs/types.md @@ -0,0 +1,78 @@ +# Tabla: types + +Almacena tipos algebraicos. Los tipos son el contrato entre funciones — permiten al agente razonar sobre composabilidad sin leer implementaciones. + +--- + +## Tipos algebraicos + +**Tipo producto** — todos los campos siempre presentes. Modela datos y entidades (struct). Número de valores posibles = N₁ × N₂ × ... × Nₙ + +**Tipo suma** — un caso activo a la vez. Modela estados, resultados y alternativas (interface/union). Número de valores posibles = N₁ + N₂ + ... + Nₙ + +--- + +## Campos + +| Campo | Tipo | Descripción | Notas / Restricciones | +|---|---|---|---| +| `id` | string | Identificador único generado. | Formato: `{name}_{lang}_{domain}` ej: `ohlcv_go_finance` | +| `name` | string | Nombre del tipo. | Obligatorio. PascalCase recomendado. | +| `lang` | enum | Lenguaje de implementación. | `go` \| `python` \| `sql` \| ... (mismo enum controlado que `functions`) | +| `domain` | string | Namespace o área de dominio. | Ej: `finance`, `dsp`, `core`. Alineado con el `domain` de las funciones que lo usan. | +| `version` | string | Versión semántica del tipo. | Semver: `1.0.0`. Cambios de campo rompen contratos en `functions.uses_types`. | +| `algebraic` | enum | Categoría algebraica del tipo. | `product`: todos los campos siempre presentes (struct). `sum`: alternativas excluyentes (union/interface). | +| `definition` | text | Definición completa del tipo. | Struct, interface, union, type alias. Código real. | +| `description` | text | Qué concepto del dominio modela, por qué existe y cuándo usarlo. | Obligatorio. | +| `tags` | []string | Etiquetas libres para búsqueda. | Dominio, patrón, utilidad. | +| `uses_types` | []string | IDs de otros tipos del registry que este tipo compone. | Solo IDs existentes en la tabla `types`. Sin referencias huérfanas. | +| `file_path` | string | Ruta relativa al archivo de implementación. | Relativa a la raíz del registry. | +| `created_at` | datetime | Fecha de creación de la entrada. | ISO 8601. Generado automáticamente. | +| `updated_at` | datetime | Fecha de última modificación. | ISO 8601. Actualizado automáticamente al indexar. | + +--- + +## Reglas de integridad + +| Condición | Regla | +|---|---| +| `algebraic: product` | Todos los campos siempre presentes. Modela datos. Número de valores posibles = producto de sus partes. | +| `algebraic: sum` | Un caso activo a la vez. Modela estados o resultados. Número de valores posibles = suma de sus partes. | +| `uses_types[]` | Todos los IDs deben existir en la tabla `types`. Sin auto-referencias ni referencias huérfanas. | +| `lang` | Debe pertenecer al enum controlado de lenguajes registrados. | +| `file_path` | Relativa a raíz del registry. Nunca absoluta. | +| `id` | Único global. Formato: `{name}_{lang}_{domain}`. Colisiones rechazadas. | + +--- + +## Ejemplos + +### Tipo producto — OHLCV + +```go +type OHLCV struct { + Open float64 + High float64 + Low float64 + Close float64 + Volume float64 +} +``` + +Todos los campos siempre presentes. Modela una vela de mercado. + +### Tipo suma — OrderResult + +```go +type OrderResult interface{ orderResult() } + +type Filled struct { Price float64; Qty float64 } +type Rejected struct { Reason string } +type Pending struct { ID string } + +func (Filled) orderResult() {} +func (Rejected) orderResult() {} +func (Pending) orderResult() {} +``` + +Un caso activo a la vez. Modela todos los estados posibles de una orden.