Defining a task is one of the most critical parts of software development. I have come by a bunch of different ways to define a task. Bullet points in a specification document, rows in a spread sheet estimate, use cases from Unified Process, user stories from initially Extreme Programming and later other agile variants and Pitches from Basecamp's Shape Up. In this article I present my distilled perspective on well-defined tasks in software development. I'm purposely use the term "task", as opposed to the term "feature", to underscore that I'm talking about getting work done and actual software shipped. This article is about what concrete characteristics you should look after, when you sit down with your team and add items to your to-do list.
First, I want to write a bit on what you are trying to do, when you define a task. The two primary reasons for defining a task is, that you want to know what gets build and when it's done. That's two of the hardest problems in software development right there. Writing code is easy compared to developing a shared understanding of a task. But achieving shared understanding is only part of the problem. Working on a task give us a new understanding or sometimes re-defines the task - what is sometimes described as back-talk, if you want to jump down a philosophical rabbit hole. When the precise understanding is inherently ambiguous and working on the task re-shapes our understanding, it is only natural that the question "of when is it done", seems to be an impossible question to answer.
Luckily techniques have been developed to mitigate the problems of defining a task.
For me the key is to embrace that any description of a task is always going to be imprecise. Therefore, the goal is not to achieve precision in describing the task, but to find the correct balance in describing too much or describing too little. I will get back to how you can describe a task later, but the question of when a task is done, can't be detached from the description of the task. When accepting that the description is imprecise, the notion of a precise estimate also evaporates. To combat this obstacle the key is to work in [[time-boxed iterations]]. A deadline forces you to make decisions and compromises. Defining the task should always be in the context of a deadline.
With the notion that a deadline is necessary when defining a task, I will now expand on what I have found to be attainable qualities in a good task definition. My inspiration comes from user stories and the INVEST acronym and Basecamp's Shape Up. I highly recommend diving into those concepts but here is the distilled version I apply; a well-defined task is:
Dependencies will kill you. That's true both for software architecture and tasks. If something you need to do, depends on something or someone else, then the risks for not completing the task within the deadline automatically goes up. This is also true with tasks within the same iteration. I recommend spending the time in making you tasks independent.
The precise scope for a task should have some degree of freedom. A problem can be solved in many different ways and you probably know more about the best solution after you have invested some real work in the task. Although you need some wiggle room in the scope, you still need to agree on what you want to achieve.
A great way to establish some degree of shared understanding is, to clearly define the success criteria. The success criteria answer the question: What is the tangible outcomes our business value when the task have been done? Often it also helps to clearly define, what is not expected to be done or what problems are out
This is a simple concept: A task is done, when it's deployed to production! It isn't real unless you show it, and you don't add value before the work is in front of users. In some circumstances you will even multiple deployments and mini-iterations (yup, you need CI/CD, but that's a topic for another day).
The right people (i.e. the needed competencies and experience) must be available to work uninterrupted for the majority of the iteration. For the team to absorb the imperfections and learnings during the development, the team needs to be comfortable with technology and have focus.
To deliver a task, the actual people doing the work, should be given the full responsibility for the problem solving and successfully delivery. Responsibility for the task is ideally what happens when all the other attributes can be checked off.
So there you have it, my take on six concrete characteristics of the well-defined task.