How Orion reads your semantic layer
How Orion grounds its answers in your CML โ loading reveals, nodes, and metric contracts so numbers match governed definitions.
When to use it โ Read this when you want to understand why Orion's answers line up with Discover and your dashboards, or why it sometimes says "no reveal covers this โ using raw SQL."
Where to find it โ This is how the Orion chat behaves everywhere it appears (the Orion panel, AI Analysts, the weekly brief). There is nothing to switch on.
Who can use it โ Tracer, Weaver, and Luminary. Lens users see Orion answers but cannot edit the semantic layer that powers them.
When you ask Orion a question like "what was revenue last week?", it does not start by writing SQL. It first reads your semantic layer โ the same nodes, domains, and reveals you build in Forge โ and uses those governed definitions to answer. This page explains what Orion loads, in what order, and why that is the reason its answers agree with your dashboards.
Overview
Orion is grounded in your CML at two moments:
- At the start of every conversation, the platform builds a system prompt that already lists the nodes, domains, and reveals available in your workspace, along with each node's attributes and metric definitions and any metric contracts you have published.
- During the conversation, Orion calls tools โ
get_reveals,get_schema, andget_metricโ to pull the exact CML for the concept you asked about before it produces a number.
The result is that Orion answers from your governed model first and only writes raw SQL when nothing in the semantic layer covers the question. Because reveals carry the correct joins, metric intents, and SQL dialect for your connected warehouse, the figures Orion returns match what you would get in Discover.
When to use it
You do not turn this behavior on or off โ it is always how Orion works. Understanding it is useful when you want to:
- Explain why an Orion number matches (or should match) a Discover query or a dashboard tile.
- Decide whether a question needs a new reveal or metric so Orion can answer it from governance instead of raw SQL.
- Read Orion's provenance footer and know whether an answer came from a governed reveal or from raw SQL.
- Debug an answer that drifted, by checking the underlying node, reveal, or metric contract.
Concepts
| Term | What it means to Orion |
|---|---|
| Node | A modeled table in CML โ its physical table, attributes, and metrics. Orion reads nodes through get_schema. |
| Domain | A grouping that holds reveals. Reveals live inside domain YAML, so Orion always pairs a reveal with its domain name. |
| Reveal | A governed, pre-joined query definition โ primary node, joins, selected attributes and metrics, and grain. Running a reveal is preferred over raw SQL. |
| Metric | A named measure inside a node, defined as an intent (SUM, COUNT, etc.) over a locus (column). Orion reads it through get_metric. |
| Metric contract | An authoritative, workspace-level definition of a metric's meaning. When present, it is injected into Orion's context as the canonical definition. |
| Dialect | The SQL flavor of your connected warehouse (Postgres, BigQuery, Snowflake, DuckDB). Reveals execute through the query engine, which applies the right dialect for you. |
Getting started
There is nothing to install. To get the most accurate grounding:
- Connect a warehouse and model your data in Forge so nodes exist for Orion to read.
- Define reveals in your domains (see Reveals) for the metrics you ask about most. Reveals are what Orion reaches for first.
- Publish metric contracts for any metric whose definition must be canonical โ these are injected into Orion's context as the authoritative meaning.
Then open Orion from the side panel or from a live Discover result and ask a question.
Step-by-step
Orion loads your semantic layer into context
Before the first reply, Celiq builds Orion's system prompt from your workspace. It loads up to 20 of your nodes (skipping internal _celiq_* nodes), and for each one it includes the physical table, description, attributes, and every metric written as intent(locus) โ for example Metric "revenue": SUM(sale_price). It also lists the available reveals and injects any published metric contracts as "authoritative definitions." This is why Orion already knows your model exists before it calls any tool.
Orion finds a governed reveal with get_reveals
For any analytical question, Orion calls get_reveals first. The tool reads the reveals list out of your domain YAML and returns each reveal's domain name, reveal name, primary node, label, and description. If your search term is too narrow and nothing matches, the tool falls back to listing all reveals in the workspace so Orion can still pick a relevant one rather than guessing.
Orion matches the reveal to your question
Orion follows fixed matching rules against the returned list โ for example revenue, GMV, orders, or AOV map to a reveal with "order" or "revenue" in the name; returns and refunds map to a reveal with "return" or "item" in the name; customers and retention map to "customer" or "user"; products and categories to "product" or "category"; inventory to "inventory". It must use a name that actually appears in the list โ it is instructed to never invent a reveal name.
Orion runs the reveal โ not raw SQL
When a relevant reveal exists, Orion calls run_reveal with the domain name and reveal name. The query engine resolves the reveal's primary node and joined nodes, reads the connection's warehouse and database, builds the SQL, applies the correct dialect, enforces your row- and column-level security, and executes. Orion does not re-run SQL afterward to filter or re-aggregate that data โ the reveal rows are the answer source.
Orion reads node and metric definitions when it needs detail
To inspect a node's CML, Orion calls get_schema with purpose: 'query', which returns the node's name and raw CML with no warehouse stats. (The same tool with purpose: 'build_node' is used when modeling a node, returning full column statistics โ that path is for building, not answering questions.) To confirm what a metric means, Orion calls get_metric, which searches your nodes' YAML for a metric whose name matches and returns its definition.
Raw SQL only as a last resort
If no reveal covers the question, Orion falls back to raw SQL โ and is required to call get_schema first and to state in its answer that no governed reveal exists. Every data answer ends with a provenance line naming the reveal (or "raw SQL โ table name"), the data's freshness date, and a confidence level.
Examples
Suppose you ask Orion: "What's our revenue last week?"
Orion calls get_reveals and gets back a list that includes an orders reveal:
{
"reveals": [
{
"domain_name": "bigquery_ecommerce",
"reveal_name": "orders_analysis",
"primary_node": "orders",
"label": "Orders Analysis",
"description": "Revenue, order counts, and AOV by day"
}
],
"count": 1,
"hint": "Use run_reveal with domain_name + reveal_name to execute a reveal without writing raw SQL."
}Because the question is about revenue, Orion matches it to orders_analysis and runs that reveal rather than writing SQL:
{
"domain_name": "bigquery_ecommerce",
"reveal_name": "orders_analysis",
"date_from": "2025-06-09",
"date_to": "2025-06-15"
}The reveal already carries the canonical revenue metric. In the underlying node CML, that metric is defined once:
name: orders
physical_table: bigquery-public-data.thelook_ecommerce.orders
metrics:
- name: revenue
intent: SUM
locus: sale_price
description: Net merchandise revenue from completed orders
Because Orion answered through the reveal, it used SUM(sale_price) โ the governed definition โ with the joins and dialect the query engine applied for BigQuery. That is why the figure matches what Discover shows for the same period. Orion closes with a provenance line such as:
> Source: orders_analysis (semantic layer) ยท Freshness: 2025-06-15 ยท Confidence: highBest practices
- Build reveals for your common questions. A reveal is the only way Orion can answer from governance instead of raw SQL โ see Reveals.
- Name reveals so the matching rules find them. Use clear concept words in reveal names ("orders", "returns", "customers", "inventory") so Orion routes to the right one.
- Publish a metric contract for any metric that must be canonical. Contracts are injected as the authoritative definition, so Orion will not drift from them โ see Metric contracts.
- Keep node descriptions and metric definitions current in Forge. Orion reads them straight from your CML, so accurate models mean accurate answers.
- Read the provenance footer. "Source:
" means a governed definition; "raw SQL โ " means no reveal covered it and you may want to add one.
Tips
TipIf Orion ever answers a metric question with raw SQL, that is a signal there is no reveal covering it. Add a reveal in the relevant domain and re-ask โ Orion will pick it up on the next question because it lists reveals fresh from your domain YAML each time.
Common mistakes
Warning- Expecting Orion to know a metric you never modeled. Orion grounds in your CML; if a metric is not defined in a node and not covered by a reveal, it has no governed definition to use.
- Assuming Orion invents reveal names. It does not โ it only uses names returned by
get_reveals. If your reveal is missing from that list, check that it is defined under a non-deleted domain in your workspace. - Reading raw-SQL answers as governed. When the provenance footer says "raw SQL โ
", the number was computed outside the semantic layer and is not bound to your governed metric definition.
Troubleshooting
Symptom Cause Fix Orion says "No reveal covers this โ using raw SQL" get_revealsfound no reveal matching the question's conceptAdd a reveal in the relevant domain (see Reveals) and re-ask. get_revealsreturnsreveals: []with arelated_revealslistYour search term was too narrow; the tool fell back to listing all reveals Orion picks the closest one automatically; if it picks wrong, give it a more specific concept word. Domain "<name>" not found. Call get_reveals to see available domains.A reveal was requested with a domain name that does not exist or was deleted Confirm the domain exists and is not deleted; let Orion re-run get_revealsto get the right domain name.Reveal "<name>" not found in domain "<domain>"The reveal name is not present in that domain's YAML Check the reveal is defined under that domain; the error lists the available reveal names. Node '<name>' not foundfromget_schemaThe node name does not match any modeled node The tool returns available_nodesso Orion can pick the right name; verify the node exists in Forge.Metric '<name>' not found in any nodefromget_metricNo node's CML defines a metric with that name Define the metric in the owning node, or publish a metric contract for it. Related pages
- Forge โ where you model the nodes, domains, and reveals Orion reads
- Discover โ the explorer whose governed numbers Orion's answers match
- Metric contracts โ authoritative metric definitions injected into Orion's context
- Reveals โ defining the governed queries Orion runs first
- How Orion writes SQL โ what happens on the raw-SQL fallback path