docs: schema de documentacion v1.0

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) <noreply@anthropic.com>
This commit is contained in:
2026-03-28 01:59:14 +01:00
parent 2a55cd99dc
commit 1e4ffba40e
5 changed files with 403 additions and 0 deletions
+29
View File
@@ -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*
+133
View File
@@ -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` |
+95
View File
@@ -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<T>(props: { data: T[]; columns: ColumnDef<T>[]; 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. |
+68
View File
@@ -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.
+78
View File
@@ -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.