The world is made up of massive, complex objects that can be broken down into component parts. For instance, our globe can be divided into continents, which have component countries, which have states and provinces, which then have cities, neighborhoods, buildings. Likewise, a bus can be broken down into its component assemblies, parts, and pieces.
In other words, every complex system is made up of some small, atomic pieces that are assembled together.
In the technical world, the small, atomic piece is a “task.” Tasks are the bite-sized chunks of work that an individual performs to ultimately assemble a complex technical system. They’re the fundamental building blocks of any form of progress on a software product. As such, they’re critically important to get right: work on the wrong tasks or do them in the wrong way and you may find yourself sliding backward on your product roadmap.
Given how important getting tasks right is, it’s a bit of a surprise that most teams I’ve seen don’t take more time and care creating and framing tasks in the right way. As a result, there is a great deal of wasted time and energy on tasks that are poorly defined, don’t make sense, or are pointing in the wrong direction.
Here’s how to create tasks the right way.
What Is a Task?
Let’s start by defining what I mean by “task” in this article. First, “task” has a specific meaning in Scrum agile, which many development shops use to build their software. That definition of task is not the one used for this article, though they are very similar. In Scrum, tasks are small pieces of work that are combined together to form a story. A task is worked on by a single person, whereas a story is a collaboration among people.
Instead, I’m using “task” in a more generic sense: any small piece of defined work that must be done to progress the development of software. It could be a bug fix, it could be a UI improvement, or it could be one part of a larger series of tasks required to launch a piece of functionality. It can be done by one person or as a collaboration among people, and it doesn’t necessarily have to be a building block for some larger story.
A task typically takes anywhere from a couple of minutes to the better part of an hour to complete. Anything more than that is a bit too complicated for what I’m talking about here, though often those longer chunks of work can be broken down into component tasks.
Writing a Task
Now that we’re on the same page, let’s explore some of the ways to write good tasks.
The most basic aspect of a task is its descriptiveness: the extent to which it explains the underlying work to be performed. Most times, a task’s description is a simple sentence briefly explaining what’s expected. For example, “Swap order of button A and button B.” Unfortunately, that often falls short of what’s required for the engineer or designer on the other end of the task to make the right decisions. Maybe buttons A and B appear in different places in the software and don’t need to be switched in all contexts.
A task should be descriptive enough that the person implementing it doesn’t have to guess what they’re supposed to do. Without adequate description, the implementer will have to waste valuable time seeking clarification or — worse — making (faulty) assumptions about what the task actually entails.
In my experience, most tasks should be more descriptive than they are. One partial sentence of description should really be two or three sentences. There should be supporting data (like object ID numbers) and screenshots. The description should include some of the “why” of the task, and not just the “what.” For instance, the button task above might better be framed as “Swap order of button A and button B on screen X. Users have given feedback that button B is the primary action.”
The lack of descriptiveness issue is doubly true when it comes to tasks for bug fixes. Many bugs are the product of a very particular set of actions of system context. It’s important to document those actions and context carefully in the task description. Otherwise, when an engineer gets around to addressing the task they may be unable to create the original bug and spin their wheels without making any progress.
A level up from a task’s description is how prescriptive it is, or to what extent the task prescribes a path toward a solution. As opposed to descriptiveness, many tasks are too prescriptive in practice: making assumptions about the “right” way to solve a problem when in reality that should be left to the judgment of the implementer.
One of the places this is most common is in UX tasks. The task logger (often a product owner) may correctly identify that a feature’s UX is suboptimal, but then take a step too far in describing a specific solution to that bad UX in the task description. The problem is that the task logger isn’t in the best position to make that judgment call. Rather, the implementing UX designer should be given autonomy in how they’d like to craft a solution.
Another common misstep is when the logger suggests a particular architecture decision (for example, “add database attribute for X”). Again, the logger just isn’t in the best position to make that call. Instead, the implementing engineer should be given the flexibility to figure out how best to solve the underlying issue.
On the flip side, there may be a cost in efficiency that comes with delegating more autonomy to the implementer. The logging manager may feel that the most efficient way to solve the problem is if they go ahead and define the solution, since they’re already thinking about it and may have a strong perspective. That tension is real, but a thoughtful manager will generally recognize that allowing the implementer more autonomy is worth a marginal hit to efficiency.
Collaborating on a Task
Of course, writing a task doesn’t happen in a vacuum. Pretty much all task creation and management could be improved through more real-time collaboration among the constituent parties.
Product manager logging a new feature request? Set up a meeting to explain the underlying context of the request to the relevant designers and engineers. QA tester logging a bug? Go ahead and shoot it over to the engineer you think is most likely to pick the task up and see if you can provide any additional context to help them eventually tackle it.
In fact, many task miscommunications could be avoided by shifting more of the task writing responsibility to the person who will ultimately complete the task. In practice, that means the product manager or QA tester above should go ahead and loop in the relevant engineer or designer before the task is even written, explain what needs to be done, and then let the implementer write the task for themselves with the supporting description and context.
When combined with good task-writing practices, collaboration can be the cherry on top that ensures tasks have all of the information they need while also allowing for the appropriate level of autonomy in implementation.