It’s good to be in the mix. If you want to be an architect, I highly recommend being embedded somewhere long enough to see a system die. That experience will change you as a programmer; there really is nothing quite like watching an ancient, code-crufted beast fall over under its own weight as an organization shifts underneath it.

Because the thing is, requirements change. Constantly.

And since we’re the ones pushing for that last 20%, nobody knows that better than us. Packaged-application developers might see specs change until they are frothing at the mouth, but that system that they engineer to within an inch of its life can quickly become outdated or find itself mothballed. Maybe two weeks after implementation someone will realize that the requirement that drove its implementation went away again, or never really existed in the first place.

Meanwhile, business people who “own” (are accountable for) systems that they do not use are beyond fickle. They pitch ideas without ever seeing the system in use. They have a vague idea based on conversations with people whose assumptions go six layers deep, and they only “get” layer seven, which blows away at the first sign of a breeze.

So when someone builds the wrong system, or someone specs the wrong system, or someone implements the right system the wrong way, it’s always the maintenance guy who ends up pulling it out, dusting it off, and chucking it on the chin so it can serve a purpose after all. Call it cost savings, call it repurposing, call it laziness. Any way you call it, it’s a kind of pursuit of excellence that looks, to outward appearances, like contentment with mediocrity.

In contrast with that last 20% of functionality, where the problem is You Can’t Please All the People, what’s really happening in the case of software salvaging is Requirements Are Hard. Agile people get this to some extent – they require that someone from either the developer or the customer “live” at the other party’s environment. What this does, theoretically, is short-circuit the refinement process for requirements – the embedded developer can watch people at work and validate assumptions about workflow and develop an implicit understanding of what people are doing, while the embedded customer can look at the software at its most malleable and respond to its state without needing to undertake analysis.

In both cases, simple usage suffices – a software user using software will always be the best engine of discovery for poorly-drawn requirements.

The maintainers of the world, the programmers-in-the-middle, we live in that place. Always, every day, we can look at what those around us are doing and make the requirements tighter. Maybe it requires a daily walk-around or a cultivation of friendships with the internal user group, maybe it requires some assumption of duties related to the program in use. But the opportunity to learn requirements analysis will never be better than it is when you live in the middle. It’s a skill that gets better as you learn more about more functional areas, as you learn more about more kinds of users, as you support more pieces of software. It’s a good place to be, even if you don’t always want to be there.