What happens when an AI keeps working after a human approves a decision? Lessons on data stewardship, agents and MDM from building Zingg 1.0 Enterprise.

For most of the history of software, work was done by one of two kinds of actors. People handled whatever needed judgment. Automation handled whatever could be written down as rules. Their territories rarely overlapped. A script ran overnight, a person reviewed the exceptions in the morning, and each knew which decisions belonged to them.
AI agents blur that line. They now work on the same records, tickets, documents and code as people do, often at the same time. The person brings domain knowledge, context and accountability: they know the customer, the regulation, and the history no dataset captures. The agent brings speed and scale: it can work through a million items while a person works through ten. For the first time, a system has two classes of users acting on the same things.
Most of the time that’s a straightforward win. But it raises questions older systems never had to answer. When a person and an agent both act on the same item, whose decision holds? What does a human decision lock in, and for how long? When the data underneath it changes, who gets to reopen it?
We ran into these questions while building data stewardship into Zingg, and very little about them is specific to our domain. If you’re building any system where people and agents share decisions, you’ll run into them too.
Every business keeps information about the same things in many places. A customer exists in the CRM, the billing system, the support desk and the marketing platform. A supplier appears in procurement, finance and logistics. These systems rarely share a common ID. Names get spelled differently, addresses change, and the same person or company ends up as a dozen slightly different records.
Entity resolution is the work of figuring out which of those records refer to the same real-world thing. Master data management (MDM) is the practice built on top of it: keeping one trusted version of a business’s core entities, such as customers, suppliers, products and locations, that every system and team can rely on.
A simple example: “John Doe” in an online store, “J. Doe” in a loyalty programme, and “Jonathan Doe” in billing. Entity resolution proposes that these are one customer. MDM makes that the single record the business uses. Get it wrong one way and he gets three welcome emails. Get it wrong the other way and two different people share a purchase history.
Zingg is an open-source entity resolution and MDM platform. It learns what a match looks like from a small number of examples labelled by people, then applies that across millions of records, natively in Databricks, Snowflake, Microsoft Fabric, BigQuery and other platforms where the data already lives.
A data steward is the person accountable for what a piece of data means and whether it can be trusted. Pipelines move data and models score it. Stewards decide what’s true when the rules can’t.
In master data management, that work is concrete. Is this customer the same as that one? When the CRM and the billing system disagree on an address, which one wins? Should a supplier listed under three slightly different names be treated as one company? Stewards resolve the exceptions automation flags, fix records that matching got wrong, and own the decisions that become a company’s golden records.
If you work in data, you probably already do some version of this, even if your title doesn’t say so:
The common thread is a human judgment the system can’t reliably make on its own, recorded somewhere, which the system then has to live with as the data keeps changing. That last part is where things get hard, and it’s what the rest of this post is about.
In entity resolution, the two kinds of workers are easy to identify. One is the matching engine. It reads millions of records, decides which ones refer to the same customer, supplier or product, and groups them. The other is the steward, who knows things the engine can’t: that two companies with the same address are actually a parent and its subsidiary, or that a nickname in one system belongs to a long-standing account in another.
For years the division of labour between them was simple. Most matching was rule-based: match on email, or on name plus postcode, or on tax ID. People wrote those rules, often the stewards themselves, so the system was deterministic, and every output could be traced back to a rule someone chose. In that sense the matching system was an extension of the steward rather than a separate decision-maker. If a steward disagreed with a result, they didn’t argue with the system. They changed the rule.
There wasn’t much room for conflict. The engine ran, produced its groups, and stopped. A steward reviewed what came out, fixed what looked wrong, and that was the end of it. Work passed from machine to human in a single direction, once.
Machine learning changed that. Modern matching is probabilistic. Instead of following rules a person wrote, a model learns from examples what a match tends to look like, then scores each pair of records by how likely they are to be the same. That lets it handle the messy cases rules never could, like typos, nicknames, transliterations and reordered addresses. It also means the system now has a judgment of its own. It can be confident and wrong, or uncertain and right. When it disagrees with a steward, there’s no single rule to go back and edit.
Zingg works this way. As customers adopted it, they asked for something that sounded small: a way for a steward to look at a group Zingg had matched and mark it as approved. One flag with three states: not yet reviewed, approved, rejected. It’s a familiar pattern, like a checkbox on a review queue. It looks simple. But as we built it, we realised the problem was much bigger than we’d first thought. Every answer raised new questions about what an approval should protect, and for how long. The flag was reopened, redesigned, argued over and partly thrown away more than once before we arrived at the design that ships in Zingg 1.0 Enterprise.
The reason is that Zingg doesn’t run once and stop. It runs incrementally, and in that mode it behaves much like an agent. Each new or updated record is a small task. The engine looks at it, finds the existing groups it might belong to, weighs the evidence, and acts: it places the record in a group, starts a new one, or reshapes the groups around it. A deleted record sets off the same process in reverse. Every run starts from the state the last one left, makes its decisions, and hands a new state to the next. Observe, decide, act, repeat, with no human in each step. That adds up to thousands of small decisions a day that nobody reviews one by one.
So the steward isn’t working after the machine anymore. They’re working alongside it, on the same groups, at the same time.
What looked like a simple approval feature therefore became a question about how an incremental matching system should preserve human decisions while it keeps processing changing data. The real question isn’t “did a human approve this?” It’s “what is the machine allowed to do next, now that a human has?”
The first instinct is to approve records. Each row gets a flag, and each row is reviewed or not. It’s easy to store and easy to explain.
It also falls apart quickly. Consider a group of five records where a steward has approved three and the matcher has since added two more. Is the group approved? Partly? What does “partly approved” promise anyone downstream? Now edit one of the approved records so it looks more like a different group. Which flag wins: the record’s or the group’s?
Come to think of it, a steward doesn’t really judge a record in isolation. They judge a boundary: these records are one real-world entity, and those aren’t. The unit of human judgment is the group, not the row.
That changes what a steward needs to be able to do. A yes or no on what the machine proposed isn’t enough. Shown five records, a steward might say three are one person and two are another. That judgment is about where the line falls, and a per-row flag has nowhere to put it.
This is the first question we’d ask anyone building a human-plus-agent system: what is the actual unit of human judgment? It’s rarely the unit your data model makes easiest to store.
Once a steward owns a group, the system has to know what that ownership rules out. Ours came down to three principles, each about what the machine may and may not do on its own:
And everything a human hasn’t touched stays fully dynamic, free to merge and split exactly as before.
Notice the asymmetry. The machine may add to a human decision but never undo it. This protection comes with a trade-off: the system gives up some freedom to revise its groups automatically, in exchange for making human-confirmed decisions predictable. The challenge is to keep that certainty without blocking appropriate changes when genuinely new records arrive. It’s worth it, because if confirming something doesn’t make it stick, people stop bothering to confirm things.
Principles are easy to state. The work is in the cases. Here’s one small example from our design discussions.
Zingg proposes five records at the same address as one person: Robert Miller, Rob Miller, R. Miller, Robert Miller Jr. and Bob Miller. On the data alone, that’s a reasonable call. The names overlap, and so do the address and phone number. But the steward knows this household: it’s a father and his son. Robert Miller, Rob Miller and R. Miller are the father. Robert Miller Jr. and Bob Miller are the son. That’s a clear human decision, based on context the data doesn’t fully carry. Now let time pass.
A new “R. Miller” arrives at the same address. It’s a plausible match for both father and son. It can only join one, and it mustn’t become the thread that quietly ties the two groups back together. Which one should it join, and on what basis?
Someone corrects a record. The date of birth on “Rob Miller” is updated, and it now matches the son’s. Fresh matching would move the record to the son’s group. But a human placed it with the father. Does the human’s earlier decision hold, or does the new data win?
A record is deleted. Suppose “Rob Miller” was what made the father’s other two records look connected. It shared an email address with “Robert Miller” and a phone number with “R. Miller”, while those two have little in common directly. Remove it, and does the human-approved group still stand? The steward approved the group, not the reasoning that produced it.
The group shrinks to one. Is a single record still an “approved group”? An approval of togetherness with nothing left to be together with is a strange thing.
Two things happen in the same run. Two new records arrive. One fits the father, one fits the son, and the two new records match each other strongly. Process them one at a time, and each finds its home. Process them together, and they form a new bridge between two groups a human deliberately kept apart. Does the order of operations decide the outcome?
The steward changes their mind. They split a group further, merge two back together, move one record across, or reopen a group entirely. Each is legitimate. Each has to leave the rest of the system consistent.
Our internal list of cases runs past twenty. None is exotic. All of them happen in real customer data, usually at a scale where nobody will notice a wrong answer until much later.
Behind the individual cases are a few bigger questions. We don’t think anyone has fully answered them, ourselves included:
One idea we threw away looked elegant. Every human decision is made against a match score. Suppose a steward says two records are not the same at a score of 0.4. Later one record is edited, and the score rises to 0.5. The data has drifted toward a match, so maybe the human should be asked again. If it drifts the other way, the decision is safe to keep. Let the score decide when a human judgment expires.
We worked it through and decided against it. The human steward stays the oracle.
The score is the machine’s opinion. A steward usually steps in precisely because that opinion was wrong or uncertain. If movements in that same score decide when the steward gets asked again, the machine is back in charge of when human judgment counts. It never overrules the steward directly. It just decides when the steward’s decision stops mattering. That’s a quieter kind of override, and in some ways a more dangerous one, because nobody sees it happen.
This doesn’t mean a human decision should be frozen forever. There are good reasons to revisit one: a source system is retired, a policy says approvals get reviewed every year, or a record changes in a way the business has explicitly defined as material. What these triggers have in common is that they come from outside the model. They’re rules people wrote, deadlines on a calendar, or explicit events. They are decisions about the review process, made by people, not the corrected system’s opinion of its own correction.
There’s a practical cost too. Every reopened decision is another review task. A system that keeps re-asking wears out the people it depends on, and tired reviewers approve things they shouldn’t.
So the lesson isn’t that human decisions can never be revisited. It’s that the trigger for revisiting them shouldn’t belong to the system they were meant to correct.
Strip out the entity resolution and these questions apply to any system where an agent and a person share decisions over time. A finance agent categorises transactions an accountant has already reconciled. A support agent routes tickets a manager has reassigned. A compliance agent flags documents a reviewer has already cleared. Each one meets the same design questions.
Across these applications the details differ, but the underlying problem is the same. An automated system must know which human decisions it can build on, which it must preserve, and when a new review is needed.
None of this is about how capable the agent is. A better model doesn’t answer “should a human’s decision survive an edit?” That’s a question about authority, and someone has to design the answer.
If you’re working through the same questions in your own systems, whether in MDM or anywhere else agents and people share decisions, we’d like to hear how you’re answering them.