People Problems

Read this on Medium or LinkedIn

Three months into a new role as the CTO of a small media company, I walked into the CEO’s office and told him that one of our senior engineers had quit. As he started to reassure me that everything would be ok, I quickly cut him off. “I just avoided the most difficult issue I was going to have to deal with in my first six months. I just won the lottery.” Clearly not the response he was anticipating. So I explained that despite being a good engineer, he was difficult to work with, disrespectful to his peers, and did not enjoy collaborating with anyone on the team. In short, he was toxic to the team and we got very lucky that he decided to leave.

I knew going into the role that there were fundamental issues that had to be fixed ranging from poor software architecture to a complete lack of process on the product and engineering teams. As challenging as those types of problems are, they are nothing compared to people problems.

People assume the biggest challenges for a CTO or VPE are technical ones. Technical challenges can be hard to solve, but they are also fun to solve. Engineers are at their best when faced with a seemingly unsolvable problem. People problems are not fun for anyone, and unfortunately, are often insoluble.

Another people problem emerged recently. Unlike the first situation where the guy was a straight-up jerk, disrespectful, unprofessional, and someone who took pleasure in actively putting down his peers — this engineer had the best intentions. He was always looking to improve things and deliver quality software. The problem was that, despite this, he was a poor cultural fit for the team; a much more difficult situation.

My initial look at the situation gave me only a partial understanding of the problem. It seemed like this engineer had strong opinions that just happened to deviate — often heavily — from those of the rest of the team. His approach to almost every aspect of developing software was just different.

But what frustrated the other team members most was less about the technical particulars and more about how he collaborated — or rather, how he failed to collaborate — with the rest of the team. Often, other engineers would describe his behavior as “bikeshedding”. (A wonderful term, click through if you aren’t familiar). His believed he was being thoughtful, seeking out discussion, trying to make everything better. But functionally, he was consistently turning simple conversations into big discussions regardless of the topic. From larger architectural issues to coding styles — even how people should word their commit messages — he would initiate a discussion that rarely led to a conclusion or even a next step beyond more discussion.

After gaining a better perspective on the conflicts it was clear the tension on the team was getting to be too much, and something had to be done immediately. I did not want to lose the contribution of a good engineer, and I thought I could solve the problem by moving him to a project where he wouldn’t have to collaborate. He’d be working with only one other person — a product manager and recent engineer who could do code reviews but would no longer offer engineering-related opinions. I was curious how this engineer would do working alone, in a situation where collaboration wasn’t even possible. Unsurprisingly, he did much better.

This went on for a few months, but ultimately projects and priorities shifted around and it was no longer an option to keep only one engineer on this project. As soon as other engineers were introduced, the exact same issues came up again. It occurred to me that I’d just been postponing the problem. That said, the time afforded me the opportunity to speak to this engineer more often and learn more about how he approached his work. When tensions (inevitably) arose again, I had much more useful information to inform my decisions.

I realized that my initial assumption — that this engineer had a different, but equally effective, way of doing things and that it was my job to make the best use of his contributions — was simply wrong. With more time and more conversation with him, I came to understand that his approach to work was more than just a fundamental misfit with our team. The first big revelation was that he conflated best practices with personal preferences. He could spend five minutes or a full hour arguing with other engineers for his approach, but at no point was he ever going to consider the other engineer’s opinion. He also made issues out of very small things, things that no other engineers on the team felt were worthy of discussions. (One of the more notable ones was how and when we should update our statuses in the #status channel on Slack. When the rest of the team blew-off his incredibly specific recommendations of how we should all speak to each other, he petulantly left the channel.) He always spoke about collaboration, but actual collaboration was beyond him. He would relentlessly push his own ideas on everyone else under the banner of collaboration, but that was the exact opposite of true collaboration. There was a disconnect.

It wasn’t all making mountains out of molehills. He also tended to over-engineer solutions at the onset of a project. Rather than take the simplest approach — develop working software, and refactor later as needed — he would “pre-factor” overly-complex solutions. This fit very poorly with with a team that believed in simple solutions and an iterative process.

As my understanding of the issue grew, our conversations got more difficult. It was then he started to demonstrate one of the most troubling and toxic behaviors of all: blaming others. He blamed everyone and everything. He argued that the root cause of the conflicts were due to the flaws of other engineers, or being the only one who “cares about the craft”. He cited being a remote worker as a cause. When I pointed out that these conflicts never arose with the other remote team members, he fired off other reasons why this was someone (anyone) else’s fault. There was no introspection, ever.

Functionally, in the end, this engineer’s problem ended up being the same as the first one. When push came to shove, he didn’t play well with others. And at this point, I knew that the situation was unfixable. To be honest, I’d probably known it for several weeks but I tried — possibly to a fault — to figure out a way to make it work. Why? I’ve been much less forgiving with other people that have wound up leaving the team I’m running, but for some reason I had a hard time getting past this engineer’s good intentions. I think it was because he framed everything as a commitment to quality, which is an ethic I hold in high regard.

The most valuable thing I took away from this experience was a strong reminder about the importance of cultural fit on a team. The first engineer was an aggressive jerk who took pleasure in putting down others. The second was a really nice guy who thought he was making things better. Both created a toxic environment that was a contributing factor to valuable engineers leaving the organization. In the end, intentions didn’t matter, and paying too much consideration to them only prolonged a bad situation.

Unlike technical problems, people problems are often insoluble. Ultimately the best resolution is often removing the person from the team quickly. And also unlike technical problems, that is never fun.

Five Outcomes of Working with Agility

Read this on Medium or on LinkedIn

Last year a company reached out to me for advice on their software development practices. They admired my organization’s ability to build engaging and usable products, and asked if I could meet with them to explain how our software engineering team worked to accomplish this.

I was asked to open the meeting with an overview of our processes and practices. While I could tell that their team was very engaged, they also seemed a little nervous — opening yourself up to criticism from an outsider isn’t easy. A few minutes into the overview I mentioned “Agile”. Instantly the tension in the room lifted and everyone seemed suddenly at ease. “We use Agile too!” The meeting proceeded and spirits continued to improve as they recognized key terms from my answers — automated testing, retrospectives, test-driven development, daily stand-ups — that they, too, used.

A few months later this organization put out a website and a native app to support a heavily promoted event. It was a disaster. It had broken images and videos; it loaded slowly and had a non-intuitive UX. The native app was even worse. It barely functioned at all and content that was supposed to update in real-time remained stagnant from a few days before the event to a few days after the event (maybe forever — I stopped checking after a while). They had released broken software to their users after spending a considerable amount of resources building and promoting it.

I thought back to the meeting and how it clearly didn’t help them. It made me realize that explicitly talking about Agile methodologies was the wrong approach. Ask a bunch of software engineering managers if their Agile practices are working. They will all say yes. Everyone thinks they work with agility, so asking the question is as meaningless as asking a bunch of people if they are smart or if they have a good sense of humor.

As I thought more about it, it occurred to me that a focus on the outcomes of a good Agile process would have been much more productive. Here are five outcomes that I believe show you are truly working with agility.

1) The process is always changing

