Every SDLC guide draws the same diagram: requirements, design, build, test, deploy, maintain, arrow back to the start. It is accurate and almost entirely useless, because the diagram is not where projects fail.
Projects fail at the handoffs — the gaps between those boxes, where information gets lost and assumptions get made. Here is what actually happens in each phase, and the specific failure that lives at each seam.
The phases, and what they are really for
| Phase | Stated purpose | Actual purpose | Typical share of effort |
|---|---|---|---|
| Requirements | Capture what is needed | Discover what is not yet decided | 10–15% |
| Design | Plan the solution | Find the expensive decisions early | 10–20% |
| Build | Write the code | Discover what requirements missed | 30–40% |
| Test | Find defects | Establish what “done” means | 15–25% |
| Deploy | Ship it | Prove it works outside your machine | 5–10% |
| Maintain | Fix and improve | Pay for every shortcut taken above | Ongoing, usually the largest total |

Seam one: requirements to design
The classic failure is a requirement written as a solution. “Add an export button” is not a requirement — it is someone’s guess at one. The requirement underneath might be “the finance team needs last month’s figures in their own spreadsheet by the third working day”, and that has several cheaper answers than a button.
The cheap fix is a single question asked relentlessly: what are you trying to do with it? Ask it three times and the real requirement surfaces. It feels tedious. It is far less tedious than building the wrong thing.
Seam two: design to build
Here the failure is silent disagreement. Everyone nods at the design review because the design is described at a level of abstraction where nobody disagrees yet. Two weeks into building, two developers have made incompatible assumptions about the same interface.
- Write the edge cases down. Not all of them — the three that people are quietly assuming differently.
- Name the things you are not doing. A short “out of scope” list prevents more argument than any spec section.
- Agree the interface first. If two components must talk, define that contract before either is built.

Seam three: build to test
The failure here is that “done” was never defined, so testing becomes a negotiation. A developer says it works; a tester says it does not; both are describing different scenarios and neither wrote theirs down first.
The fix costs about ten minutes per feature: write the acceptance criteria before building, in plain language, as a short list of things that must be true. Everyone reads them, and testing becomes a check rather than an argument.
This single habit removes more schedule slippage than any tooling change, and it is the one most often skipped because it feels like paperwork.
Seam four: test to deploy
“It worked on staging” is the phrase that precedes most bad evenings. The gap is environment drift — different data volumes, different configuration, different permissions, a service that exists in one place and not the other.
| Common drift | Cheap mitigation |
|---|---|
| Different data volume | Test with a production-sized copy at least once per release |
| Config differences | Same config mechanism everywhere; no manual edits on servers |
| Missing migrations | Migrations run automatically as part of deploy, never by hand |
| Permissions | Deploy with the same account type production uses |
And have a rollback you have actually tested. An untested rollback plan is a wish.

Which model to use, honestly
The waterfall-versus-agile argument is mostly theatre. What actually determines the right approach is one thing: how expensive is it to change your mind later?
- Cheap to change — a web app, an internal tool. Build in small increments, get feedback constantly, plan lightly.
- Expensive to change — embedded firmware, regulated systems, anything with a certification cycle. Spend properly on requirements and design, because a late change costs months.
- Mixed — most real projects. Plan the expensive-to-change parts (data model, integrations, anything customer-facing and public) carefully, and iterate on everything else.
Teams get into trouble by applying one answer to both categories — either planning an internal dashboard to death, or iterating on a database schema that fifty other systems depend on.
Common questions
How much documentation is enough?
Enough that someone joining in six months can answer “why is it like this?” without asking anyone. That is usually far less than a formal spec and far more than most teams write. Decisions and their reasons matter; descriptions of code do not.
Where does AI fit into this?
It helps most in build and test — boilerplate, test cases, translating between formats. It helps least at the seams, because the seams are about human agreement, and that is not a generation problem. We looked at where the returns actually are in our six-task test.
Does a small team need any of this?
A team of two needs the acceptance criteria and the tested rollback. It does not need phase gates or sign-offs. The process should be proportional to the cost of getting it wrong, not to how professional it makes you look.
What about maintenance planning?
Budget for it explicitly, as a percentage of ongoing capacity rather than as something that happens between projects. Teams that leave no room for maintenance end up doing it anyway, at emergency prices.

Leave a Reply