GaurGaur docs

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 → Consumers

Each 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_clean reshapes raw_orders so monetary columns are USD instead of integer cents.
  • sku_costs rolls up the bill-of-materials in raw_supplies to one row per sku, 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

ObjectWhat it isWho edits it
TableA raw ingested dataset with a declared primary key.Builder, at ingestion.
ModelA reusable SQL view over tables and other models.Builder.
ContractA validated, governed interface callers query.Builder.
CollectionA named grouping of related objects plus shared context.Builder.
ConsumerAn API endpoint exposing a scoped subset of contracts.Builder.
API keyA credential authorized for one consumer.Builder, per integration.

Where to next

On this page