docs: añadir spec fn_operations con entities, relations y types_snapshot
Schema de inteligencia operacional para proyectos. Define tablas entities, relations, relation_inputs y types_snapshot con reglas de integridad, referencias cruzadas al registry central y ejemplos de uso.
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
# fn_operations — Schema de inteligencia operacional
|
||||
|
||||
Base de datos local por proyecto. Cada proyecto tiene su propio archivo `.db` independiente.
|
||||
Referencia IDs del registry central (`fn_registry`) pero no los duplica — solo apunta a ellos.
|
||||
|
||||
---
|
||||
|
||||
## Propósito
|
||||
|
||||
El registry almacena **lo que sabes hacer**.
|
||||
fn_operations almacena **lo que has hecho y cómo fluye** en un proyecto concreto.
|
||||
|
||||
| | fn_registry | fn_operations |
|
||||
|---|---|---|
|
||||
| **Naturaleza** | Conocimiento estático | Conocimiento dinámico |
|
||||
| **Contenido** | Lo que sabes hacer | Lo que has hecho y cómo fluye |
|
||||
| **Scope** | Compartida entre todos los proyectos | Local a cada proyecto — un `.db` por proyecto |
|
||||
| **Tablas** | `functions`, `types` | `entities`, `relations`, `relation_inputs` |
|
||||
| **Cuándo cambia** | Al añadir código al registry | En cada proyecto activo |
|
||||
|
||||
---
|
||||
|
||||
## Estructura de directorios
|
||||
|
||||
```
|
||||
fn-registry/
|
||||
fn_operations/
|
||||
fn_operations.md ← este archivo
|
||||
project_template/
|
||||
operations.db ← plantilla vacía con schema y WAL mode aplicados
|
||||
migrations/
|
||||
001_init.sql ← script de creación de tablas
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tabla: entities
|
||||
|
||||
Una entity es una instancia concreta de un tipo del registry dentro del contexto de un proyecto.
|
||||
No es el tipo en abstracto — es el dato real que fluye: `ticks_btcusdt_2024`, `ohlcv_1h_binance`, `user_session_web`.
|
||||
|
||||
El tipo del registry (`type_ref`) aporta conocimiento heredado — campos, estructura, semántica algebraica.
|
||||
La entity aporta conocimiento contextual — qué rol juega aquí, de dónde viene, qué propiedades específicas tiene.
|
||||
|
||||
```
|
||||
type_ref → lo que la entidad ES (heredado del registry)
|
||||
metadata → lo que la entidad TIENE (específico de este contexto)
|
||||
```
|
||||
|
||||
| Campo | Tipo | Descripción | Notas / Restricciones |
|
||||
|---|---|---|---|
|
||||
| `id` | string | Identificador único de la entidad en el proyecto. | Formato: `{name}_{context}` ej: `ticks_btcusdt_2024`. Único dentro del proyecto. |
|
||||
| `name` | string | Nombre semántico de la entidad. | Descriptivo y específico al dominio del proyecto. Obligatorio. |
|
||||
| `type_ref` | string | ID del tipo del registry que modela esta entidad. | Referencia a `types.id` en `fn_registry`. Obligatorio. |
|
||||
| `status` | enum | Estado actual de la entidad. | `active` \| `stale` \| `corrupted` \| `archived` |
|
||||
| `description` | text | Qué representa esta entidad en el contexto del proyecto. | No qué es el tipo en abstracto, sino qué rol juega aquí. |
|
||||
| `domain` | string | Área de dominio dentro del proyecto. | Ej: `market_data`, `auth`, `reporting`. |
|
||||
| `tags` | []string | Etiquetas libres para búsqueda y agrupación. | |
|
||||
| `source` | string | Origen del dato. | Obligatorio. Ej: `binance_api`, `csv_upload`, `user_input`, `pipeline_output`. |
|
||||
| `metadata` | json | Propiedades específicas del contexto no capturadas por el tipo. | Valores concretos de los campos del tipo. Ej: `{"pair":"BTCUSDT","exchange":"binance"}`. |
|
||||
| `notes` | text | Contexto extra libre sobre la entidad. | Para el agente o para ti. Decisiones, observaciones, advertencias, historial informal. |
|
||||
| `created_at` | datetime | Fecha de registro de la entidad. | ISO 8601. Generado automáticamente. |
|
||||
| `updated_at` | datetime | Fecha de última modificación. | ISO 8601. Actualizado automáticamente. |
|
||||
|
||||
### Valores de status — entities
|
||||
|
||||
| Valor | Significado |
|
||||
|---|---|
|
||||
| `active` | Dato en uso, actualizado y fiable. |
|
||||
| `stale` | Existe pero puede estar desactualizado. El agente debe verificar antes de usar. |
|
||||
| `corrupted` | Se sabe que tiene problemas de integridad. No usar en pipelines. |
|
||||
| `archived` | Ya no se usa activamente. Se conserva por trazabilidad histórica. |
|
||||
|
||||
### Reglas de integridad — entities
|
||||
|
||||
| Condición | Regla |
|
||||
|---|---|
|
||||
| `type_ref` | Debe existir en `fn_registry.types.id`. Sin referencias huérfanas. |
|
||||
| `id` | Único dentro del proyecto. Formato `{name}_{context}`. |
|
||||
| `source` | Obligatorio. Todo dato tiene un origen conocido. |
|
||||
| `name` | Obligatorio. Sin espacios, snake_case. |
|
||||
| `metadata` | JSON válido. Debe contener los valores de los campos definidos por el tipo del registry. |
|
||||
| `status: corrupted` | El agente nunca debe usar esta entidad como input de una relation activa. |
|
||||
|
||||
---
|
||||
|
||||
## Tabla: relations
|
||||
|
||||
Una relation describe cómo una entidad se conecta o transforma en otra. Puede documentar una
|
||||
transformación técnica a través de una función del registry, o una relación puramente semántica
|
||||
sin función asociada. El campo `name` expresa el significado humano de la conexión.
|
||||
|
||||
```
|
||||
juan (type: person) → CONOCE A → paula (type: person)
|
||||
ticks → AGREGA → ohlcv_1h (via: tick_to_ohlcv_go_finance)
|
||||
```
|
||||
|
||||
Para relaciones que consumen **múltiples entidades** (joins, merges, agregaciones multi-fuente),
|
||||
se usa la tabla `relation_inputs` en lugar de `from_entity`. Ver sección correspondiente.
|
||||
|
||||
| Campo | Tipo | Descripción | Notas / Restricciones |
|
||||
|---|---|---|---|
|
||||
| `id` | string | Identificador único de la relación. | Formato: `{from}__to__{to}__via__{fn}`. Legible sin joins. |
|
||||
| `name` | string | Etiqueta semántica de la relación. | El verbo o concepto que describe la conexión. Ej: `CONOCE A`, `TRANSFORMA`, `PRODUCE`, `DEPENDE DE`. Obligatorio. |
|
||||
| `from_entity` | string | ID de la entidad origen para relaciones simples (1-a-1). | Referencia a `entities.id`. Opcional si se usa `relation_inputs`. |
|
||||
| `to_entity` | string | ID de la entidad destino. | Referencia a `entities.id`. Obligatorio. |
|
||||
| `via` | string | ID de la función o pipeline del registry que realiza la transformación. | Referencia a `functions.id` en `fn_registry`. Opcional — vacío si la relación es puramente semántica. |
|
||||
| `description` | text | Qué ocurre en esta conexión en el contexto del proyecto. | No qué hace la función en abstracto, sino qué significa aquí. |
|
||||
| `purity` | enum | Naturaleza de la transformación. | `pure` \| `impure`. Si `via` está informado, debe ser consistente con `via.purity` en el registry. |
|
||||
| `direction` | enum | Dirección semántica de la relación. | `unidirectional` \| `bidirectional` \| `inverse`. Ver valores abajo. |
|
||||
| `weight` | float | Ponderación opcional de la relación. | Rango `0.0 – 1.0`. Permite queryar "relaciones con peso > 0.8". Opcional. |
|
||||
| `status` | enum | Estado del flujo. | `designed` \| `implemented` \| `tested` \| `running` \| `deprecated` |
|
||||
| `started_at` | datetime | Cuándo empezó el flujo realmente. | ISO 8601. Distinto de `created_at` — ese es cuándo lo documentaste. |
|
||||
| `ended_at` | datetime | Cuándo terminó o dejó de ejecutarse el flujo. | ISO 8601. Vacío si sigue activo. |
|
||||
| `order` | int | Posición en el pipeline si forma parte de una secuencia ordenada. | Opcional. Permite reconstruir el grafo en orden de ejecución. |
|
||||
| `tags` | []string | Etiquetas libres. | |
|
||||
| `notes` | text | Observaciones, decisiones de diseño, problemas conocidos. | Libre. El agente lee esto para entender contexto histórico del flujo. |
|
||||
| `created_at` | datetime | Fecha de registro de la relación. | ISO 8601. Generado automáticamente. |
|
||||
| `updated_at` | datetime | Fecha de última modificación. | ISO 8601. Actualizado automáticamente. |
|
||||
|
||||
### Valores de direction
|
||||
|
||||
| Valor | Significado |
|
||||
|---|---|
|
||||
| `unidirectional` | A → B. La relación fluye en un solo sentido. Valor por defecto. |
|
||||
| `bidirectional` | A ↔ B. La relación es simétrica — vale en ambos sentidos. Ej: `CONOCE A`. |
|
||||
| `inverse` | La relación se documenta de B a A pero su lectura natural es de A a B. Útil para linaje inverso. |
|
||||
|
||||
### Valores de status — relations
|
||||
|
||||
| Valor | Significado |
|
||||
|---|---|
|
||||
| `designed` | Flujo planificado. Existe en el grafo de arquitectura pero no hay código todavía. |
|
||||
| `implemented` | Código escrito. No verificado en este contexto de proyecto aún. |
|
||||
| `tested` | Verificado en este proyecto. Los datos fluyen correctamente. |
|
||||
| `running` | Activo en producción o en uso continuo. |
|
||||
| `deprecated` | Ya no se usa. Se mantiene por trazabilidad histórica. |
|
||||
|
||||
### Reglas de integridad — relations
|
||||
|
||||
| Condición | Regla |
|
||||
|---|---|
|
||||
| `name` | Obligatorio. Describe el verbo semántico de la relación. |
|
||||
| `from_entity` | Si informado, debe existir en `entities.id`. Vacío si se usa `relation_inputs`. |
|
||||
| `from_entity` o `relation_inputs` | Al menos uno de los dos debe estar presente. Una relation sin origen es inválida. |
|
||||
| `to_entity` | Debe existir en `entities.id`. Obligatorio. |
|
||||
| `via` | Si informado, debe existir en `fn_registry.functions.id`. |
|
||||
| `purity` | Si `via` está informado, debe ser consistente con `via.purity` en el registry. |
|
||||
| `weight` | Si informado, debe estar en el rango `0.0 – 1.0`. |
|
||||
| `from_entity != to_entity` | Una entidad no puede relacionarse consigo misma. |
|
||||
| `started_at` / `ended_at` | Si ambos informados, `started_at` debe ser anterior a `ended_at`. |
|
||||
| `id` | Único dentro del proyecto. |
|
||||
| **Sin ciclos** | El CLI valida al insertar que la nueva relation no crea un ciclo en el grafo. Si lo crea, la inserción se rechaza. SQLite no detecta ciclos — esta validación ocurre en la capa de aplicación. |
|
||||
|
||||
---
|
||||
|
||||
## Tabla: relation_inputs
|
||||
|
||||
Tabla intermedia para relaciones que consumen **múltiples entidades simultáneamente** — joins,
|
||||
merges, agregaciones multi-fuente. Cuando una relation usa `relation_inputs`, el campo
|
||||
`from_entity` en `relations` se deja vacío.
|
||||
|
||||
```
|
||||
join(ticks_btcusdt, metadata_binance) → ENRIQUECE → ohlcv_enriquecido
|
||||
↑ input role: "base" ↑ to_entity
|
||||
↑ input role: "lookup"
|
||||
```
|
||||
|
||||
| Campo | Tipo | Descripción | Notas / Restricciones |
|
||||
|---|---|---|---|
|
||||
| `id` | string | Identificador único del input. | Generado automáticamente. |
|
||||
| `relation_id` | string | ID de la relation a la que pertenece este input. | Referencia a `relations.id`. Obligatorio. |
|
||||
| `entity_id` | string | ID de la entidad que actúa como input. | Referencia a `entities.id`. Obligatorio. |
|
||||
| `role` | string | Rol semántico de este input en la relación. | Ej: `base`, `lookup`, `filter`, `left`, `right`. Obligatorio. Permite al agente entender cómo se usa cada input. |
|
||||
| `order` | int | Orden del input si la relación es sensible al orden. | Opcional. Ej: en un join `left`/`right` el orden importa. |
|
||||
|
||||
### Reglas de integridad — relation_inputs
|
||||
|
||||
| Condición | Regla |
|
||||
|---|---|
|
||||
| `relation_id` | Debe existir en `relations.id`. |
|
||||
| `entity_id` | Debe existir en `entities.id`. |
|
||||
| `role` | Obligatorio. Sin rol el agente no puede razonar sobre cómo se usa el input. |
|
||||
| Mínimo 2 inputs | Una relation con `relation_inputs` debe tener al menos 2 entradas. Si solo hay una, usar `from_entity` en su lugar. |
|
||||
|
||||
---
|
||||
|
||||
## Referencias cruzadas completas
|
||||
|
||||
| Campo origen | → | Destino |
|
||||
|---|---|---|
|
||||
| `entities.type_ref` | → | `fn_registry → types.id` |
|
||||
| `relations.from_entity` | → | `entities.id` (opcional) |
|
||||
| `relations.to_entity` | → | `entities.id` |
|
||||
| `relations.via` | → | `fn_registry → functions.id` (opcional) |
|
||||
| `relation_inputs.relation_id` | → | `relations.id` |
|
||||
| `relation_inputs.entity_id` | → | `entities.id` |
|
||||
|
||||
---
|
||||
|
||||
## Ejemplo — pipeline de market data
|
||||
|
||||
### Entities
|
||||
|
||||
| id | type_ref | status | source | metadata |
|
||||
|---|---|---|---|---|
|
||||
| `ticks_btcusdt_2024` | `tick_go_finance` | `active` | `binance_api` | `{"pair":"BTCUSDT","exchange":"binance"}` |
|
||||
| `metadata_binance` | `exchange_meta_go_finance` | `active` | `binance_api` | `{"version":"v3"}` |
|
||||
| `ohlcv_1h_btcusdt` | `ohlcv_go_finance` | `active` | `pipeline_output` | `{"interval":"1h","pair":"BTCUSDT"}` |
|
||||
| `sma_20_btcusdt` | `float64_slice_go_core` | `active` | `pipeline_output` | `{"period":20,"field":"close"}` |
|
||||
|
||||
### Relations simples
|
||||
|
||||
| name | from_entity | to_entity | via | direction | status | weight |
|
||||
|---|---|---|---|---|---|---|
|
||||
| `CALCULA` | `ohlcv_1h_btcusdt` | `sma_20_btcusdt` | `sma_go_finance` | `unidirectional` | `tested` | 1.0 |
|
||||
|
||||
### Relation con múltiples inputs (relation_inputs)
|
||||
|
||||
**Relation:** `id: ticks_y_meta__to__ohlcv__via__enrich`, `name: ENRIQUECE`, `to_entity: ohlcv_1h_btcusdt`
|
||||
|
||||
| relation_id | entity_id | role | order |
|
||||
|---|---|---|---|
|
||||
| `ticks_y_meta__to__ohlcv__via__enrich` | `ticks_btcusdt_2024` | `base` | 1 |
|
||||
| `ticks_y_meta__to__ohlcv__via__enrich` | `metadata_binance` | `lookup` | 2 |
|
||||
|
||||
### Grafo resultante
|
||||
|
||||
```
|
||||
[ticks_btcusdt_2024] ──┐
|
||||
├─ ENRIQUECE (impure · running) ──→ [ohlcv_1h_btcusdt]
|
||||
[metadata_binance] ──┘ ↓
|
||||
CALCULA (pure · tested)
|
||||
↓
|
||||
[sma_20_btcusdt]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ejemplo — relaciones semánticas puras (sin via)
|
||||
|
||||
```
|
||||
[juan] (type: person) → CONOCE A (bidirectional, weight: 0.9) → [paula]
|
||||
[servicio_auth] → DEPENDE DE (unidirectional, weight: 1.0) → [bbdd_usuarios]
|
||||
[modelo_riesgo] → ALIMENTA (unidirectional, weight: 0.7) → [dashboard_trading]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Escalabilidad
|
||||
|
||||
| Fase | BBDD | Cuándo migrar |
|
||||
|---|---|---|
|
||||
| Inicial | SQLite + WAL mode | Proyectos personales, un agente escribiendo |
|
||||
| Crecimiento | PostgreSQL | Múltiples agentes escribiendo concurrentemente |
|
||||
| Analítico | ClickHouse | Millones de operaciones, dashboards de uso |
|
||||
Reference in New Issue
Block a user