1 · Author
Escriu YAML a mà o des del modelador. Convenció: project.yml + models/
metrics/+facets/+joints/+lexicon/+contracts/.
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:
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
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.
OSL és la spec compartida entre totes aquestes peces, no les peces.