Mycroft's Data Contract Simulation: Catching Silent Metric Corruption Before Release
Hussain shows a data contract agent that runs compiled SQL from a dbt manifest against a throwaway database in two passes. The simulation turns a vague warning about a renamed column into a measured change in monthly recurring revenue.
This video presents a data contract agent and a feature that was added to it the same day. The feature targets a particular class of schema change: one that compiles, runs, passes every test, and still returns a number that is simply wrong. The presenter, Hussain, shows how the agent moves from knowing which models read a column to measuring how much a business metric changes when that column is altered.
A change that nothing flags
The example starts with an ordinary change. An engineer renames a column from amount cents to amount and divides by 100 to match. Nothing crashes. The problem is that the staging layer was already dividing by 100. Monthly revenue is now 100 times too low, and not one test fires.
The agent could already prove which models read that column. The video points out that this is not the same as knowing what breaks. Knowing who reads a column does not tell you what happens to the numbers.
Building the warehouse before and after
The new layer measures. It builds the warehouse before the change and after it, then diffs the marts. The video notes what the code never does: it never calls dbt. Every model's compiled SQL already sits in the manifest, so the agent runs that SQL in dependency order against a throwaway database. A model that fails to build becomes a finding.
Why the first run is not enough
The first run failed usefully, but not informatively. Dropping the old column means every model that reads it stops compiling. Four go red. That is the loud half of the problem, and an ordinary build would have caught it, so it tells the team nothing new.
The realistic situation is different. Nobody merges a red pipeline. A reviewer renames the column in staging and moves on, and that is exactly the state in which the number is wrong.
Two passes and a lineage-scoped patch
So the simulation builds twice: once as the change stands, then again with the reviewer's fix. Pass one records what breaks. Pass two applies the rename and measures from there.
The patch is scoped by lineage, not by name. A transactions model has its own amount cents column, and a plain find and replace would have corrupted a second metric. Scoping by lineage avoids that.
In the second run everything compiles and nothing is red, yet monthly recurring revenue reads one hundredth of what it read before. The warning is now a number rather than a hunch.
Three layers, each with a job
The video summarises the design as three layers. The deterministic layer proves structure. The language model reads intent. The simulation measures damage. The row count never moved, which is exactly why schema tests sail straight past this kind of error.
Key takeaways
- A schema change can compile, run and pass every test while still corrupting a business metric.
- Renaming a column and dividing by 100 when staging already divides by 100 makes monthly revenue 100 times too low.
- Knowing which models read a column is different from knowing what breaks.
- The simulation runs each model's compiled SQL from the manifest, in dependency order, against a throwaway database, without calling dbt.
- Building twice separates what breaks from what changes after a reviewer's fix.
- Patches scoped by lineage avoid the second corruption that find and replace would cause.
- Row counts do not move in this scenario, so schema tests miss it.
Try it yourself
The video ends with a direct instruction. Paste the approach into Claude Code pointed at your own warehouse. Replay a migration you already shipped and ask which mart totals move. The video says the interesting answer is the one you were not expecting.
Chapters
- 0:00Silent metric corruption: Why clean builds still return wrong numbers
- 0:15Running compiled SQL manifest dependencies against throwaway databases
- 0:30Two-pass simulation: Recording breaks and measuring reviewer fixes
- 0:50Lineage-scoped patches: Preventing find-and-replace metric corruption
- 1:10Proving metric shifts: Turning warnings into concrete numbers
Full transcript(auto-generated, with timestamps)
Silent metric corruption: Why clean builds still return wrong numbers
[0:00]Hi, I am Hussein and this video is about a data contract agent I built and the feature I shipped into it today. It catches schema changes that compile, run, pass every test, and return a number that is simply wrong. Here is the shape of it. An engineer renames amount cents to amount and
Running compiled SQL manifest dependencies against throwaway databases
[0:16]Divides by 100 to match. Nothing crashes, but the staging layer was already dividing by 100. Monthly revenue is now 100 times too low and not one test fires. My agent already proved which models read that column. That is not the same
Two-pass simulation: Recording breaks and measuring reviewer fixes
[0:31]As knowing what breaks. So, I asked for the layer that measures. Build the warehouse before and after and diff the marts. This is the real code. Notice what it never does, call DBT. Every model's compiled SQL already sits in the manifest, so it just runs it in dependency order against a throwaway database. A model that fails to build is
Lineage-scoped patches: Preventing find-and-replace metric corruption
[0:50]The finding. And the first run failed usefully. Dropping the old column means every model that reads it stops compiling. Four go red, but that is the loud half your build would have caught it. It tells me nothing new. So, here is the change. Nobody merges a red pipeline. A reviewer renames the column in staging and moves on and that is exactly the state where the number is
Proving metric shifts: Turning warnings into concrete numbers
[1:11]Wrong. So, build twice, once as it is, then again with the reviewer's fix. Two things to verify. Pass one records what breaks. Pass two applies the rename and measures from there. And the patch is scoped by lineage, not by name. Transactions has its own amount cents column and a find and replace would have corrupted a second metric. Now, the second run, everything compiles, nothing is red, and monthly recurring revenue reads 1/100 of what it read before. The warning is a number now, not a hunch. Three layers, each earning its place. The deterministic layer proves structure. The language model reads intent. The simulation measures damage. And the row count never moved, which is exactly why schema tests sail straight past this. Your turn. Paste this into Claude code pointed at your own warehouse. Replay a migration you already shipped and ask which mart totals move. The interesting answer is the one you were not expecting. Prove the number changed.
More from Mycroft Financial AI
9:48Mycroft: Cross-Agent Validation & The Number That Wasn't There
3:08Mycorft's Vendor Intelligence System: Fail-Closed Architecture & Noise Reduction
3:52Mycroft Finance Investigator: Evidence Gap Planner & Specialist Routing
3:35Mycroft: Private AI Valuation, Price Panels, Stock Split Detection
3:49Mycroft Finance Investigator: Reviewer-Guided Reinvestigation & Refusal Loops
2:12