RUBIX × CARBON · LA SEPARACIÓN DE PLANOS
⚠️ IDEA INICIAL — no es el estado vigente de Rubix.
Este documento es la investigacion del 17 de agosto de 2026 de la que salio Rubix
como producto y como repositorio aparte (describeloai/Rubix, cuyos docs fundacionales
se escribieron hora y media despues). No se ha promovido al repo nuevo a proposito:
alli seria ruido — lo que aqui se explora, alli ya esta decidido. Se conserva en Carbon
como registro del ORIGEN, y porque las consecuencias que deriva para Carbon siguen
gobernando esta linea.
Decisión del owner (2026-08-17): son dos productos distintos que convergen. El
sustrato de gobierno nativo pasa a stand by. Se construye con separaciones claras
entre el plano federado (Rubix, en todo su espectro) y el plano de catálogo nativo
enterprise (Carbon Warehouse), sin perjudicar a ninguno y sin manchar la arquitectura.Este documento fija dónde está el corte, qué se comparte, y qué NO significa el
stand by — que es la parte que, si no se escribe, se decide sola y mal.
0 · ⭐⭐⭐ El corte, en una frase
La separación es de PLANO DE CONTROL, no de plano de datos.
Dos catálogos. Dos gobiernos. Dos ciclos de vida. UN ejecutor y UNA identidad.
No se separan porque compartir sea malo: se separan las autoridades. Compartir el motor es sano —lo hace cualquier sistema serio—; compartir la autoridad es lo que hace que un producto arrastre al otro cada vez que cambia.
┌──────────────────────────┐ ┌──────────────────────────┐
│ RUBIX · plano FEDERADO │ │ CARBON · catálogo NATIVO │
│ │ │ │
│ connections (SERVER) │ │ Gravitino + cara IRC │
│ foreign_databases │ │ datasets · N·4 · R2 │
│ espejo (FD·2) │ │ runQuery · plan · ledger│
│ ontología OSI · grafo │ │ securables · privilegios│
│ puerta semántica (I4) │ │ │
│ OpenFGA (ReBAC) │ │ ⏸️ STAND BY │
└──────────────────────────┘ └──────────────────────────┘
└──────────┬──────────────┘
LO COMPARTIDO, y es poco:
· la IDENTIDAD (quién pide)
· el EJECUTOR (Spark, por el puente)
· la CREDENCIAL del origen (C·3)
1 · Qué es cada uno, en una frase
| Carbon Warehouse (nativo) | El lakehouse gobernado del inquilino: los datos viven dentro, en Iceberg sobre R2, con su catálogo, su régimen de nombres y su puerta. |
| Rubix (federado) | La capa que hace consumible por aplicaciones y agentes el dato que vive fuera: lo consulta sin copiarlo, lo describe, lo relaciona y lo publica en un estándar semántico. |
⭐ Y por eso convergen sin fundirse: uno responde «dónde guardo mi dato», el otro «cómo entiendo el dato que ya tengo repartido». Un cliente puede comprar cualquiera de los dos sin el otro — y ésa es la prueba de que son dos productos y no uno con dos módulos.
2 · ⭐⭐ LA REGLA QUE SOSTIENE LA SEPARACIÓN
La dependencia es UNIDIRECCIONAL: Rubix puede consumir Carbon. Carbon no sabe que
Rubix existe.
Un solo sentido, y comprobable: ningún fichero del plano nativo importa nada del plano federado. Si algún día hace falta lo contrario, no es un import — es una decisión de producto que se toma en un documento.
⇒ Y de aquí sale la forma más limpia del JOIN mixto, que es la función por la que alguien paga:
Para Rubix, el Warehouse nativo es UNA BASE MÁS — sólo que la que está en casa.
Con eso, SELECT … FROM ventas.public.pedidos JOIN main.default.clientes … deja de ser un
caso especial cosido a mano: es un cruce entre dos bases del catálogo de Rubix, una remota
y una local. La uniformidad no es estética — es lo que evita que cada combinación de planos
tenga su propio camino.
⚠️ Y la crítica a mi propia propuesta, porque hoy NO es así
F·1 hace lo contrario: reescribe la referencia federada y mete la consulta entera por
runQuery, que es la puerta del plano nativo. O sea, hoy Rubix se apoya en la puerta
de Carbon — dependencia en el sentido correcto (Rubix→Carbon), pero dentro del camino
de ejecución.
Hay dos salidas y conviene no fingir que sólo hay una:
(a) mantenerlo — runQuery es el ejecutor compartido | Funciona hoy y está medido. runQuery es el punto de aplicación del plano nativo: sacarlo de ahí sería salir de la cara, que es el veto del 08-16. Coste: una consulta de Rubix arrastra el plan y el ledger del nativo aunque no toque ni una tabla suya. |
| (b) ejecutor propio de Rubix | Separación total. Coste: rehacer lo que ya funciona, y duplicar el punto de aplicación — dos sitios donde olvidarse de autorizar. |
Recomendación: (a), con la costura declarada. runQuery se usa como motor de
ejecución, nunca como catálogo — que es exactamente lo que ya hace hoy
(fuentesDeMotor). La separación se mantiene donde importa: catálogo y gobierno.
⚠️ Con una condición para que no se pudra: si una consulta puramente federada empieza a pagar peajes del plano nativo (validaciones de tenencia de tablas que no existen, asientos de ledger vacíos), eso es la señal de que (a) se agotó y toca (b). Merece una medida, no una intuición.
3 · ⛔⛔ QUÉ NO SIGNIFICA EL STAND BY
Ésta es la parte que se decide sola y mal si no se escribe. Stand by = no se invierte, NO = se puede romper.
| ⏸️ Se congela | nuevas capacidades del catálogo nativo: más gramática de gobernanza, Gravitino 1.3.0, los 7 fantasmas, «Explorar», borrar las 9.711 líneas del tubo |
| 🔒 Sigue vivo, y es OBLIGATORIO | los trinquetes: check:sin-tubo, check:regimen-namespace, check:catalog-sql, check:storage-perimeter. Un trinquete sobre algo congelado sigue protegiendo — y es más necesario, porque ya nadie mira ese código a diario |
| 🔧 Queda vivo porque RUBIX LO USA | connections + el vending de credenciales (C·2/C·3) · runQuery como ejecutor · la identidad de sesión · el puente a Spark · jdbc-vista.ts |
| ⛔ No se toca «de paso» | datasets, el régimen N·4, la cara IRC, el plan y el ledger. Si Rubix necesita algo de ahí, se pide por su interfaz, no editando dentro |
⭐ La lista de la tercera fila es la importante: sin ella, la primera vez que Rubix
necesite tocar connections nadie sabrá si eso viola el stand by, y la respuesta se
improvisará. Con ella, la regla es simple: lo que Rubix usa, se mantiene; lo demás, se
conserva pero no evoluciona.
4 · Las costuras, nombradas — son cuatro y no debe haber una quinta
| costura | sentido | por qué es sana | |
|---|---|---|---|
| S1 | identidad — quién pide | compartida | Un usuario es el mismo en los dos productos. Dos identidades para la misma persona es cómo se acaba con dos verdades sobre quién es. |
| S2 | credencial del origen (C·2 + C·3) | Rubix → Carbon | El contacto físico con el sistema del cliente. Ya está construido, cifrado y auditado; duplicarlo sería tener dos sitios donde vive un secreto. |
| S3 | ejecutor (runQuery → puente → Spark) | Rubix → Carbon | Motor compartido, autoridad no. Ver §2. |
| S4 | el Warehouse como base | Rubix → Carbon | Lo que hace uniforme el JOIN mixto. Y sólo de lectura: Rubix no escribe en el catálogo nativo. |
⛔ Una quinta costura es la señal de alarma. Sobre todo estas dos, que van a tentar:
- que el espejo de Rubix escriba en
datasets«para que aparezca en el árbol» ⇒ rompeRUBIX·I1y N·4 de un golpe; - que el gobierno de Rubix se resuelva con
decidePrivilegesobre securables de Carbon ⇒ ata el ciclo de vida de los dos y hace imposible venderlos por separado.
5 · ⭐⭐ OSI como forma nativa — y la crítica que hay que hacerle
La decisión es adoptar OSI «como mano al guante»: construir las ontologías y las aplicaciones en su formato, sin capa de traducción, para poder apoyarse en su infraestructura sin migraciones.
Es la decisión correcta, y por un motivo que va más allá de la interoperabilidad: te
ahorra inventar los conceptos. dataset, metric, dimension, relationship,
context ya están nombrados por 60+ organizaciones. Cada concepto propio que no se inventa
es una discusión que no se tiene y una migración que no se hace.
⚠️ Pero un formato de INTERCAMBIO no es automáticamente un buen modelo de ALMACÉN
OSI está diseñado para moverse entre herramientas: YAML declarativo, vendor-neutral, optimizado para que dos plataformas se entiendan. Un modelo de almacén tiene otras presiones —consultarse en grano fino, versionarse, permisarse por elemento, evolucionar sin reescribir— y son presiones distintas, no menores.
⇒ La postura defendible, que conserva lo bueno sin comprarse el riesgo:
- OSI es la forma CANÓNICA y el contrato de FRONTERA: lo que entra y lo que sale es OSI, sin traducción conceptual. Nada de conceptos propios que dupliquen los suyos.
- El almacén es fiel a OSI, y está VERSIONADO: se guarda qué versión de la spec produjo cada objeto. Es incubación en Apache (Apache Ossie) — va a moverse, y un almacén que no sabe de qué versión es cada fila no puede migrar por partes.
- Lo que OSI no cubre, vive AL LADO y se declara: procedencia (PROV-O), permisos (OpenFGA) y coordenada física del origen no son de su ámbito. Meterlos dentro con extensiones propias sería exactamente el silo del que se huye.
6 · OpenFGA, que deja de estar huérfano
Está desplegado desde antes del cutover y huérfano desde entonces: lo usaba Lakekeeper, que quedó fuera, y Gravitino no lo soporta. Se ha estado buscando dónde encaja en el catálogo de tablas — y no encajaba, porque no era su sitio.
Su sitio es el plano semántico de Rubix: un modelo ReBAC es un grafo de permisos, y lo que hay que gobernar es un grafo de conocimiento. La forma del problema y la forma de la herramienta coinciden — que es la única razón buena para elegir una.
⭐ Y encaja con la separación: OpenFGA gobierna Rubix, decidePrivilege gobierna
Carbon. Dos productos, dos planos de autorización, cero solapamiento — en vez de un
plano estirado para cubrir dos formas distintas de preguntar «¿puede?».
7 · Lo que esto reordena
| FD·2 (el espejo) | sigue siendo lo siguiente, y ahora es el núcleo de Rubix, no una fase de una entrega de Carbon |
| FD·7 (puerta semántica) | pasa a ser de Rubix, con OpenFGA detrás — y deja de ser una ampliación de la puerta de Carbon |
plan-gobernado-hoja-de-ruta (S·0-S·6) | ⏸️ stand by — es del plano nativo |
catalogo-origen-del-grafo | ⚠️ hay que releerlo: nació suponiendo un solo plano. Su tesis —la gobernanza emana del catálogo y el grafo la hereda— vale para el nativo; en Rubix el catálogo del que emana es el del cliente |
ontology-projection | ⚠️ acotar al plano nativo, o mentirá donde Rubix compite (ver rubix-tesis-critica §1·④) |
8 · ⚠️ Los riesgos de esta decisión, dichos en voz alta
① El riesgo real de dos productos es DUPLICAR. Las cuatro costuras existen para acotarlo, pero hay dos sitios donde la duplicación va a doler y conviene verla venir: el listado de objetos (Rubix necesita su propio árbol) y la auditoría (dos registros de acceso). Duplicar el árbol es aceptable; duplicar la auditoría no — un registro de seguridad partido en dos es un registro que nadie sabe leer entero. ⇒ candidata a quinta costura, y hay que decidirla a propósito, no por acumulación.
② El stand by tiene fecha de caducidad silenciosa. Un plano congelado seis meses no se retoma: se reescribe. Si la intención es volver, conviene poner una condición explícita de retorno —qué tiene que pasar para descongelarlo— en vez de dejarlo abierto.
③ Y la asimetría de madurez. Carbon tiene gates, trinquetes y medidas; Rubix arranca con dos fases cerradas. La tentación será relajar el listón «porque es un producto nuevo». ⭐ Al revés: es un producto nuevo sobre datos que no son nuestros, así que el listón sube — y la disciplina de medir que Carbon ya tiene es lo mejor que puede heredar.