Core concepts
The mental model behind Gaur, and how data moves from a source system to a governed consumer.
Gaur has a small vocabulary. Once these concepts click, the rest of the docs is detail. We use the Jaffle Shop sample dataset (a multi-location cafe chain) as a running example throughout.
The data flow
Data in Gaur always travels the same path:
Source data → Tables → Models → Contracts → ConsumersEach step takes raw, flexible data and makes it a little more stable and a little more governed.
Source data
The systems where your data already lives: object storage, databases, or
SaaS sources. Gaur connects to them, it doesn't replace them. For Jaffle
Shop, the source is six CSV files: raw_orders, raw_items,
raw_customers, raw_products, raw_stores, and raw_supplies.
Tables
When you connect a source, Gaur ingests a copy of its data into its own analytical storage as a table: a raw analytical object with a known schema and a declared primary key. Gaur isn't a live query layer over your databases, so analytical work never touches your source systems.
Jaffle Shop's six raw files land as six tables, each with its primary key
declared at ingest (raw_orders.id, the composite (raw_supplies.id, raw_supplies.sku), and so on). Tables are what everything else is built on.
See Tables.
Models
A model is a reusable, SQL-defined object built on top of tables. Models are how you clean raw data, conform two datasets to a shared grain, or collapse a fan-out before a contract joins it.
Jaffle Shop has five models:
orders_cleanreshapesraw_ordersso monetary columns are USD instead of integer cents.sku_costsrolls up the bill-of-materials inraw_suppliesto one row persku, collapsing the BOM fan-out so contracts can join it many-to-one.- Three smaller reshapes (
products_clean,stores_enriched,customer_lifetime).
Models are optional, but they're how you keep contracts simple. See Models.
Contracts
A contract is the governed interface a caller actually queries. It declares its sources (tables and models), the dimensions callers may group by, the measures they may aggregate, the filters that always apply, and the row-level security that scopes each caller.
Jaffle Shop publishes five contracts: product_performance,
store_performance, customer_cohorts, hourly_demand, and
sales_tax_remittance. Each one is a single, validated definition that every
caller reads from. See Contracts.
Consumers
A consumer is the API endpoint that exposes contracts to the outside world. It has its own API keys and is scoped to a specific set of contracts. Applications and agents talk to consumers, never to tables directly.
A jaffle-public consumer might expose all five Jaffle contracts to internal
dashboards; a jaffle-store-manager consumer might expose only
store_performance and hourly_demand, scoped per store via row-level
security. See Consumers.
Exploration vs. consumption
The most important distinction in Gaur is the line between exploration and consumption. They're different modes with different rules; don't mix them.
Exploration
Builder-facing. Schema inspection and read-only SQL are allowed; iteration is expected. This is where analytical logic gets discovered and drafted.
Consumption
Consumer-facing. Access is contract-only: no raw SQL, no schema browsing. Row-level rules apply to every caller. This is where approved logic gets used.
Exploration is flexible because mistakes there are cheap (nothing is live). Consumption is locked down because mistakes there reach real applications. Promoting logic into a contract is the moment it crosses from draft to governed.
How a contract is queried
A caller sends a structured query that names dimensions and measures, never
raw SQL. The same query against product_performance looks like this through
each protocol:
REST:
{
"contract_name": "product_performance",
"query": {
"dimensions": [{ "name": "category" }],
"measures": ["revenue_usd", "cogs_ratio"]
}
}Chat: the assistant calls the contract on the caller's behalf in response to "what's our revenue and margin by category".
MCP: an agent calls query_contract("product_performance", { … }) from
inside Claude, Cursor, or its own tool loop.
In every case Gaur compiles the query against the contract, injects row-level security, runs the result against its own copy of the data, and returns governed rows.
Context: the AI-readability layer
Every table, model, contract, and collection carries author-written context:
short prose explaining what the object represents in business terms. Context
is what makes natural-language and agent queries reliable. A column named
customer_id in raw_orders is per-order (a new value per ticket); the
column with the same name in raw_customers is per-person. The context tells
the agent which one is the entity identity, so it doesn't quietly count
tickets when you asked for customers.
Context lives alongside the schema and gets surfaced to chat and MCP automatically. See Context.
The objects, at a glance
| Object | What it is | Who edits it |
|---|---|---|
| Table | A raw ingested dataset with a declared primary key. | Builder, at ingestion. |
| Model | A reusable SQL view over tables and other models. | Builder. |
| Contract | A validated, governed interface callers query. | Builder. |
| Collection | A named grouping of related objects plus shared context. | Builder. |
| Consumer | An API endpoint exposing a scoped subset of contracts. | Builder. |
| API key | A credential authorized for one consumer. | Builder, per integration. |