I do "pathing" when I project my work into the future: laying out a sequence of work steps, where each step ends with the code in a shippable state.
More than design, and more than planning, pathing is a kind of work-style, and it brings me several benefits.
Here in the US, citizens are out in the streets on a quest for equity, and the truth is that geekery just isn’t the main story. If you’re out there working for change, I strongly support your efforts.
Stay safe, stay strong, stay angry, stay kind. Black lives matter.
When we’re pathing, we’re really just decomposing a problem, breaking it into several smaller problems. What makes me call it pathing — instead of design or planning — are two requirements we want each sub-problem to meet before we’re satisfied with it: size and shippability.
I use the pathing workstyle most frequently in two related but different tasks: in close-up coding at the keyboard, and in near-term feature layout around the meeting room. These are different scales, with different sizes that will satisfy, but shippability is the same in both.
With shippability, don’t get too distracted with markets or distribution mechanisms. Imagine you have some source code, and you have a working program out there in the world, and you have a button somewhere, labeled "Emit!".
When you press the Emit button, the source code is instantly and magically put into play: it becomes the program that your users are running. It’s free, and you can push it whenever you want, with no cost or stress or anything, just push the button and it’s done.
Once you’ve emitted the code, you can continue changing it until the next time.
Here’s the thing: "Shippable" just means that you, the maintainer of that source code, would be willing to press that button.
If you’re not willing, it ain’t shippable, if you are, it is.
So, at both scales, close-up coding and near-term feature layout, shippable means the same thing: every sub-problem must leave the codebase in a shippable state.
What about size? Well, the two different tasks are related, but they’re at different scales and levels, so the size constraint is different for each.
In coding, the overall timeline of the problem is about a day and half, and the size constraint I’m seeking for the sub-problems is under an hour each. The day-and-a-half problem is a story, and the sub-problems are steps.
In feature layout, the overall timeline of the vision is anywhere from a few days to several weeks. Here, the large problem is the feature, and the sub-problems are the stories, the same ones that represent the outer limit in the coding timeline.
So pathing is problem decomposition, but it’s a particular kind of problem decomposition, where we want the sub-problems to meet a size constraint and a shippability constraint. For me, when I can’t get that, I don’t have a design or a plan, I just have a desire.
We’ve talked about the RAT (Rework Avoidance Theory) and how it slows us down.
The most common way it does that is by dropping either or both of those constraints during problem decomposition.
The RAT: Rework Avoidance Theory | GeePawHill.org
Rework Avoidance Theory is a cluster of related ideas seeing a change as having a clear start-point & end-point and a straight & stable path between
RAT argues the shippability constraint is inefficient, because it virtually requires us to change things we’ve already changed before. But it over-simplifies professional software development, with multi-team parallel development and constantly changing pay-as-you-go markets.
RAT argues the size constraint is inefficient, because step-effort rises only linearly with the size of a step, and steps are a cost, so fewer larger steps is better. In fact, steps have intrinsic value to offset their cost, & effort rises w/step-size in non-linear ways.
Pathing is hard. It’s one of the more difficult skills a modern development team has to have. Like most such, some of us are better at it than others. And like most such, one gets better at it by practicing it.
I claimed that the pathing approach has several benefits. Let’s take a second and list some of them.
- Market responsiveness: when we don’t honor size & shippability, we get large bodies of work in progress (WIP). When the market shifts, we’re forced to decide whether to throw that WIP away, or to finish it before we respond.
- Multi-team parallel development: when we do this w/o the constraints, we’re forced to create multi-threaded syncs and wait-states in our development process. Holding the constraints virtually eliminates that very high control cost.
- Distributed inward-facing value: When individuals or teams complete small steps, they gain energy, enthusiasm, and focus. It’s a way to help a team bring itself to that ultimately desired state: "relaxed with pep".
- Distributed outward-facing value: any partial value we obtain from a shippable story we can start reaping the second it’s done. And in most — not all, but most — markets, customers love knowing that their products are getting steadily better.
- Idea-gathering from the field. Live feedback from humans outside your building is invaluable to establishing a good sorting of priorities for future work.
- Stress-testing early and often. Even if you are not literally pressing the Emit button, your developers are all seeing, using, and testing the code that is at head, because it’s shippable. You’ll detect problems long before they ever hit the user.
That’s a lot of benefit! But there are no free lunches. Pathing itself, to begin with, is hard, and it’s not taught or emphasized well, so it takes time to develop that skill. Further, there’s real technique involved in maintaining shippability, like TDD, refactoring, and so on.
But for me, and for many of the teams I work with, pathing provides more benefit than cost. I do it everyday all the time, at micro-scale in the code, and at the larger scale in feature development.
Experiment: you’ll have some feature in your near-term plans, a month or so work sometime in the next quarter. See if you can de-compose that feature into stories such that you honor both the size and the shippability constraint.
As you do it, ignore the little voice of the RAT: don’t worry about whether any given step changes something that was already changed in a previous one. Just make sure each step is shippable and small.
I genuinely believe you will be amazed at the results.
I spend a lot of time "pathing": decomposing a large problem into many small ones, each one constrained by size and shippability. I ignore RAT theory, and I get mad levels of effectiveness from it.
Supporting The PawCast
If you love the GeePaw Podcast, consider a monthly donation to help keep the content flowing. Support GeePaw Here.
Great stuff again GeePaw, thanks!
When I read the last sentence “I ignore RAT theory, and I get mad levels of effectiveness from it”, I’m pretty sure you mean “…I get mad levels of effectiveness from DOING SO”, as you have in the audio. Applying that clarification in the text might be useful for folks, WDYT?