Saltar al contingut

OSL — la capa de consum

La OpenDome Semantic Layer (OSL) és una especificació oberta (Apache-2.0) que descriu, en YAML declaratiu, un model semàntic que abasta dos plans físics: taules estructurades a Iceberg i col·leccions vectorials a Lance. Una spec, un llenguatge, una cadena de governança.

Aquesta pàgina fixa el vocabulari i el model mental. Per al contracte normatiu vegeu l’especificació; per a la superfície d’API vegeu la referència.

Les capes semàntiques OSS d’avui (dbt MetricFlow, Cube, WrenAI) descriuen taules relacionals. Cap tracta les col·leccions vectorials com a ciutadanes de primera classe. Això força dos models paral·lels — el semàntic-SQL i “el que el RAG sap del client” — que divergeixen l’endemà de posar-los en producció.

OSL abasta els dos plans:

  1. Estructurat — entitats, mètriques, dimensions, contractes de dades. Aquí OSL és un superset de dbt MetricFlow: qualsevol projecte MetricFlow vàlid és OSL vàlid.
  2. No estructurat — col·leccions Lance amb el seu chunk schema, embeddings, índexs, filtres de metadata i ACL row-level. L’extensió OSL-only.
  3. El pont — la JointEntity, un objecte lògic (Customer, Policy, Order) que uneix columnes d’Iceberg amb facetes Lance sota una sola clau.

Declares un cop. La governança, el lineage, les APIs i els agents consumeixen el mateix model.

El model

ESTRUCTURAT · ICEBERGNO ESTRUCTURAT · LANCEJOINTENTITY
Una sola spec declarativa abasta tots dos plans físics; la JointEntity els uneix sota una sola clau.

OSL descriu un model semàntic sobre dos substrats físics amb un sol llenguatge declaratiu. Cada pla té les seves primitives, la seva convenció de FQN, el seu motor d’execució i el seu camí d’evolució. La JointEntity és la peça que els compon.

Taules Iceberg, queries SQL, agregacions, joins. Aquí OSL passa per MetricFlow sense modificacions:

  • semantic_models/*.yml descriuen entitats físiques amb les seves dimensions i measures.
  • metrics/*.yml defineixen mètriques certificades (simple, ratio, cumulative, derived).
  • saved_queries/*.yml empaqueten consultes reutilitzables.
  • time_spine.yml defineix el gra temporal del projecte.

El motor de referència (tenant-semantic-api) compila aquests YAML a SQL sobre Trino, executat contra Iceberg al bucket del tenant.

Col·leccions Lance amb chunks indexats. Aquí OSL defineix primitives noves:

  • facets/*.yml (kind: UnstructuredFacet) descriu una col·lecció Lance: el seu dataset path, chunk schema, model d’embedding, índexs (vector + FTS + escalar), camps de metadata, ACL row-level i límits de retrieval.

El motor executa retrieval híbrid (vector ⊕ BM25 ⊕ filtre de metadata) sobre LanceDB i retorna passatges amb citació, respectant l’ACL i els límits declarats.

  • joints/*.yml (kind: JointEntity) declara un objecte lògic la clau primària del qual prové d’un semantic_model i que exposa atributs compostos — uns del pla estructurat (columnes, mètriques), altres del no estructurat (retrieval scoped per la clau).

El pont és honest: cada join_on mapeja una clau d’entitat a un camp de metadata autoritatiu i indexat de la faceta. Un camp amb provenance: derived mai pot ser clau de join — l’extracció derivada passa a l’ingest, mai a query time.

Un agent que invoca entity_get(Customer, customer_id=X) rep, en una sola resposta, els atributs canònics de l’entitat, les mètriques preagregades que apliquin i els chunks Lance filtrats per customer_id=X. Una crida, una decisió de política, una traça d’auditoria.

Encara que la spec tingui primitives separades (SemanticModel, JointEntity), qui consumeix OSL veu una sola paraula: Entity. El que distingeix una Entity d’una altra no és el seu kind sinó la seva composició:

Composició Què és D’on surt
structured Entity purament tabular (només Iceberg) un SemanticModel que no és àncora de joint ni bridge
structured+content Columnes estructurades unides a facetes Lance un JointEntity amb potes no estructurades
content Un corpus Lance autònom, sense àncora estructurada una UnstructuredFacet que cap joint absorbeix

Les relacions entre Entities surten de dos llocs: entitats MetricFlow compartides (primary / foreign / unique) per a veïns estructurat ↔ estructurat, i N-N via bridge — una taula pont (SemanticModel amb ≥2 entitats foreign) que col·lapsa a una aresta N-N directa en comptes de ser un node.

Aquest vocabulari és el que serveix el domain-map (GET /osl/domain-map): un únic node kind entity etiquetat per composició, més nodes metric i candidate.

Família Kind Propòsit MetricFlow
Modelatge estructurat SemanticModel, Metric, SavedQuery, TimeSpine Descriure taules Iceberg + mètriques ✅ idèntic / estès
Modelatge no estructurat UnstructuredFacet Descriure una col·lecció Lance ❌ OSL-only
Composició JointEntity Unir tots dos plans sota una entitat lògica ❌ OSL-only
Catàleg i contractes Lexicon, DataContract, PolicyBinding Sinonímia, SLAs, hints per a la PDP ❌ OSL-only

Tota primitiva porta apiVersion: osl.opendome.eu/v1, un kind i un name únic. La identitat d’un objecte és (kind, name) — tret de SemanticModel, la identitat del qual és (catalog, schema, table).

OSL declara; el motor executa. Entre tots dos hi ha un pas de compilació.

1 · Author

Escriu YAML a mà o des del modelador. Convenció: project.yml + models/

  • metrics/ + facets/ + joints/ + lexicon/ + contracts/.

2 · Validate

osl validate corre JSON Schema per fitxer més cross-reference (cada FQN referenciat ha d’existir). Errors a E0xx (schema) o E1xx (resolve).

3 · Compile

osl compile emet un únic target/manifest.json — la representació canònica i reproduïble que el motor serveix i la policy engine llegeix.

4 · Publish

osl publish puja el manifest al motor del tenant. Atòmic (revert amb osl publish --revert), emet un esdeveniment de lineage osl.publish.

A partir d’aquí el motor serveix consultes: REST per a BI/apps, tools MCP per a agents.

OSL és estricte amb els noms perquè les polítiques en depenen. Quatre espais de FQN:

Espai Forma Exemple
Estructurat <catalog>.<schema>.<table>[:<column>] iceberg.curated.customer:email
No estructurat lance://<collection>[/*][:<metadata_field>] lance://meeting_transcripts:attendees
Tools <tool_kind>:<resource> metrics:revenue, joints:Customer
Joint-exposed joint://<Entity>.<attribute> joint://Customer.recent_meeting_topics

Els FQN són case-sensitive i no porten versió — el versionat viu al manifest compilat i signat amb SHA. La policy engine consumeix aquests FQNs a la seva tupla 4-D (data, action, actor, context). OSL no inventa una semàntica d’accés paral·lela; emet els fets que la PDP indexa.

  • No és un motor SQL. Trino ho és; OSL li dóna significat.
  • No és un orquestrador. Dagster executa els Jobs d’ingest/embedding.
  • No és una base vectorial. LanceDB ho és; OSL descriu les col·leccions.
  • No és un IAM. OPA / cell-model ho és; OSL emet fets que la PDP consumeix.
  • No és un BI tool. Metabase, Superset, Streamlit consumeixen OSL.
  • No és un agent framework. LangGraph, MCP servers consumeixen OSL.

OSL és la spec compartida entre totes aquestes peces, no les peces.