Teaching Project Leadership


Black Trans Lives Matter. Before you get started here, consider setting up a monthly repeating donation to a non-profit such as LGBTQ Freedom Fund.

All engineers should strive to be more than just coders pounding away on the tasks they're assigned. I've found that making the jump from "I do what I'm assigned" to "I can plan and execute this feature" is a very difficult one. Most teams are not set up to develops a person's ability to plan, they just... assign people work and let them try to figure it out. My strategy for developing planning skills isn't unique or special, but I hope that describing it might help other folks find the patterns that are right for them.

I call this style of project planning "primary/secondary". The "primary" person is responsible for delivering a project, and the "secondary" is responsible for helping the primary learn how to do that effectively. During the entire arc of the feature development, the primary and secondary work very closely on all aspects of planning, organizing, and documenting the work. Primary/secondary should not be thought of as akin to "paired planning", because there is an explicit focus on the primary being guided by and learning from the secondary.

Crucially, the secondary is not responsible for delivering the project. The secondary is responsible for helping the primary plan and execute the project. Sometimes, but not always, the secondary engineer will contribute code. There may be other engineers who work on the actual implementation once the planning is complete, but we're focused here on how the project is planning and executed, rather than the specific implementation.

The Primary #

The goal for the primary is to learn. We want the primary to get experience in a psychologically safe way. They need to ask questions, push the secondary for more knowledge, and above all else, seek to gain an understanding of why they're doing things in a certain way. The primary should be viewing everything from the lens of needing to be able to do this work on their own in the future. For junior engineers on their first big feature, this means getting a deeper understanding of how to break problems down into tickets, plan for delivery dates, and define success. For more experienced engineers, this means feeling confident that they can plan for multiple streams of work to be handled by other engineers.

When working on a project like this, a primary can be said to have succeeded if they come out of it with a good understanding of how to plan and execute on a similar sized future feature without any help. In this light, it doesn't specifically matter whether there were problems with launching the feature in question. What matters is whether the primary learned from the problems they encountered and feels confident that they would be able to anticipate or avoid such problems in the future. Because the primary is responsible for delivering the feature, any team standups, updates, or questions should be handled by the primary, not the secondary. The system won't work if the primary has to look at the secondary for answers every time something comes up. Every aspect of delivering a feature (including communication) is important to learn as part of a primary/secondary project.

The Secondary #

The goal for the secondary is to enable the primary. The secondary's focus should be on providing a paved path for the primary. For this reason, it is very important that the secondary be someone with lots of experience running projects -- someone of a similar experience level won't be sufficiently able to provide a safe and controlled environment for the primary.

When paired with junior engineers acting as primary on their first project, the secondary will often be explaining a lot of their own method of approaching problems. An important aspect here is that a secondary should give examples for the primary, but try very hard not to then actually break the current feature down for them. To facilitate learning, the secondary should provide guidance but ensure that the primary is the one who actually takes each step for the current project. It won't always be possible to do perfectly, either due to the temperment of the primary/secondary or else because some folks do a lot better when shown rather than guided. A secondary needs to be pragmatic -- one primary might learn best from examples, but another one might learn best by having part of the current project broken down. As long as the primary is truly learning to do it themselves, then the secondary is succeeding.

When working on a project, the secondary should (whenever possible) have a good idea about what potential problems the primary will run in to, and be prepared to guide the primary towards these gently. Leading questions are great for this, and can involve longer discussions. For example, if the primary isn't sure about how to start breaking down a feature, it might be good to ask questions like, "Would it make more sense to implement X or Y first?" and then have a discussion about the various trade-offs. As the discussion wraps up, bring things back to the original question, "Would it make more sense to implement X or Y first?" and ensure that the primary is able to apply the theoretical discussion to the practical example in front of them.

