Anticipated change does NOT occur (the system is left with costly, unused and confusing configuration mechanisms)

There is an attempt to extend the scope of the existing system to areas not covered by initial analysis (new lines of business, new territories)

Very often, despite the best efforts of talented developers, systems will not have adequately been prepared for the change that comes. Chaos ensues.

How can we do things differently? For one thing, we can take a very wide definition of which requirements should be regarded as volatile, and plan to support this in a structured way

Volatile requirements

Anything driven by regulation is volatile

Anything driven by “products” is volatile

Anything driven by markets and competition is volatile

Anything unique to the line of business, market sector, or territory should be regarded as volatile.

We can then analyse these volatile requirements and capture their variation in open-ended and structurally sophisticated configuration. We call this process modelling, and the configuration definitions thus obtained are models. Every effort goes into making modelling easy, so that as far as is possible, model change becomes a non-programming skill.

Enduring requirements are those aspects which are unlikely to change over a period of decades. For example:“In supporting any contract, we need to know who the contracting parties are”; “We will need to keep track of financial movements”;"We need to track changes in contract terms: when, and what changed".These are all fair candidates for enduring requirements: characteristics of the way in which business is done.

Enduring requirements should be supported by software applications that we call engines.

Engines provide raw, generic capability.

Models shape that capability into purpose-specific services.

When volatile requirements change, as we expect them to do, these changes are managed without change to the engines, purely as model change.

This is not to say that engines do not change: they do. But engines change only to extend generic capability. This means that engine change is exclusively a positive thing. This is hugely important. It means that as time progresses, we expect the engines to improve: extended capabilities, better performance, more flexibility in deployment.

Instead of systems succumbing to the ravages of time, they become more resilient. The effect of changing requirements is to strengthen the engine, not to weaken it.

Engines + Models = Services

Priority lists: can't escape them, can't trust them. As developers, we all make our lists: a list of issues to be triaged, a list of bugs to be fixed, a list of features to be implemented, but which to do first?

It seems so easy to just go down the list and assign a priority to each item, then to start work on one of those you have assigned the highest priority to. BUT:

We often confuse importance with urgency - an urgency-based priority list will often conflict with an importance-based priority. And both can be valid.

Whose priority? Yours, your client's, your co-worker's, your boss's? A client or colleague bashing down your door may in the end be just one voice among many demanding your attention.

Priority/Urgency/Importance may not be visible at first glance. A live production system bug may need to be triaged urgently, but may reveal an issue of low urgency.

Issues are often related to one another: often a single fix can hit several problems at once, each of which is of low importance but which taken together are a good use of effort.

Often a low-priority job may be tacked on to a high-priority job in a related area and so be addressed at a very low effort cost.

Priorities change over time: a task that may be useful to carry out today may have no value tomorrow: for example, a task needed by the month-end will increase in priority as the month progresses.

All this is bad enough when you are in control. When others (e.g. clients or managers) are in charge of the prioritisation process, things can become very frustrating as irrational choices are made on the basis of indadequate information.

So, is there a more rational way of choosing which job to work on next? The two extremes are the obvious approach: highest priority first; and on the other extreme, a random choice. In practice, nobody would run their daily lives according to either these extremes: most of us would arrange things so that low priority tasks simply took a smaller slice of our attention through the day. And so it should be with work priorities: it makes sense that even low priority jobs should receive SOME attention.

To make good choices here, you need good triage (and that deserves a write-up of its own): good decision-making needs good inputs, and it makes sense to think about what these inputs should be: a single crude "priority" rating is not enough.

I think that what is then needed is some sort of calculus of priority, whereby all the above considerations are included to work out the relative value of carrying out various jobs at different times, and an algorithm (formal or informal) that selects what items, performed when, would give the best overall result.

Good developers have good intuitions in this regard, have some knowledge of the target system, and would unconsciously weigh these factors in comparing candidate tasks, thereby getting a “sense” of when the time was right to tackle particular jobs. It's interesting to speculate whether this process could be assisted by smart "prioritising" tools.