{"id":"dbt-ingest","name":"dbt_ingest","summary":"dbtの「schema.yml」/「properties.yml」モデルやソースをktxセマンティックレイヤーのオーバーレイやカラムノートにマッピングします。","body":"# dbt → ktx (bundle ingest)\n\nUse this skill for **uploaded** dbt projects (`dbt_project.yml` at stage root, `models/**`, `sources/**`, `schema.yml`). There is **no** `fetch()` in v1 - scheduled `dbt parse` / `manifest.json` pulls are out of scope; host-provided dbt sync may still backfill structured test metadata into `_schema` on the next sync.\n\n## Mapping (models / sources → SL)\n\n| dbt | ktx | Notes |\n|-----|--------|--------|\n| `models:` entry with `columns:` | **Overlay** on the manifest table with the same name (after `discover_data` / `entity_details`) | One SL source per physical table; model name may differ from DB name - resolve with `read_raw_file` + warehouse context. |\n| `sources:` → `tables:` | Same as models; use `identifier` when present instead of logical `name`. | Schema + name must match how the connection sees tables. |\n| Column `description` | `column_overrides[].descriptions.user` on the overlay | Do not overwrite `dbt` description keys from sync. |\n| `data_tests: not_null` / `unique` | Short hint in column `descriptions` or notes: “dbt: not null”, “dbt: unique” | Full structured metadata lands in manifest via **sync**; the skill keeps bundle-time SL text useful for the agent. |\n| `accepted_values` | Add a **brief** line in the column description: allowed values (truncate long lists) | Also mention enum-like use in `discover_data` / filters. |\n| `relationships` | Add or confirm `joins:` on the overlay **only** when `to` resolves to a real table via `read_raw_file` + `discover_data` / `entity_details` | If the ref cannot be resolved, capture the intent in a wiki page instead. |\n\n## Physical schema grounding\n\ndbt YAML is documentation and test metadata; it is not permission to invent physical columns. Before writing any table-backed SL source, confirm the real warehouse shape with `discover_data`, `sl_discover`, or `entity_details` and use only confirmed column names in `column_overrides:`, computed-only `columns:`, `grain:`, `joins:`, `segments:`, and `measures[].expr`.\n\nFor dbt context-source ingest, the dbt connection is usually not the warehouse connection. Call `sl_discover` without `connectionId` first, then write overlays to the connection that owns the matching manifest-backed source (for example `postgres-warehouse`), not to the dbt connection (for example `dbt-main`). If no matching manifest-backed source is visible on any warehouse connection, do not call `sl_write_source`; record `emit_unmapped_fallback` and keep the fact wiki-only.\n\nIf a `models:` entry has no `columns:` block, or the available raw files do not confirm the physical column names, do **not** synthesize a full standalone source. Write a wiki note or a description-only overlay for the resolved manifest table instead. If a business metric is described but its referenced column is not confirmed in the warehouse schema, omit the measure and capture the unresolved intent in the wiki.\n\nInclude `rawPaths` on every `wiki_write`, `sl_write_source`, and `sl_edit_source` call with only the dbt YAML files that directly support the action.\n\nAfter every `sl_write_source`, call `sl_validate`. A validation error saying a declared column or measure reference is absent from the physical table is a hard stop: re-read the warehouse-backed source and rewrite with confirmed names, or remove the invalid SL fields.\n\n## Identifier Verification Protocol\n\nBefore writing a wiki page or SL source on any topic:\n\n1. `discover_data({query: \"<topic>\"})` - see what wikis, SL sources, and raw\n   tables already exist. Prefer updating existing pages over creating new ones.\n\nBefore emitting any `schema.table` or `schema.table.column` into a wiki body,\nSL source, `tables:` frontmatter, `sl_refs`, or `emit_unmapped_fallback`:\n\n2. `entity_details({connectionId, targets: [{display: \"<identifier>\"}]})` -\n   confirm the identifier resolves; inspect native types, FK/PK, and\n   sampleValues.\n3. For literal values from the source, such as status codes or plan tiers,\n   check whether they appear in `entity_details` sampleValues for the relevant\n   column. If sampleValues is short or the sample may have missed real values,\n   run a `sql_execution` probe with the same warehouse connection id:\n   `sql_execution({connectionId, sql: \"SELECT DISTINCT <col> FROM <ref> LIMIT 50\"})`.\n4. If the candidate identifier still does not resolve, do one of:\n   - Use `sql_execution({connectionId, sql: \"SELECT 1 FROM <ref> LIMIT 0\"})`.\n     If it errors, the identifier is fictional.\n   - Wrap the identifier in `[unverified - from <rawPath>]` in the wiki body,\n     citing the exact raw path that mentioned it.\n   - When recording `emit_unmapped_fallback` with `no_physical_table`, include\n     the failing probe error in `clarification`.\n5. Never copy `<schema>.<table>` placeholder strings from these instructions\n   into output.\n\n## 1.1 test hints (descriptions / meta)\n\nWhen YAML shows `accepted_values` or `not_null`, add **short** hints into `column_overrides[].descriptions` (for example under `user`) or freeform column notes so chat and validation see intent before the next git sync refreshes `constraints` / `enum_values` in `_schema`. Keep hints under a few words when possible.\n\n## Overlap with MetricFlow\n\nIf the same bundle also has MetricFlow `semantic_models:` / `metrics:`, the **`metricflow_ingest`** skill owns semantic/metric shapes. This skill focuses on **raw dbt schema** YAML (`models`, `sources`, tests). If both apply, load `metricflow_ingest` first when the file is clearly MetricFlow; otherwise use `dbt_ingest` for `schema.yml` without semantic_models.\n\n## Do not\n\n- Do not run `dbt` CLI or assume `target/` / `manifest.json` exists in the upload.\n- Do not invent column names, grain keys, or measure expressions from dbt model names, descriptions, tests, or common naming patterns.\n- Do not write computed `columns:`, `column_overrides:`, `grain:`, or `measures:` for a dbt model unless those exact column names are confirmed by dbt YAML columns or warehouse schema discovery.\n- Do not invent joins from `relationships` tests if the target model/table is not found in SL or the warehouse.\n- Do not read `peerFileIndex` paths - use `read_raw_file` only on `rawFiles` and `dependencyPaths` from the WorkUnit.","author":"@Kaelio","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/Kaelio/ktx/tree/main/packages/cli/src/skills/dbt_ingest","license":"Apache-2.0","category":"testing","lang":"en","tokens":1472,"stars":0,"calls30d":1,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":[]}}