A few years into a senior role at a major global firm, I was asked to diagnose a problem that had puzzled the CFO.
Every year, sales targets were hit. Revenue targets were not. Since the sales targets were supposed to generate the revenue needed to hit those targets, something was wrong. Nobody could explain exactly what was broken.
I found it. I also found that I couldn’t fully fix it. The tools available at the time couldn’t bridge the gap between knowing what was broken and actually repairing it.
That gap has now closed. Here is what was broken, why it was so hard to solve then, and what the solution looks like today.
What was actually broken
The firm ran two core systems. Sales were tracked in Salesforce: opportunity value, client entity, service line, deal duration. Revenue was recognised through an ERP, organised around project codes. Each project code captured the line of business, contract type, and client entity, and the revenue recognition method flowed from the project type.
The theory was that these two systems would speak to each other. A sale would close in Salesforce. A project code would be created in the ERP. Revenue would flow. Targets would align.
The practice was different. Consultants found creating new project codes administratively costly and personally unrewarding. So they reused codes. A code created for a client engagement in year one would still be receiving time entries in year three, accumulating retained revenue, renewed revenue, expanded revenue, replacement revenue, and carryforward from prior years, all in the same bucket.
The cost of accurate data entry was borne by the consultant. The benefit accrued to finance. No individual ever felt the aggregate failure. This is a classic operating model design flaw, and it is almost never named as such.
The consequence was that nobody knew, at any point in the year, how much of the revenue target was already secured from retained and carryforward work. Which meant nobody knew how much net new sales were actually required. Sales targets were being set against an unknown baseline. Every year.
Why it was hard to fix then
The obvious interventions were tried. We simplified the process of creating a new project code to reduce the effort required. Creating a project code to close a Salesforce opportunity was then mandated. Teams complied. They created codes at close, then ignored them and kept posting time to the old ones. The mandate addressed the symptom without touching the behaviour. The effort of completing time entry with multiple codes to choose from was still a barrier.
We considered linking sales incentive payments to the linked revenue instead of closed sales. Given that nearly every sale spanned multiple years, it wasn’t a practical solution.
Manual remediation was scoped. The volume of historical codes, combined with the unstructured nature of the data (project names, free-text descriptions, inconsistent naming conventions), made it economically implausible. You would have needed an army of analysts and months of effort to reconstruct what the data “should have been”.
The technology of the time could enforce rules and run queries. It could not read intent from messy text, classify ambiguous cases, or learn from corrections. So the problem persisted.
What the solution looks like now
Three things have changed that make this solvable today: generative AI can read and interpret unstructured data at scale; agentic AI can take action autonomously at the moment a trigger fires; and MCP connectors mean that agents can read from and write to multiple systems simultaneously without human intervention.
Here is the architecture I would propose.
Layer one: the linking agent.
When a Salesforce opportunity closes, an agent fires immediately. It reads the opportunity fields (client entity, service line, contract type, duration) and either maps the deal to the correct existing ERP project code or creates a new one, pre-populated, with no human action required. The behaviour that caused the original failure disappears because the task disappears.
Layer two: the classification agent.
For each active project code, an agent reads the combination of signals across both systems and assigns a revenue category: new, renewal, expansion, replacement, or carryforward. This is the categorisation that was impossible before, because all of those revenue types were collapsed into the same reused codes.
Layer three: the time entry assistant.
Creating the right codes solves half the problem. Consultants still need to record time accurately against them. Now that a single client might have multiple valid codes (plan design, systems advisory, planning support), the selection burden has shifted from creation to navigation.
An AI assistant addresses this at the point of time entry. It reads calendar data, email signals, and meeting context for the period being logged, and proposes the correct code with a confidence score. Above a threshold, it pre-fills the suggestion for the consultant to confirm. Below it, it asks a single plain-language disambiguation question: ‘Was Tuesday’s session with the client team about plan design or the implementation?’ The consultant answers in seconds. The model learns from every confirmation and correction.
The resulting output: the CFO revenue waterfall.
With classified revenue data flowing continuously, a live dashboard becomes possible. Retained revenue, expanded revenue, replacement revenue, lost revenue, carryforward, and net new: all visible at any point in the year. More importantly, the required sales figure becomes dynamic rather than an annual guess. The forecast loop closes.
The framing I want to leave you with
This was not a data problem. It was never a data problem. It was a system design problem. The cost and benefit of accurate data entry were held by different people, and no one had designed the system to account for that gap.
The AI architecture described above works not because it makes the right behaviour easier. It works because it removes the need for the behaviour entirely in the places where human compliance was always going to be unreliable, and it augments human judgement in the places where context and nuance actually matter.
That distinction matters enormously when you are designing these systems. If you automate the wrong thing, you do not solve the problem. You move it.
The question worth asking is not ‘where can we apply AI?’ It is ‘where is the cost-benefit gap between data quality and the people responsible for it?’ Those are the places where agentic AI creates real, structural change.
I spent a significant part of my career inside operating models that had exactly these kinds of silent failures: known problems, partial diagnoses, interventions that addressed symptoms rather than causes. The tools available then made full resolution difficult or impossible.
They are not impossible now.