The secondary should also be prepared to remove blockers for the primary. For some projects, there may be specific parts of a feature which would be significantly more complicated for the primary to understand/implement. Because the goal for this is to teach people how to run a project rather than specifically improving their coding skills, the secondary would handle the blocker by saying, "I'll handle this particular aspect of the feature, it's enough that you know it exists as an issue", and then move on. Examples of this might be something like setting up a particularly complicated series of backend data fetches in order to ensure optimal data fetching patterns, setting up Redux stores, or creating the initial code for a React project, etc. These are very valuable skills for a junior developer to learn another time, but they would be a distraction from learning how to plan and execute on a project.

One particular note is that it can be difficult to know when to intervene if a primary is making an incorrect decision despite guidance in a different direction. My general approach is that the more junior someone is, the harder I work to guide them to the correct answer. For a junior engineer who has successfully shipped several projects, though, I would be a bit less firm in my guidance -- I might say, "I think that there will be an issue with X" or "How sure are you that Y is going to work?", but if they remain sure of their incorrect answer, then I won't always correct the issue. It's a difficult balance, but some of the most educational experiences I had as a junior engineer was when I ignored a more-senior engineer gently warning me that perhaps I hadn't thought through something enough... and then had to deal with the consequences. In this case, in a primary/secondary environment, a secondary's responsibility would be to prepare ahead of time for the consequences of the mistake and be ready to help the primary through dealing with them when they encounter the problem.

Examples #

First Real Feature #

Junior engineers often spend the first year (or two) of their career working on well-defined tasks which are assigned to them by others on the team. These could be small project features (add a button, fix a style, record new data) or bug fixes. In these scenarios, someone else has done all of the planning necessary, so the junior's real task is to learn enough about this (hopefully) small issue and learn how to write code to handle it. Once our junior engineer has done this enough times, they will be ready to start learning the next steps:

In a primary/secondary environment, the junior engineer would be the primary on our feature, and a senior+ engineer would be the secondary. As the secondary, I'd be spending a lot of time pairing with the primary in order to explain how to break down the feature, how to plan for incremental delivery, estimating difficulty, etc. These skills are the work of an entire career to develop, but getting to pair directly with someone who has a lot of experience with them can be a great way to jumpstart things for a junior. My experience has been that the explicit pairing and encouragement will help people feel safe to ask questions that they would not have otherwise felt safe to ask in a larger group (or even in a one-on-one). After team meetings where the primary is delivering updates, we might spend time talking about the way that the update was given and how to tailor it for the audience (IE, how to present information to the team). I will often be the primary code reviewer for the project, which means that my focus will be split between the technical implementation and also the degree to which the reviews stay close to the original plan. When snags are hit, I emphasize stopping to re-examine the plan and talk through whether we could have anticipated those problems earlier. If I make a mistake or miss something during planning, I make sure to explain it and what I could have done differently (or why I couldn't have spotted the issue until we got into the code). I like to show junior engineers that even with lots of experience, it's possible to miss details during planning. The goal isn't perfection, but flexibility.

First Feature With Others #

At some point, our junior engineer has delivered a few features, hopefully with the help of a good secondary to smooth things out. For this project, our junior engineer is for the first time leading a project that other more junior engineers are working on. In this case, the primary's responsibilities become a lot more complicated, they're in charge of planning and organizing parallel work streams. A lot of the skills that juniors learn at this phase are essentially more-complex versions of those from earlier. Your primary will need to think about:

Leading a project for other engineers is a big milestone in someone's career, as it is a big step toward demonstrating that they are becoming a senior engineer. These sorts of projects are a lot more complicated, and there's a lot more to worry about. As the secondary, the responsibilities would be to guide the primary through all of these issues slowly, and to help them work through what's going on during the course of the project. At this stage of the primary's development, the secondary might still contribute code to solve particularly thorny blockers, but the emphasis would be much more heavily on the primary learning to recognize and solve these problems on their own. As a secondary in these situations, I would:

