It was the tenth call.
I had been on the first one. A customer data project, matching records across systems to connect outcomes to the right source. It seemed straightforward enough that I handed it off and moved on. What followed was eight more calls between my team and the customer, each one ending with a tweak to the logic, each tweak fixing something and revealing something else.
The problem wasn’t the code. It wasn’t the team. It was that nobody had defined success criteria before the work started. Nobody had asked: what does done actually look like?
By the time my team pulled me back in, it was already swirling. The customer’s manager had joined too. I suspect that because the issue still wasn’t resolved, he felt the need to get involved. We had a piece of logic built by people who were no longer on the team, results that were almost always right, and a team that had been grinding on this for weeks.
I asked a simple question: What do you actually want?
That was it. Every previous conversation had been about what the code wasn’t doing right, assuming the approach was sound and just needed adjustment. Nobody had stopped to ask whether the approach itself was the right one. The answer to that simpler question was: when this happens, here is what we expect to see. And the solution that followed was far simpler than what we had been building toward. A defined set of conditions, clearly mapped to outcomes. The complexity we had been wrestling with wasn’t a feature of the problem. It was a feature of never having properly defined the problem.
We left that meeting with a clear destination. We should have had that conversation on call one.
The Road That Never Shortens
The frustrating thing about this kind of problem is that it doesn’t feel like you’re lost. You can see the destination. The direction feels right. Every adjustment produces a result that is better than the last one. You can look back and see real distance covered.
But the destination never gets closer.
It is not a treadmill. On a treadmill, nothing changes. This is different. The scenery changes. The code changes. The outputs change. Progress is real. It just isn’t progress toward the right place, because the right place was never precisely defined.
I think of it as a receding horizon. You walk toward it. The ground behind you is real and covered. But the horizon moves as you move, and no amount of forward motion closes the gap. The destination stays visible, just always slightly further ahead.
What makes it so hard to catch is that the evidence of progress is genuine. In our case, the logic was better after each call than it was before. The team wasn’t spinning their wheels. They were solving real problems. The issue was that the problems they were solving were symptoms of a question nobody had fully asked.
The Assumption Cascade
When I look back at those ten calls, the thing that strikes me isn’t that anyone did something wrong. It’s that everyone did something reasonable, and the reasonable things stacked up into an expensive mess.
The customer assumed the existing logic was doing what they needed, just imperfectly. My team assumed the approach was sound and needed tweaking. When a new team member joined and inherited the code, they assumed the foundation was correct. Their job was to fix the edges, not question the core. I assumed the problem was simple enough that my continued involvement wasn’t necessary. Each assumption was defensible in isolation. Together, they meant that nobody stopped to validate whether the foundation was right in the first place.
There was another assumption underneath all of them. The code had been built by someone with more context than anyone currently on the team. That history gave it authority. When the results looked wrong, the natural conclusion was that something in the current implementation needed fixing, not that the original approach was built on the wrong question. We trusted the expert’s work even after the expert was gone. And in doing so, we inherited not just the code but the assumptions baked into it.
When we finally looked at what the logic was actually doing versus what the business needed, the gap was significant. There were layers of code built on assumptions about the data that were no longer accurate. That had always been true. Nobody had thought to check because everyone assumed the foundation had already been validated. Each tweak revealed new issues that had always been there. It felt like discovery. It was actually just uncovering more road.
The Same Pattern in AI
I have watched this exact dynamic play out in AI projects more times than I can count, and it is worse there for a specific reason: AI systems always produce output.
A piece of analytics logic can return null or error in a way that is obviously wrong. A model returns a prediction. An LLM returns a response. The output looks like an answer even when the question was never properly defined. That makes it even easier to convince yourself you are iterating toward something real when you are actually just generating variations on an undefined target.
I have seen teams spend months adjusting prompts, tuning thresholds, and debating evaluation criteria for systems where nobody had written down what success looked like in concrete, measurable terms. Defining success criteria sounds like a step teams can skip when they’re moving fast. It isn’t. The model kept producing output. The output kept improving on the metrics the team had defined. The business kept saying it wasn’t right yet. And the team kept tweaking, because tweaking was the only tool they had.
The problem was never the model. It was the missing destination.
Two Questions That Define Your Success Criteria
There is a question I now try to ask at the beginning of any project, before any code is written or any model is selected or any dashboard is designed.
Do you know where you are going?
Most teams will say yes. They have a goal. They have a use case. They have a sense of what they are trying to accomplish. But the follow-up question is the one that matters.
How will you know when you get there?
That second question is where undefined destinations get exposed. A team that can answer it will describe arrival in specific, observable terms. A team that cannot will describe a feeling. Something like: the results will just look right, or the stakeholders will be satisfied, or we’ll know it when we see it.
Justice Potter Stewart famously said that about obscenity. The bar for a product should be higher.
If a team cannot describe what arrival looks like in concrete terms, they do not yet have a destination. They have a direction. And direction without destination is how you end up on your tenth call, fixing logic that was never going to get you where you needed to go.
Stop Before You Tweak
When a project starts accumulating meetings, when each session ends with a new adjustment rather than a resolved question, when the results are always almost right but never quite there: stop. Not to debug the logic. Not to adjust the model. Stop to ask the two questions.
Do we know where we are going? And how will we know when we get there?
Challenge every assumption that has been made about what the system is doing and what the business actually needs. In our case, the assumptions were layered three teams deep. Nobody was hiding anything. Everyone was trying to help. But the assumptions meant that the wrong question had been quietly powering the work for weeks.
The destination, when we finally named it, was clear. Focused. Achievable.
It didn’t require less ambition. It required less swirl.












