(This post describes the first yak category. You might choose to start with the Taxonomy of Yak Shaving intro.)
When you feel that your task is 80% complete, these yaks form the next 80%. They are the distance between “works on my box” and “this is done.”
All the data setup. Verification. Approvals. Status checks. Linters and code review. These are the yaks we have summoned voluntarily. There are also surprises like, I’m ready to integration test, but the dev environment is broken. Or merge conflicts. Or an unrelated test failure. Or someone wants to argue about whether this change is even a good idea.
Attack yaks are very frustrating, but there’s no getting around them (without cheating). You have to shave them. They make our development flow rough, by forcing us to context switch. What can we do?
Be cautious about summoning these yaks. We choose to all write automated tests. It doesn’t make us faster today, but it makes our development smoother in the medium and long term. Except when it doesn’t; intermittent failures, especially in tests that are too wide to be diagnostic, can make development rough instead. Many fine-grained tests prevent refactoring, or enforce functionality that isn’t needed anymore but nobody knows it. Be conscious in your yak shaving. Don’t shave its eyebrows.
On some projects, we summon the yak of code reviews. What is the objective? If it’s code quality, pairing is live, yakless code review with no context switches yeah! If it’s keeping up the team’s mental model, then keep reviews focused on that; discourage nitpicks. As a reviewer, if you want to see another test, add it. Give me a commit instead of an attack yak.
Track the attacks. We have a yak emoji in Slack for these.
:attack-yak: Staging environment is down, I can't test
If we all do that, we can search Slack before the retrospective to find out which ones are interrupting us the most. Our retro can have a little more data than our gut feel, which is really based on the last few days.
Coordinate your attack. Once we know which yaks are holding us back, shave them with automation. Shave them until they’re not an interruption anymore. Autofix on the linter. Script creation of the dev environment, so that “it’s broken” means “recreate it” instead of “figure out what the problem is today and create a special custom fix.” Then automate regular re-creation.
This work can feel like a waste of time, because it isn’t getting features delivered. Yet, if we think about our work as more than personal productivity, we see the value. On my team, we care about generativity (as opposed to productivity): the difference in what your team does with you, vs what it would get done without you. It’s about the team, not about me. And it’s about the team in the future, not only right now. Not about going faster, but about going smoother: removing obstacles for everyone, present and future us.
Every time you hit a build or environment failure, ask yourself, “How could this be easier to diagnose?” It might be “put a better error message here.” Fill the potholes you encounter. Smooth the path for future-you and future-team.
Sometimes you’re coding along, writing tests as little experiments “this should fail because I haven’t implemented the parser for it yet” — and it fails in a way you didn’t expect. And then you start digging and the parsing library isn’t working how you expected. And that library (it’s our library) doesn’t have a test for this case. Now you need to switch your development environment over to work on that (have you automated that?). The yak stack is getting deeper. You have encountered …