The pit of success, in practice

Doing the right thing should be what happens by default. Leaving the path should be possible, but harder. A short list of what that means in practice.

Articles By

Jeff Atwood wrote about the pit of success in 2007, borrowing a term Rico Mariani used about language design at Microsoft. The idea is simple. Most systems ask people to climb towards good practice and punish every slip. A well-designed one is a pit. Do nothing special and you fall into the right way of working.

Atwood’s line is the one worth keeping. A good system “makes it easy to do the right things and annoying (but not impossible) to do the wrong things”. Experienced people sometimes need to leave the path, and that’s fine. It should just take a deliberate step.

He didn’t say what any of that looks like day to day. Here’s what I’d point to.

Sensible defaults

Every library, template and config has a default, and the default is what most people will use forever. So the default should be the recommended choice. The HTTP client has a timeout. The storage module has encryption and backups switched on. The new service template already has tests, linting, logging and CI wired in. Nobody has to know these things exist to benefit from them.

Ugly opt outs

Leaving the default should be visible and slightly embarrassing. An option called allowInsecure, a lint suppression comment that needs a reason, Rust’s unsafe block. The name does the teaching. Anyone reading the code later knows the author chose this on purpose and that it’s not the recommended route. It also makes the exits easy to count, which tells a team where the defaults need work.

Do the work up front

A pit has to be dug. Somebody spends the time making the template, writing the module, setting up the pipeline, and then keeps it maintained. Teams often skip this because the payoff is spread thinly across everyone else’s week. It’s still the highest leverage work on most projects, and when a default rots it’s worse than none at all, because people still trust it.

One command

Running the project, running the tests, deploying. Each should be a single short command that works on a fresh machine. If getting started means a wiki page and an afternoon, people will find a shortcut, and the shortcut becomes the real process.

Don’t make people remember credentials

The same applies to secrets and environment variables. If the right way to run something needs six values copied from a password manager, it’ll get done once and then hard-coded. Put secrets in one place the tooling reads from, and make the local setup script fetch what it needs. The path of least resistance should also be the safe one.

A test to apply

For any practice that matters, three questions. What happens if someone does nothing? How many steps does the right way take compared with the wrong way? When someone leaves the path, does anyone find out?

If the answers are “the right thing”, “fewer” and “yes”, the pit is in the right place.

References