One objection I get very often when I publicly talk about this process is whether this is not a step back to the waterfall planning we tried to get rid of with agile. We worked hard to get away from rigid waterfall and the handovers we suffered so much from.
Waterfall
Whatās the problem with waterfall? Most engineers today have never experienced what it means to work on a real waterfall project. With the advent of agile around 2006, most companies adopted some agile practices in hope of getting more flexibility in their daily work.
For some it worked, for most it didnāt.
The idea of waterfall was originally defined in the paper āManaging the Development of Large Software Systemsā by Winston W. Royce. In summary: software is built by first analyzing the system requirements on a high level, then going into detailed requirements, design, coding, testing, and finally deployment.
This idea is still very much alive, even in companies that claim to be agile. And even reading it, it seems to make sense. Of course I first need to analyze and understand the problem before I can write any code. Who would argue with that? The problem is the scale at which this is done.
Applied at a project level, it starts to fall apart. First understanding all requirements, then translating them into requirements documents, then doing the design - this is costly and takes a lot of time and effort. By the time those requirements reach implementation, theyāve typically changed, and all that earlier work was nothing but waste, since we now have to rework whatās been done, which is often even more work than designing from scratch.
Dwight D. Eisenhower famously said, āPlans are worthless, but planning is essential.ā This sounds paradoxical at first, but itās essentially how successful software projects work. Heās also quoted as saying: āThe details of a plan which was designed years in advance are often incorrect, but the planning process demands the thorough exploration of options and contingencies. The knowledge gained during this probing is crucial to the selection of appropriate actions as future events unfold.ā
The details of the plan donāt matter so much, because they will change rather quickly. Whatās missing in classic waterfall is the flexibility to change. I canāt count how many projects Iāve endured that insisted on implementing a specification everybody knew was a waste of time and resources, because the requirements had long since changed.
This is also a kind of sunk cost fallacy. Oftentimes we invest so much time into a plan that we simply canāt throw it away. It was too expensive to come up with in the first place.
Handovers
The second problem with a classic waterfall approach is the handovers that invariably happen between the different phases of a project. Requirements need to be translated into a specification, the specification needs to be translated into a design. Every time we hand something over to the next phase, information gets lost or mistreated, and small misunderstandings accumulate until we end up building something that was never requested.
The best-case scenario is that we realize something is missing from the requirements. But then we need to go back to earlier phases, answer questions, and adjust the designs and the plan. By that point, budgets may already be allocated and plans may already have been communicated to stakeholders. Change becomes expensive, and sometimes devastating.
Being Agile
Agile tried to fix this by tackling the biggest problem we faced in waterfall: the size of the plan. Having weeks and months planned in advance is a massive waste, since most of those plans will never make it to production. So we started planning smaller. Instead of planning the whole project in advance, we plan a sprint, just two weeks of work.
We started defining sprint goals and breaking bigger chunks of work down into smaller user stories: āAs a ā¦, I need ā¦, so that ā¦ā
To break down and orchestrate the work, we added all kinds of meetings during a sprint: estimation sessions, backlog grooming, refinements, standups. In the beginning, this felt comfortable. Stakeholders could add new tickets to the backlog and trust that those tickets would be broken down, estimated properly, and put into production based on the priority defined in the backlog.
There are only three levers you can use to adjust a project: time, quality, or scope. Either you deliver everything but not by a fixed date, or you deliver by a fixed date but maybe not everything. Most companies choose a third option, which was never really an option: deliver everything by a fixed date but sacrifice quality, and happily call it ātechnical debt.ā Debt is something we can pay off later. What most companies donāt realize is that to take on debt, you need to provide some guarantees. Thereās no such thing as free debt.
In theory this doesnāt sound so bad. Prioritize the work, break it down, build the most important things first, and if we canāt deliver everything, at least guarantee that the most important things get delivered on time.
What we donāt take into account is that most companies simply donāt work like that. Budgets need to be allocated, delivery dates need to be committed to, campaigns need to be planned. For this we need reliable estimates and delivery dates we can count on. But estimates themselves were always a big problem, at least in every project Iāve been involved with.
Typically the requirements used for estimation are coarse-grained, describing at a pretty high level what needs to be done, and typically those requirements are pretty big. Breaking them down into manageable chunks of work usually takes a lot of effort from engineers - effort thatās far too expensive to spend properly, especially when itās not even clear whether those requirements will ever get built. So we try to invest as little as possible in those early requirements.
I can pretty accurately tell you what I can do in a day, maybe even two days, but anything beyond that gets very blurry. Humans are simply bad at estimating how long something will take. Weāre typically far too optimistic, underestimating how much overhead development actually involves.
Building software isnāt just writing code, or nowadays, letting an agent write it for you. It involves exactly the meetings mentioned above, all in an attempt to make the plan work. And funny enough, the one question every project manager needs a simple answer to almost never gets one: āWhen is it done?ā
Since we canāt commit to a date, we get creative in dodging the question. For me it started with T-shirt sizes (āthis feature is an Lā). When a customer asked what that meant, they usually got a shoulder shrug. To be more accurate, we then moved on to story points, which made things even worse.
āThis feature is 5 story points.ā Same question: what does that mean? āStory points measure complexity, you canāt translate them into person-days.ā To get an expected delivery date, you just multiply the estimated story points by the teamās typical velocity. Now itās the other person who does the shoulder shrug.
āLast sprint we delivered 17 story points, so our current velocity is 1.7 story points per day.ā In reality, most companies have a table somewhere in Confluence that translates story points into person-days at a fixed exchange rate. So if a product owner needs a feature by a certain date, all they have to do is prioritize the features so the story points match the teamās velocity for that date.
This completely misses the point that most company processes arenāt āagileā in that sense. They rely on accurate estimates, budget allocations, and delivery plans measured in person-days. So we tried to force an agile culture onto companies, which resulted in shallow agile implementations layered on top of existing processes that couldnāt be changed so easily.
How Do We Make It Flexible?
So whatās different this time? Now that we realize agile, as most companies apply it, doesnāt work, are we going back to waterfall? No. Neither approach works well. But thereās one thing we do differently that makes all the difference: the size of the work items. Instead of looking at XXL user stories, we break requirements down by modeling them in slices.
Slices are typically very small and manageable, describing one small business capability end to end. Slices are roughly equal in size. Similar to the idea of velocity, we simply measure how long it takes us to implement a slice. We call this āslice cycle time.ā For us that number is currently half a day on average.
A slice includes the UI, the API, the business logic, and the persistence - technically something that delivers value and that we could build, deliver, and run in production.
So we invest the time to break requirements down, but at the same time we remove all handovers. Defining those slices isnāt done in isolation, but in collaboration. This makes all the difference. Since stakeholders, engineers, and management are in the same room, itās possible to address requirements gaps and open questions early, when theyāre still cheap to answer. But this alone doesnāt guarantee flexibility.
True flexibility becomes possible through feature isolation with slices. Since every slice stands on its own, we can move it, swap it, or delete it without changing the overall plan. The whole plan starts to behave like a big box of Lego bricks. When we start building, we might have a plan in mind, but in the process of building, that plan typically changes, whether we run out of the right bricks or simply have a better idea thanks to what we learned while building.
So the big difference is - we do the hard work of breaking it down right in the beginning. We can rearrange parts of what weāve already built without much effort and without breaking everything apart. The unit of work becomes the slice, and each decision typically focuses on one slice at a time. Have you ever heard the phrase āif itās painful, do it more oftenā? Of course you have. Breaking requirements down into small enough chunks to make them manageable has always been one of the hardest parts of the engineering process. There was never a clear process for it, and doing it properly involved so much work that you might as well just build the feature. It didnāt make much of a difference.
Using Event Modeling to break down the system collaboratively solves exactly that. We make the plan flexible, and fully expect - even embrace - change by being able to change single slices in the system in isolation. And this is exactly what typically happens in reality: single slices change, but the overall plan stays intact.
This is a draft of a chapter in my upcoming book āSpec Drivenā. Iām helping teams design business solutions with AI and Spec-Driven Development using a proven process.
Join the Agentic Engineer Program
Apply Spec-Driven Development Hands-On - Event Modeling, Event Sourcing, and AI Engineering with autonomous agents.
Book a Call Today
Want to talk through how Event Modeling could work for your team or project? Letās have a quick, no-pressure conversation.
