The difference between completing tasks and taking ownership#
A developer is an expert in solving problems, as that's what software development is all about.
So when I ask a developer to add a button to a page that, when clicked, sends an invoice per email, that is precisely what the developer will build. The developer is capable of developing that exact feature pretty quickly, but the developer might not spend much time thinking about the actual problem that's going to get solved by this. When developers receive such detailed implementation instructions without any context they may reasonably assume the problem is already completely analysed and decide to just build it as requested. The risk is that the developer delivers exactly what was requested, without questioning whether it actually solves the problem of the customer.
That's a characteristic of what we call "feature factories" or "ticket-factories", which is a term used to describe development teams that are primarily focused on completing tasks and delivering features, instead of focusing on the problem they want to solve.
Because the actual problem might not get solved by just solving that single task. Let's get back to the task of adding a button to a page that, when clicked, sends an invoice per email. The actual problem might be that the customer wants an easy way to deliver invoices to a specific billing email address, and there are many ways to solve that problem.
When the developer takes ownership, questions like these will come up:
- Who needs to receive the invoice? Is it the user who is logged in, or the email address of the customer? Does the customer need a specific email address for their invoices?
- Does the invoice need to be sent immediately, or should it be queued for later?
- What does the content of the email have to look like?
- ... And much more.
That's why ownership is so important. When the developer takes ownership of the problem, they will take their time to understand the actual problem and will come up with a solution that solves the actual problem, instead of just focusing on completing the task.
What does ownership actually mean?#
So we know that ownership is important, but what is "ownership"? Firstly, it's a term that is sometimes abused in the software development world. Some people mistake it for "working independently", just "being responsible" and "getting the task done" or even worse, use it as an excuse to dump incomplete tasks on developers (for example, unprocessed feedback, a copy of an email of the client, etc.) and let them figure everything out.
But what does ownership then actually mean?
Ownership means taking the responsibility for understanding the actual problem, finding a suitable solution and following through to ensure that the solution delivers the intended outcome, while considering the context and constraints.
Why task-driven development is not what you should aim for#
Let's take the previous example of the task to add a button to a page that, when clicked, sends an invoice per email. When the developer takes ownership of this task, they will take the time to properly understand the problem the client is trying to solve.
In this case, the developer gets to know that:
- The application doesn't currently have a queue worker running yet
- E-mails are sent through a reliable mail delivery service
- It is a small application for a small business
- The client doesn't have a huge budget for implementing this feature
- An important part of the feature is that the invoice is sent to a specific billing email address of the customer
By asking those questions and gaining a proper understanding, the developer discovers something was missing from the original task. The invoices must be sent to a specific billing email address, not just the general email address. The developer also realizes that the application doesn't have a queue worker running yet, but as the application already uses a reliable mail delivery service, that's not something they are going to implement for this task as the developer also knows that the client doesn't have a huge budget.
That's why the developer decides to implement a simple solution by adding a billing email field to the customer, and when the button is clicked, the invoice is sent directly to the email service provider for delivery. While this is a trade-off, as even those mail service providers could experience issues which result in mail not being delivered, introducing a queue worker that will retry delivering the email for just for this single feature would outweigh its benefits. This solution solves the actual problem and is a good fit considering the context and constraints.
Ownership requires clarity and trust#
Is ownership something we should expect from just developers? No, certainly not. Ownership requires the involvement of the team, including product owners, developer, and everyone else involved.
That means the product owner must feel the same ownership as the developers, so the product owner provides clear expectations, enough context, and shares any constraints with the developers so they can take proper ownership of the problem. That also requires the company to trust the developers by sharing the budget and giving them access to all relevant information about the customer and the application's development history.
Developers should have the autonomy to make decisions within the context and constraints. However, when they encounter, hit, or suspect they might hit the constraints, they should involve the team to discuss the problem and find a solution together. You should favor trust over micromanagement, but every team member must know that the freedom they have also has boundaries. Otherwise, you might end up with developers doing whatever they want, for example, by over-engineering every task just because they like to develop the most fancy solutions. That's why it is important to have clear responsibilities, expectations, and boundaries, so the developers can take ownership of the problem and make the best decisions they can within those boundaries.
It also requires the developers to be accountable for their decisions and actions and to be able to explain the reasoning behind their decisions. Being accountable is not the same as being blamed for mistakes. When a developer makes a mistake, it is a huge opportunity for them to learn and grow, especially when they reflect on the mistake.
Encouraging ownership in your team#
So now we know what ownership is, why it's important, and what it requires. Let's take a look at how you can encourage ownership in your team.
Providing context#
An important part of ownership is providing context instead of just requirements. It starts with sharing context, like:
- Business goals (what is the goal of the company or the customer, but also what is the vision of the company that develops the application)
- Customer needs (what is it they actually need, and why do they need it?)
- Proper understanding of the product (what is the purpose of the product, which problems does it solve for its users, and what is the vision behind it)
- Learning the application has no queue worker running yet, but it does use a reliable mail delivery service
Providing room for decision-making#
With that context, we need to provide the developers the room to make their own decisions by:
- Providing clear expectations (what is the expected outcome of the task, and what is the definition of done)
- Providing clear constraints (what are the boundaries of the task, what is not allowed)
- Providing insights into the agreement with the customer (what is the budget, what is the timeline, and what are the priorities?)
- Allowing them to make technical decisions, for example: do we need to implement a queue worker for this task, or can we use the existing mail delivery service?
Be explicit#
People tend to make plenty of assumptions. Not just in development, but in life. When working in a team, assumptions can be dangerous, because they usually lead to misunderstandings or misalignment. That's why being explicit is an important skill to have in a team. In this case being explicit about:
- Ownership boundaries (what is the scope of the task, what is not part of the task)
- Accountability (who is accountable for what, and who is responsible for what)
- Expectations (what is the expected outcome of the task, what is the definition of done)
- Roles (what is the role of each team member, and what are their responsibilities)
Encouraging critical thinking#
With these three pillars in place, we can encourage the developers to think critically. You can encourage this by:
- Asking questions about the requirements (why is this requirement needed, what is the actual problem we are trying to solve)
- Critically evaluating the requirements (Is this requirement really needed? Is this the best way to solve the problem?)
- Suggesting alternative solutions (what are other ways to solve the problem, and what are the pros and cons of each solution?)
- Questioning any leftover assumptions
Continuous improvement#
An important part of encouraging ownership is to ensure that continuous improvement is part of the team culture. That can be achieved by:
- Having a retrospective after a sprint, project or even a feature, depending on the size or complexity of the work. Every team member should join the retrospective and prepare the meeting by thinking about what went well or what could be improved. The team should discuss those findings, and it should result in improved guidelines, more efficient processes, or even new tools that can help the team to work better together.
- Another important part of continuous improvement is introducing "feedback loops". Feedback loops are a way to ensure that the team watches over each other, helps each other, and provide feedback early on. Code reviews are a good example of a feedback loop, but that can also be applied to designs, requirements, or even the way the team works together. Early feedback results in a more efficient process and higher quality results.
The example#
Looking back at the invoice example, ownership made a meaningful difference. By asking questions, the developer discovered that the invoice needs to be sent to a specific billing email address, which was something the original task didn't mention. With a clear understanding of the customer's request, budget and constraints, the developer was able to come up with a suitable solution that was efficient to build and didn't introduce extra complexity to the application. The product owner learned which information the developers need, while the developer learned more about the customer and the application. Both can apply these lessons to future tasks, which will result in a more efficient and effective team.
Ownership is not the same as working independently#
A common mistake is that ownership means the same as working independently. But that's absolutely not the case. Ownership can also mean that you ask questions more often or earlier. It can also mean discussing the solutions with the team. Ownership is about taking responsibility for the problem, not just the task. And that means that you can ask questions, discuss solutions, and even ask for help when needed. That means that ownership is encouraging actions like:
- Collaborating with the team to find the most suitable solution
- Asking questions to understand the actual problem
- Asking for help when needed
- Discussing solutions with the team to find the best solution
- Raising risks and concerns as early as possible
- Taking responsibility for decisions within your area of influence
- Supporting the team, sharing knowledge, and watching each other's workload
A developer who takes ownership doesn't have to solve everything on their own. By reaching out early, the developer prevents problems that otherwise would have been discovered much later during development and are then much harder to solve.
From task completion to ownership#
Ownership goes beyond completing tasks. While individual team members have their own responsibilities, the team shares responsibility for delivering a solution that solves the customer's actual problem. But ownership isn't something you can simply demand from developers. As an engineering/operational leader, you need to create an environment where developers have the context, feel the trust and autonomy to take responsibility for their work.
To achieve ownership, the team needs to share context, expectations, constraints, and insights into the agreement with the customer. The team also needs to be explicit about ownership boundaries, accountability, expectations, and roles. And finally, the team has to encourage critical thinking and strive for continuous improvement.
When a developers take ownership of the problems they are solving, they don't just deliver features, they deliver high-quality solutions that solve the actual problems of their customers.