# 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.