YYRAGNI: Yes, You Really Are Going to Need It
Development work is blocked when a dependency for that work is unavailable. One of the great challenges in managing a project is identifying all the dependencies in the workflow so that all the work can be done in the order that prevents anyone from waiting for someone else to complete a task.
Dependency discovery and task ordering is very challenging even when the design goals are fixed. It's especially difficult on agile, software projects where the design goals are fluid. It's almost certain that shifting priorities will create dependencies that will naturally block a team member.
There's a solution to this problem that should be simple, but due to arbitrary definitions and expectations about workflow, the most obvious solution isn't implemented.
What's the obvious solution? Have the person whose blocked work on something else. And this doesn't have to require task switching either, because if you have well-defined tickets, or user stories, it's generally easy to see that a ticket has a dependency on another task, so it shouldn't be assigned until the dependency is resolved.
Common sense, no?
Yes, but no. Yes, this sounds reasonable, and if you look closely, it actually is reasonable; but it doesn't happen often enough. In fact, I generally see people follow the unreasonable path:
- Have the developer start on the story
- Hope the developer doesn't get blocked
- Watch the developer get blocked
- Flounder for a day or so, leaving the developer hanging, hoping the blocker goes away
- Begin assigning menial tasks to the developer, subjecting the developer to task switching hell, while waiting for the blocker to disappear
- Find out the blocker isn't going away until next sprint
- Try to find something productive to do until the end of the current sprint
- Roll the incomplete ticket into the next sprint and start the process over
Why do development managers, project managers, and product managers let this happen, or frequently cause this to happen? Four reasons are generally offered.
Reason 1: We can't wait to start on this feature. Someone important has determined that the feature is the priority, and the team leadership has decided the best response is to look as busy as possible on this feature. Every ticket for the feature is pulled into the sprint regardless of internal or external dependencies. This will not be effective, but often the appearance of commitment takes precedence over actual effectiveness.
Reason 2: Bad definitions of done. Someone has defined 'Done' as a user facing production deployment, or anything else that prevents sensible, working, and tested code from being called 'Done.' So, the team can't assign a ticket for some piece of work, because it can't be marked 'Done' by the end of sprint. So, assign work that probably won't be 'Done' by the end of sprint because it has a chance to be 'Done.'
Reason 3: Bad metrics. Similar to reason two, but generally because someone has a metric on feature cycle time. That is the work for a ticket could be done in the sprint, but the feature it's part of will have to wait once the blocker is removed and the blocked feature can proceed. So, the feature started by this filler ticket will remain open for a few extra sprints and make the average cycle time look bad.
Reason 4: We haven't scoped any new features. This is the worst. The product and management teams don't have a robust backlog of work to do that has been defined for someone to work on, so they stick developers with work that can't be finished while the business tries to figure out what's going on.
To address these reasons always involves some level of organizational change. There are no quick fixes available. But the end state is easy to understand.
Build a list of work that you know will have to be done. Yes, you really are going to need it. Break into small, discrete, well-defined stories. Define "Done" as code-complete, tested modules. Don't make metrics, like feature cycle time, the goals. Build a backlog that's 6 to 8 weeks deep. Don't schedule any stories that have open dependencies. And deliver excellent software.