Features in software are answers to questions. How can customers send what they're looking at to someone else? That's share via email. How can customers distill all the data about my project's tasks down to raw data to analyze it? That's a report, probably with a CSV export.
All of these answers exist on some kind of spectrum. There are simplistic and sophisticated answers. Maybe reporting has no interaction affordances at all; it's an HTML table and a link to download it as a CSV. Perhaps reporting is full of interactions, using metaphors of spreadsheets like sorting or filtering.
It hurts to waste time and effort. We get attached to the things we work on. But that’s the Sunk Cost Fallacy talking. If you don’t think a feature is worth the time it takes to make it great, then it is not rational to ship a crappier version simply because you have sunk time into it.
Julie Zhou, How to Make Things High-Quality
Early in the development of a feature is the time to seriously consider whether to ship the simplistic or sophisticated version of the feature. Before Sunk Cost starts to weigh on our souls. The first few days of building the feature are often about figuring out how much sophistication we can afford to build given the amount of time we have to ship the feature.
It is tempting to stop when it works, but it is only the beginning. That’s the shitty first draft you’d never turn in. Now you must go through the process to make it as simple as possible for others to understand.
Simon Hørup Eskildsen, Shitty First Software Drafts
In a sense, we’re matching a time budget to a mental complexity budget. In one week, we could figure out how to do a very simplistic CSV export. We could get it to work, make the implementation clear, test it out, iterate on code review, and have it ready to ship. In four weeks, we could add all the features that make a crisp and clear customer feature: generating it in the background, emailing a link to download the CSV after its generated, showing progress of the export to a user, etc.
With the teams I work with, we operate with the idea of peak complexity: the time at which a project reaches its highest complexity. Peak complexity has proved a useful mental model to us for reasoning about complexity. It helps inform decisions about when to step back and refactor, how many people should be working on the project at a given point in time, and how we should structure the project.
Simon Hørup Eskildsen, Peak Complexity
Somewhere in the middle of the time allotted to the project, a feature might start to feel like its getting out of hand. Inevitably, there's some surprise complexity or scope that no one anticipated. If the code of the feature were a combustion engine, it is sitting on a stand, partially disassembled, and in need of a rebuilt component.
Maybe we decide that the surprise scope isn't worth the toil and scrap part of the feature. We might decide it is essential and scrap some other part of the feature so we can finish this while affording the time and complexity budget.
Eventually you reach a point where there aren’t any more unsolved problems. That’s like standing at the top of the hill. You can see clearly all the way down the other side. Then the downhill phase is just about execution.
Basecamp Hill Charts
We reach that Peak Complexity, decide how to get through it, and start working downhill. We're now reaping the benefits of the thought and effort we put into managing the complexity budget of the feature, given the our time budget. We're crossing t's and dotting i's, finishing detail work, and getting the project ready to ship.
I find that managing software projects as time plus complexity works far better than viewing it as tasks for people to work on until it's "done".