Almost every late project we have been asked to rescue was late for the same reason, and it was rarely the code. The team could build the thing. What nobody could say, in a sentence, was what the thing was. Scope had been agreed in a document that read well and meant something slightly different to each person who signed it.
Overruns are usually definition failures. They surface as engineering problems because engineering is where the cost finally lands, but the decision that caused them was made weeks earlier, in a conversation where everyone nodded.
Price the problem after you understand it
The most expensive habit in this industry is quoting from a brief. A brief describes an outcome; it does not describe the constraints that determine the cost. Data volumes, the integration nobody mentioned, the compliance review, the deadline behind the deadline — these are what move a number, and none of them are in the brief.
So we run discovery as a paid, scoped piece of work before committing to a figure. It ends in a written document: the architecture options with their trade-offs, the risks we found, and a fixed scope with a date. If you take that document to another firm, it still holds value — that is deliberate. It is a deliverable, not a sales step.
Ship a working slice in the first fortnight
Before the bulk of a build, we ship one thin vertical slice that runs end to end in a real environment: one feature, through the real stack, deployed on the real pipeline. It is usually unglamorous and it is always the most informative fortnight of the project.
A plan is a hypothesis. A slice tests it against the actual codebase, the actual API you have to integrate with, and the actual latency of the actual database. When the plan survives, everyone relaxes. When it does not, you have found out in week two rather than month four, at a point where changing course is cheap.
If a schedule cannot survive two weeks of contact with the codebase, it was never a schedule. It was a wish with dates on it.
Make change visible instead of absorbing it
Scope does not usually break in one dramatic moment. It erodes through a hundred small, individually reasonable requests, each absorbed quietly because refusing felt petty. Six weeks later the team is behind and nobody can point to the decision that put them there.
The fix is unglamorous: every change is written down with its cost and its effect on the date, and you decide. Not a committee, not a process — you. Most requests are worth it. Some are not. The point is that the trade is explicit, so the schedule reflects reality instead of quietly diverging from it.
What this looks like in practice
- Discovery before estimate. Architecture options, risks and a fixed scope, in writing, before a number is agreed.
- A running slice by week two. One feature end to end in a real environment, with the deployment pipeline already working.
- Change in writing. Every request costed against the date, decided by you, never absorbed silently.
- One owner. A named engineer accountable for the schedule, not a rotating account manager relaying messages.
- Handover as you go. Documentation written while the work happens, not reconstructed at the end.
None of this is clever. It is the difference between a delivery date that means something and one that gets renegotiated every fortnight, and it is why we can hold a fixed scope without hedging the number.
If you have a project where the estimate has already moved more than once, that is usually a definition problem rather than a team problem. We do technical advisory engagements for exactly that situation, and you are welcome to talk it through with us.