Agile is about constant improvement and adapting to change. These only happen when every member of the team feels empowered to suggest improvements. If the process remains stagnant for a few months you have either failed to foster a “safe to try” environment, you lack a forum for people to suggest change, or your team does not feel invested in the process.

Our software engineering teams always have weekly retrospectives. Thirty minutes are set aside every Friday afternoon to discuss what was good, bad, or confusing; and what actions should be taken the following week to make improvements. We are constantly applied to the task of making small changes to our process. Half the time we decide to revert the change. The other half of the time we stick with the change and continue to build from there. Week-to-week things don’t change very much, but year-to-year the cumulative improvements to our process are noticeable, as is the team’s increased effectiveness.

2) Clarity is pushed up the chain

Too often it’s the software engineer that exposes incorrect assumptions, unanswered questions, or other issues that act as blockers to building something. Such flaws often permeate through the entire system right up until the last possible moment, which is, of course, the worst possible moment. Waiting until someone starts to write code to discover these shortcomings is a clear sign the process has failed.

Well-implemented Agile practices help prevent this by pushing clarity up the chain. A test-driven development approach allows an engineer to discover issues before they begin writing code. But this clarity can be pushed even further up the chain. By writing user stories with clear and detailed acceptance criteria, this clarity can be achieved as the features of the product are still being defined.

For example, our organization involves the engineers as stories are put into the backlog. Sometimes we discuss implementation, but we always make sure all the engineers have an opportunity to challenge the story. This small investment of time upfront saves a lot of time that would be spent uncovering issues later.

We also include the engineering team in a process called “inception” that we use to start new projects. Getting engineers involved at the outset not only makes them more invested in the project, but it also allows them to make valuable contributions to the “why” as well as the “how” by contextualizing those contributions from the start.

3) Agile principles spread to other parts of the organization

If any team or department in an organization is highly productive, other people take notice. They start to ask questions and become curious about how they, too, can start to work with agility. At our organization people consistently notice the engineering team’s ability to make small chunks of progress very quickly and with confidence. Other departments ask us to run workshops to surface their own team’s true priorities. Our marketing team talks about minimum viable products. And our CEO went from asking us to build new products and features to asking us if we can run A/B experiments to test his ideas. A department run with agility becomes an excellent incubator.

4) Usable software is pushed to production daily

Software should be pushed into production every single day. Even if your industry has regulations that prevent this, code that is deemed ready for production by the engineer who wrote it should be committed every day.

This will produce hard evidence that your work is being done in small, logical chunks. We make sure that every user story could be pushed to production on its own even if it’s part of a very large project. We do this with feature flags or by simply knowing that the code will not get called. It also means your user stories aren’t too big. When the engineers point stories (1,2,3,5,8), a value of 8 almost always means that the story should be broken into multiple stories. If it’s common for engineers to work on the same story for multiple days, you are not breaking up your work into small enough chunks. And when work isn’t broken down into small enough pieces, complexity gets overlooked and becomes an issue later.

5) Less talking, more doing

It’s all too common for people to try to solve a complex issue by “getting into a room together.” Most of these meetings probably happen without any kind of structure directed toward meaningful decision-making. We’ve all participated in such meetings. Everyone going into a meeting should be able to explain the goal of that meeting.

Too many emails is also a bad sign. At a previous job, I witnessed an email chain for a big project between 20 people that topped out at over 100 individual emails. The subtext of every email was, “I just did this thing, and I don’t know what’s supposed to happen next.” Too much communication without clear results is a strong indicator that your process is not working.

When done well, working with agility can be a powerful and transformative force. But software engineering managers all too often implement something basic, check the “Agile” box, and walk away. They forget that working with agility means testing, learning, and iterating not only the product, but the process itself. It’s about responding to change. If you’re not doing the responding part, you are not doing Agile. The five outcomes above are good indicators that you are truly working with agility.