Promoting Shared Accountability of a Codebase

Brendan Cone
The Startup
Published in
5 min readJul 3, 2019
Shoutout to /r/ProgrammerHumor

Every programmer who’s maintained a production system long enough has had a moment where they’ve investigated a production issue, made a snap judgement that the code which produced the bug was careless and shouldn’t have passed code review, gone on a warpath to figure out who wrote it, and then had the humbling experience running git blame and realizing that it was them, two years ago, who committed that code.

We may run through the seven stages of grief —maybe we’ll frantically look through the git history during the denial phase to see if perhaps we copied the code from somewhere else in some expert-level refactor and that’s how our username landed there. And then finally we’ll reach the acceptance phase after all the necessary cognitive dissonance — we wrote bad code.

The Fundamental Attribution Error in Programming

There’s a very important lesson to be learned in this common story, and it relates back to a cognitive bias that we all share — the fundamental attribution error. When we see an undesirable behaviour in ourselves that goes against what we believe, we tend to chalk that behaviour up to some external factor or circumstance, but when we see someone else show that same undesirable behaviour, we often attribute it to internal factors baked into their personality, ability or way of being.

“You’re actually talking about the actor-observer bias” — Jeremy Cone, my brother, a social psychologist reviewing this article — thanks Jer!

Here’s the very interesting caveat about the fundamental attribution error as it relates to programming: because of the nature of the craft, we often have the behaviour (the code) separated from the individual showing that behaviour, until we dig into it further when it warrants inspection. This dynamic allows for us to have this crisis of identity when we discover that the behaviour was our own, only after analyzing the behaviour in isolation.

Taking this idea further, the really interesting insight to be gleaned from this concept is that the code itself is a living entity, worked on by a team — it is completely irrelevant who contributed the code that caused that production bug. It could have been you. It could have been last semester’s intern. It could have been your principal engineer. The fact that the code is there, staring you in the face, is proof enough that there was a decision made by the team, either implicitly or explicitly, to introduce it into the codebase. This higher level of thinking about the code helps to promote healthy team dynamics, behaviours, and management methodologies, because it promotes shared accountability of the codebase.

Sharing Accountability in Practice

Shoutout to /r/BadCode

Any number of factors could have allowed the code above into production: there could have been a last minute requirements change the night before a launch, an absent code review process, an established coding anti-pattern in the codebase that was followed or copied, a lack of seniority in the engineering organization to guide more junior developers, a lack of trust and transparency that made it so that the principal developer who wrote the code went unquestioned, a timeline squeeze due to poorly-planned vacations across the team, or it could even have been that this was a deliberate decision from an experienced developer given the time constraints of the project.

If we trust our hiring, and trust our engineering department to make good decisions in general (and I hope that we do!), then we treat this code as something that we all made the decision to write together, and have to deal with accordingly.

If everyone on the team, including management, adopts this way of thinking, it helps to create a few extremely valuable outcomes:

  • A Trusting and Fail-Safe Culture: If people feel free to make mistakes because the burden of failure is spread out across each member of a team, including management, post-mortems become a lot healthier. We are able to abstract away individual contributors and understand at a macro level what improvements can be made that will benefit everyone.
  • Increased Quality: When every team member, regardless of role, feels comfortable speaking up (or engaging in debate in code reviews), knowing that their silence could very well be the cause for a future issue that they could have helped prevent, we will invariably see better code come out the other side of the process. If everybody is unafraid to ask stupid questions, the one stupid question that might cause everybody to reconsider a terrible solution to a problem will surface to the team.
  • Management as Collaborators: Over time, if managers feel responsible for production issues just as much as the individual contributor that committed the code, they can come to be seen as another role player for the team. They can also push for solutions to problems that are beyond the purview of the average individual contributor. Perhaps the real reason that a production issue killed the app for half a day was because the team was overworked, or the communication of risk between the team and management was poor, or the team was lacking critical information to make a proper decision. Managers can action on the team’s insights and leverage their broader exposure to other company functions to generate more robust organizational solutions than the team could generate on their own.
  • Better, More Scalable Products: Engineers who are not proud of what they are producing will speak up if they feel like they are jointly responsible for its success. The worst end state for an engineering organization is when people stop caring about the product, the user or the codebase, to lean on broken windows theory. If we are being short-sighted with our architecture to the detriment of our long-term success, the team will speak up if they feel responsible.

All this is not to say that each individual should be absolved of all responsibility to produce high-quality output and to improve. And it is true that continued patterns of low performance at the individual level can and do happen and need to be managed accordingly, but the reality is that these problems are even easier to identify and solve if everybody feels the weight of that continued low performance and treats it as a problem for the team to address.

It is not necessarily an easy task to get a team to think in this manner, but the best things that we can do to promote the culture are to make simple adjustments to post-mortems, advertise the mentality often, reinforce it with our hiring decisions, and finally to truly live it and show it through our actions; when high-pressure situations arise, standing with our team, remaining calm and collected, and working together on solutions all will send a much more impactful message than words or policies ever could.

--

--

Brendan Cone
The Startup

I’m a generally optimistic engineering manager who loves talking about engineering, management, music of all sorts, and a whole lot of other stuff.