> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getcanonic.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

> The context layer that lets AI agents query your data correctly.

Point canonic at your database and it builds the context an agent needs to answer data questions accurately: definitions, relationships, business meaning, and the guardrails that stop confidently-wrong answers. It keeps that context up to date as your data changes, and it never touches your warehouse beyond reading it.

## The problem

An AI agent connected straight to your warehouse sees **tables and columns**, not **meaning**. It doesn't know that `revenue` lives in `orders.amount` but excludes refunds, that "active customer" has a specific definition your finance team agreed on, or that summing a daily balance across a week is nonsense. So it guesses. A confidently-wrong answer is the worst kind of wrong: a confident, well-formatted, *incorrect* number that looks right.

Schema access makes an agent *fluent*. It doesn't make it *correct*.

## Why you need a context layer

Real output, captured from a live run against the [ecommerce example](https://github.com/mischuh/canonic/tree/main/examples/ecommerce), not hand-written:

**❌ Without canonic (the guess):**

```bash theme={null}
$ canonic sql "SELECT SUM(amount) FROM fct_orders"
┏━━━━━━━━━┓
┃ sum     ┃
┡━━━━━━━━━┩
│ 4050.50 │
└─────────┘
```

The problem: this total includes two refunded orders (\$260). Refunds are reversals, not revenue: a confident, well-formatted number that's off by 6.4%.

**✅ With canonic (the truth):**

```bash theme={null}
$ canonic --json query --metrics revenue
```

```json theme={null}
{
  "result": { "rows": [["3790.50"]] },
  "compiled": {
    "sql": "SELECT SUM(\"orders\".\"amount\") AS \"total_revenue\" FROM \"fct_orders\" AS \"orders\" WHERE \"orders\".\"status\" <> 'refunded'"
  },
  "metadata": {
    "resolved": { "metrics": { "revenue": "orders.total_revenue" } },
    "guardrails_fired": [{ "id": "revenue-excludes-refunds", "kind": "mandatory_filter" }]
  }
}
```

canonic resolves "revenue" to its canonical definition, compiles the guardrail into the SQL whether or not anyone asked for it, and returns the right number with the reasoning attached. Zero guessing.

## What canonic does

canonic sits between your data and your agents as a **context layer**: an auto-built, auto-maintained, version-controlled description of what your data *means* and how to query it *safely*. Agents ask for a metric by name. canonic resolves it to the canonical definition, compiles correct read-only SQL, runs it, and returns the answer **with the caveats that make it trustworthy**: how fresh the data is, which guardrails applied, whether the number is final or provisional.

When canonic isn't sure, it **refuses and asks** instead of guessing. A confidently-wrong answer is the one outcome it's built to never produce.

Connect Claude, Cursor, or any [MCP client](/mcp-integration/connecting-your-agent) and your agent resolves metrics through the same context layer, no separate integration to build.

Every output in these docs is real, captured from a live run, not hand-written. See the [end-to-end example](/end-to-end-example) for the full loop with actual commands and diffs.

## Why canonic, not something else

| Alternative                                 | What goes wrong                                                            | With canonic                                                                                                                                    |
| ------------------------------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Giving the agent raw schema/SQL access      | Fluency without correctness: it guesses definitions and picks wrong tables | Resolved canonical definitions, enforced guardrails, never a silent wrong number                                                                |
| Hand-building a semantic layer from scratch | Months of modeling before any value                                        | Context auto-drafted from your live schema on day one: you review, not author from zero                                                         |
| Migrating onto a new metrics platform       | Lock-in and a rebuild                                                      | canonic **ingests** your dbt (definitions), BI tools (usage evidence), and docs (evidence). It feeds your existing stack, it doesn't replace it |
| A hosted "AI analytics" SaaS                | Your data and definitions leaving your environment                         | Local-first, fully **air-gapped-capable**: nothing has to leave your machine                                                                    |

What makes it different in one line: **canonic builds the context for you, keeps it honest, and refuses to lie when it isn't sure.**

canonic is not a BI tool and not a chat interface: it's the layer that feeds the tools you already have (a BI dashboard, an agent, a notebook) correct, governed answers. If you want a place to explore data visually, or a standalone chatbot, canonic isn't that. It's the plumbing underneath one.

## The three layers

canonic's context lives in three committed surfaces: plain files in your git repo, reviewed like code. Each answers a different question.

| Layer         | File                  | Answers                                                                | Owned by        |
| ------------- | --------------------- | ---------------------------------------------------------------------- | --------------- |
| **Semantics** | `semantics/**/*.yaml` | "How do I query this safely?": tables, types, grains, joins, measures  | auto-maintained |
| **Knowledge** | `knowledge/**/*.md`   | "What does this mean to the business?": definitions, caveats, policies | auto-maintained |
| **Contracts** | `contracts/**/*.yaml` | "Which definition is canonical, and what must the answer obey?"        | human-owned     |

**The split rule:**

* Changes how the SQL *runs* → **semantics**.
* A human needs it to *trust* the answer → **knowledge**.
* Governs *which* definition is authoritative or *what an answer must satisfy* → **contracts**.

The key idea: a knowledge page *explains* why "amount includes refunds unless filtered." A contract *makes the SQL obey* it. Documented caveats become enforced guardrails, so the warning can't be silently ignored.

## What you can rely on

* **Read-only.** canonic never mutates your warehouse. It reads, it never writes back.
* **Propose-only.** It never silently edits your context: every change is a reviewable diff anchored to evidence.
* **Refuse-and-ask.** Ambiguous or unsafe? It returns a structured reason, not a guess.
* **No LLM in the answer path.** Queries compile deterministically: the same question always produces the same SQL. An LLM only helps *draft* context, never *compute* an answer.
* **Local-first & air-gapped-capable.** Run entirely on your machine with a local model and local embeddings. Nothing has to leave your network.
* **Measurable.** A local event log tracks accuracy, freshness, and answer quality, so "trustworthy" is something you can check, not just claim.

<CardGroup cols={2}>
  <Card title="Installation" icon="download" href="/installation">
    Install the canonic CLI via uv, pip, or Docker.
  </Card>

  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Get your first answer in minutes with a local SQLite or DuckDB file.
  </Card>
</CardGroup>
