There’s a particular kind of almost-strike called “work-to-rule.” It’s when workers in a factory “adhere strictly to all the working rules laid down by their employers, with the deliberate intention of reducing the rate of working.” Doing exactly what they’re told, and nothing else, means production grinds to a halt. Every formal system in life “is parasitic on an informal system.” We count on people to notice problems, to adjust and improvise in small ways.
The perfect example of work-to-rule is: every program ever. The computer always does exactly what it’s told, nothing less or more. This is incredibly hard to get right! Every human endeavor so far, we rely on people with local awareness. Your blueprint may be lovely, but it’s a construction worker who’s going to notice when the materials aren’t quite right and the walls aren’t fitting, and react to it. A person on the manufacturing line will see when the product is out of whack and correct it. They learned what “out of whack” means from someone else. There’s an informal system underneath.
In the program, there is no person on the ground when decisions are made at runtime. All of that awareness, everything that could go wrong and should be noticed, it all must be programmed in up front. That pushes all of the human context up a level: it’s the developers who supply all of it. We need to understand the program’s environment, the business context, the data, everything. Which problems matter? What can we fix, and what should halt the whole operation? What clues can tell it “this is out of whack?” How will our program react to surprise?
This means all the creativity and conscientiousness and context of all the runtimes is crammed into the development at code-time. The team communication, the adjustment, the humanity: maximize this on the development team. Because we need every ounce of this we can get of this going into the code. It’s all we have to lean on.
We’ve seen from the waterfall process what happens when we try to create a program based on a written set of requirements. Create a development process with a bunch of rules and regulations, emphasizing vertical (in the org chart) communication, and what will you get? That program is already work-to-rule. When the people coding it are also working-to-rule, to any degree, then the code is brittle and unresponsive, just like the production output of a plant whose workers are on this almost-strike.
Be careful about the rules we impose on development. Communication YES, knowledge sharing YES. But let the rules be the ones the work itself imposes. Blind adherence to standards, that’s what the computers are for.
 Seeing Like a State, James C Scott. Introduction.
There are these wineglasses that my partner likes. They’re pretty, but they’re so tall they only fit in the cupboard above the fridge. He can reach that cupboard, but I have to fetch a stool to get in there. He uses these glasses all the time, while I always choose the squattier glasses that I can reach unaided. It’s free (in time costs) for him to use the pretty glasses, expensive for me.
At work, what tools do you reach for that your coworkers don’t? Or do some of them have tools that you ask them to use for you, because they understand them and you’d have to look stuff up?
When something is free, we use it all the time. Once we do that, we get benefits never thought possible. Branching in git is like that. Autocomplete as a way of exploring an API. Some of us use grep and cut to explore log files, because we know these tools well enough that it’s just as easy as opening the file and searching inside. At a previous job, I was the fastest at production support because I built up a library of SQL joins that tracked down the useful data.
When we take the time to learn a new tool, it’s like we get taller. We can bring down answers and build solutions that were out of reach before. That’s not an option for me with the wine glasses, but it is with Chef and Jenkins, Graphite and the Typesafe Console, Kleisli and Liebniz (strange scalaz types).
Learning a new tool might feel like yak-shaving. Learn it well enough that it’s free (no cognitive load), and you just gained a few inches on everyone else.
In computers and in people, weakness and vulnerability are different. Separate the concerns: 
Vulnerability is an openness to being wounded.
Weakness is inability to live through wounds.
In D&D terms: vulnerability is a low armor class, weakness is low hit points. Armor class determines how hard it is for an enemy to hit you, and hit points determine how many hits you can take. So you have a choice: prevent hits, or endure more hits.
If you try to make your software perfect, so that it never experiences a failure, that’s a high armor class. That’s aiming for invulnerability.
Thing is, in D&D, no matter how high your armor class, if the enemy makes a perfect roll (a 20 on a d20, a twenty-sided die), that’s a critical hit and it strikes you. Even if your software is bug-free, hardware goes down or misbehaves.
If you’ve spent all your energy on armor class and little on hit points, that single hit can kill you.
Embracing failure is about letting go of ideal invulnerability, and thinking about recovery instead. I could implement signal handlers, and maintain them, and this is a huge pain and makes my code ugly. Or I could implement a separate cleanup mechanism for crashed processes. That’s a separation of concerns, and it’s more robust: signal handlers don’t help when the app is out of memory, a separate recovery does.
In relationships, vulnerability lets us form connections. When emotional defenses are high, deep communication doesn’t happen. If we leave ourselves open to hurt, if we take that risk, there are payoffs. If we build a network of honest, compassionate friendships, those friends become our recovery mechanism for when we do get hurt. Friends who hug you and say “You are good. I love you.” Fall in love, get burned, cry to my people and be comforted.
In the software I currently work on, I take the strategy of building safety nets at the application, process, subsystem, and module levels, as feasible. Then while I try to get my code right, I don’t convolute my code looking for hardware and network failures, bad data and every error I can conceive. There are always going to be errors I don’t conceive. Fail gracefully, and pick up the pieces.
 Someone tweeted a quote from some book on this, on the difference between weakness and vulnerability, a few weeks ago and it clicked with me. I can’t find the tweet or the quote anymore. Anyone recognize this?
 Brené Brown on Vulnerability. Twenty minutes that can change you or affirm you.
 The actor model (Akka in my case) helps with recovery. It implements “Have you restarted your computer?” at the small scale.
