[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-dbt-labs-working-with-dbt-mesh":3,"mdc-rf6enp-key":35,"related-repo-dbt-labs-working-with-dbt-mesh":3096,"related-org-dbt-labs-working-with-dbt-mesh":3196},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":24,"repoUrl":25,"updatedAt":26,"license":27,"forks":28,"topics":29,"repo":30,"sourceUrl":33,"mdContent":34},"working-with-dbt-mesh","implement dbt Mesh governance and collaboration","Use when changing a dbt model in a way that could break its consumers — renaming, removing, or retyping a column, or changing a model that downstream models, exposures, dashboards, or BI tools depend on — to judge whether the change is breaking and who it affects. Also use when versioning a model (model versions, latest_version, latest_version_pointer, deprecation_date, migration windows), enforcing contracts, setting access or groups, or doing multi-project dbt Mesh work (cross-project refs via dependencies.yml, disambiguating similarly-named models, splitting a monolith). Covers single- and multi-project, and planning or advising as well as implementing.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"dbt-labs","dbt Labs","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fdbt-labs.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"Architecture","architecture","tag",{"name":17,"slug":18,"type":15},"Data Engineering","data-engineering",{"name":20,"slug":21,"type":15},"Governance","governance",{"name":23,"slug":23,"type":15},"dbt",623,"https:\u002F\u002Fgithub.com\u002Fdbt-labs\u002Fdbt-agent-skills","2026-04-06T18:09:10.192152",null,52,[],{"repoUrl":25,"stars":24,"forks":28,"topics":31,"description":32},[],"A curated collection of Agent Skills for working with dbt, to help AI agents understand and execute dbt workflows more effectively.","https:\u002F\u002Fgithub.com\u002Fdbt-labs\u002Fdbt-agent-skills\u002Ftree\u002FHEAD\u002Fskills\u002Fdbt\u002Fskills\u002Fworking-with-dbt-mesh","---\nname: working-with-dbt-mesh\ndescription: Use when changing a dbt model in a way that could break its consumers — renaming, removing, or retyping a column, or changing a model that downstream models, exposures, dashboards, or BI tools depend on — to judge whether the change is breaking and who it affects. Also use when versioning a model (model versions, latest_version, latest_version_pointer, deprecation_date, migration windows), enforcing contracts, setting access or groups, or doing multi-project dbt Mesh work (cross-project refs via dependencies.yml, disambiguating similarly-named models, splitting a monolith). Covers single- and multi-project, and planning or advising as well as implementing.\nuser-invocable: false\nmetadata:\n  author: dbt-labs\n---\n\n# Working with dbt Mesh\n\n**Core principle:** In a mesh project, upstream data comes through `ref()`, not `source()`. Every cross-project reference requires the project name. When in doubt, read `dependencies.yml` first.\n\n## When to Use\n\n- Making a potentially breaking change to a model — renaming, removing, or retyping a column — **especially when other models, exposures, or BI tools depend on it.** Assess the blast radius *before* changing it, and reach for model versions rather than editing in place.\n- Versioning a model (`versions:`, `latest_version`, `latest_version_pointer`, `deprecation_date`) — this applies in a **single project**, not just multi-project setups\n- Working in a dbt project that references models from other dbt projects\n- Resolving ambiguity when multiple upstream projects have similarly-named models (e.g. multiple `stg_` models)\n- Adding model contracts, access modifiers, or groups\n- Setting up cross-project references with `dependencies.yml`\n- Splitting a monolithic dbt project into multiple mesh projects\n\n**Do NOT use for:**\n\n- General model building or debugging (use the `using-dbt-for-analytics-engineering` skill)\n- Unit testing models (use the `adding-dbt-unit-test` skill)\n- Semantic layer work (use the `building-dbt-semantic-layer` skill)\n\n## First: Orient Yourself in a Multi-Project Setup\n\nBefore writing or modifying any SQL in a project that uses dbt Mesh, follow these steps:\n\n### 1. Read `dependencies.yml`\n\nThis file at the project root tells you which upstream projects exist:\n\n```yaml\n# dependencies.yml\nprojects:\n  - name: core_platform\n  - name: marketing_platform\n```\n\nIf this file has a `projects:` key, you are in a multi-project mesh setup. Every model you reference from those upstream projects **must** use cross-project `ref()`.\n\n### 2. Understand how upstream data gets into this project\n\nIn a mesh setup, upstream project models replace what would alternatively be sources:\n\n| Alternative | Mesh multi-project |\n|---|---|\n| `{{ source('stripe', 'payments') }}` | `{{ ref('core_platform', 'stg_payments') }}` |\n| Data comes from raw database tables | Data comes from another dbt project's public models |\n| Defined in `sources.yml` | Declared in `dependencies.yml` |\n\nThe upstream project has already staged and transformed the raw data. Your project builds on top of their public models, not their raw sources.\n\n### 3. Disambiguate similarly-named models\n\nWhen multiple upstream projects have models with the same name (e.g. `stg_customers` in both `core_platform` and `marketing_platform`), you **must** use the two-argument `ref()`:\n\n```sql\n-- Correct: explicit project name, no ambiguity\nselect * from {{ ref('core_platform', 'stg_customers') }}\nselect * from {{ ref('marketing_platform', 'stg_customers') }}\n\n-- WRONG: dbt cannot determine which project's stg_customers you mean\nselect * from {{ ref('stg_customers') }}\n```\n\n### 4. Check existing patterns in the codebase\n\nBefore writing new SQL:\n- Search for existing two-argument `ref()` calls to see which upstream projects and models are already in use\n- Look at the upstream project's YAML for `access: public` models — only these are referenceable cross-project\n- The first argument of `ref()` must exactly match the `name` field in the upstream project's `dbt_project.yml` (case-sensitive)\n\n### 5. Know what you can and cannot reference\n\n| Upstream model access | Can you `ref()` it cross-project? |\n|---|---|\n| `access: public` | Yes |\n| `access: protected` (default) | No — only within the same project |\n| `access: private` | No — only within the same group |\n\nIf you need a model that isn't `public`, coordinate with the upstream team to widen its access.\n\n## Cross-Project Refs Require dbt Cloud Enterprise\n\nCross-project `ref()` and the `projects:` key in `dependencies.yml` are only available on **dbt Cloud Enterprise or Enterprise+** plans. Before setting up any cross-project collaboration, verify plan eligibility:\n\n1. **If `dependencies.yml` already has a `projects:` key and the project is actively using cross-project refs** — Enterprise is already in place. Proceed.\n2. **Otherwise** — ask the user to confirm they are on dbt Cloud Enterprise or Enterprise+ before adding `projects:` to `dependencies.yml` or writing new two-argument `ref()` calls.\n\nIf the user cannot confirm the plan level, or confirms they are on a plan below Enterprise, **do not set up cross-project refs**. Explain that this feature requires upgrading to Enterprise or Enterprise+ and suggest they use the intra-project governance features (groups, access modifiers, contracts) instead.\n\n## Cross-Project `ref()` Syntax\n\n```sql\n-- Reference an upstream model (latest version)\nselect * from {{ ref('upstream_project', 'model_name') }}\n\n-- Reference a specific version\nselect * from {{ ref('upstream_project', 'model_name', v=2) }}\n```\n\nFor full cross-project setup details (dependencies.yml, prerequisites, orchestration), see [references\u002Fcross-project-collaboration.md](references\u002Fcross-project-collaboration.md).\n\n## Governance Features\n\ndbt Mesh includes four governance features. These work independently and can be adopted incrementally:\n\n| Feature | Purpose | Key Config | Reference |\n|---------|---------|------------|-----------|\n| **Model Contracts** | Guarantee column names, types, and constraints at build time | `contract: {enforced: true}` | [references\u002Fmodel-contracts.md](references\u002Fmodel-contracts.md) |\n| **Groups** | Organize models by team\u002Fdomain ownership | `group: finance` | [references\u002Fgroups-and-access.md](references\u002Fgroups-and-access.md) |\n| **Access Modifiers** | Control which models can `ref` yours | `access: public \u002F protected \u002F private` | [references\u002Fgroups-and-access.md](references\u002Fgroups-and-access.md) |\n| **Model Versions** | Manage breaking changes with migration windows | `versions:` with `latest_version:` and `latest_version_pointer` (v1.12+) | [references\u002Fmodel-versions.md](references\u002Fmodel-versions.md) |\n\n### YAML placement rule\n\nIn model property YAML files, `access`, `group`, and `contract` are **configs** and must always be nested under the `config:` key — never placed as top-level model properties. Placing them at the top level may appear to work in dbt Core but causes parse errors in dbt's Fusion engine.\n\n```yaml\n# ✅ CORRECT — all governance configs under `config:`\nmodels:\n  - name: fct_orders\n    config:\n      group: finance\n      access: public\n      contract:\n        enforced: true\n    columns:\n      - name: order_id\n        data_type: int\n\n# ❌ WRONG — governance configs as top-level properties (breaks Fusion)\nmodels:\n  - name: fct_orders\n    access: public          # WRONG — not under config:\n    group: finance          # WRONG — not under config:\n    contract:               # WRONG — not under config:\n      enforced: true\n    columns:\n      - name: order_id\n        data_type: int\n```\n\nThis applies to property YAML files only. In `dbt_project.yml`, use the `+` prefix for directory-level assignment (e.g. `+group: finance`, `+access: private`). In SQL files, use `{{ config(access='public', group='finance') }}`.\n\n### Adoption order\n\n```\n1. Groups & Access  →  2. Contracts  →  3. Versions  →  4. Cross-Project Refs\n   (organize teams)     (lock shapes)    (manage changes)  (split projects)\n```\n\n- **Groups & Access** — no schema changes needed, start here\n- **Contracts** — require declaring every column and data type in YAML\n- **Versions** — needed when a model must introduce a breaking change that consumers need time to migrate to (an enforced contract is recommended alongside, but not required)\n- **Cross-Project Refs** — require **dbt Cloud Enterprise or Enterprise+** and a successful upstream production job. Do not set up cross-project refs if you cannot confirm the plan level is Enterprise or higher.\n\n## Contracts vs. Tests\n\n| | Contracts | Data Tests |\n|---|---|---|\n| **When** | Build-time (pre-flight) | Post-build (post-flight) |\n| **What** | Column names, data types, constraints | Data quality, business rules |\n| **Failure** | Model does not materialize | Model exists but test fails |\n| **Use for** | Shape guarantees for downstream consumers | Content validation and anomaly detection |\n\nContracts are enforced **before** tests run. If a contract fails, the model is not built, and no tests execute.\n\n## Decision Framework\n\n### Should this model have a contract?\n\nUse a contract when:\n- The model is `access: public` (especially if referenced cross-project)\n- Other teams depend on this model's schema stability\n- The model feeds an exposure (dashboard, ML pipeline, reverse ETL)\n- External consumers (other dbt projects, BI dashboards, reverse ETL) query the table directly and would break from column renames or removals\n\nDo NOT add a contract when:\n- **Staging models** (`stg_*`) — these are internal implementation details, not consumer-facing APIs\n- **The model is still evolving** — if the user says they are iterating on the design, advise waiting until the schema stabilizes\n- **No external consumers exist** — in a single-project setup with no cross-project refs, no BI tools depending on the schema, and no exposures, contracts add maintenance overhead without benefit. Ask about consumers before recommending contracts.\n- **Dynamic\u002Fpivot columns** — models that use `pivot()`, `unpivot()`, or dynamically generate columns are poor candidates because the column list isn't fixed and the contract will break whenever the dynamic values change\n- **Ephemeral models** — contracts are not supported on ephemeral materializations\n\n**If the user asks for a contract on a model that matches the \"do NOT add\" criteria above, advise against it and explain why.** Do not simply comply — the user may not realize the contract is inappropriate. Suggest alternatives (e.g., data tests for staging models, waiting for schema stability, or switching materialization for ephemeral models).\n\n### Should this model be versioned?\n\nVersion a model when:\n- You need to make a **breaking change** (column removal, rename, or type change) to a model that consumers depend on — **whether or not it has an enforced contract.** A contract makes the break a build-time error; *without* one the break is silent and ships straight to downstream models and dashboards, so a migration window matters even more. Don't let \"there's no contract\" talk you out of versioning a breaking change.\n- Consumers need a migration window before the old shape goes away — **including consumers you can't update atomically:** other teams' models, exposures, dashboards, and BI tools that read the table directly.\n\nDo NOT version a model:\n- For additive changes (new columns) — these are non-breaking\n- For bug fixes — fix in place\n- Preemptively \"just in case\" — version only when a breaking change is actually needed\n- Only skip versioning if **nothing reads this model outside dbt** — no exposures, no BI tools, no other projects. If even one exists, version it.\n\n#### Versioning alone does NOT create the migration window — `latest_version` does\n\nAdding the new version and promoting it to `latest_version` are **two separate deploys, separated by the migration window — never the same change.** This is the single most common way a \"safe\" versioned change still breaks a dashboard.\n\nExternal consumers (BI tools, reverse ETL, dashboards) read a physical relation **by name** — almost always the unsuffixed `model_name` (the latest-version pointer view, or the plain model when unversioned). That name resolves to whatever `latest_version` points at. So:\n\n- **Deploy 1 — introduce:** add the new version (e.g. `v2`) with the new shape, but **keep `latest_version` on the OLD version (`v1`).** So external consumers keep reading the old columns by name, **maintain a canonical (unsuffixed) relation that tracks the latest version** — with `latest_version` still on `v1`, that canonical relation serves the old shape (mechanism table below). The new shape is available at `model_v2` for consumers to migrate against; internal consumers you control can migrate early by pinning `ref('model', v=2)`.\n- **Deploy 2 — promote (later):** only after every external consumer confirms migration, bump `latest_version` to `2` and set `deprecation_date` on `v1`. The canonical relation then auto-re-points to the new shape — no relation rename needed.\n\n**Keep the canonical relation serving the old shape — pick ONE mechanism (never two):**\n\n| dbt version | Default mechanism | Result |\n|---|---|---|\n| **≥ 1.12 \u002F Fusion** | built-in `latest_version_pointer` (currently **beta**) | `model_v1`, `model_v2`, pointer view `model` (3 relations) |\n| **≤ 1.11** | `create_latest_version_view()` macro + project `post-hook` (dbt's officially recommended pattern) | `model_v1`, `model_v2`, canonical view `model` (3 relations) |\n| either — **fallback only** | `config.alias` pinning the OLD version to the unsuffixed name | 2 relations; forces manual un-aliasing + rewiring at Deploy 2 |\n\nAlways prefer the version-appropriate pointer; reach for `config.alias` only when neither pointer is available or the user explicitly declines. Never combine a pointer\u002Fview with `alias` on the same name (collision error). See [model-versions.md](references\u002Fmodel-versions.md#latest-version-pointer).\n\n**Bumping `latest_version` is itself the breaking release for unsuffixed consumers.** If you introduce the new version *as* latest (or bump latest in the same change), the migration window is zero and the dashboard breaks immediately. The new version always starts as **non-latest**.\n\nAfter Deploy 1, verify the window is actually open — the consumer's relation must still return the old columns:\n\n```bash\ndbt show --inline \"select \u003Cold_col> from {{ target.schema }}.\u003Cunsuffixed_relation>\"\n```\n\nA `column does not exist` error means `latest_version` was promoted too early and the consumer is already broken.\n\n### What access level should this model have?\n\n```\nIs it referenced cross-project?\n  └─ Yes → public (with contract recommended)\n  └─ No\n      Is it referenced outside its group?\n        └─ Yes → protected (default)\n        └─ No\n            Is it internal to a small team?\n              └─ Yes → private\n              └─ No → protected (default)\n```\n\n**Best practice:** Default new models to `private` and widen access only when needed. The default `protected` is permissive — be intentional.\n\n## Common Mistakes\n\n| Mistake | Why It's Wrong | Fix |\n|---------|----------------|-----|\n| Using single-argument `ref()` in multi-project setups | Ambiguous — dbt may not resolve to the intended project | Always use `ref('project_name', 'model_name')` for cross-project refs |\n| Using `source()` for upstream project data | In mesh, upstream data comes through public models, not raw sources | Use `ref('upstream_project', 'model_name')` instead |\n| Not reading `dependencies.yml` first | You won't know which upstream projects exist or what they're called | Always read `dependencies.yml` before writing cross-project SQL |\n| Making all models `public` | Exposes internal implementation details cross-project | Only mark models `public` that are intentional APIs for other teams |\n| Skipping contracts on public models | Downstream consumers can break silently when schema changes | Always enforce contracts on `access: public` models |\n| Versioning for non-breaking changes | Creates unnecessary maintenance burden and warehouse cost | Only version for breaking changes (column removal, type change, rename) |\n| Introducing the new version *as* `latest_version` (or bumping latest in the same change) | The unsuffixed\u002Fpointer relation immediately serves the new shape, breaking BI tools and reverse ETL that read it by name — the migration window is zero | Introduce the new version with `latest_version` still on the OLD version; bump only after consumers confirm migration |\n| Reaching for `config.alias` to hold the unsuffixed name when a version-appropriate pointer is available | Collapses to 2 relations and forces manual un-aliasing + rewiring at promotion instead of an automatic re-point | Default to `latest_version_pointer` (≥1.12) or the `create_latest_version_view` post-hook (≤1.11); use `alias` only as a fallback |\n| Forgetting `dependencies.yml` | Cross-project refs fail without declaring the upstream project | Add upstream project to `dependencies.yml` before using two-argument `ref()` |\n| Referencing non-public models cross-project | Only `public` models are available to other projects | Set `access: public` on models intended for cross-project consumption |\n| Placing `access`, `group`, or `contract` as top-level model properties in YAML | Breaks Fusion engine parsing; top-level placement is not valid config | Always nest under `config:` — e.g. `config: { access: public }` |\n| Adding contracts to staging models | Staging models are internal — contracts add friction without protecting external consumers | Advise against it; suggest data tests instead |\n| Adding contracts to models with dynamic\u002Fpivot columns | Column list changes with data, breaking the contract | Advise against it; explain why the column list isn't fixed |\n| Adding contracts without establishing external consumers | Contracts protect a schema boundary — no consumers means no boundary to protect | Ask who depends on this model before adding a contract |\n| Making a model `private` that is already referenced outside its group | Existing refs break with a `DbtReferenceError` | Widen access to `protected` or refactor callers into the same group first |\n| Setting up cross-project refs without confirming dbt Cloud Enterprise | Cross-project `ref()` is unavailable on lower plan tiers | Confirm the plan level before adding `projects:` to `dependencies.yml` or writing two-argument `ref()` calls |\n| Adding `dependencies.yml` without a successful upstream production job | dbt Cloud resolves cross-project refs via the upstream `manifest.json` — no job run means no manifest | Run at least one successful production deployment in the upstream project first |\n",{"data":36,"body":39},{"name":4,"description":6,"user-invocable":37,"metadata":38},false,{"author":8},{"type":40,"children":41},"root",[42,50,87,94,199,207,247,253,258,270,275,360,387,393,398,484,489,495,536,596,602,607,663,669,750,763,769,802,861,873,886,932,944,950,955,1141,1147,1190,1545,1587,1593,1603,1652,1658,1766,1777,1783,1789,1794,1824,1829,1905,1915,1921,1926,1967,1972,2002,2016,2034,2061,2178,2186,2349,2376,2406,2411,2453,2473,2479,2488,2514,2520,3090],{"type":43,"tag":44,"props":45,"children":46},"element","h1",{"id":4},[47],{"type":48,"value":49},"text","Working with dbt Mesh",{"type":43,"tag":51,"props":52,"children":53},"p",{},[54,60,62,69,71,77,79,85],{"type":43,"tag":55,"props":56,"children":57},"strong",{},[58],{"type":48,"value":59},"Core principle:",{"type":48,"value":61}," In a mesh project, upstream data comes through ",{"type":43,"tag":63,"props":64,"children":66},"code",{"className":65},[],[67],{"type":48,"value":68},"ref()",{"type":48,"value":70},", not ",{"type":43,"tag":63,"props":72,"children":74},{"className":73},[],[75],{"type":48,"value":76},"source()",{"type":48,"value":78},". Every cross-project reference requires the project name. When in doubt, read ",{"type":43,"tag":63,"props":80,"children":82},{"className":81},[],[83],{"type":48,"value":84},"dependencies.yml",{"type":48,"value":86}," first.",{"type":43,"tag":88,"props":89,"children":91},"h2",{"id":90},"when-to-use",[92],{"type":48,"value":93},"When to Use",{"type":43,"tag":95,"props":96,"children":97},"ul",{},[98,119,161,166,179,184,194],{"type":43,"tag":99,"props":100,"children":101},"li",{},[102,104,109,111,117],{"type":48,"value":103},"Making a potentially breaking change to a model — renaming, removing, or retyping a column — ",{"type":43,"tag":55,"props":105,"children":106},{},[107],{"type":48,"value":108},"especially when other models, exposures, or BI tools depend on it.",{"type":48,"value":110}," Assess the blast radius ",{"type":43,"tag":112,"props":113,"children":114},"em",{},[115],{"type":48,"value":116},"before",{"type":48,"value":118}," changing it, and reach for model versions rather than editing in place.",{"type":43,"tag":99,"props":120,"children":121},{},[122,124,130,132,138,139,145,146,152,154,159],{"type":48,"value":123},"Versioning a model (",{"type":43,"tag":63,"props":125,"children":127},{"className":126},[],[128],{"type":48,"value":129},"versions:",{"type":48,"value":131},", ",{"type":43,"tag":63,"props":133,"children":135},{"className":134},[],[136],{"type":48,"value":137},"latest_version",{"type":48,"value":131},{"type":43,"tag":63,"props":140,"children":142},{"className":141},[],[143],{"type":48,"value":144},"latest_version_pointer",{"type":48,"value":131},{"type":43,"tag":63,"props":147,"children":149},{"className":148},[],[150],{"type":48,"value":151},"deprecation_date",{"type":48,"value":153},") — this applies in a ",{"type":43,"tag":55,"props":155,"children":156},{},[157],{"type":48,"value":158},"single project",{"type":48,"value":160},", not just multi-project setups",{"type":43,"tag":99,"props":162,"children":163},{},[164],{"type":48,"value":165},"Working in a dbt project that references models from other dbt projects",{"type":43,"tag":99,"props":167,"children":168},{},[169,171,177],{"type":48,"value":170},"Resolving ambiguity when multiple upstream projects have similarly-named models (e.g. multiple ",{"type":43,"tag":63,"props":172,"children":174},{"className":173},[],[175],{"type":48,"value":176},"stg_",{"type":48,"value":178}," models)",{"type":43,"tag":99,"props":180,"children":181},{},[182],{"type":48,"value":183},"Adding model contracts, access modifiers, or groups",{"type":43,"tag":99,"props":185,"children":186},{},[187,189],{"type":48,"value":188},"Setting up cross-project references with ",{"type":43,"tag":63,"props":190,"children":192},{"className":191},[],[193],{"type":48,"value":84},{"type":43,"tag":99,"props":195,"children":196},{},[197],{"type":48,"value":198},"Splitting a monolithic dbt project into multiple mesh projects",{"type":43,"tag":51,"props":200,"children":201},{},[202],{"type":43,"tag":55,"props":203,"children":204},{},[205],{"type":48,"value":206},"Do NOT use for:",{"type":43,"tag":95,"props":208,"children":209},{},[210,223,235],{"type":43,"tag":99,"props":211,"children":212},{},[213,215,221],{"type":48,"value":214},"General model building or debugging (use the ",{"type":43,"tag":63,"props":216,"children":218},{"className":217},[],[219],{"type":48,"value":220},"using-dbt-for-analytics-engineering",{"type":48,"value":222}," skill)",{"type":43,"tag":99,"props":224,"children":225},{},[226,228,234],{"type":48,"value":227},"Unit testing models (use the ",{"type":43,"tag":63,"props":229,"children":231},{"className":230},[],[232],{"type":48,"value":233},"adding-dbt-unit-test",{"type":48,"value":222},{"type":43,"tag":99,"props":236,"children":237},{},[238,240,246],{"type":48,"value":239},"Semantic layer work (use the ",{"type":43,"tag":63,"props":241,"children":243},{"className":242},[],[244],{"type":48,"value":245},"building-dbt-semantic-layer",{"type":48,"value":222},{"type":43,"tag":88,"props":248,"children":250},{"id":249},"first-orient-yourself-in-a-multi-project-setup",[251],{"type":48,"value":252},"First: Orient Yourself in a Multi-Project Setup",{"type":43,"tag":51,"props":254,"children":255},{},[256],{"type":48,"value":257},"Before writing or modifying any SQL in a project that uses dbt Mesh, follow these steps:",{"type":43,"tag":259,"props":260,"children":262},"h3",{"id":261},"_1-read-dependenciesyml",[263,265],{"type":48,"value":264},"1. Read ",{"type":43,"tag":63,"props":266,"children":268},{"className":267},[],[269],{"type":48,"value":84},{"type":43,"tag":51,"props":271,"children":272},{},[273],{"type":48,"value":274},"This file at the project root tells you which upstream projects exist:",{"type":43,"tag":276,"props":277,"children":282},"pre",{"className":278,"code":279,"language":280,"meta":281,"style":281},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# dependencies.yml\nprojects:\n  - name: core_platform\n  - name: marketing_platform\n","yaml","",[283],{"type":43,"tag":63,"props":284,"children":285},{"__ignoreMap":281},[286,298,314,339],{"type":43,"tag":287,"props":288,"children":291},"span",{"class":289,"line":290},"line",1,[292],{"type":43,"tag":287,"props":293,"children":295},{"style":294},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[296],{"type":48,"value":297},"# dependencies.yml\n",{"type":43,"tag":287,"props":299,"children":301},{"class":289,"line":300},2,[302,308],{"type":43,"tag":287,"props":303,"children":305},{"style":304},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[306],{"type":48,"value":307},"projects",{"type":43,"tag":287,"props":309,"children":311},{"style":310},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[312],{"type":48,"value":313},":\n",{"type":43,"tag":287,"props":315,"children":317},{"class":289,"line":316},3,[318,323,328,333],{"type":43,"tag":287,"props":319,"children":320},{"style":310},[321],{"type":48,"value":322},"  -",{"type":43,"tag":287,"props":324,"children":325},{"style":304},[326],{"type":48,"value":327}," name",{"type":43,"tag":287,"props":329,"children":330},{"style":310},[331],{"type":48,"value":332},":",{"type":43,"tag":287,"props":334,"children":336},{"style":335},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[337],{"type":48,"value":338}," core_platform\n",{"type":43,"tag":287,"props":340,"children":342},{"class":289,"line":341},4,[343,347,351,355],{"type":43,"tag":287,"props":344,"children":345},{"style":310},[346],{"type":48,"value":322},{"type":43,"tag":287,"props":348,"children":349},{"style":304},[350],{"type":48,"value":327},{"type":43,"tag":287,"props":352,"children":353},{"style":310},[354],{"type":48,"value":332},{"type":43,"tag":287,"props":356,"children":357},{"style":335},[358],{"type":48,"value":359}," marketing_platform\n",{"type":43,"tag":51,"props":361,"children":362},{},[363,365,371,373,378,380,385],{"type":48,"value":364},"If this file has a ",{"type":43,"tag":63,"props":366,"children":368},{"className":367},[],[369],{"type":48,"value":370},"projects:",{"type":48,"value":372}," key, you are in a multi-project mesh setup. Every model you reference from those upstream projects ",{"type":43,"tag":55,"props":374,"children":375},{},[376],{"type":48,"value":377},"must",{"type":48,"value":379}," use cross-project ",{"type":43,"tag":63,"props":381,"children":383},{"className":382},[],[384],{"type":48,"value":68},{"type":48,"value":386},".",{"type":43,"tag":259,"props":388,"children":390},{"id":389},"_2-understand-how-upstream-data-gets-into-this-project",[391],{"type":48,"value":392},"2. Understand how upstream data gets into this project",{"type":43,"tag":51,"props":394,"children":395},{},[396],{"type":48,"value":397},"In a mesh setup, upstream project models replace what would alternatively be sources:",{"type":43,"tag":399,"props":400,"children":401},"table",{},[402,421],{"type":43,"tag":403,"props":404,"children":405},"thead",{},[406],{"type":43,"tag":407,"props":408,"children":409},"tr",{},[410,416],{"type":43,"tag":411,"props":412,"children":413},"th",{},[414],{"type":48,"value":415},"Alternative",{"type":43,"tag":411,"props":417,"children":418},{},[419],{"type":48,"value":420},"Mesh multi-project",{"type":43,"tag":422,"props":423,"children":424},"tbody",{},[425,447,460],{"type":43,"tag":407,"props":426,"children":427},{},[428,438],{"type":43,"tag":429,"props":430,"children":431},"td",{},[432],{"type":43,"tag":63,"props":433,"children":435},{"className":434},[],[436],{"type":48,"value":437},"{{ source('stripe', 'payments') }}",{"type":43,"tag":429,"props":439,"children":440},{},[441],{"type":43,"tag":63,"props":442,"children":444},{"className":443},[],[445],{"type":48,"value":446},"{{ ref('core_platform', 'stg_payments') }}",{"type":43,"tag":407,"props":448,"children":449},{},[450,455],{"type":43,"tag":429,"props":451,"children":452},{},[453],{"type":48,"value":454},"Data comes from raw database tables",{"type":43,"tag":429,"props":456,"children":457},{},[458],{"type":48,"value":459},"Data comes from another dbt project's public models",{"type":43,"tag":407,"props":461,"children":462},{},[463,474],{"type":43,"tag":429,"props":464,"children":465},{},[466,468],{"type":48,"value":467},"Defined in ",{"type":43,"tag":63,"props":469,"children":471},{"className":470},[],[472],{"type":48,"value":473},"sources.yml",{"type":43,"tag":429,"props":475,"children":476},{},[477,479],{"type":48,"value":478},"Declared in ",{"type":43,"tag":63,"props":480,"children":482},{"className":481},[],[483],{"type":48,"value":84},{"type":43,"tag":51,"props":485,"children":486},{},[487],{"type":48,"value":488},"The upstream project has already staged and transformed the raw data. Your project builds on top of their public models, not their raw sources.",{"type":43,"tag":259,"props":490,"children":492},{"id":491},"_3-disambiguate-similarly-named-models",[493],{"type":48,"value":494},"3. Disambiguate similarly-named models",{"type":43,"tag":51,"props":496,"children":497},{},[498,500,506,508,514,516,522,524,528,530,535],{"type":48,"value":499},"When multiple upstream projects have models with the same name (e.g. ",{"type":43,"tag":63,"props":501,"children":503},{"className":502},[],[504],{"type":48,"value":505},"stg_customers",{"type":48,"value":507}," in both ",{"type":43,"tag":63,"props":509,"children":511},{"className":510},[],[512],{"type":48,"value":513},"core_platform",{"type":48,"value":515}," and ",{"type":43,"tag":63,"props":517,"children":519},{"className":518},[],[520],{"type":48,"value":521},"marketing_platform",{"type":48,"value":523},"), you ",{"type":43,"tag":55,"props":525,"children":526},{},[527],{"type":48,"value":377},{"type":48,"value":529}," use the two-argument ",{"type":43,"tag":63,"props":531,"children":533},{"className":532},[],[534],{"type":48,"value":68},{"type":48,"value":332},{"type":43,"tag":276,"props":537,"children":541},{"className":538,"code":539,"language":540,"meta":281,"style":281},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","-- Correct: explicit project name, no ambiguity\nselect * from {{ ref('core_platform', 'stg_customers') }}\nselect * from {{ ref('marketing_platform', 'stg_customers') }}\n\n-- WRONG: dbt cannot determine which project's stg_customers you mean\nselect * from {{ ref('stg_customers') }}\n","sql",[542],{"type":43,"tag":63,"props":543,"children":544},{"__ignoreMap":281},[545,553,561,569,578,587],{"type":43,"tag":287,"props":546,"children":547},{"class":289,"line":290},[548],{"type":43,"tag":287,"props":549,"children":550},{},[551],{"type":48,"value":552},"-- Correct: explicit project name, no ambiguity\n",{"type":43,"tag":287,"props":554,"children":555},{"class":289,"line":300},[556],{"type":43,"tag":287,"props":557,"children":558},{},[559],{"type":48,"value":560},"select * from {{ ref('core_platform', 'stg_customers') }}\n",{"type":43,"tag":287,"props":562,"children":563},{"class":289,"line":316},[564],{"type":43,"tag":287,"props":565,"children":566},{},[567],{"type":48,"value":568},"select * from {{ ref('marketing_platform', 'stg_customers') }}\n",{"type":43,"tag":287,"props":570,"children":571},{"class":289,"line":341},[572],{"type":43,"tag":287,"props":573,"children":575},{"emptyLinePlaceholder":574},true,[576],{"type":48,"value":577},"\n",{"type":43,"tag":287,"props":579,"children":581},{"class":289,"line":580},5,[582],{"type":43,"tag":287,"props":583,"children":584},{},[585],{"type":48,"value":586},"-- WRONG: dbt cannot determine which project's stg_customers you mean\n",{"type":43,"tag":287,"props":588,"children":590},{"class":289,"line":589},6,[591],{"type":43,"tag":287,"props":592,"children":593},{},[594],{"type":48,"value":595},"select * from {{ ref('stg_customers') }}\n",{"type":43,"tag":259,"props":597,"children":599},{"id":598},"_4-check-existing-patterns-in-the-codebase",[600],{"type":48,"value":601},"4. Check existing patterns in the codebase",{"type":43,"tag":51,"props":603,"children":604},{},[605],{"type":48,"value":606},"Before writing new SQL:",{"type":43,"tag":95,"props":608,"children":609},{},[610,622,635],{"type":43,"tag":99,"props":611,"children":612},{},[613,615,620],{"type":48,"value":614},"Search for existing two-argument ",{"type":43,"tag":63,"props":616,"children":618},{"className":617},[],[619],{"type":48,"value":68},{"type":48,"value":621}," calls to see which upstream projects and models are already in use",{"type":43,"tag":99,"props":623,"children":624},{},[625,627,633],{"type":48,"value":626},"Look at the upstream project's YAML for ",{"type":43,"tag":63,"props":628,"children":630},{"className":629},[],[631],{"type":48,"value":632},"access: public",{"type":48,"value":634}," models — only these are referenceable cross-project",{"type":43,"tag":99,"props":636,"children":637},{},[638,640,645,647,653,655,661],{"type":48,"value":639},"The first argument of ",{"type":43,"tag":63,"props":641,"children":643},{"className":642},[],[644],{"type":48,"value":68},{"type":48,"value":646}," must exactly match the ",{"type":43,"tag":63,"props":648,"children":650},{"className":649},[],[651],{"type":48,"value":652},"name",{"type":48,"value":654}," field in the upstream project's ",{"type":43,"tag":63,"props":656,"children":658},{"className":657},[],[659],{"type":48,"value":660},"dbt_project.yml",{"type":48,"value":662}," (case-sensitive)",{"type":43,"tag":259,"props":664,"children":666},{"id":665},"_5-know-what-you-can-and-cannot-reference",[667],{"type":48,"value":668},"5. Know what you can and cannot reference",{"type":43,"tag":399,"props":670,"children":671},{},[672,695],{"type":43,"tag":403,"props":673,"children":674},{},[675],{"type":43,"tag":407,"props":676,"children":677},{},[678,683],{"type":43,"tag":411,"props":679,"children":680},{},[681],{"type":48,"value":682},"Upstream model access",{"type":43,"tag":411,"props":684,"children":685},{},[686,688,693],{"type":48,"value":687},"Can you ",{"type":43,"tag":63,"props":689,"children":691},{"className":690},[],[692],{"type":48,"value":68},{"type":48,"value":694}," it cross-project?",{"type":43,"tag":422,"props":696,"children":697},{},[698,714,733],{"type":43,"tag":407,"props":699,"children":700},{},[701,709],{"type":43,"tag":429,"props":702,"children":703},{},[704],{"type":43,"tag":63,"props":705,"children":707},{"className":706},[],[708],{"type":48,"value":632},{"type":43,"tag":429,"props":710,"children":711},{},[712],{"type":48,"value":713},"Yes",{"type":43,"tag":407,"props":715,"children":716},{},[717,728],{"type":43,"tag":429,"props":718,"children":719},{},[720,726],{"type":43,"tag":63,"props":721,"children":723},{"className":722},[],[724],{"type":48,"value":725},"access: protected",{"type":48,"value":727}," (default)",{"type":43,"tag":429,"props":729,"children":730},{},[731],{"type":48,"value":732},"No — only within the same project",{"type":43,"tag":407,"props":734,"children":735},{},[736,745],{"type":43,"tag":429,"props":737,"children":738},{},[739],{"type":43,"tag":63,"props":740,"children":742},{"className":741},[],[743],{"type":48,"value":744},"access: private",{"type":43,"tag":429,"props":746,"children":747},{},[748],{"type":48,"value":749},"No — only within the same group",{"type":43,"tag":51,"props":751,"children":752},{},[753,755,761],{"type":48,"value":754},"If you need a model that isn't ",{"type":43,"tag":63,"props":756,"children":758},{"className":757},[],[759],{"type":48,"value":760},"public",{"type":48,"value":762},", coordinate with the upstream team to widen its access.",{"type":43,"tag":88,"props":764,"children":766},{"id":765},"cross-project-refs-require-dbt-cloud-enterprise",[767],{"type":48,"value":768},"Cross-Project Refs Require dbt Cloud Enterprise",{"type":43,"tag":51,"props":770,"children":771},{},[772,774,779,781,786,788,793,795,800],{"type":48,"value":773},"Cross-project ",{"type":43,"tag":63,"props":775,"children":777},{"className":776},[],[778],{"type":48,"value":68},{"type":48,"value":780}," and the ",{"type":43,"tag":63,"props":782,"children":784},{"className":783},[],[785],{"type":48,"value":370},{"type":48,"value":787}," key in ",{"type":43,"tag":63,"props":789,"children":791},{"className":790},[],[792],{"type":48,"value":84},{"type":48,"value":794}," are only available on ",{"type":43,"tag":55,"props":796,"children":797},{},[798],{"type":48,"value":799},"dbt Cloud Enterprise or Enterprise+",{"type":48,"value":801}," plans. Before setting up any cross-project collaboration, verify plan eligibility:",{"type":43,"tag":803,"props":804,"children":805},"ol",{},[806,830],{"type":43,"tag":99,"props":807,"children":808},{},[809,828],{"type":43,"tag":55,"props":810,"children":811},{},[812,814,819,821,826],{"type":48,"value":813},"If ",{"type":43,"tag":63,"props":815,"children":817},{"className":816},[],[818],{"type":48,"value":84},{"type":48,"value":820}," already has a ",{"type":43,"tag":63,"props":822,"children":824},{"className":823},[],[825],{"type":48,"value":370},{"type":48,"value":827}," key and the project is actively using cross-project refs",{"type":48,"value":829}," — Enterprise is already in place. Proceed.",{"type":43,"tag":99,"props":831,"children":832},{},[833,838,840,845,847,852,854,859],{"type":43,"tag":55,"props":834,"children":835},{},[836],{"type":48,"value":837},"Otherwise",{"type":48,"value":839}," — ask the user to confirm they are on dbt Cloud Enterprise or Enterprise+ before adding ",{"type":43,"tag":63,"props":841,"children":843},{"className":842},[],[844],{"type":48,"value":370},{"type":48,"value":846}," to ",{"type":43,"tag":63,"props":848,"children":850},{"className":849},[],[851],{"type":48,"value":84},{"type":48,"value":853}," or writing new two-argument ",{"type":43,"tag":63,"props":855,"children":857},{"className":856},[],[858],{"type":48,"value":68},{"type":48,"value":860}," calls.",{"type":43,"tag":51,"props":862,"children":863},{},[864,866,871],{"type":48,"value":865},"If the user cannot confirm the plan level, or confirms they are on a plan below Enterprise, ",{"type":43,"tag":55,"props":867,"children":868},{},[869],{"type":48,"value":870},"do not set up cross-project refs",{"type":48,"value":872},". Explain that this feature requires upgrading to Enterprise or Enterprise+ and suggest they use the intra-project governance features (groups, access modifiers, contracts) instead.",{"type":43,"tag":88,"props":874,"children":876},{"id":875},"cross-project-ref-syntax",[877,879,884],{"type":48,"value":878},"Cross-Project ",{"type":43,"tag":63,"props":880,"children":882},{"className":881},[],[883],{"type":48,"value":68},{"type":48,"value":885}," Syntax",{"type":43,"tag":276,"props":887,"children":889},{"className":538,"code":888,"language":540,"meta":281,"style":281},"-- Reference an upstream model (latest version)\nselect * from {{ ref('upstream_project', 'model_name') }}\n\n-- Reference a specific version\nselect * from {{ ref('upstream_project', 'model_name', v=2) }}\n",[890],{"type":43,"tag":63,"props":891,"children":892},{"__ignoreMap":281},[893,901,909,916,924],{"type":43,"tag":287,"props":894,"children":895},{"class":289,"line":290},[896],{"type":43,"tag":287,"props":897,"children":898},{},[899],{"type":48,"value":900},"-- Reference an upstream model (latest version)\n",{"type":43,"tag":287,"props":902,"children":903},{"class":289,"line":300},[904],{"type":43,"tag":287,"props":905,"children":906},{},[907],{"type":48,"value":908},"select * from {{ ref('upstream_project', 'model_name') }}\n",{"type":43,"tag":287,"props":910,"children":911},{"class":289,"line":316},[912],{"type":43,"tag":287,"props":913,"children":914},{"emptyLinePlaceholder":574},[915],{"type":48,"value":577},{"type":43,"tag":287,"props":917,"children":918},{"class":289,"line":341},[919],{"type":43,"tag":287,"props":920,"children":921},{},[922],{"type":48,"value":923},"-- Reference a specific version\n",{"type":43,"tag":287,"props":925,"children":926},{"class":289,"line":580},[927],{"type":43,"tag":287,"props":928,"children":929},{},[930],{"type":48,"value":931},"select * from {{ ref('upstream_project', 'model_name', v=2) }}\n",{"type":43,"tag":51,"props":933,"children":934},{},[935,937,943],{"type":48,"value":936},"For full cross-project setup details (dependencies.yml, prerequisites, orchestration), see ",{"type":43,"tag":938,"props":939,"children":941},"a",{"href":940},"references\u002Fcross-project-collaboration.md",[942],{"type":48,"value":940},{"type":48,"value":386},{"type":43,"tag":88,"props":945,"children":947},{"id":946},"governance-features",[948],{"type":48,"value":949},"Governance Features",{"type":43,"tag":51,"props":951,"children":952},{},[953],{"type":48,"value":954},"dbt Mesh includes four governance features. These work independently and can be adopted incrementally:",{"type":43,"tag":399,"props":956,"children":957},{},[958,984],{"type":43,"tag":403,"props":959,"children":960},{},[961],{"type":43,"tag":407,"props":962,"children":963},{},[964,969,974,979],{"type":43,"tag":411,"props":965,"children":966},{},[967],{"type":48,"value":968},"Feature",{"type":43,"tag":411,"props":970,"children":971},{},[972],{"type":48,"value":973},"Purpose",{"type":43,"tag":411,"props":975,"children":976},{},[977],{"type":48,"value":978},"Key Config",{"type":43,"tag":411,"props":980,"children":981},{},[982],{"type":48,"value":983},"Reference",{"type":43,"tag":422,"props":985,"children":986},{},[987,1020,1053,1093],{"type":43,"tag":407,"props":988,"children":989},{},[990,998,1003,1012],{"type":43,"tag":429,"props":991,"children":992},{},[993],{"type":43,"tag":55,"props":994,"children":995},{},[996],{"type":48,"value":997},"Model Contracts",{"type":43,"tag":429,"props":999,"children":1000},{},[1001],{"type":48,"value":1002},"Guarantee column names, types, and constraints at build time",{"type":43,"tag":429,"props":1004,"children":1005},{},[1006],{"type":43,"tag":63,"props":1007,"children":1009},{"className":1008},[],[1010],{"type":48,"value":1011},"contract: {enforced: true}",{"type":43,"tag":429,"props":1013,"children":1014},{},[1015],{"type":43,"tag":938,"props":1016,"children":1018},{"href":1017},"references\u002Fmodel-contracts.md",[1019],{"type":48,"value":1017},{"type":43,"tag":407,"props":1021,"children":1022},{},[1023,1031,1036,1045],{"type":43,"tag":429,"props":1024,"children":1025},{},[1026],{"type":43,"tag":55,"props":1027,"children":1028},{},[1029],{"type":48,"value":1030},"Groups",{"type":43,"tag":429,"props":1032,"children":1033},{},[1034],{"type":48,"value":1035},"Organize models by team\u002Fdomain ownership",{"type":43,"tag":429,"props":1037,"children":1038},{},[1039],{"type":43,"tag":63,"props":1040,"children":1042},{"className":1041},[],[1043],{"type":48,"value":1044},"group: finance",{"type":43,"tag":429,"props":1046,"children":1047},{},[1048],{"type":43,"tag":938,"props":1049,"children":1051},{"href":1050},"references\u002Fgroups-and-access.md",[1052],{"type":48,"value":1050},{"type":43,"tag":407,"props":1054,"children":1055},{},[1056,1064,1077,1086],{"type":43,"tag":429,"props":1057,"children":1058},{},[1059],{"type":43,"tag":55,"props":1060,"children":1061},{},[1062],{"type":48,"value":1063},"Access Modifiers",{"type":43,"tag":429,"props":1065,"children":1066},{},[1067,1069,1075],{"type":48,"value":1068},"Control which models can ",{"type":43,"tag":63,"props":1070,"children":1072},{"className":1071},[],[1073],{"type":48,"value":1074},"ref",{"type":48,"value":1076}," yours",{"type":43,"tag":429,"props":1078,"children":1079},{},[1080],{"type":43,"tag":63,"props":1081,"children":1083},{"className":1082},[],[1084],{"type":48,"value":1085},"access: public \u002F protected \u002F private",{"type":43,"tag":429,"props":1087,"children":1088},{},[1089],{"type":43,"tag":938,"props":1090,"children":1091},{"href":1050},[1092],{"type":48,"value":1050},{"type":43,"tag":407,"props":1094,"children":1095},{},[1096,1104,1109,1133],{"type":43,"tag":429,"props":1097,"children":1098},{},[1099],{"type":43,"tag":55,"props":1100,"children":1101},{},[1102],{"type":48,"value":1103},"Model Versions",{"type":43,"tag":429,"props":1105,"children":1106},{},[1107],{"type":48,"value":1108},"Manage breaking changes with migration windows",{"type":43,"tag":429,"props":1110,"children":1111},{},[1112,1117,1119,1125,1126,1131],{"type":43,"tag":63,"props":1113,"children":1115},{"className":1114},[],[1116],{"type":48,"value":129},{"type":48,"value":1118}," with ",{"type":43,"tag":63,"props":1120,"children":1122},{"className":1121},[],[1123],{"type":48,"value":1124},"latest_version:",{"type":48,"value":515},{"type":43,"tag":63,"props":1127,"children":1129},{"className":1128},[],[1130],{"type":48,"value":144},{"type":48,"value":1132}," (v1.12+)",{"type":43,"tag":429,"props":1134,"children":1135},{},[1136],{"type":43,"tag":938,"props":1137,"children":1139},{"href":1138},"references\u002Fmodel-versions.md",[1140],{"type":48,"value":1138},{"type":43,"tag":259,"props":1142,"children":1144},{"id":1143},"yaml-placement-rule",[1145],{"type":48,"value":1146},"YAML placement rule",{"type":43,"tag":51,"props":1148,"children":1149},{},[1150,1152,1158,1159,1165,1167,1173,1175,1180,1182,1188],{"type":48,"value":1151},"In model property YAML files, ",{"type":43,"tag":63,"props":1153,"children":1155},{"className":1154},[],[1156],{"type":48,"value":1157},"access",{"type":48,"value":131},{"type":43,"tag":63,"props":1160,"children":1162},{"className":1161},[],[1163],{"type":48,"value":1164},"group",{"type":48,"value":1166},", and ",{"type":43,"tag":63,"props":1168,"children":1170},{"className":1169},[],[1171],{"type":48,"value":1172},"contract",{"type":48,"value":1174}," are ",{"type":43,"tag":55,"props":1176,"children":1177},{},[1178],{"type":48,"value":1179},"configs",{"type":48,"value":1181}," and must always be nested under the ",{"type":43,"tag":63,"props":1183,"children":1185},{"className":1184},[],[1186],{"type":48,"value":1187},"config:",{"type":48,"value":1189}," key — never placed as top-level model properties. Placing them at the top level may appear to work in dbt Core but causes parse errors in dbt's Fusion engine.",{"type":43,"tag":276,"props":1191,"children":1193},{"className":278,"code":1192,"language":280,"meta":281,"style":281},"# ✅ CORRECT — all governance configs under `config:`\nmodels:\n  - name: fct_orders\n    config:\n      group: finance\n      access: public\n      contract:\n        enforced: true\n    columns:\n      - name: order_id\n        data_type: int\n\n# ❌ WRONG — governance configs as top-level properties (breaks Fusion)\nmodels:\n  - name: fct_orders\n    access: public          # WRONG — not under config:\n    group: finance          # WRONG — not under config:\n    contract:               # WRONG — not under config:\n      enforced: true\n    columns:\n      - name: order_id\n        data_type: int\n",[1194],{"type":43,"tag":63,"props":1195,"children":1196},{"__ignoreMap":281},[1197,1205,1217,1237,1249,1266,1283,1296,1315,1328,1350,1368,1376,1385,1397,1417,1440,1462,1480,1497,1509,1529],{"type":43,"tag":287,"props":1198,"children":1199},{"class":289,"line":290},[1200],{"type":43,"tag":287,"props":1201,"children":1202},{"style":294},[1203],{"type":48,"value":1204},"# ✅ CORRECT — all governance configs under `config:`\n",{"type":43,"tag":287,"props":1206,"children":1207},{"class":289,"line":300},[1208,1213],{"type":43,"tag":287,"props":1209,"children":1210},{"style":304},[1211],{"type":48,"value":1212},"models",{"type":43,"tag":287,"props":1214,"children":1215},{"style":310},[1216],{"type":48,"value":313},{"type":43,"tag":287,"props":1218,"children":1219},{"class":289,"line":316},[1220,1224,1228,1232],{"type":43,"tag":287,"props":1221,"children":1222},{"style":310},[1223],{"type":48,"value":322},{"type":43,"tag":287,"props":1225,"children":1226},{"style":304},[1227],{"type":48,"value":327},{"type":43,"tag":287,"props":1229,"children":1230},{"style":310},[1231],{"type":48,"value":332},{"type":43,"tag":287,"props":1233,"children":1234},{"style":335},[1235],{"type":48,"value":1236}," fct_orders\n",{"type":43,"tag":287,"props":1238,"children":1239},{"class":289,"line":341},[1240,1245],{"type":43,"tag":287,"props":1241,"children":1242},{"style":304},[1243],{"type":48,"value":1244},"    config",{"type":43,"tag":287,"props":1246,"children":1247},{"style":310},[1248],{"type":48,"value":313},{"type":43,"tag":287,"props":1250,"children":1251},{"class":289,"line":580},[1252,1257,1261],{"type":43,"tag":287,"props":1253,"children":1254},{"style":304},[1255],{"type":48,"value":1256},"      group",{"type":43,"tag":287,"props":1258,"children":1259},{"style":310},[1260],{"type":48,"value":332},{"type":43,"tag":287,"props":1262,"children":1263},{"style":335},[1264],{"type":48,"value":1265}," finance\n",{"type":43,"tag":287,"props":1267,"children":1268},{"class":289,"line":589},[1269,1274,1278],{"type":43,"tag":287,"props":1270,"children":1271},{"style":304},[1272],{"type":48,"value":1273},"      access",{"type":43,"tag":287,"props":1275,"children":1276},{"style":310},[1277],{"type":48,"value":332},{"type":43,"tag":287,"props":1279,"children":1280},{"style":335},[1281],{"type":48,"value":1282}," public\n",{"type":43,"tag":287,"props":1284,"children":1286},{"class":289,"line":1285},7,[1287,1292],{"type":43,"tag":287,"props":1288,"children":1289},{"style":304},[1290],{"type":48,"value":1291},"      contract",{"type":43,"tag":287,"props":1293,"children":1294},{"style":310},[1295],{"type":48,"value":313},{"type":43,"tag":287,"props":1297,"children":1299},{"class":289,"line":1298},8,[1300,1305,1309],{"type":43,"tag":287,"props":1301,"children":1302},{"style":304},[1303],{"type":48,"value":1304},"        enforced",{"type":43,"tag":287,"props":1306,"children":1307},{"style":310},[1308],{"type":48,"value":332},{"type":43,"tag":287,"props":1310,"children":1312},{"style":1311},"--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC",[1313],{"type":48,"value":1314}," true\n",{"type":43,"tag":287,"props":1316,"children":1318},{"class":289,"line":1317},9,[1319,1324],{"type":43,"tag":287,"props":1320,"children":1321},{"style":304},[1322],{"type":48,"value":1323},"    columns",{"type":43,"tag":287,"props":1325,"children":1326},{"style":310},[1327],{"type":48,"value":313},{"type":43,"tag":287,"props":1329,"children":1331},{"class":289,"line":1330},10,[1332,1337,1341,1345],{"type":43,"tag":287,"props":1333,"children":1334},{"style":310},[1335],{"type":48,"value":1336},"      -",{"type":43,"tag":287,"props":1338,"children":1339},{"style":304},[1340],{"type":48,"value":327},{"type":43,"tag":287,"props":1342,"children":1343},{"style":310},[1344],{"type":48,"value":332},{"type":43,"tag":287,"props":1346,"children":1347},{"style":335},[1348],{"type":48,"value":1349}," order_id\n",{"type":43,"tag":287,"props":1351,"children":1353},{"class":289,"line":1352},11,[1354,1359,1363],{"type":43,"tag":287,"props":1355,"children":1356},{"style":304},[1357],{"type":48,"value":1358},"        data_type",{"type":43,"tag":287,"props":1360,"children":1361},{"style":310},[1362],{"type":48,"value":332},{"type":43,"tag":287,"props":1364,"children":1365},{"style":335},[1366],{"type":48,"value":1367}," int\n",{"type":43,"tag":287,"props":1369,"children":1371},{"class":289,"line":1370},12,[1372],{"type":43,"tag":287,"props":1373,"children":1374},{"emptyLinePlaceholder":574},[1375],{"type":48,"value":577},{"type":43,"tag":287,"props":1377,"children":1379},{"class":289,"line":1378},13,[1380],{"type":43,"tag":287,"props":1381,"children":1382},{"style":294},[1383],{"type":48,"value":1384},"# ❌ WRONG — governance configs as top-level properties (breaks Fusion)\n",{"type":43,"tag":287,"props":1386,"children":1388},{"class":289,"line":1387},14,[1389,1393],{"type":43,"tag":287,"props":1390,"children":1391},{"style":304},[1392],{"type":48,"value":1212},{"type":43,"tag":287,"props":1394,"children":1395},{"style":310},[1396],{"type":48,"value":313},{"type":43,"tag":287,"props":1398,"children":1400},{"class":289,"line":1399},15,[1401,1405,1409,1413],{"type":43,"tag":287,"props":1402,"children":1403},{"style":310},[1404],{"type":48,"value":322},{"type":43,"tag":287,"props":1406,"children":1407},{"style":304},[1408],{"type":48,"value":327},{"type":43,"tag":287,"props":1410,"children":1411},{"style":310},[1412],{"type":48,"value":332},{"type":43,"tag":287,"props":1414,"children":1415},{"style":335},[1416],{"type":48,"value":1236},{"type":43,"tag":287,"props":1418,"children":1420},{"class":289,"line":1419},16,[1421,1426,1430,1435],{"type":43,"tag":287,"props":1422,"children":1423},{"style":304},[1424],{"type":48,"value":1425},"    access",{"type":43,"tag":287,"props":1427,"children":1428},{"style":310},[1429],{"type":48,"value":332},{"type":43,"tag":287,"props":1431,"children":1432},{"style":335},[1433],{"type":48,"value":1434}," public",{"type":43,"tag":287,"props":1436,"children":1437},{"style":294},[1438],{"type":48,"value":1439},"          # WRONG — not under config:\n",{"type":43,"tag":287,"props":1441,"children":1443},{"class":289,"line":1442},17,[1444,1449,1453,1458],{"type":43,"tag":287,"props":1445,"children":1446},{"style":304},[1447],{"type":48,"value":1448},"    group",{"type":43,"tag":287,"props":1450,"children":1451},{"style":310},[1452],{"type":48,"value":332},{"type":43,"tag":287,"props":1454,"children":1455},{"style":335},[1456],{"type":48,"value":1457}," finance",{"type":43,"tag":287,"props":1459,"children":1460},{"style":294},[1461],{"type":48,"value":1439},{"type":43,"tag":287,"props":1463,"children":1465},{"class":289,"line":1464},18,[1466,1471,1475],{"type":43,"tag":287,"props":1467,"children":1468},{"style":304},[1469],{"type":48,"value":1470},"    contract",{"type":43,"tag":287,"props":1472,"children":1473},{"style":310},[1474],{"type":48,"value":332},{"type":43,"tag":287,"props":1476,"children":1477},{"style":294},[1478],{"type":48,"value":1479},"               # WRONG — not under config:\n",{"type":43,"tag":287,"props":1481,"children":1483},{"class":289,"line":1482},19,[1484,1489,1493],{"type":43,"tag":287,"props":1485,"children":1486},{"style":304},[1487],{"type":48,"value":1488},"      enforced",{"type":43,"tag":287,"props":1490,"children":1491},{"style":310},[1492],{"type":48,"value":332},{"type":43,"tag":287,"props":1494,"children":1495},{"style":1311},[1496],{"type":48,"value":1314},{"type":43,"tag":287,"props":1498,"children":1500},{"class":289,"line":1499},20,[1501,1505],{"type":43,"tag":287,"props":1502,"children":1503},{"style":304},[1504],{"type":48,"value":1323},{"type":43,"tag":287,"props":1506,"children":1507},{"style":310},[1508],{"type":48,"value":313},{"type":43,"tag":287,"props":1510,"children":1512},{"class":289,"line":1511},21,[1513,1517,1521,1525],{"type":43,"tag":287,"props":1514,"children":1515},{"style":310},[1516],{"type":48,"value":1336},{"type":43,"tag":287,"props":1518,"children":1519},{"style":304},[1520],{"type":48,"value":327},{"type":43,"tag":287,"props":1522,"children":1523},{"style":310},[1524],{"type":48,"value":332},{"type":43,"tag":287,"props":1526,"children":1527},{"style":335},[1528],{"type":48,"value":1349},{"type":43,"tag":287,"props":1530,"children":1532},{"class":289,"line":1531},22,[1533,1537,1541],{"type":43,"tag":287,"props":1534,"children":1535},{"style":304},[1536],{"type":48,"value":1358},{"type":43,"tag":287,"props":1538,"children":1539},{"style":310},[1540],{"type":48,"value":332},{"type":43,"tag":287,"props":1542,"children":1543},{"style":335},[1544],{"type":48,"value":1367},{"type":43,"tag":51,"props":1546,"children":1547},{},[1548,1550,1555,1557,1563,1565,1571,1572,1578,1580,1586],{"type":48,"value":1549},"This applies to property YAML files only. In ",{"type":43,"tag":63,"props":1551,"children":1553},{"className":1552},[],[1554],{"type":48,"value":660},{"type":48,"value":1556},", use the ",{"type":43,"tag":63,"props":1558,"children":1560},{"className":1559},[],[1561],{"type":48,"value":1562},"+",{"type":48,"value":1564}," prefix for directory-level assignment (e.g. ",{"type":43,"tag":63,"props":1566,"children":1568},{"className":1567},[],[1569],{"type":48,"value":1570},"+group: finance",{"type":48,"value":131},{"type":43,"tag":63,"props":1573,"children":1575},{"className":1574},[],[1576],{"type":48,"value":1577},"+access: private",{"type":48,"value":1579},"). In SQL files, use ",{"type":43,"tag":63,"props":1581,"children":1583},{"className":1582},[],[1584],{"type":48,"value":1585},"{{ config(access='public', group='finance') }}",{"type":48,"value":386},{"type":43,"tag":259,"props":1588,"children":1590},{"id":1589},"adoption-order",[1591],{"type":48,"value":1592},"Adoption order",{"type":43,"tag":276,"props":1594,"children":1598},{"className":1595,"code":1597,"language":48},[1596],"language-text","1. Groups & Access  →  2. Contracts  →  3. Versions  →  4. Cross-Project Refs\n   (organize teams)     (lock shapes)    (manage changes)  (split projects)\n",[1599],{"type":43,"tag":63,"props":1600,"children":1601},{"__ignoreMap":281},[1602],{"type":48,"value":1597},{"type":43,"tag":95,"props":1604,"children":1605},{},[1606,1616,1626,1636],{"type":43,"tag":99,"props":1607,"children":1608},{},[1609,1614],{"type":43,"tag":55,"props":1610,"children":1611},{},[1612],{"type":48,"value":1613},"Groups & Access",{"type":48,"value":1615}," — no schema changes needed, start here",{"type":43,"tag":99,"props":1617,"children":1618},{},[1619,1624],{"type":43,"tag":55,"props":1620,"children":1621},{},[1622],{"type":48,"value":1623},"Contracts",{"type":48,"value":1625}," — require declaring every column and data type in YAML",{"type":43,"tag":99,"props":1627,"children":1628},{},[1629,1634],{"type":43,"tag":55,"props":1630,"children":1631},{},[1632],{"type":48,"value":1633},"Versions",{"type":48,"value":1635}," — needed when a model must introduce a breaking change that consumers need time to migrate to (an enforced contract is recommended alongside, but not required)",{"type":43,"tag":99,"props":1637,"children":1638},{},[1639,1644,1646,1650],{"type":43,"tag":55,"props":1640,"children":1641},{},[1642],{"type":48,"value":1643},"Cross-Project Refs",{"type":48,"value":1645}," — require ",{"type":43,"tag":55,"props":1647,"children":1648},{},[1649],{"type":48,"value":799},{"type":48,"value":1651}," and a successful upstream production job. Do not set up cross-project refs if you cannot confirm the plan level is Enterprise or higher.",{"type":43,"tag":88,"props":1653,"children":1655},{"id":1654},"contracts-vs-tests",[1656],{"type":48,"value":1657},"Contracts vs. Tests",{"type":43,"tag":399,"props":1659,"children":1660},{},[1661,1679],{"type":43,"tag":403,"props":1662,"children":1663},{},[1664],{"type":43,"tag":407,"props":1665,"children":1666},{},[1667,1670,1674],{"type":43,"tag":411,"props":1668,"children":1669},{},[],{"type":43,"tag":411,"props":1671,"children":1672},{},[1673],{"type":48,"value":1623},{"type":43,"tag":411,"props":1675,"children":1676},{},[1677],{"type":48,"value":1678},"Data Tests",{"type":43,"tag":422,"props":1680,"children":1681},{},[1682,1703,1724,1745],{"type":43,"tag":407,"props":1683,"children":1684},{},[1685,1693,1698],{"type":43,"tag":429,"props":1686,"children":1687},{},[1688],{"type":43,"tag":55,"props":1689,"children":1690},{},[1691],{"type":48,"value":1692},"When",{"type":43,"tag":429,"props":1694,"children":1695},{},[1696],{"type":48,"value":1697},"Build-time (pre-flight)",{"type":43,"tag":429,"props":1699,"children":1700},{},[1701],{"type":48,"value":1702},"Post-build (post-flight)",{"type":43,"tag":407,"props":1704,"children":1705},{},[1706,1714,1719],{"type":43,"tag":429,"props":1707,"children":1708},{},[1709],{"type":43,"tag":55,"props":1710,"children":1711},{},[1712],{"type":48,"value":1713},"What",{"type":43,"tag":429,"props":1715,"children":1716},{},[1717],{"type":48,"value":1718},"Column names, data types, constraints",{"type":43,"tag":429,"props":1720,"children":1721},{},[1722],{"type":48,"value":1723},"Data quality, business rules",{"type":43,"tag":407,"props":1725,"children":1726},{},[1727,1735,1740],{"type":43,"tag":429,"props":1728,"children":1729},{},[1730],{"type":43,"tag":55,"props":1731,"children":1732},{},[1733],{"type":48,"value":1734},"Failure",{"type":43,"tag":429,"props":1736,"children":1737},{},[1738],{"type":48,"value":1739},"Model does not materialize",{"type":43,"tag":429,"props":1741,"children":1742},{},[1743],{"type":48,"value":1744},"Model exists but test fails",{"type":43,"tag":407,"props":1746,"children":1747},{},[1748,1756,1761],{"type":43,"tag":429,"props":1749,"children":1750},{},[1751],{"type":43,"tag":55,"props":1752,"children":1753},{},[1754],{"type":48,"value":1755},"Use for",{"type":43,"tag":429,"props":1757,"children":1758},{},[1759],{"type":48,"value":1760},"Shape guarantees for downstream consumers",{"type":43,"tag":429,"props":1762,"children":1763},{},[1764],{"type":48,"value":1765},"Content validation and anomaly detection",{"type":43,"tag":51,"props":1767,"children":1768},{},[1769,1771,1775],{"type":48,"value":1770},"Contracts are enforced ",{"type":43,"tag":55,"props":1772,"children":1773},{},[1774],{"type":48,"value":116},{"type":48,"value":1776}," tests run. If a contract fails, the model is not built, and no tests execute.",{"type":43,"tag":88,"props":1778,"children":1780},{"id":1779},"decision-framework",[1781],{"type":48,"value":1782},"Decision Framework",{"type":43,"tag":259,"props":1784,"children":1786},{"id":1785},"should-this-model-have-a-contract",[1787],{"type":48,"value":1788},"Should this model have a contract?",{"type":43,"tag":51,"props":1790,"children":1791},{},[1792],{"type":48,"value":1793},"Use a contract when:",{"type":43,"tag":95,"props":1795,"children":1796},{},[1797,1809,1814,1819],{"type":43,"tag":99,"props":1798,"children":1799},{},[1800,1802,1807],{"type":48,"value":1801},"The model is ",{"type":43,"tag":63,"props":1803,"children":1805},{"className":1804},[],[1806],{"type":48,"value":632},{"type":48,"value":1808}," (especially if referenced cross-project)",{"type":43,"tag":99,"props":1810,"children":1811},{},[1812],{"type":48,"value":1813},"Other teams depend on this model's schema stability",{"type":43,"tag":99,"props":1815,"children":1816},{},[1817],{"type":48,"value":1818},"The model feeds an exposure (dashboard, ML pipeline, reverse ETL)",{"type":43,"tag":99,"props":1820,"children":1821},{},[1822],{"type":48,"value":1823},"External consumers (other dbt projects, BI dashboards, reverse ETL) query the table directly and would break from column renames or removals",{"type":43,"tag":51,"props":1825,"children":1826},{},[1827],{"type":48,"value":1828},"Do NOT add a contract when:",{"type":43,"tag":95,"props":1830,"children":1831},{},[1832,1850,1860,1870,1895],{"type":43,"tag":99,"props":1833,"children":1834},{},[1835,1840,1842,1848],{"type":43,"tag":55,"props":1836,"children":1837},{},[1838],{"type":48,"value":1839},"Staging models",{"type":48,"value":1841}," (",{"type":43,"tag":63,"props":1843,"children":1845},{"className":1844},[],[1846],{"type":48,"value":1847},"stg_*",{"type":48,"value":1849},") — these are internal implementation details, not consumer-facing APIs",{"type":43,"tag":99,"props":1851,"children":1852},{},[1853,1858],{"type":43,"tag":55,"props":1854,"children":1855},{},[1856],{"type":48,"value":1857},"The model is still evolving",{"type":48,"value":1859}," — if the user says they are iterating on the design, advise waiting until the schema stabilizes",{"type":43,"tag":99,"props":1861,"children":1862},{},[1863,1868],{"type":43,"tag":55,"props":1864,"children":1865},{},[1866],{"type":48,"value":1867},"No external consumers exist",{"type":48,"value":1869}," — in a single-project setup with no cross-project refs, no BI tools depending on the schema, and no exposures, contracts add maintenance overhead without benefit. Ask about consumers before recommending contracts.",{"type":43,"tag":99,"props":1871,"children":1872},{},[1873,1878,1880,1886,1887,1893],{"type":43,"tag":55,"props":1874,"children":1875},{},[1876],{"type":48,"value":1877},"Dynamic\u002Fpivot columns",{"type":48,"value":1879}," — models that use ",{"type":43,"tag":63,"props":1881,"children":1883},{"className":1882},[],[1884],{"type":48,"value":1885},"pivot()",{"type":48,"value":131},{"type":43,"tag":63,"props":1888,"children":1890},{"className":1889},[],[1891],{"type":48,"value":1892},"unpivot()",{"type":48,"value":1894},", or dynamically generate columns are poor candidates because the column list isn't fixed and the contract will break whenever the dynamic values change",{"type":43,"tag":99,"props":1896,"children":1897},{},[1898,1903],{"type":43,"tag":55,"props":1899,"children":1900},{},[1901],{"type":48,"value":1902},"Ephemeral models",{"type":48,"value":1904}," — contracts are not supported on ephemeral materializations",{"type":43,"tag":51,"props":1906,"children":1907},{},[1908,1913],{"type":43,"tag":55,"props":1909,"children":1910},{},[1911],{"type":48,"value":1912},"If the user asks for a contract on a model that matches the \"do NOT add\" criteria above, advise against it and explain why.",{"type":48,"value":1914}," Do not simply comply — the user may not realize the contract is inappropriate. Suggest alternatives (e.g., data tests for staging models, waiting for schema stability, or switching materialization for ephemeral models).",{"type":43,"tag":259,"props":1916,"children":1918},{"id":1917},"should-this-model-be-versioned",[1919],{"type":48,"value":1920},"Should this model be versioned?",{"type":43,"tag":51,"props":1922,"children":1923},{},[1924],{"type":48,"value":1925},"Version a model when:",{"type":43,"tag":95,"props":1927,"children":1928},{},[1929,1955],{"type":43,"tag":99,"props":1930,"children":1931},{},[1932,1934,1939,1941,1946,1948,1953],{"type":48,"value":1933},"You need to make a ",{"type":43,"tag":55,"props":1935,"children":1936},{},[1937],{"type":48,"value":1938},"breaking change",{"type":48,"value":1940}," (column removal, rename, or type change) to a model that consumers depend on — ",{"type":43,"tag":55,"props":1942,"children":1943},{},[1944],{"type":48,"value":1945},"whether or not it has an enforced contract.",{"type":48,"value":1947}," A contract makes the break a build-time error; ",{"type":43,"tag":112,"props":1949,"children":1950},{},[1951],{"type":48,"value":1952},"without",{"type":48,"value":1954}," one the break is silent and ships straight to downstream models and dashboards, so a migration window matters even more. Don't let \"there's no contract\" talk you out of versioning a breaking change.",{"type":43,"tag":99,"props":1956,"children":1957},{},[1958,1960,1965],{"type":48,"value":1959},"Consumers need a migration window before the old shape goes away — ",{"type":43,"tag":55,"props":1961,"children":1962},{},[1963],{"type":48,"value":1964},"including consumers you can't update atomically:",{"type":48,"value":1966}," other teams' models, exposures, dashboards, and BI tools that read the table directly.",{"type":43,"tag":51,"props":1968,"children":1969},{},[1970],{"type":48,"value":1971},"Do NOT version a model:",{"type":43,"tag":95,"props":1973,"children":1974},{},[1975,1980,1985,1990],{"type":43,"tag":99,"props":1976,"children":1977},{},[1978],{"type":48,"value":1979},"For additive changes (new columns) — these are non-breaking",{"type":43,"tag":99,"props":1981,"children":1982},{},[1983],{"type":48,"value":1984},"For bug fixes — fix in place",{"type":43,"tag":99,"props":1986,"children":1987},{},[1988],{"type":48,"value":1989},"Preemptively \"just in case\" — version only when a breaking change is actually needed",{"type":43,"tag":99,"props":1991,"children":1992},{},[1993,1995,2000],{"type":48,"value":1994},"Only skip versioning if ",{"type":43,"tag":55,"props":1996,"children":1997},{},[1998],{"type":48,"value":1999},"nothing reads this model outside dbt",{"type":48,"value":2001}," — no exposures, no BI tools, no other projects. If even one exists, version it.",{"type":43,"tag":2003,"props":2004,"children":2006},"h4",{"id":2005},"versioning-alone-does-not-create-the-migration-window-latest_version-does",[2007,2009,2014],{"type":48,"value":2008},"Versioning alone does NOT create the migration window — ",{"type":43,"tag":63,"props":2010,"children":2012},{"className":2011},[],[2013],{"type":48,"value":137},{"type":48,"value":2015}," does",{"type":43,"tag":51,"props":2017,"children":2018},{},[2019,2021,2026,2027,2032],{"type":48,"value":2020},"Adding the new version and promoting it to ",{"type":43,"tag":63,"props":2022,"children":2024},{"className":2023},[],[2025],{"type":48,"value":137},{"type":48,"value":1174},{"type":43,"tag":55,"props":2028,"children":2029},{},[2030],{"type":48,"value":2031},"two separate deploys, separated by the migration window — never the same change.",{"type":48,"value":2033}," This is the single most common way a \"safe\" versioned change still breaks a dashboard.",{"type":43,"tag":51,"props":2035,"children":2036},{},[2037,2039,2044,2046,2052,2054,2059],{"type":48,"value":2038},"External consumers (BI tools, reverse ETL, dashboards) read a physical relation ",{"type":43,"tag":55,"props":2040,"children":2041},{},[2042],{"type":48,"value":2043},"by name",{"type":48,"value":2045}," — almost always the unsuffixed ",{"type":43,"tag":63,"props":2047,"children":2049},{"className":2048},[],[2050],{"type":48,"value":2051},"model_name",{"type":48,"value":2053}," (the latest-version pointer view, or the plain model when unversioned). That name resolves to whatever ",{"type":43,"tag":63,"props":2055,"children":2057},{"className":2056},[],[2058],{"type":48,"value":137},{"type":48,"value":2060}," points at. So:",{"type":43,"tag":95,"props":2062,"children":2063},{},[2064,2140],{"type":43,"tag":99,"props":2065,"children":2066},{},[2067,2072,2074,2080,2082,2102,2104,2109,2111,2116,2118,2123,2125,2131,2133,2139],{"type":43,"tag":55,"props":2068,"children":2069},{},[2070],{"type":48,"value":2071},"Deploy 1 — introduce:",{"type":48,"value":2073}," add the new version (e.g. ",{"type":43,"tag":63,"props":2075,"children":2077},{"className":2076},[],[2078],{"type":48,"value":2079},"v2",{"type":48,"value":2081},") with the new shape, but ",{"type":43,"tag":55,"props":2083,"children":2084},{},[2085,2087,2092,2094,2100],{"type":48,"value":2086},"keep ",{"type":43,"tag":63,"props":2088,"children":2090},{"className":2089},[],[2091],{"type":48,"value":137},{"type":48,"value":2093}," on the OLD version (",{"type":43,"tag":63,"props":2095,"children":2097},{"className":2096},[],[2098],{"type":48,"value":2099},"v1",{"type":48,"value":2101},").",{"type":48,"value":2103}," So external consumers keep reading the old columns by name, ",{"type":43,"tag":55,"props":2105,"children":2106},{},[2107],{"type":48,"value":2108},"maintain a canonical (unsuffixed) relation that tracks the latest version",{"type":48,"value":2110}," — with ",{"type":43,"tag":63,"props":2112,"children":2114},{"className":2113},[],[2115],{"type":48,"value":137},{"type":48,"value":2117}," still on ",{"type":43,"tag":63,"props":2119,"children":2121},{"className":2120},[],[2122],{"type":48,"value":2099},{"type":48,"value":2124},", that canonical relation serves the old shape (mechanism table below). The new shape is available at ",{"type":43,"tag":63,"props":2126,"children":2128},{"className":2127},[],[2129],{"type":48,"value":2130},"model_v2",{"type":48,"value":2132}," for consumers to migrate against; internal consumers you control can migrate early by pinning ",{"type":43,"tag":63,"props":2134,"children":2136},{"className":2135},[],[2137],{"type":48,"value":2138},"ref('model', v=2)",{"type":48,"value":386},{"type":43,"tag":99,"props":2141,"children":2142},{},[2143,2148,2150,2155,2156,2162,2164,2169,2171,2176],{"type":43,"tag":55,"props":2144,"children":2145},{},[2146],{"type":48,"value":2147},"Deploy 2 — promote (later):",{"type":48,"value":2149}," only after every external consumer confirms migration, bump ",{"type":43,"tag":63,"props":2151,"children":2153},{"className":2152},[],[2154],{"type":48,"value":137},{"type":48,"value":846},{"type":43,"tag":63,"props":2157,"children":2159},{"className":2158},[],[2160],{"type":48,"value":2161},"2",{"type":48,"value":2163}," and set ",{"type":43,"tag":63,"props":2165,"children":2167},{"className":2166},[],[2168],{"type":48,"value":151},{"type":48,"value":2170}," on ",{"type":43,"tag":63,"props":2172,"children":2174},{"className":2173},[],[2175],{"type":48,"value":2099},{"type":48,"value":2177},". The canonical relation then auto-re-points to the new shape — no relation rename needed.",{"type":43,"tag":51,"props":2179,"children":2180},{},[2181],{"type":43,"tag":55,"props":2182,"children":2183},{},[2184],{"type":48,"value":2185},"Keep the canonical relation serving the old shape — pick ONE mechanism (never two):",{"type":43,"tag":399,"props":2187,"children":2188},{},[2189,2210],{"type":43,"tag":403,"props":2190,"children":2191},{},[2192],{"type":43,"tag":407,"props":2193,"children":2194},{},[2195,2200,2205],{"type":43,"tag":411,"props":2196,"children":2197},{},[2198],{"type":48,"value":2199},"dbt version",{"type":43,"tag":411,"props":2201,"children":2202},{},[2203],{"type":48,"value":2204},"Default mechanism",{"type":43,"tag":411,"props":2206,"children":2207},{},[2208],{"type":48,"value":2209},"Result",{"type":43,"tag":422,"props":2211,"children":2212},{},[2213,2268,2320],{"type":43,"tag":407,"props":2214,"children":2215},{},[2216,2224,2243],{"type":43,"tag":429,"props":2217,"children":2218},{},[2219],{"type":43,"tag":55,"props":2220,"children":2221},{},[2222],{"type":48,"value":2223},"≥ 1.12 \u002F Fusion",{"type":43,"tag":429,"props":2225,"children":2226},{},[2227,2229,2234,2236,2241],{"type":48,"value":2228},"built-in ",{"type":43,"tag":63,"props":2230,"children":2232},{"className":2231},[],[2233],{"type":48,"value":144},{"type":48,"value":2235}," (currently ",{"type":43,"tag":55,"props":2237,"children":2238},{},[2239],{"type":48,"value":2240},"beta",{"type":48,"value":2242},")",{"type":43,"tag":429,"props":2244,"children":2245},{},[2246,2252,2253,2258,2260,2266],{"type":43,"tag":63,"props":2247,"children":2249},{"className":2248},[],[2250],{"type":48,"value":2251},"model_v1",{"type":48,"value":131},{"type":43,"tag":63,"props":2254,"children":2256},{"className":2255},[],[2257],{"type":48,"value":2130},{"type":48,"value":2259},", pointer view ",{"type":43,"tag":63,"props":2261,"children":2263},{"className":2262},[],[2264],{"type":48,"value":2265},"model",{"type":48,"value":2267}," (3 relations)",{"type":43,"tag":407,"props":2269,"children":2270},{},[2271,2279,2298],{"type":43,"tag":429,"props":2272,"children":2273},{},[2274],{"type":43,"tag":55,"props":2275,"children":2276},{},[2277],{"type":48,"value":2278},"≤ 1.11",{"type":43,"tag":429,"props":2280,"children":2281},{},[2282,2288,2290,2296],{"type":43,"tag":63,"props":2283,"children":2285},{"className":2284},[],[2286],{"type":48,"value":2287},"create_latest_version_view()",{"type":48,"value":2289}," macro + project ",{"type":43,"tag":63,"props":2291,"children":2293},{"className":2292},[],[2294],{"type":48,"value":2295},"post-hook",{"type":48,"value":2297}," (dbt's officially recommended pattern)",{"type":43,"tag":429,"props":2299,"children":2300},{},[2301,2306,2307,2312,2314,2319],{"type":43,"tag":63,"props":2302,"children":2304},{"className":2303},[],[2305],{"type":48,"value":2251},{"type":48,"value":131},{"type":43,"tag":63,"props":2308,"children":2310},{"className":2309},[],[2311],{"type":48,"value":2130},{"type":48,"value":2313},", canonical view ",{"type":43,"tag":63,"props":2315,"children":2317},{"className":2316},[],[2318],{"type":48,"value":2265},{"type":48,"value":2267},{"type":43,"tag":407,"props":2321,"children":2322},{},[2323,2333,2344],{"type":43,"tag":429,"props":2324,"children":2325},{},[2326,2328],{"type":48,"value":2327},"either — ",{"type":43,"tag":55,"props":2329,"children":2330},{},[2331],{"type":48,"value":2332},"fallback only",{"type":43,"tag":429,"props":2334,"children":2335},{},[2336,2342],{"type":43,"tag":63,"props":2337,"children":2339},{"className":2338},[],[2340],{"type":48,"value":2341},"config.alias",{"type":48,"value":2343}," pinning the OLD version to the unsuffixed name",{"type":43,"tag":429,"props":2345,"children":2346},{},[2347],{"type":48,"value":2348},"2 relations; forces manual un-aliasing + rewiring at Deploy 2",{"type":43,"tag":51,"props":2350,"children":2351},{},[2352,2354,2359,2361,2367,2369,2375],{"type":48,"value":2353},"Always prefer the version-appropriate pointer; reach for ",{"type":43,"tag":63,"props":2355,"children":2357},{"className":2356},[],[2358],{"type":48,"value":2341},{"type":48,"value":2360}," only when neither pointer is available or the user explicitly declines. Never combine a pointer\u002Fview with ",{"type":43,"tag":63,"props":2362,"children":2364},{"className":2363},[],[2365],{"type":48,"value":2366},"alias",{"type":48,"value":2368}," on the same name (collision error). See ",{"type":43,"tag":938,"props":2370,"children":2372},{"href":2371},"references\u002Fmodel-versions.md#latest-version-pointer",[2373],{"type":48,"value":2374},"model-versions.md",{"type":48,"value":386},{"type":43,"tag":51,"props":2377,"children":2378},{},[2379,2391,2393,2398,2400,2405],{"type":43,"tag":55,"props":2380,"children":2381},{},[2382,2384,2389],{"type":48,"value":2383},"Bumping ",{"type":43,"tag":63,"props":2385,"children":2387},{"className":2386},[],[2388],{"type":48,"value":137},{"type":48,"value":2390}," is itself the breaking release for unsuffixed consumers.",{"type":48,"value":2392}," If you introduce the new version ",{"type":43,"tag":112,"props":2394,"children":2395},{},[2396],{"type":48,"value":2397},"as",{"type":48,"value":2399}," latest (or bump latest in the same change), the migration window is zero and the dashboard breaks immediately. The new version always starts as ",{"type":43,"tag":55,"props":2401,"children":2402},{},[2403],{"type":48,"value":2404},"non-latest",{"type":48,"value":386},{"type":43,"tag":51,"props":2407,"children":2408},{},[2409],{"type":48,"value":2410},"After Deploy 1, verify the window is actually open — the consumer's relation must still return the old columns:",{"type":43,"tag":276,"props":2412,"children":2416},{"className":2413,"code":2414,"language":2415,"meta":281,"style":281},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","dbt show --inline \"select \u003Cold_col> from {{ target.schema }}.\u003Cunsuffixed_relation>\"\n","bash",[2417],{"type":43,"tag":63,"props":2418,"children":2419},{"__ignoreMap":281},[2420],{"type":43,"tag":287,"props":2421,"children":2422},{"class":289,"line":290},[2423,2428,2433,2438,2443,2448],{"type":43,"tag":287,"props":2424,"children":2426},{"style":2425},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[2427],{"type":48,"value":23},{"type":43,"tag":287,"props":2429,"children":2430},{"style":335},[2431],{"type":48,"value":2432}," show",{"type":43,"tag":287,"props":2434,"children":2435},{"style":335},[2436],{"type":48,"value":2437}," --inline",{"type":43,"tag":287,"props":2439,"children":2440},{"style":310},[2441],{"type":48,"value":2442}," \"",{"type":43,"tag":287,"props":2444,"children":2445},{"style":335},[2446],{"type":48,"value":2447},"select \u003Cold_col> from {{ target.schema }}.\u003Cunsuffixed_relation>",{"type":43,"tag":287,"props":2449,"children":2450},{"style":310},[2451],{"type":48,"value":2452},"\"\n",{"type":43,"tag":51,"props":2454,"children":2455},{},[2456,2458,2464,2466,2471],{"type":48,"value":2457},"A ",{"type":43,"tag":63,"props":2459,"children":2461},{"className":2460},[],[2462],{"type":48,"value":2463},"column does not exist",{"type":48,"value":2465}," error means ",{"type":43,"tag":63,"props":2467,"children":2469},{"className":2468},[],[2470],{"type":48,"value":137},{"type":48,"value":2472}," was promoted too early and the consumer is already broken.",{"type":43,"tag":259,"props":2474,"children":2476},{"id":2475},"what-access-level-should-this-model-have",[2477],{"type":48,"value":2478},"What access level should this model have?",{"type":43,"tag":276,"props":2480,"children":2483},{"className":2481,"code":2482,"language":48},[1596],"Is it referenced cross-project?\n  └─ Yes → public (with contract recommended)\n  └─ No\n      Is it referenced outside its group?\n        └─ Yes → protected (default)\n        └─ No\n            Is it internal to a small team?\n              └─ Yes → private\n              └─ No → protected (default)\n",[2484],{"type":43,"tag":63,"props":2485,"children":2486},{"__ignoreMap":281},[2487],{"type":48,"value":2482},{"type":43,"tag":51,"props":2489,"children":2490},{},[2491,2496,2498,2504,2506,2512],{"type":43,"tag":55,"props":2492,"children":2493},{},[2494],{"type":48,"value":2495},"Best practice:",{"type":48,"value":2497}," Default new models to ",{"type":43,"tag":63,"props":2499,"children":2501},{"className":2500},[],[2502],{"type":48,"value":2503},"private",{"type":48,"value":2505}," and widen access only when needed. The default ",{"type":43,"tag":63,"props":2507,"children":2509},{"className":2508},[],[2510],{"type":48,"value":2511},"protected",{"type":48,"value":2513}," is permissive — be intentional.",{"type":43,"tag":88,"props":2515,"children":2517},{"id":2516},"common-mistakes",[2518],{"type":48,"value":2519},"Common Mistakes",{"type":43,"tag":399,"props":2521,"children":2522},{},[2523,2544],{"type":43,"tag":403,"props":2524,"children":2525},{},[2526],{"type":43,"tag":407,"props":2527,"children":2528},{},[2529,2534,2539],{"type":43,"tag":411,"props":2530,"children":2531},{},[2532],{"type":48,"value":2533},"Mistake",{"type":43,"tag":411,"props":2535,"children":2536},{},[2537],{"type":48,"value":2538},"Why It's Wrong",{"type":43,"tag":411,"props":2540,"children":2541},{},[2542],{"type":48,"value":2543},"Fix",{"type":43,"tag":422,"props":2545,"children":2546},{},[2547,2580,2613,2645,2675,2700,2718,2756,2803,2838,2870,2921,2939,2957,2975,3013,3057],{"type":43,"tag":407,"props":2548,"children":2549},{},[2550,2562,2567],{"type":43,"tag":429,"props":2551,"children":2552},{},[2553,2555,2560],{"type":48,"value":2554},"Using single-argument ",{"type":43,"tag":63,"props":2556,"children":2558},{"className":2557},[],[2559],{"type":48,"value":68},{"type":48,"value":2561}," in multi-project setups",{"type":43,"tag":429,"props":2563,"children":2564},{},[2565],{"type":48,"value":2566},"Ambiguous — dbt may not resolve to the intended project",{"type":43,"tag":429,"props":2568,"children":2569},{},[2570,2572,2578],{"type":48,"value":2571},"Always use ",{"type":43,"tag":63,"props":2573,"children":2575},{"className":2574},[],[2576],{"type":48,"value":2577},"ref('project_name', 'model_name')",{"type":48,"value":2579}," for cross-project refs",{"type":43,"tag":407,"props":2581,"children":2582},{},[2583,2595,2600],{"type":43,"tag":429,"props":2584,"children":2585},{},[2586,2588,2593],{"type":48,"value":2587},"Using ",{"type":43,"tag":63,"props":2589,"children":2591},{"className":2590},[],[2592],{"type":48,"value":76},{"type":48,"value":2594}," for upstream project data",{"type":43,"tag":429,"props":2596,"children":2597},{},[2598],{"type":48,"value":2599},"In mesh, upstream data comes through public models, not raw sources",{"type":43,"tag":429,"props":2601,"children":2602},{},[2603,2605,2611],{"type":48,"value":2604},"Use ",{"type":43,"tag":63,"props":2606,"children":2608},{"className":2607},[],[2609],{"type":48,"value":2610},"ref('upstream_project', 'model_name')",{"type":48,"value":2612}," instead",{"type":43,"tag":407,"props":2614,"children":2615},{},[2616,2628,2633],{"type":43,"tag":429,"props":2617,"children":2618},{},[2619,2621,2626],{"type":48,"value":2620},"Not reading ",{"type":43,"tag":63,"props":2622,"children":2624},{"className":2623},[],[2625],{"type":48,"value":84},{"type":48,"value":2627}," first",{"type":43,"tag":429,"props":2629,"children":2630},{},[2631],{"type":48,"value":2632},"You won't know which upstream projects exist or what they're called",{"type":43,"tag":429,"props":2634,"children":2635},{},[2636,2638,2643],{"type":48,"value":2637},"Always read ",{"type":43,"tag":63,"props":2639,"children":2641},{"className":2640},[],[2642],{"type":48,"value":84},{"type":48,"value":2644}," before writing cross-project SQL",{"type":43,"tag":407,"props":2646,"children":2647},{},[2648,2658,2663],{"type":43,"tag":429,"props":2649,"children":2650},{},[2651,2653],{"type":48,"value":2652},"Making all models ",{"type":43,"tag":63,"props":2654,"children":2656},{"className":2655},[],[2657],{"type":48,"value":760},{"type":43,"tag":429,"props":2659,"children":2660},{},[2661],{"type":48,"value":2662},"Exposes internal implementation details cross-project",{"type":43,"tag":429,"props":2664,"children":2665},{},[2666,2668,2673],{"type":48,"value":2667},"Only mark models ",{"type":43,"tag":63,"props":2669,"children":2671},{"className":2670},[],[2672],{"type":48,"value":760},{"type":48,"value":2674}," that are intentional APIs for other teams",{"type":43,"tag":407,"props":2676,"children":2677},{},[2678,2683,2688],{"type":43,"tag":429,"props":2679,"children":2680},{},[2681],{"type":48,"value":2682},"Skipping contracts on public models",{"type":43,"tag":429,"props":2684,"children":2685},{},[2686],{"type":48,"value":2687},"Downstream consumers can break silently when schema changes",{"type":43,"tag":429,"props":2689,"children":2690},{},[2691,2693,2698],{"type":48,"value":2692},"Always enforce contracts on ",{"type":43,"tag":63,"props":2694,"children":2696},{"className":2695},[],[2697],{"type":48,"value":632},{"type":48,"value":2699}," models",{"type":43,"tag":407,"props":2701,"children":2702},{},[2703,2708,2713],{"type":43,"tag":429,"props":2704,"children":2705},{},[2706],{"type":48,"value":2707},"Versioning for non-breaking changes",{"type":43,"tag":429,"props":2709,"children":2710},{},[2711],{"type":48,"value":2712},"Creates unnecessary maintenance burden and warehouse cost",{"type":43,"tag":429,"props":2714,"children":2715},{},[2716],{"type":48,"value":2717},"Only version for breaking changes (column removal, type change, rename)",{"type":43,"tag":407,"props":2719,"children":2720},{},[2721,2739,2744],{"type":43,"tag":429,"props":2722,"children":2723},{},[2724,2726,2730,2732,2737],{"type":48,"value":2725},"Introducing the new version ",{"type":43,"tag":112,"props":2727,"children":2728},{},[2729],{"type":48,"value":2397},{"type":48,"value":2731}," ",{"type":43,"tag":63,"props":2733,"children":2735},{"className":2734},[],[2736],{"type":48,"value":137},{"type":48,"value":2738}," (or bumping latest in the same change)",{"type":43,"tag":429,"props":2740,"children":2741},{},[2742],{"type":48,"value":2743},"The unsuffixed\u002Fpointer relation immediately serves the new shape, breaking BI tools and reverse ETL that read it by name — the migration window is zero",{"type":43,"tag":429,"props":2745,"children":2746},{},[2747,2749,2754],{"type":48,"value":2748},"Introduce the new version with ",{"type":43,"tag":63,"props":2750,"children":2752},{"className":2751},[],[2753],{"type":48,"value":137},{"type":48,"value":2755}," still on the OLD version; bump only after consumers confirm migration",{"type":43,"tag":407,"props":2757,"children":2758},{},[2759,2771,2776],{"type":43,"tag":429,"props":2760,"children":2761},{},[2762,2764,2769],{"type":48,"value":2763},"Reaching for ",{"type":43,"tag":63,"props":2765,"children":2767},{"className":2766},[],[2768],{"type":48,"value":2341},{"type":48,"value":2770}," to hold the unsuffixed name when a version-appropriate pointer is available",{"type":43,"tag":429,"props":2772,"children":2773},{},[2774],{"type":48,"value":2775},"Collapses to 2 relations and forces manual un-aliasing + rewiring at promotion instead of an automatic re-point",{"type":43,"tag":429,"props":2777,"children":2778},{},[2779,2781,2786,2788,2794,2796,2801],{"type":48,"value":2780},"Default to ",{"type":43,"tag":63,"props":2782,"children":2784},{"className":2783},[],[2785],{"type":48,"value":144},{"type":48,"value":2787}," (≥1.12) or the ",{"type":43,"tag":63,"props":2789,"children":2791},{"className":2790},[],[2792],{"type":48,"value":2793},"create_latest_version_view",{"type":48,"value":2795}," post-hook (≤1.11); use ",{"type":43,"tag":63,"props":2797,"children":2799},{"className":2798},[],[2800],{"type":48,"value":2366},{"type":48,"value":2802}," only as a fallback",{"type":43,"tag":407,"props":2804,"children":2805},{},[2806,2816,2821],{"type":43,"tag":429,"props":2807,"children":2808},{},[2809,2811],{"type":48,"value":2810},"Forgetting ",{"type":43,"tag":63,"props":2812,"children":2814},{"className":2813},[],[2815],{"type":48,"value":84},{"type":43,"tag":429,"props":2817,"children":2818},{},[2819],{"type":48,"value":2820},"Cross-project refs fail without declaring the upstream project",{"type":43,"tag":429,"props":2822,"children":2823},{},[2824,2826,2831,2833],{"type":48,"value":2825},"Add upstream project to ",{"type":43,"tag":63,"props":2827,"children":2829},{"className":2828},[],[2830],{"type":48,"value":84},{"type":48,"value":2832}," before using two-argument ",{"type":43,"tag":63,"props":2834,"children":2836},{"className":2835},[],[2837],{"type":48,"value":68},{"type":43,"tag":407,"props":2839,"children":2840},{},[2841,2846,2858],{"type":43,"tag":429,"props":2842,"children":2843},{},[2844],{"type":48,"value":2845},"Referencing non-public models cross-project",{"type":43,"tag":429,"props":2847,"children":2848},{},[2849,2851,2856],{"type":48,"value":2850},"Only ",{"type":43,"tag":63,"props":2852,"children":2854},{"className":2853},[],[2855],{"type":48,"value":760},{"type":48,"value":2857}," models are available to other projects",{"type":43,"tag":429,"props":2859,"children":2860},{},[2861,2863,2868],{"type":48,"value":2862},"Set ",{"type":43,"tag":63,"props":2864,"children":2866},{"className":2865},[],[2867],{"type":48,"value":632},{"type":48,"value":2869}," on models intended for cross-project consumption",{"type":43,"tag":407,"props":2871,"children":2872},{},[2873,2898,2903],{"type":43,"tag":429,"props":2874,"children":2875},{},[2876,2878,2883,2884,2889,2891,2896],{"type":48,"value":2877},"Placing ",{"type":43,"tag":63,"props":2879,"children":2881},{"className":2880},[],[2882],{"type":48,"value":1157},{"type":48,"value":131},{"type":43,"tag":63,"props":2885,"children":2887},{"className":2886},[],[2888],{"type":48,"value":1164},{"type":48,"value":2890},", or ",{"type":43,"tag":63,"props":2892,"children":2894},{"className":2893},[],[2895],{"type":48,"value":1172},{"type":48,"value":2897}," as top-level model properties in YAML",{"type":43,"tag":429,"props":2899,"children":2900},{},[2901],{"type":48,"value":2902},"Breaks Fusion engine parsing; top-level placement is not valid config",{"type":43,"tag":429,"props":2904,"children":2905},{},[2906,2908,2913,2915],{"type":48,"value":2907},"Always nest under ",{"type":43,"tag":63,"props":2909,"children":2911},{"className":2910},[],[2912],{"type":48,"value":1187},{"type":48,"value":2914}," — e.g. ",{"type":43,"tag":63,"props":2916,"children":2918},{"className":2917},[],[2919],{"type":48,"value":2920},"config: { access: public }",{"type":43,"tag":407,"props":2922,"children":2923},{},[2924,2929,2934],{"type":43,"tag":429,"props":2925,"children":2926},{},[2927],{"type":48,"value":2928},"Adding contracts to staging models",{"type":43,"tag":429,"props":2930,"children":2931},{},[2932],{"type":48,"value":2933},"Staging models are internal — contracts add friction without protecting external consumers",{"type":43,"tag":429,"props":2935,"children":2936},{},[2937],{"type":48,"value":2938},"Advise against it; suggest data tests instead",{"type":43,"tag":407,"props":2940,"children":2941},{},[2942,2947,2952],{"type":43,"tag":429,"props":2943,"children":2944},{},[2945],{"type":48,"value":2946},"Adding contracts to models with dynamic\u002Fpivot columns",{"type":43,"tag":429,"props":2948,"children":2949},{},[2950],{"type":48,"value":2951},"Column list changes with data, breaking the contract",{"type":43,"tag":429,"props":2953,"children":2954},{},[2955],{"type":48,"value":2956},"Advise against it; explain why the column list isn't fixed",{"type":43,"tag":407,"props":2958,"children":2959},{},[2960,2965,2970],{"type":43,"tag":429,"props":2961,"children":2962},{},[2963],{"type":48,"value":2964},"Adding contracts without establishing external consumers",{"type":43,"tag":429,"props":2966,"children":2967},{},[2968],{"type":48,"value":2969},"Contracts protect a schema boundary — no consumers means no boundary to protect",{"type":43,"tag":429,"props":2971,"children":2972},{},[2973],{"type":48,"value":2974},"Ask who depends on this model before adding a contract",{"type":43,"tag":407,"props":2976,"children":2977},{},[2978,2990,3001],{"type":43,"tag":429,"props":2979,"children":2980},{},[2981,2983,2988],{"type":48,"value":2982},"Making a model ",{"type":43,"tag":63,"props":2984,"children":2986},{"className":2985},[],[2987],{"type":48,"value":2503},{"type":48,"value":2989}," that is already referenced outside its group",{"type":43,"tag":429,"props":2991,"children":2992},{},[2993,2995],{"type":48,"value":2994},"Existing refs break with a ",{"type":43,"tag":63,"props":2996,"children":2998},{"className":2997},[],[2999],{"type":48,"value":3000},"DbtReferenceError",{"type":43,"tag":429,"props":3002,"children":3003},{},[3004,3006,3011],{"type":48,"value":3005},"Widen access to ",{"type":43,"tag":63,"props":3007,"children":3009},{"className":3008},[],[3010],{"type":48,"value":2511},{"type":48,"value":3012}," or refactor callers into the same group first",{"type":43,"tag":407,"props":3014,"children":3015},{},[3016,3021,3032],{"type":43,"tag":429,"props":3017,"children":3018},{},[3019],{"type":48,"value":3020},"Setting up cross-project refs without confirming dbt Cloud Enterprise",{"type":43,"tag":429,"props":3022,"children":3023},{},[3024,3025,3030],{"type":48,"value":773},{"type":43,"tag":63,"props":3026,"children":3028},{"className":3027},[],[3029],{"type":48,"value":68},{"type":48,"value":3031}," is unavailable on lower plan tiers",{"type":43,"tag":429,"props":3033,"children":3034},{},[3035,3037,3042,3043,3048,3050,3055],{"type":48,"value":3036},"Confirm the plan level before adding ",{"type":43,"tag":63,"props":3038,"children":3040},{"className":3039},[],[3041],{"type":48,"value":370},{"type":48,"value":846},{"type":43,"tag":63,"props":3044,"children":3046},{"className":3045},[],[3047],{"type":48,"value":84},{"type":48,"value":3049}," or writing two-argument ",{"type":43,"tag":63,"props":3051,"children":3053},{"className":3052},[],[3054],{"type":48,"value":68},{"type":48,"value":3056}," calls",{"type":43,"tag":407,"props":3058,"children":3059},{},[3060,3072,3085],{"type":43,"tag":429,"props":3061,"children":3062},{},[3063,3065,3070],{"type":48,"value":3064},"Adding ",{"type":43,"tag":63,"props":3066,"children":3068},{"className":3067},[],[3069],{"type":48,"value":84},{"type":48,"value":3071}," without a successful upstream production job",{"type":43,"tag":429,"props":3073,"children":3074},{},[3075,3077,3083],{"type":48,"value":3076},"dbt Cloud resolves cross-project refs via the upstream ",{"type":43,"tag":63,"props":3078,"children":3080},{"className":3079},[],[3081],{"type":48,"value":3082},"manifest.json",{"type":48,"value":3084}," — no job run means no manifest",{"type":43,"tag":429,"props":3086,"children":3087},{},[3088],{"type":48,"value":3089},"Run at least one successful production deployment in the upstream project first",{"type":43,"tag":3091,"props":3092,"children":3093},"style",{},[3094],{"type":48,"value":3095},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":3097,"total":1378},[3098,3110,3129,3139,3153,3170,3181],{"slug":233,"name":233,"fn":3099,"description":3100,"org":3101,"tags":3102,"stars":24,"repoUrl":25,"updatedAt":3109},"add dbt unit tests","Creates unit test YAML definitions that mock upstream model inputs and validate expected outputs. Use when adding unit tests for a dbt model or practicing test-driven development (TDD) in dbt.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3103,3104,3107],{"name":23,"slug":23,"type":15},{"name":3105,"slug":3106,"type":15},"Testing","testing",{"name":3108,"slug":280,"type":15},"YAML","2026-04-06T18:09:14.01391",{"slug":3111,"name":3111,"fn":3112,"description":3113,"org":3114,"tags":3115,"stars":24,"repoUrl":25,"updatedAt":3128},"answering-natural-language-questions-with-dbt","answer business questions using dbt Semantic Layer","Writes and executes SQL queries against the data warehouse using dbt's Semantic Layer or ad-hoc SQL to answer business questions. Use when a user asks about analytics, metrics, KPIs, or data (e.g., \"What were total sales last quarter?\", \"Show me top customers by revenue\"). NOT for validating, testing, or building dbt models during development.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3116,3119,3122,3123,3126],{"name":3117,"slug":3118,"type":15},"Analytics","analytics",{"name":3120,"slug":3121,"type":15},"Data Analysis","data-analysis",{"name":23,"slug":23,"type":15},{"name":3124,"slug":3125,"type":15},"Metrics","metrics",{"name":3127,"slug":540,"type":15},"SQL","2026-04-06T18:09:07.651959",{"slug":245,"name":245,"fn":3130,"description":3131,"org":3132,"tags":3133,"stars":24,"repoUrl":25,"updatedAt":3138},"build dbt Semantic Layer components","Use when creating or modifying dbt Semantic Layer components — semantic models, metrics, dimensions, entities, measures, or time spines. Covers MetricFlow configuration, metric types (simple, derived, cumulative, ratio, conversion), and validation for both latest and legacy YAML specs.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3134,3135,3136,3137],{"name":3117,"slug":3118,"type":15},{"name":17,"slug":18,"type":15},{"name":23,"slug":23,"type":15},{"name":3124,"slug":3125,"type":15},"2026-07-18T05:12:20.387564",{"slug":3140,"name":3140,"fn":3141,"description":3142,"org":3143,"tags":3144,"stars":24,"repoUrl":25,"updatedAt":3152},"configuring-dbt-mcp-server","configure dbt MCP server","Generates MCP server configuration JSON, resolves authentication setup, and validates server connectivity for dbt. Use when setting up, configuring, or troubleshooting the dbt MCP server for AI tools like Claude Desktop, Claude Code, Cursor, or VS Code.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3145,3148,3149],{"name":3146,"slug":3147,"type":15},"Agent Context","agent-context",{"name":23,"slug":23,"type":15},{"name":3150,"slug":3151,"type":15},"MCP","mcp","2026-04-06T18:09:12.757804",{"slug":3154,"name":3154,"fn":3155,"description":3156,"org":3157,"tags":3158,"stars":24,"repoUrl":25,"updatedAt":3169},"creating-mermaid-dbt-dag","generate Mermaid diagrams of dbt model lineage","Generates a Mermaid flowchart diagram of dbt model lineage using MCP tools, manifest.json, or direct code parsing as fallbacks. Use when visualizing dbt model lineage and dependencies as a Mermaid diagram in markdown format.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3159,3162,3163,3166],{"name":3160,"slug":3161,"type":15},"Data Pipeline","data-pipeline",{"name":23,"slug":23,"type":15},{"name":3164,"slug":3165,"type":15},"Diagrams","diagrams",{"name":3167,"slug":3168,"type":15},"Documentation","documentation","2026-04-06T18:09:15.270247",{"slug":3171,"name":3171,"fn":3172,"description":3173,"org":3174,"tags":3175,"stars":24,"repoUrl":25,"updatedAt":3180},"fetching-dbt-docs","search dbt documentation","Retrieves and searches dbt documentation pages in LLM-friendly markdown format. Use when fetching dbt documentation, looking up dbt features, or answering questions about dbt Cloud, dbt Core, or the dbt Semantic Layer.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3176,3177,3178],{"name":23,"slug":23,"type":15},{"name":3167,"slug":3168,"type":15},{"name":983,"slug":3179,"type":15},"reference","2026-04-06T18:09:06.36975",{"slug":3182,"name":3182,"fn":3183,"description":3184,"org":3185,"tags":3186,"stars":24,"repoUrl":25,"updatedAt":3195},"migrating-dbt-core-to-fusion","triage dbt-core to Fusion migration errors","Use when a user needs help triaging dbt-core to Fusion migration errors. Runs dbt-autofix first, then classifies remaining errors into actionable categories (auto-fixable, guided fixes, needs input, blocked).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3187,3188,3189,3192],{"name":17,"slug":18,"type":15},{"name":23,"slug":23,"type":15},{"name":3190,"slug":3191,"type":15},"Migration","migration",{"name":3193,"slug":3194,"type":15},"Triage","triage","2026-04-06T18:09:01.250175",{"items":3197,"total":1419},[3198,3204,3212,3219,3225,3232,3238,3245,3259,3271,3283,3293],{"slug":233,"name":233,"fn":3099,"description":3100,"org":3199,"tags":3200,"stars":24,"repoUrl":25,"updatedAt":3109},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3201,3202,3203],{"name":23,"slug":23,"type":15},{"name":3105,"slug":3106,"type":15},{"name":3108,"slug":280,"type":15},{"slug":3111,"name":3111,"fn":3112,"description":3113,"org":3205,"tags":3206,"stars":24,"repoUrl":25,"updatedAt":3128},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3207,3208,3209,3210,3211],{"name":3117,"slug":3118,"type":15},{"name":3120,"slug":3121,"type":15},{"name":23,"slug":23,"type":15},{"name":3124,"slug":3125,"type":15},{"name":3127,"slug":540,"type":15},{"slug":245,"name":245,"fn":3130,"description":3131,"org":3213,"tags":3214,"stars":24,"repoUrl":25,"updatedAt":3138},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3215,3216,3217,3218],{"name":3117,"slug":3118,"type":15},{"name":17,"slug":18,"type":15},{"name":23,"slug":23,"type":15},{"name":3124,"slug":3125,"type":15},{"slug":3140,"name":3140,"fn":3141,"description":3142,"org":3220,"tags":3221,"stars":24,"repoUrl":25,"updatedAt":3152},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3222,3223,3224],{"name":3146,"slug":3147,"type":15},{"name":23,"slug":23,"type":15},{"name":3150,"slug":3151,"type":15},{"slug":3154,"name":3154,"fn":3155,"description":3156,"org":3226,"tags":3227,"stars":24,"repoUrl":25,"updatedAt":3169},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3228,3229,3230,3231],{"name":3160,"slug":3161,"type":15},{"name":23,"slug":23,"type":15},{"name":3164,"slug":3165,"type":15},{"name":3167,"slug":3168,"type":15},{"slug":3171,"name":3171,"fn":3172,"description":3173,"org":3233,"tags":3234,"stars":24,"repoUrl":25,"updatedAt":3180},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3235,3236,3237],{"name":23,"slug":23,"type":15},{"name":3167,"slug":3168,"type":15},{"name":983,"slug":3179,"type":15},{"slug":3182,"name":3182,"fn":3183,"description":3184,"org":3239,"tags":3240,"stars":24,"repoUrl":25,"updatedAt":3195},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3241,3242,3243,3244],{"name":17,"slug":18,"type":15},{"name":23,"slug":23,"type":15},{"name":3190,"slug":3191,"type":15},{"name":3193,"slug":3194,"type":15},{"slug":3246,"name":3246,"fn":3247,"description":3248,"org":3249,"tags":3250,"stars":24,"repoUrl":25,"updatedAt":3258},"migrating-dbt-project-across-platforms","migrate dbt projects across data platforms","Use when migrating a dbt project from one data platform or data warehouse to another (e.g., Snowflake to Databricks, Databricks to Snowflake) using dbt Fusion's real-time compilation to identify and fix SQL dialect differences.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3251,3252,3255,3256,3257],{"name":17,"slug":18,"type":15},{"name":3253,"slug":3254,"type":15},"Database","database",{"name":23,"slug":23,"type":15},{"name":3190,"slug":3191,"type":15},{"name":3127,"slug":540,"type":15},"2026-04-06T18:09:02.513828",{"slug":3260,"name":3260,"fn":3261,"description":3262,"org":3263,"tags":3264,"stars":24,"repoUrl":25,"updatedAt":3270},"running-dbt-commands","run dbt CLI commands","Formats and executes dbt CLI commands, selects the correct dbt executable, and structures command parameters. Use when running models, tests, builds, compiles, or show queries via dbt CLI. Use when unsure which dbt executable to use or how to format command parameters.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3265,3268,3269],{"name":3266,"slug":3267,"type":15},"CLI","cli",{"name":17,"slug":18,"type":15},{"name":23,"slug":23,"type":15},"2026-04-06T18:09:03.791122",{"slug":3272,"name":3272,"fn":3273,"description":3274,"org":3275,"tags":3276,"stars":24,"repoUrl":25,"updatedAt":3282},"troubleshooting-dbt-job-errors","troubleshoot dbt job errors","Diagnoses dbt Cloud\u002Fplatform job failures by analyzing run logs, querying the Admin API, reviewing git history, and investigating data issues. Use when a dbt Cloud\u002Fplatform job fails and you need to diagnose the root cause, especially when error messages are unclear or when intermittent failures occur. Do not use for local dbt development errors.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3277,3278,3279],{"name":3160,"slug":3161,"type":15},{"name":23,"slug":23,"type":15},{"name":3280,"slug":3281,"type":15},"Debugging","debugging","2026-04-06T18:09:05.065669",{"slug":220,"name":220,"fn":3284,"description":3285,"org":3286,"tags":3287,"stars":24,"repoUrl":25,"updatedAt":3292},"build dbt models and tests","Builds and modifies dbt models, writes SQL transformations using ref() and source(), creates tests, and validates results with dbt show. Use when doing any dbt work - building or modifying models, debugging errors, exploring unfamiliar data sources, writing tests, or evaluating impact of changes.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3288,3289,3290,3291],{"name":3117,"slug":3118,"type":15},{"name":17,"slug":18,"type":15},{"name":23,"slug":23,"type":15},{"name":3127,"slug":540,"type":15},"2026-04-06T18:09:11.455851",{"slug":3294,"name":3294,"fn":3295,"description":3296,"org":3297,"tags":3298,"stars":24,"repoUrl":25,"updatedAt":3305},"using-dbt-state","configure and optimize dbt state","Use when a user is enabling, configuring, optimizing, or debugging dbt State (the server-backed reuse mechanism that clones or skips nodes instead of rebuilding them). Use when they conflate dbt State with the `state:modified` selector or `--state` deferral. Use when asked about models rebuilding unexpectedly, views with `select *` rebuilding, volatile SQL (`current_timestamp()`, `random()`) rebuilding or not, cross-developer cloning, lag_tolerance.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3299,3300,3301,3302],{"name":17,"slug":18,"type":15},{"name":3160,"slug":3161,"type":15},{"name":23,"slug":23,"type":15},{"name":3303,"slug":3304,"type":15},"Performance","performance","2026-06-25T07:12:16.623154"]