From dex
Detects and reconciles drift in dbt projects across schema, volume, grain, and semantic axes. Reads a baseline snapshot and proposes reviewable diffs for warehouse changes.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dex:maintainThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Keep the dbt project correct as the world underneath it moves. Maintenance is the
Keep the dbt project correct as the world underneath it moves. Maintenance is the recurring half of the loop: warehouses drift, loads half-fail, models go stale, keys stop being unique, and business definitions change. This skill compares a known-good baseline against current reality, classifies what drifted, and proposes the reconciling edit. It is manual and on-demand here; continuous drift detection and automated PRs are the commercial product.
Drift is measured against a baseline (the .dex/snapshot.json fingerprint of
the warehouse map and the project's per-layer definitions). Detection is
read-only; only reconcile proposes edits.
Snapshot discipline matters. A snapshot is only as trustworthy as the moment
it froze. Take one right after a known-good build (maintain snapshot), and
commit .dex/snapshot.json like a lockfile so the whole team diffs against
the same reference. Snapshot a state that is already drifted and check will
mask the very drift you care about. When you accept a change as the new normal
(re-run explore map first, then maintain snapshot); check warns when the
baseline looks stale.
uv run "${CLAUDE_SKILL_DIR}/scripts/run.py" <subcommand> [flags]
maintain snapshot captures or refreshes the baseline. Run it after a clean
explore or transform session so later runs have a known-good reference. It pins
the current .dex/cache.json (so the grain baseline is the exact-distinct
verdicts explore map already computed) plus per-layer fingerprints of the dbt
project. Without a cache it captures a metadata-only baseline and says so.maintain check is the everyday entry point: it sweeps every axis and returns
a report ranked by blast radius. Read-only.maintain schema [<objects>] detects structural drift: source columns and
tables added, dropped, retyped, or renamed; nullability changes; declared
sources the warehouse no longer honors.maintain volume [<objects>] detects freshness drift: row counts that
collapsed, spiked, or went to zero. This is the "is the data still flowing
correctly?" axis, distinct from "did the shape change?".maintain grain [<objects>] detects grain drift: a declared primary or
unique key that now has duplicates, a changed row-per-entity cardinality, or an
increased join fanout. Uses aggregates, never raw rows.maintain semantic [<objects>] detects definition drift: metric, measure,
dimension, or entity definitions that changed against the baseline; semantic
references that no longer resolve to a model or column; and categorical
dimensions whose set of values widened or narrowed underneath their metrics.maintain reconcile [<class>] proposes the dbt edits that bring the project
back in sync, as reviewable diffs. Optionally scope it to one class (schema,
volume, grain, or semantic).The usual flow: check to triage, a focused detector to understand one axis in
depth, then reconcile to get the proposed fix.
Detection is read-only, but read-only is not the same as free on a metered connector (BigQuery, Snowflake, Databricks, Postgres). The axes split:
needs_confirmation with an estimate in cost.estimate (and a per-table
breakdown). Surface it to the user in human units, get an explicit budget, and
re-issue the same command with --confirm --budget <magnitude> in the
paradigm's unit (bytes on BigQuery, warehouse-seconds on Snowflake and
Databricks, database-seconds on Postgres). Never invent a budget the user
did not agree to, and never retry with a raised budget on an over-ceiling
refusal without asking.check is two-phase on a metered connector: the free axes complete
immediately and their findings ride along in the needs_confirmation envelope,
with one combined estimate for the scanning axes. Confirm to complete the sweep.On DuckDB everything is free and local, so nothing prompts.
Reconcile tags every proposal by kind, because the fix differs sharply by axis:
mechanical: schema drift on a dex-scaffolded staging model re-scaffolds
the model from the drifted source. High-confidence, but still a reviewable diff:
read it for hand-written logic the scaffold cannot know about.advisory: grain, volume, and semantic drift are decisions, not auto-fixes
(dex cannot dedup your warehouse or decide whether a new 'refunded' status
belongs in a metric). The proposal is the decision surfaced, at most backed by a
test edit that makes the break visible in builds.When reconcile produces edits it stores them as a plan and prints a plan_id.
Apply them with transform apply <plan-id> (the one apply door): a human edit made
since detection surfaces as a conflict, never a silent overwrite.
transform apply. Human dbt edits are authoritative; on conflict the
engine surfaces the divergence and asks rather than overwriting..dex/ snapshot is a non-canonical
fingerprint used only to detect change.npx claudepluginhub exmergo/exmergo-agent-plugins --plugin dexBuilds and modifies dbt models with SQL transformations using ref() and source(), creates tests, validates results with dbt show. For dbt projects: modeling, debugging errors, data exploration, testing, change evaluation.
Generates SQL validation notebooks for dbt PR changes with before/after comparison queries, usable with Monte Carlo.
Author and refactor a dbt project: bootstrap, write SQL models, add tests/docs, and define the semantic layer (MetricFlow) with reviewable diffs.