Changing habits is hard. Changing team habits is even harder.
Even knowing that changes are going in the right direction, I find myself irritated by the churn and change. I know we should do more code reviews (particularly responsively). We should require more tests for new features. I know we should work in a single main branch. These are things I will always advocate for on any project, but it is hard to move in that direction when the current low-friction way has been established.
So, how do we fix this? Great question! I don’t know yet. We are still working through that. Hopefully, this is a topic I (or others) can discuss in the future once we have been able to work through it. Instead, I will ask a slightly different question:
How do we avoid this?
The answer is irritatingly simple, but can be deceptively hard: get it right the first time. Set standards and expectations to keep friction low, but feedback high. Tighten the feedback loop. Make this part of your team rituals.
Establish a team schedule.
The first part of creating good team habits is to establish a team schedule. Not everyone’s schedules will sync. In our current hybrid life, it is impossible to know when and where other team members will be available. Also, it’s unlikely that everyone will work the same hours. Between morning people, night owls, and everyone else, you will need to target certain windows of availability each day. Take time early to establish good team hours where collaboration can be successful.
These team hours need not be restricted just to hours everyone is available. It is healthy and helpful to find times that work for your team, your pair, and your collaborations so as not to get hung up on the ever-changing dynamics and schedules of larger teams. A full team may only ever have one hour a week to sync (and sometimes even none). In these cases, find your sub-team for the sprint and establish the best available schedule.
Celebrate sprint ceremonies.
As anyone who has run an agile workflow knows, sprint ceremonies are an important way to acknowledge progress and address friction. Establishing both the practice of celebration with the acknowledgment of friction is key to maintaining healthy team relationships. However, a team may fall into a simple pitfall by creating a celebration-only process. When the key focus of each celebration is progress and only the celebration of progress, it is easy to lose sight of where you are losing momentum. Elevating and discussing friction within the team is crucial to keeping the momentum high, even if it can be hard to discuss.
Make testing a part of your everyday work. Retroactively adding tests is hard, and getting those tests right is even harder. You are stuck guessing at what the original specifications were and possibly encoding errors or buggy behavior into the test, reinforcing them in the future. Writing tests from the beginning will not prevent all bugs, but it will outline how we are anticipating the system to work. If a bug is discovered or new functionality is added, building on the previous expectations helps cover more cases while still having confidence the original expectations are not dropped.
Create a tight feedback loop.
Create an environment where feedback and review are a first-class priority. It is easy to get into a cycle where you create pull requests and wait for review so long that the context has left your brain. It is also easy to back-burner other people’s PRs in favor of squeezing just one more change or feature into your sprint. However, by doing this, you have created a loose and possibly ineffective feedback loop.
Instead, as part of your team habits, set firm and fast deadlines on code reviews. I like to set an expectation of responding within 24 hours. A day may not seem like much time, but it helps keep things moving. This does not mean the PR has to be approved and merged within one day, but it pushes the conversation to be regular and timely. Some of the added outcomes of a tight feedback loop could be smaller PRs. Team members may be incentivized to give meaningful reviews to prevent repeats. Finally, developers can stay in context more often, preventing future bugs.
Good team habits aren’t established by accident.
No single practice can keep a team productive and healthy. Good team habits are not established by accident (though bad habits might be). They take diligence and intentionality to get right. It is a learning process, with a focus on collaborating to find the right rhythm and norms for each team. The above suggestions are focused on ways to keep feedback regular and give space to address all forms of friction, whether they are timing-related, code-related, or even interpersonal. These practices may not answer the question of how to fix an established team. However, they give a good blueprint of where we should go and how we prevent problems in the future.