1. State what the model should mean
Tell the agent the grain and population you want, not just the model name:Start a new dbt project
Start a new dbt project
After connecting and exploring, use
dex transform init analytics to create a
project named analytics. This command creates the project files and records
the connection in configuration, returning the changes as diffs. It refuses to
overwrite an existing project. Existing projects are discovered from the
repository; dbt_project_dir can select one when the repository holds several.The generated dev profile still needs a valid target. For DuckDB, a new dev file
that reads sources must be populated before the build can succeed. Follow the
DuckDB dev-target guidance.2. Review the plan
The agent submits the edits and declarations together:edits.json is the agent’s prepared change, not a file Dex creates from this
command alone. The result includes a plan ID, diffs, warnings, and declaration
feedback. Resolve missing intent and contradictions, then plan again before
applying. For an existing model, also review row attribution: a refactor should
preserve its results.
When the plan rewrites a model that already exists, it carries
data.refactor_comparison_offer. If the change is meant to keep that model’s
results (a refactor, an extracted intermediate, a cleanup), compare before
applying, because applying discards the baseline:
equivalent holds for the relations named in input_scope at compared_at.
different means the rewrite changed the rows or the schema: fix it, or state an
intended rename with --map or type change with --accept-type. not_checked
is not a pass: its reason_code names what to repair, such as a parent whose last
build failed. The offer’s static_attribution says when this comparison is the
only evidence a refactor kept its results, for example when the model’s SQL
calls a macro. A change meant to alter results needs no comparison. The verdict
is recorded on the plan, and transform apply reports it.
When the plan adds a cast or a lower, upper or trim to an identifier, such
as a try_cast(product_id as integer) is not null that makes a broken join
compile, it reports the conversion under data.identifier_conversions, with
counts and their denominator. The counts show how many identifiers do not
convert, how many collapse into one key (7 and 007), and how many the prior
model held that the authored one does not, even when the row count is unchanged.
A text identifier may be a second legitimate scheme rather than bad data, and
Dex does not decide which. An undeclared conversion needs a decision: keep
the other scheme (compare as text, normalize, use a bridge or a namespace), or
record the exclusion as an assumption naming its column. On DuckDB the counts
are free. Elsewhere they need --attribute-rows and are priced with row
attribution.
Read the command contract
when you need to construct the edits payload yourself.
3. Apply the reviewed plan
ReplacePLAN_ID with the ID returned by planning:
4. Build and verify on dev
data.completion first. It is the first key
of the payload and is held to 4 KiB, so it survives a cut-off read even when
hundreds of nodes follow it. With --for-plan, its deliverables say which of
the nodes the plan changed were built, failed, skipped, missing or stale, and
blocked names what stopped each one. A skipped report is not done, even if dev
still holds a table from an earlier run. assurance.build_only lists what built
with nothing checking its rows. Without --for-plan, coverage is unknown.
data.verification.scope lists the models this run built successfully;
scope_not_built names the other reported models. In the evidence block,
coverage.covered includes failed and skipped nodes present in run results.
Use coverage.built and coverage.not_built to distinguish successful execution.
When something upstream stopped the build, data.prerequisites names the failed
node’s owner (your project or an installed package), whether the plan could have
caused it, and the repairs dbt supports for it. An edit under dbt_packages/ is
not one of them, because the next dbt deps replaces it. Add --cold-deps to
reinstall packages into an isolated copy and build from there, which proves the
repair survives and lists anything your installed tree held that a reinstall does
not reproduce. It may reach the network, so a normal build never does it.
Each prerequisite’s previous_run gives its earlier status and run context when
available. This history survives pricing and confirmation retries without an
extra build. It may describe a different selection or source tree, so it does
not establish whether the plan caused the failure or change plan_relation.
The command contract gives every
field. Then read data.outcome (only validated means every required node ran
and passed) and data.verification.ran, its findings,
and suppressed checks. Missing parents, multiplied rows, or an entirely NULL column
need investigation before the change is finished. data.verification.column_contract
says which built models had their columns compared with schema.yml, which declare
none, and which could not be checked and why.
Rebuild an incremental model from its full history
Rebuild an incremental model from its full history
Use A full refresh drops and rebuilds selected incremental relations on dev. It can
scan substantially more data. Review the full-rebuild estimate before approving
it; this flag is not a routine fix for a failed build.A model configured with
--full-refresh when the requested change requires rebuilding the selected
incremental relation, rather than processing its next batch:full_refresh: false is not rebuilt: check
data.full_refresh.not_refreshed before treating a selected relation as
rebuilt. --verify does not run its row-population checks on incremental
models, so a green verification does not show the rebuilt history is right.
Check the rebuilt rows yourself before accepting the change, for example with
dex explore profile <relation> --target dev --refresh.Find the dbt artifacts
Find the dbt artifacts
By default, Dex writes dbt artifacts under
target/dex/<dbt-version>/ rather
than mixing them with another runtime’s artifacts. The build result’s
data.artifact_directory names the directory used. Follow that path when
investigating a failure instead of assuming the project’s previous manifest
describes this run. See the
build command contract.Keep it correct
Once the change is verified, establish a maintenance baseline. For refactoring tools, test scaffolding, mutation testing, and every build flag, seedex transform.