Early in the journey of moving toward more Agile ways of creating software, it is a common misconception that somehow either we completely abandon planning efforts, or that we must somehow get to production-ready software impossibly fast. Neither of these are entirely true; rather they are recast within Agile values and principles.
To begin, let’s take a brief look at both sides of the value statement from the Agile Manifesto: Working software over comprehensive documentation.
Notice that the emphasis is on *working* software. Not perfect software. Not software that even completely solves a customer problem. Instead, it might be a small piece of an end-to-end flow. It might be something only demonstrable in a command line environment. It might be something that requires test harnesses to show functionality. In short, it could be a building block to something bigger and more complex, or even many of these blocks partially assembled. The deeper key point is that the greatest learning and value come from software that we can see functioning in a state that is understood. At this point we can verify whether or not the investment of development is tracking toward desired outcomes.
“Notice that the emphasis is on *working* software. Not perfect software. Not software that even completely solves a customer problem.”
The key underlying assumption, is that prior to having working software, *we simply cannot and do not know* what will get us to our goal (we *do* have a goal or target condition, right?!). Any experienced professional that has spent sufficient time on software projects will be able to recall times when the place the code ended up was very, very different than where it began. Even more important, that end state was a discovery in and of itself.
Working software may meet any criteria of done, depending on what states work goes through on its journey to generating value. In contexts of high uncertainty, which is safe to say most, if not all, software projects spend time in, getting real feedback is the most important outcome. Having *something* that works for stakeholders to see and give input on is the most important tactic to mitigate uncertainty and risk.
We learn the most when we build the actual thing, rather than theorizing about it. Delivering small batches of working pieces encourages us to constantly look for abstractions and seams in the design where we can break it apart. It also encourages technical practices that enable the cost of change to be minimized over time. Software that is costly or risky to change has accumulated technical debt. Technical debt begins immediately costing the organization in ways that may be unacceptable.
“We learn the most when we build the actual thing, rather than theorizing about it.”
Notice that the emphasis is on *comprehensive* documentation. There is an inherent tension between the lean principle of “Just In Time” and Stephen Covey’s habit of “Starting With The End In Mind”. I realize these are from very different contexts, though for the sake of clarity, it is helpful to put them together here. Most software development is inherently complex. While there are certainly known knowns of design patterns, technology, and team stability, there are the unknowns as well. In some cases, those can also be known: problems that can be clearly identified though the solution not yet understood. And finally, there are the unknown unknowns: things that are discovered along the way and are simply unknowable until found.
Documentation seeks to address all of these. The problem is quite simply: it can’t, at least not in the traditional sense. Instead, there is a need to learn just enough to have confidence to move on our best guess toward the next goal. If documentation supports that effort, as can be the case with approaches such as User Story Mapping and Specification by Example, it contributes to the value-generating efforts. If it simply slows the delivery process down, it’s an anchor to be dragged along. Such are the types of documentation the Agile Manifesto authors were attempting to define.
In short, Agile practice seeks to embrace the complexity that software projects tend to operate in. Effectiveness in complexity is less about following a plan, as captured in big upfront design, and more about adapting to an evolving understanding. Working software is the ongoing proof of that understanding, and why such weight is given to it.