Skip to content

Keep the definition

3

The change

Keep the definition

A filled record and a filled brief can still go stale the next time the query changes. This page is what stays after that meeting: the owner of the definition, the shape the publish promises, and the stop when that shape breaks.

My operating rule: name the owner of the published definition, enforce its shape before the next build, and stop the old publish when that shape breaks.

Checked 16 Oct 2026

The keep

This is what I leave in place after the record and the brief are filled. A blank field means the publish is not kept. The shape is dbt's model contract. The stop, when that shape breaks, is the contract error. The owner is my rule, and it is the approval the analytics field card requires. A change to the grain is not filled on this worksheet. That change goes back to Reconcile or block.

Owner

The role that approves a change to the published definition. One person, or one role. A distribution list is not the owner. The field is filled when that role can restate the grain. Otherwise the publish is not kept.

Shape

Every column the publish promises, by name and data type, with the contract enforced. The build checks that the query returns that shape. If it does not, the model does not build. The grain sentence stays on the record. This field is the columns.

Break

A removed column, a changed data type, or a removed or modified constraint on a column the publish already promised. That is a breaking change, and the build raises a contract error. The old publish stops. Adding a column is not a break.

Version

When other people or systems depend on the model, the breaking change is a new version, and the previous version stays for a migration window. When nothing outside this team depends on it, the break can land at once. The field is filled when one of those two is named.

Reopen

A change to the grain or the scope, with the column names and types unchanged, goes back to the record. A change to the decision goes back to the brief. A green contract does not close either of those.

What the shape does not catch

dbt's contract is a set of guarantees about the shape of a model that other people and processes query. When it is enforced, the build checks that the query returns every promised column, with the promised data type. The check does not depend on column order. dbt recommends a contract for a public model that reports and other systems rely on. A data test is a different check. It runs on the content after the model has built, and it can be set to warn. The contract fails the build when the shape does not match. I do not use a warn test as a substitute for that failure.

A breaking change, in that contract, is removing a column, changing its data type, removing or modifying a constraint on it, or removing the contracted model. dbt then presents a contract error. Model versions are how the producer of a model that other teams depend on can introduce that break: a new version, the latest bumped, and a window in which the old version can still be referenced. dbt says forcing every consumer to take the break at once is appropriate while the model is still changing quickly, or where the group that depends on it is small. Versions do not remove the cost of keeping two shapes. They put a boundary on it.

The contract does not know the grain. Kimball's declaration is what one row means, in business terms. A query can keep every column name and type and still change which rows are in scope. dbt says fixing a bug in a column's calculation is not a breaking change and does not require a new version. That fix can still change the definition. When it does, I send it back to the record. A green contract is not that record.

The Green Book includes comparisons and reconciliations in ongoing monitoring, and it ties a detective control to a correction that is timely. I use that as the reason a break stops the next publish, rather than waiting for the changed number to be noticed. The standard does not describe a model contract. The stop on a broken shape is the contract's. The owner is my rule.

An illustrative break

This is an illustrative scenario. It is not a record of a portfolio I measured, and it states no amount.

The overdue-balance publish is the invoice grain from the filled record. Charged-off accounts are out of scope. The owner is the role that approved that grain. The contract includes the column that marks that scope. The decision is still whether to extend terms.

A change removes that column. The shape breaks. The build stops. The lit sheet is the publish that was kept. The cracked sheet is the shape that no longer matches. The sheet in the tray is the next version, and it is not the publish until the owner accepts it. No amount is written.

A second change leaves every column name and type in place, and starts treating charged-off accounts as in scope. The contract can stay green. That change is a new record on Reconcile or block. This page does not choose a number between the two scopes. If the room changes the decision from extending terms to a call list, that change is the brief on Name the decision.

How I would know

I track four signals. I have no target times, and these definitions are not results I have collected. A green contract that hides a changed grain is not the practice.

Unowned publishes are published measures whose definition has no named owner.

Shape breaks are builds that stopped because the contract did not match.

Quiet grain changes are green contracts whose grain or scope changed, and the record was not reopened.

Kept versions are breaking changes that still offer the previous version for the migration window.

The rows that follow are written for the illustration on this page. Neither is a result I collected, and neither states an amount.

Shape break

The column that marked charged-off accounts out of scope is removed.

Measure

Overdue balance. No amount is written.

Owner

The role that approved the invoice grain.

Action

Stop the build.

Outcome

The old publish stops. The sheet in the tray is not the publish yet.

Quiet change

The same title, with every column name and type left in place, and charged-off accounts moved into scope. Action: reopen the record. Outcome: the contract stayed green, and the new scope was not published. No amount is written.

Where I do not use it

A model that is still changing, and an exploration that is not offered as an answer, do not get a contract. dbt says introducing this governance while models are still changing complicates later changes.

The comparison of two reports stays on Reconcile or block. This page does not publish a number between them.

The decision, the actor, and the moves stay on Name the decision.

A contract does not apply to a seed, a snapshot, a source, or a Python model. A data test can still run on those.

Adding a column is not a breaking change. I do not open a new version for it.

The calendar, the blast radius, and the cutover stay on the technology delivery field card, and a slow PD or ECL backtest stays on the Bayesian optimisation card.