Making Scope Explicit

As a young software engineer, I learned three variables by which to manage projects: speed, quality, and price. The sponsor gets to fix two of these variables and the team gets to estimate the third. If the plan is unacceptable, the negotiating starts. This model doesn’t work well in practice. Time and costs are generally set outside the project. That leaves quality as the only variable you can manipulate. Lowering the quality of your work doesn’t eliminate work, it just shifts it later so delays are not clearly your responsibility. You can create the illusion of progress this way, but you pay in reduced satisfaction and damaged relationships. Satisfaction comes from doing quality work. The variable left out of this model is scope. If we make scope explicit, then we have a safe way to adapt, we have a safe way to negotiate, we have a limit to ridiculous and unnecessary demands.

—Kent Beck, Extreme Programming Explained

I spent all last week working on my web server. It’s a fun project so far, filled with the joy of taking something apart and looking inside to see how it works, but it’s also been a challenge: I had a long checklist of features to implement and only a week to get them all working.

Even though I was still frantically coding on the train to work the day of my demo, I managed to check off all the boxes. Like the 100% test coverage my project reported, 100% box coverage felt great—like the satisfaction of crossing the last item off a long to-do list. But as any test-driven developer knows, even 100% test coverage can’t guarantee that a project will work. This week I learned that box coverage is the same: ticking off features is no guarantee of quality.

Sure, my server met the requirements, but much of the code wasn’t pretty, and I knew it. And though I was proud of the progress I made and looking forward to showing off my work, the demo went off the rails early on, when the server hung and crashed trying to handle concurrent connections. (If you’re thinking of using Thread.run(), you probably want Thread.start(), by the way). In an instant, all the little details I’d put effort into—nice looking directory pages, support for extra headers and obscure content types, clean request parsing under the hood— were outweighed by one big defect.

The attitude towards quality at 8th Light is clear: quality is non-negotiable, we will never ship software with known defects, and when an unknown one slips by, we’ll fix it for free. That leaves scope as the only free variable in the planning and development process. Although the scope of my web server project was already explicit, I didn’t do a good job negotiating. In retrospect, it’s clear that showing a clean, stable server that only handles GET requests is a greater accomplishment than one with extra bells and whistles that’s prone to random catastrophic failure. But it sure felt good to check off all those boxes.

I’ve learned two lessons over the last week: first, quality and stability matter most. Never sacrifice quality, and never ever tolerate unstable code. Second, renegotiating and giving feedback is part of making scope explicit. Trading off quality for features is guaranteed to be a bad bargain.

Comments