The dashboard your customers log into has no grace period. An internal report that’s wrong at 9am gets a Slack message. A customer-facing one gets a support ticket, or a screenshot in a renewal call.
Most data observability software is built to tell you about bad data quickly. That’s useful, and it isn’t protection. If the monitor fires after the gold table is written, the dashboard already refreshed on it.
Alerting tells you. Gating stops it.
| Approach | When it acts | What the customer sees |
|---|---|---|
| Anomaly and freshness monitors on gold | After the load lands | The bad number, until someone fixes it |
| Tests that log results, run after the pipeline | After the load lands | The bad number, plus a red row in a test report |
| Tripwire between silver and gold | Before gold is written | Yesterday’s correct number |
| Tripwire plus a check on the dashboard refresh | Before gold, and after the refresh | Yesterday’s number, and you know the refresh ran |
A tripwire is a test task in the job DAG. After bronze-to-silver runs, it hands control to TestGen, waits for results, and exits non-zero if the data failed. The orchestrator treats that like any failed task. Gold doesn’t get written. The bad silver data sits where it is, and the dashboard keeps reading the last good run.
That’s the trade. Your customer sees a number that’s a day old instead of a number that’s wrong. For a dashboard people pay for, that’s the right trade almost every time.
The gap is shrinking
On a nightly batch, you have hours between a bad load and the morning login. Not anymore on every stack. Under Power BI Direct Lake, which reads gold straight from OneLake, DataKitchen’s Fabric medallion post puts the gap between a bad write and a bad dashboard at seconds. Nobody is fast enough to respond to an alert in seconds.
The test has to run before the write.
Where the tripwires go
The four points of data testing give the layout. Measure bronze on arrival with freshness, volume, and schema monitors, but don’t gate it. Gate the two transitions:
- Bronze to silver. Reconcile row counts against the prior layer. Check uniqueness on keys, completeness on required fields, and referential integrity.
- Silver to gold. Balance aggregates by group against silver, so a fanned-out join or a remapped category fails before it moves a total. The Guide to DataOps Tests calls this an aggregate balance test.
Make keys and totals hard failures from day one. Keep learned statistical checks warn-only until they’ve learned the data, because you don’t stop a customer’s dashboard on a statistical hunch. If two of your dashboards already disagree with each other, find out why first, or you’ll gate the wrong definition.
The last mile is a tool, not a table
Data is only half of production. The Guide’s examples: an Airflow job hangs for three hours, or a report’s scheduled refresh silently doesn’t run. Every table test passes. The dashboard still shows last Tuesday.
That’s data in use, and it needs its own checks: did the refresh run, did it run on time, and does the headline number on the dashboard match the gold table it came from. One of the questions in DataKitchen’s data production checklist is simply “Is my dashboard displaying the correct data?” Most teams can’t answer it without opening the dashboard.
DataOps Observability has a pre-built agent for Power BI alongside Airflow, dbt Core, Databricks, and Azure Data Factory, so a late or failed refresh can fire a rule the same way a failed job does. It watches the jobs; it doesn’t test data. TestGen writes and runs the tests, including the tripwires. Both have free Apache 2.0 editions.
One limit worth knowing before you start. A tripwire stops bad data, which means it also stops the refresh. Somebody has to own the failure and fix it before the next customer login, or you’ve traded a wrong number for a stale one indefinitely.