I’m going to post a condensed version on my real blog.
Something I love about agile and iterative development: acknowledgement that software is never done. It’s never the best it could be — even if it were, “best” changes quickly. A typical project is “done” by decision, not by any inherent completeness. We could always improve.
There’s a beauty in that, an embracing of imperfection and balance. And there’s a dichotomy of striving that defies traditional goals. Within any iteration and any one day, there’s a victory condition of completing a feature or small set of changes. Small victory conditions, achieved all the time. At the same time there’s a larger direction: a striving for software that delights people who use it. This is the Unreachable Star of an agile project, the target that is always in the distance, always moving away from us.
At the same time, within the team, there’s work toward becoming better as developers individually and collectively. Each retrospective has its victory conditions of the week, and we always find more ways to improve. The Unreachable Star is perfect communication, productivity, creativity. We aim for it, yet if we ever think we’ve achieved it, we stop growing and instantly fail.
Contrast with waterfall projects, which define “success” as a particular featureset by a particular date. Work really hard for a long time! Hit the milestone (if you’re really lucky), put up a banner, and then miss the real target. Software developed in isolation never delights people who use it. And then what? Athletes who work their whole lives and finally win gold - then what? Victory is fleeting, so keep it small and frequent. The big-milestone strategy lacks the vision of the Unreachable Star and the daily satisfaction of meeting victory conditions.
This works for me in life. Every day I have small victories, like writing this post, tweeting something that is meaningful to me, completing a task, hearing my daughter laugh. In the larger scale, I don’t have “goals” that I work toward blindly only because I set them for myself. Instead I have Unreachable Stars: as a developer, to keep learning higher levels of abstraction and to share it with others; as a partner, to be completely honest with my connections; as a mother, that my children know I love them and can grow in directions of their choosing.
There are many paths toward my Unreachable Stars, sometimes too many (property-based testing! scalaz-streams! clojure!). It isn’t important which I follow, nor is it important that I head straight there. Any small step in the general direction is a victory. If I define a milestone of some sort (“speak at conferences”) and then achieve that, it’s another victory for the day. If I don’t achieve it, there are many other paths to the Star. No milestone, achieved or missed, can end the quest.
Big milestones (what most people call “goals”) are valuable in defining a strategy toward the Star. They give us something to break down into our daily victory conditions. That’s all. They’re not the real objective, and they can distract us if we’re not careful. It is the mission, the quest, the target-that-is-only-aimed-for-never-reached, that inspires me.
I’ve been looking for a word for this, for the target that sets my direction with no expectation of hitting it. The song from Man of La Mancha, sung by Don Quixote, expresses it. Even in his delusion he has no expectation of fixing the world. Yet he finds happiness in every small move he can make toward rightness. Others are inspired by him, and start to move the world in their small ways. He spread hope, and so became larger than one person.
"And the world will be better for this, that one man, scorned and covered with scars, still strove with his last ounce of courage to reach the Unreachable Star."
- this is a direct parody of @unclebobmartin’s post, “Where is the Foreman?” -
The nanny in a household is the lady who is responsible for making sure all the kids do things right. She’s the lady with the tape-measure that goes around making sure all the clothes fit properly. She’s the lady who examines all the hair, teeth, and floors to make sure they are clean, and don’t have any significant food particles. She’s the lady who counts the buttons on the jackets to make sure they won’t gap open when they’re worn. She’s the lady — the lady who takes responsibility — the lady who makes sure everything is done right.
Where is the nanny on our software projects? Where’s the lady who makes sure all the tests are written. Where’s the lady who makes sure that all the exceptions are caught. Where’s the lady who makes sure all the errors are checked, and that references can’t be null, and that variables are thread-safe? Where’s the lady who makes sure that the programmers are pairing enough, talking enough, planning enough? Where’s the lady who keeps the food off the floor?
Without a good nanny, a nursery would fall apart into chaos. The children wouldn’t line up. The jackets would hang askew. The pants would be on backwards, and the underwear on the outside. Without a good nanny the diapers and the cups would both leak, and the whining of babies would be heard in the drawing room. Without a good nanny the children would get to school very late, with a huge mess left behind them, and have abysmal outfits.
Without a nanny, the floors would be covered in food.
What would the nanny do on software project? She’d do the same thing she does in a household nursery. She’d make sure everything was done, done right, and done on time. She’d be the only one with commit rights. Everybody else would send her pull requests. She’d review each request in turn and reject those that didn’t have sufficient test coverage, or that had dirty code, or bad variable names, or functions that were too long. She’d reject those that, in her opinion, did not meet the level of quality she demands for the project.
I imagine that many programmers recoil in horror from the idea that someone else would have the power to judge their code and reject their commits. After all, how can you get done on time if the code has to be right? How can you possibly meet your schedule if you have to write all those tests? I mean, if there’s a lady who’s actually going to look at the code, then there’s no way to make yourself look good by saying that the code is done when it’s not. It’d be awful.
Awful or not, it’s what most industries do. If you want to get a project done, done right, and done on time, you need a nanny. And that nanny has to be so technically astute that she can check the work of all the workers. She has to have the authority to reject any work she considers sub-standard. And she also has to have the power to say “No” to the unreasonable demands of the customers and managers.
Where is the nanny on our software projects? Where is the lady with the commit rights? Where is the lady who makes sure all the tests are written, and all the concerns are separated, and all the right dependencies are inverted?
Why don’t we have this lady?
Is it any wonder that our floors smell like breakfast?
Gendered language matters. It matters to who feels like they belong, who feels like they should be in charge. If you are skeptical of this, please please read (or at least skim) this satirical piece by Douglas Hofstadter:
"Politics and culture often function as ‘prisonhouses’ of knowledge… yet they can and often do function as ‘toolboxes,’ enabling new perpectives."
A framework places restrictions on what we do. It makes decisions for us. This makes our lives easier. And it’s OK, when we choose the framework, and we consciously accept those limitations. Libraries, on the other hand, only support us in our decisions. Sometimes that’s all we need.
Each of us lives in a cultural framework. We didn’t choose it, we just grew up in it. It’s the way we know, the “obvious” way things are. Yet, there are people around us whose circumstances aren’t the same. People of a different class, race, gender, or background. They grew up in a different cultural framework. They know some things we don’t. If we recognize this, we can learn those things. Like using pieces of Angular within your Bootstrap site. You can’t switch frameworks, but once you realize that other frameworks exist, you can use bits of them like libraries.
 The Feminist Standpoint Theory Reader, Sandra Harding. Introduction.
