Full source:
examples/ecommerce/The full loop
Setup
setup.sql is idempotent; re-running it drops and recreates all tables in the correct order.
Metrics
| Metric | Source · measure | Aliases |
|---|---|---|
revenue | orders.total_revenue | ”net revenue”, “rev” |
order_count | orders.order_count | ”orders”, “number of orders” |
units_sold | order_items.units_sold | ”units”, “quantity sold” |
revenue-excludes-refunds guardrail (mandatory_filter) AND-s status != 'refunded' into every query touching orders.total_revenue. Expected revenue after the guardrail: 3790.50 (7 completed + 1 pending order; the seed data’s two refunded orders, totaling 260.00, never appear).
Example queries
query() for executable SQL + search_knowledge() for business context: both calls together, one decision. See Knowledge for how caveats auto-surface.
MCP server: stdio vs. HTTP
Stdio (the MCP client owns the process: Claude Code, Cursor):/mcp (SSE at /sse for clients that only support that). Only --http mode writes .canonic/mcp.json: in stdio mode the MCP client owns the process and no state file is created.
Ingestion: keep semantics current
human_curated file (e.g. a column type changes), ingest flags a contradiction but keeps the curated file untouched; see Ingestion & reconciliation.
Evidence connectors beyond Postgres
Postgres introspection tells canonic what tables exist; connectors tell it what those tables mean:canonic ingest --connection warehouse_dbt --dry-run reconciles it into semantic proposals with no Postgres and no LLM: modeling-tier evidence outranks raw introspection where they overlap, and a genuine disagreement (e.g. conflicting column types) surfaces as a contradiction, never a silent merge.
To make the Notion evidence flow concrete without a live workspace, the demo ships five sample page sources at docs/notion-pages/, the format the Notion connector expects, including the two page properties it reads (Canonic Type → usage_mode, Canonic Topics → candidate topic refs).
Accuracy tracking
eval/grain_cases.jsonl exercise the shape of the live schema: a single surrogate key, a descriptive surrogate key, and a line-item fact where the grain is a single column rather than a composite key. See Instrumentation & evaluation.
CLI usage
Observability
served_answer event to the local, git-ignored event log; every canonic ingest run appends reconcile_decision events to the same log. See Instrumentation & evaluation for exactly what is (and isn’t) recorded.
Air-gapped mode
air_gapped: true is a hard error at load. See LLM & embeddings runtime.
Knowledge pages
knowledge/global/ adds searchable business context on top of the semantic layer:
| Page | usage_mode | Effect |
|---|---|---|
revenue-definition | definition | Canonical prose definition, surfaced by search |
revenue-excludes-refunds-caveat | caveat | Auto-surfaced whenever a result references total_revenue |
revenue-reporting-policy | policy | Month-end cutoff rules |
order-items-fanout-caveat | caveat | Auto-surfaced whenever a result references units_sold/line_revenue |