We wrote governance policies for humans. Then we gave the data to machines.
I want to tell you about a Thursday afternoon that changed how I think about data governance.
We had a data contract. A good one. It covered a customer transactions table that half the company depended on. The contract specified the schema, the freshness SLA (updated by 6 am daily), the owner (a team in data engineering), the data quality thresholds (null rate under 2% for key fields), and a plain-English description of what the table represented and what it should not be used for.
The contract lived in a YAML file in a GitHub repo. It had been reviewed, approved, and merged four months earlier. It was, by every standard I've seen written about in the data contracts discourse, a solid contract.
That Thursday, someone on our product team asked our NL-to-SQL interface: "What was the average transaction value for enterprise customers last month?"
The AI agent found the table. Generated a query. Returned an answer: $4,312.
The answer was wrong. Not because the query was wrong. The query was syntactically correct and logically sound for what it was trying to do. It was wrong because the table hadn't been refreshed since Tuesday morning. A pipeline failure had stalled the load, and Monday and Tuesday's transactions were missing. The average was calculated on an incomplete dataset. The number was low by roughly 15%.
The data contract said the table should be refreshed by 6 am daily. The contract was being violated. The observability tool had flagged it. The data engineering team had a ticket open. A human looking at the situation would have known not to trust the table.
The AI agent didn't look at the situation. It looked at the table. The table existed, had rows, and answered the query. The agent had no mechanism to check the contract, no way to know the SLA was breached, and no reason to suspect the data was stale. It did what we asked. We just forgot to tell it everything it needed to know.
The Gap Nobody's Talking About
Data contracts have had a good two years. Andrew Jones published the foundational work. The open-source ecosystem grew. Tools like Soda, Great Expectations, and Monte Carlo now integrate contract-style checks into pipelines. Conference talks about data contracts are everywhere. The core argument is compelling: producers and consumers should agree on what data looks like, how fresh it is, and who's responsible when something breaks.
I agree with all of it. I've implemented contracts on my own teams. They work.
But every data contract I've seen, every spec I've read, every implementation I've evaluated, is designed for one type of consumer: a human operating a pipeline or building a dashboard. The contracts assume someone will read the YAML. Someone will check the monitoring. Someone will notice when the SLA is breached and decide not to use the data.
That assumption broke the moment we started letting AI agents query our data autonomously.
An AI agent doesn't read YAML files. It doesn't check observability dashboards. It doesn't have the institutional knowledge to think "this table is usually fresh by 6 am, and it's 2 pm, and the last load was Tuesday, so something's wrong." It has a schema, a SQL engine, and a prompt. If the table is there and the columns match, the agent will query it.
The contract exists. The governance exists. But the agent can't see either one.
What I Tested
I took five of our data contracts (real contracts, covering real production tables) and evaluated each one against a simple question: if an AI agent were the consumer instead of a human, what information in this contract would the agent actually be able to access and act on at query time?
I wasn't testing the quality of the contracts. They were all well-written. I was testing whether the contracts were machine-readable in any meaningful sense.
Here's what I found.
Contract 1: Customer Transactions
The contract specified a freshness SLA of daily by 6 am. The agent had no access to this SLA at query time. The warehouse metadata showed a last_modified timestamp on the table, but the agent wasn't configured to check it, and even if it had been, it wouldn't have known that "last modified Tuesday" was a violation because it didn't know the expected refresh cadence.
Contract said: "This table should not be used for financial reporting without reconciliation against the GL."
The agent used it for a question about transaction values. Was that financial reporting? Depends on who's asking. The contract's usage restriction was written in English for a human to interpret. The agent can't interpret it.
Accessible to the agent: schema, column types, row count. Not accessible: freshness SLA, usage restrictions, quality thresholds, and owner contact.
Contract 2: Product Events
This contract had the most detailed quality section I've seen. Null rate thresholds for six columns. An enumerated list of valid event types. A note that the event_value field is in cents, not dollars.
The agent queried event_value and returned results in cents. The stakeholder read them as dollars. A 100x error.
The unit specification was in the contract. The agent never saw it. The column name was event_value with no unit suffix. A human reading the contract would know. An AI agent reading the schema would not.
Accessible to the agent: column name "event_value" (ambiguous). Not accessible: unit specification, null rate expectations, valid enum values.
Contract 3: Marketing Attribution
The contract specified that the attribution model changed three months ago from last-touch to multi-touch. Historical data before the change used the old model. A note warned that comparing pre-change and post-change data without adjustment would produce misleading results.
The agent was asked about year-over-year attribution performance. It compared Q4 this year (multi-touch) with Q4 last year (last-touch) and reported a 40% improvement in paid search effectiveness.
The improvement was mostly an artifact of the model change, not an actual performance shift. The contract warned about this. The agent couldn't read the warning.
Accessible to the agent: the numbers. Not accessible: methodology change history, comparison caveats, and temporal validity boundaries.
Contract 4: Employee Data
The contract had a clear access restriction: this table contains PII and should only be accessed by HR and People Analytics. A row-level security policy was referenced but implemented in a separate access control layer, not in the contract itself.
The agent, operating under a service account with broad read permissions (a common pattern for NL-to-SQL interfaces), queried the table without issue. No policy violation was raised because the policy was enforced at the user level, and the agent's service account wasn't subject to the same restrictions as individual users.
The contract defined the access boundary. The implementation didn't enforce it for machine consumers. The governance was real on paper and absent in practice.
Accessible to the agent: full table (including PII). Not accessible: the knowledge that it shouldn't be looking at this data.
Contract 5: Revenue Summary
This was the best contract of the five. It included a semantic description: "Net revenue is defined as gross order value minus refunds, using the refund date (not the original order date) for period assignment." It specified the authoritative source for the metric and warned against using any other table for revenue reporting.
The agent was asked about revenue. It found this table first (good). But it also found three other tables with "revenue" in the name. It picked the one with the most recent data, which happened to be a staging table that hadn't been deduplicated.
The contract said this table was authoritative. The agent had no mechanism to evaluate authority. It optimized for recency.
Accessible to the agent: table name, freshness. Not accessible: authoritative status, metric definition, warning against alternatives.
The Scorecard
|
Contract |
Freshness SLA |
Usage Restrictions |
Quality Thresholds |
Semantic Definitions |
Access Policies |
|---|---|---|---|---|---|
|
Customer Transactions |
Not readable |
Not readable |
Not readable |
N/A |
Not enforced |
|
Product Events |
N/A |
Not readable |
Not readable |
Not readable |
N/A |
|
Marketing Attribution |
N/A |
Not readable |
N/A |
Not readable |
N/A |
|
Employee Data |
N/A |
Not readable |
N/A |
N/A |
Not enforced |
|
Revenue Summary |
Not readable |
Not readable |
N/A |
Not readable |
N/A |
What I Learned That I Didn't Expect
The contracts were all good. The governance was all real. And none of it was visible to the AI agent. Zero out of five contracts had any mechanism to surface their constraints at query time to a machine consumer. The information existed. It just existed in a format (YAML files, Confluence pages, inline comments, separate access control systems) that an autonomous agent couldn't access when it mattered.
Data contracts are designed for a supply chain that has humans at every checkpoint. The producer defines the contract. Consumer reads the contract. When something breaks, a human notices, checks the contract, and decides what to do. That workflow works. It's the right model for human-operated pipelines.
But when the consumer is an AI agent, there's no human at the checkpoint. The agent needs the contract information embedded in its query path, not stored in a repo it can't access. The freshness SLA needs to be a queryable metadata field, not a line in a YAML file. The usage restriction needs to be an enforceable policy on the table, not a paragraph of English. The semantic definition needs to be in the semantic layer, not in a contract document.
LinkedIn's recent move to configuration-driven ingestion is the right pattern here. They shifted extraction logic from code to machine-readable configuration files, reducing onboarding from weeks to hours. The same principle applies to data contracts. As long as the contract is a document for humans, it's invisible to machines. The moment you make the contract a configuration that's queryable, enforceable, and surfaced at the point of consumption, it becomes governance that actually works for AI.
What Needs to Change
Data contracts need a machine-readable runtime layer. The YAML spec is fine for definition. But at query time, an agent should be able to ask: Is this table fresh according to its SLA? Is this table authoritative for this metric? Am I allowed to access this table? What units is this column in? What caveats apply to comparisons across these date ranges? Those answers need to come back as structured metadata, not as prose in a document the agent will never read.
The current contract specs (SodaCL, dbt contracts, open data contract standard) are close. They define the right information. What's missing is the consumption API. A lightweight protocol where an AI agent, before or during query execution, can check a table's contract status the way a browser checks an SSL certificate. Not by reading the certificate authority's documentation. By getting a programmatic yes or no.
Until that exists, your data contracts protect you from human errors. They do not protect you from machine errors. And in 2026, the machine errors are the ones that scale.
What I'd Tell My Past Self
Write your data contracts. They matter. But also ask yourself: if I replaced every human consumer of this data with an AI agent tomorrow, which parts of my governance would survive?
The answer, for most of us, is almost none of it.
The contract is not the governance. The contract is the specification. The governance is what enforces the specification at the point of consumption. And right now, for AI consumers, that enforcement layer doesn't exist.
We built governance for a world where humans read the warning labels. The machines don't read. They just query.