Children ask “Why?” and when you answer, they say “Why?”
It’s “Why” all the way down with them, sometimes. There is no end.
As an adult, we ask “Why?” now and then, and pretty quickly we get to “In my observation, it has already worked this way.” This isn’t a reason, but it is a heuristic that works, and it lets us get stuff done.
This happens in programming, too. When pairing, a curious beginner asks, “Why do we do it this way?” and the senior programmer says, “YAGNI.” and the beginner asks, “Why?” A philosophical discussion ensues, and the senior programmer is bored and frustrated. She wants to write some code!
In her observation, you ain’t gonna need it, so code it the simple way and move on. The beginner wants to investigate the concepts and learn. They’re both right. Both are good uses of time… but maybe not this time right now. Adults get stuff done, curious beginners (such as children) learn.
In a board game the other day, my partner went for the direct route of “How can I get points?” while I went the indirect route of “How can I give myself more options for later?” I won that game.
Those of us who continue to question will win in the long term. Yet, as adults can know when it’s time to go on experience. The best of both is to reflect on our work later, question our assumptions and dig into the “Why?” and the “Is there a better way?”
Conferences are great for this. Step back and reflect, learn new viewpoints, and discuss. We are grownups most of the time at work. Go to development conferences, and be a kid. Play! Expand your options and connections and keep asking “Why?”
In real life, people struggle to hear, categorize, and remember stories that don’t fit one of the traditional narratives. A story of an open marriage that didn’t work out, where complete honesty wasn’t enough to bring acceptance for romantic love in the plural, where love died gradually until by the time the danger was recognized it was too late
becomes “he cheated and chose his girlfriend over his marriage.” Not the truth, but it fits the pattern, people can classify that and talk about that. Simple models, we like simple models, who cares about accuracy if it’s a nice simple model?
There are accepted narratives in software, too. The web application. The algorithm. The formal scrum iteration or the mostly-waterfall model. The agony of Release Week. When a project or framework or (what can we even call it when there are no clear application boundaries?) breaks out of established modes of computation, when User Acceptance Testing no longer makes sense, how do you even explain that to people?
"I don’t see how this could work. This doesn’t make sense. Stop it." If we can’t see the reasons for something, there must not be a reason. That person is stopped in the middle of the parking lot because they’re an idiot! There is no other explanation in my simple model!
I grow beyond myself when I am small in the world. Everything happens for a million reasons, and I might know a few, but usually I’m wrong. New ways to see, new ways to think, new ways to learn things I could not conceive before, this is the goal. In relationships and in computing.
A good novelist makes every piece of the story essential to the final resolution. Each event described in the book leads up to one big finale. That’s a good narrative.
We like to see the past in that light. We like to believe everything happens for a reason, and that reason is to get things where they are right now. “It was good this guy broke up with me, because I wouldn’t be who I am now otherwise.” Like the present circumstances are superior somehow to all the alternatives that don’t exist. It was all meant to be, we like to believe.
Kanban suggests we apply this model to the future.
"The first rule of kanban is that the later process goes to the earlier process to pick up products" ~ Taichii Ohno
That is, pull model: start with the customer demand. Figure out what we must do to meet that (deploy), what is the prerequisite for that (testing), what is the prereq for that (code), and so on down a forking chain. Anything not in demand by the next step in the process is busywork. If repairing your development environment is needed to write the code effectively, then it is not yak shaving. If you’re distracted by all the code formatting options, that is the non-work that seeps in to distract us from the end goal.
This is harder than we think. It’s harder because it is not the way the real world works. The Gulf of Mexico doesn’t suck water from the Mississippi River, and the river’s tributaries don’t pull rain down from the sky. This is not how the past works either: all those “it was meant to be” warm fuzzies are a coping mechanism to help us accept the past. Causality runs forward in time. Things are the way they are because they got that way. Everything happens for a reason - usually a million reasons - and every one of those reasons existed before the result. Not after.
Yet, the first rule of Kanban is right. When we’re aiming for something, when we’re building our project’s narrative, we can set up the causalities. Plan backwards, work forwards. If we aren’t careful and deliberate, then our work will emanate from our current situation, as reality does. Water will flow down the path of least resistance. We’ll have pretty colors in our IDE and a feature that no one asked for. Conscious effort can direct our flow.
And be careful to check over and over that our destination is still where we most want to go. Check, re-aim, and proceed down the shortest path from the new-here to the new-there. Otherwise we’re back to Waterfall.
Our project history may never read like a good novel, because we should change our minds on the best ending, and we don’t go back and edit the first chapters. Yet, if we think about it that way - how can all the characters on my team be important to the final solution? - we might get somewhere faster, and be part of a story bigger than ourselves.