For projects like this, it is not an explicit goal of the secondary to prevent the primary from making mistakes. You can (and should) guide the primary toward possible issues, but it is an important step in the careers of junior engineers to make mistakes and then learn from them. It is an explicit goal that the secondary be ready to help the primary deal with the consequences of these mistakes in a psychologically safe way. This means helping the primary work through any possible imposter syndrome (say it again, in a psychologically safe way) while also providing guidance on what and how to communicate up to team leaders. The secondary should not be informing product managers or engineering managers that things are going wrong unless the primary is completely failing to tell anyone that there are issues, because the goal is to ensure that the primary is learning how to manage expectations and reduce surprise for other team leads. As with the first project, the primary should be the one handling these communications and the secondary is there to help make things easier and provide guidance. A project where the secondary tells the primary how to do everything doesn't help anyone grow.

Mentoring Seniors #

As a staff engineer, one of my explicit responsibilities is to develop senior engineers into team leads or staff engineers. Primary/secondary also works great for this, because it provides a high touch (and private) way to work through more complex project planning. This can be a particularly difficult inflection point in the career of most senior engineers, because it's the point at which they will need to start growing the people around them. Rather than fixing every problem, people who want to be team leads have to learn how to teach their skills to others. They also have to come to terms with the fact that their day-to-day work on a project will include a larger focus on the people working on a project, rather than purely on the code they write. For a senior primary working with a staff or lead secondary on a large project, you might expect to look at a quarter-long project and think about:

At this point in their career, the senior might be learning how to balance their own coding work with time spent as a secondary for the various features for their project. They will generally realize that in order to run the project well, they will need to hand off features that they might prefer to do themselves and instead be prepared to guide others through the implementation process. As the secondary for this senior engineer, you are (to some extent) guiding the senior engineer through the process of learning to be a good leader and secondary on all of the smaller parts of the project.

When To Use Primary/Secondary #

Primary/Secondary works best for medium or small projects. It shines in situations where a single person can be reasonably plan and lead the entire project. It is not a good choice for projects which might have features which are themselves medium-sized projects. That is, if a project is so large that its features require their own independent research, planning, and delivery dates, then those smaller features would be good candidates, but the overall project might not. The reason for this is that at that scale, it's not feasible or desirable to have two people trying to manage all of the planning and organizing work -- it is the work for an entire team.

Primary/Secondary can work for larger projects if your team runs the risk of being heavily siloed. When I've worked on platform or infrastructure teams, projects were often long-running efforts by one or two people. We used Primary/Secondary to keep everyone supported and ensure that no one was going off the rails or getting stuck. It also gave us a great strategy for developing more junior engineers, for whom platform/infrastructure work can be extremely difficult to ramp up in. In these situations, we might have a junior engineer who is the primary on a specific feature, and a more experienced engineer who is the secondary on that project while also working as the primary on a different project (with their own secondary there). This creates a much better sense of cohesion and develops team-wide best practices than would exist if everyone were off doing their own thing.

Your team has to actually have an engineer with a lot of experience running projects to act as a secondary. This does not mean a manager, even if the manager was previously an engineer. My experience is that it is difficult for junior engineers to feel sufficiently psychologically safe asking "dumb" questions to their manager, because they don't want that manager to think that they aren't good enough. If you don't have an engineer experienced with project planning on your team, then you would be far better off doing all planning and organizing as a full team. Have all of your discussions together, plan things out as a group, and do your best to learn and grow when things go wrong. If you do it all as a team, then you ensure that when things go wrong, no one person is left taking the blame (whether from the rest of the team or purely internalized). If possible, you can also seek mentors from other teams and find people who can help act as secondaries without being on the team with you. This winds up being closer to pure mentorship/advice-giving, but is better than nothing.

Finally, Primary/Secondary is probably not a great choice on teams with high-pressure deadlines. People can definitely grow in those sorts of situations, but being under significant pressure does not create the kind of psychologically safe spaces that a primary needs in order to learn how to organize a project. For these sorts of situations, the best bet is (unfortunately) to have your experienced project leaders taking charge and ensuring that things happen correctly. If your team only operates in this mode, you are in crisis and need to make significant changes in order to ensure the long-term health and development of your team members. If you as a team member (whether junior or more senior) can't change things, go somewhere else -- another team, another company, whatever. Psychological safety is a crucial element for long-term growth.

Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated 💖! For feedback, please ping me on Mastodon: @sangster@macaw.social.

Published