The Modernisation Control Papers — 06

Modernisation should be sliced by risk, not repository structure

A completely new application can be built through a sequence of bounded engineering work. This paper examines how consequences, dependencies, useful learning and recovery should shape that sequence.

Illustrative Harten Modernisation Control Paper 06 cover: Modernisation should be sliced by risk, not repository structure, by Lavan Nallainathan. A business flow branches into candidate work packages with illustrative risk, dependency and value indicators, leading to a proposed modernisation plan. The indicators are conceptual, not measured results.
Illustrative cover artwork, not an application screenshot or a record of measured results.

What This Paper Examines

Once an organisation has chosen the application it wants to build, it needs to decide how the engineering work should proceed. Dividing the backlog by repository or component makes allocation straightforward, but can leave important behaviour untested until those pieces are joined. Using an illustrative payments service, this paper examines how to organise work around the decisions that affect customers, the dependencies that must work together and the evidence needed before the new application takes responsibility. The replacement can still be completely new. The purpose is to distinguish its architecture from the order in which we build, verify and introduce it, so each completed piece of work supports a specific next decision.

A New Application and a Familiar Delivery Plan

Imagine a team preparing to replace an established payments application. Customer instructions arrive through one part of the system, validation happens in another, and a later process sends accepted payments for settlement. Staff use an operational queue to investigate instructions that cannot proceed automatically. Several repositories, a shared database and scheduled jobs support that work. The service is familiar to its operators, but the reasons for some of its technical divisions have become less clear over time.

The organisation has already agreed what the future service must do. It has distinguished necessary controls from workarounds, examined alternative designs and decided to build a new application. The replacement does not have to preserve the existing repositories, programming language or database layout. Engineers can give it a different internal structure, provided it satisfies the approved requirements and can be operated effectively.

Then the delivery plan arrives. There is a workstream for customer instructions, another for validation, another for settlement and a separate database migration. Each has an owner, an estimate and a set of milestones. This looks manageable because it resembles the material the team already knows how to assign. It also risks making the inherited implementation the organising principle of a programme that deliberately chose to move beyond it.

Suppose the validation repository is selected first because it is small. The new code will read account information, apply the payment rules and return a decision. That sounds like a contained deliverable. Yet the decision can allow money to move, send work to an operational queue, change a customer notification or determine what a later settlement process does. Finishing the repository will not, by itself, establish that those consequences are correct.

This is the planning question that follows How to build a new application and keep it evergreen. We have the freedom to build a new implementation. How do we use that freedom without postponing the most consequential questions until the end of the programme?

Three Different Boundaries in the Same Programme

I would separate the boundaries of the application, the boundaries of the engineering work and the boundaries of a live release. They are related, but they answer different questions. The architecture describes responsibilities and interactions in the application we intend to operate. A piece of engineering work establishes or changes something we need on the way there. A release determines what the running application is permitted to do for actual users.

For example, the new payment decision and the explanation shown to an operator might belong in the same application. Engineers can still develop and check those responsibilities through smaller pieces of work. They might first establish the treatment of an operational hold, then exercise the complete decision path with representative instructions, and then examine how the explanation survives a retry. None of those choices requires a separately deployed service or the extraction of the old validator.

Equally, completing a piece of engineering work does not require giving it authority over live payments immediately. An executable path through the new application can be tested against controlled inputs while the existing application continues serving customers. A shadow comparison may later provide additional evidence. The organisation can then choose a single rehearsed introduction or a staged transfer, according to the service's actual constraints.

Here, a slice means a bounded piece of work with an identifiable outcome and a way to examine it. It does not mean a thin copy of one legacy component. Nor does it mean reducing the programme to a pilot and leaving the intended replacement unfinished. A team can build the whole new application while deliberately ordering the questions it resolves and the responsibilities it exercises.

DORA's guidance on working in small batches describes using smaller units of work to shorten feedback and revisit assumptions. The application here is to modernisation planning: choose units that expose important behaviour early, rather than interpreting a small batch as an arbitrary number of files or a compulsory microservice boundary.

Three views of the same payments application: its target responsibilities, a bounded engineering task that checks operational holds across those responsibilities, and a separately approved transfer of live payment authority. Smaller tasks do not require separate services or immediate releases.

Figure 1. The target architecture, the scope of an engineering task and the scope of a production release need not have the same boundaries. A team can build and verify behaviour across the new application before allowing it to control live payments. View the diagram at full size.

The Payment Decision That Changes the Plan

Consider an instruction that would normally be eligible for automatic processing. Its account is active, its amount is within the applicable limit and the ordinary validation checks pass. Before the instruction proceeds, an operator places it on hold because something requires investigation. The future requirement says that this hold must prevent automatic release until an authorised person removes it.

An implementation can calculate the ordinary validation result correctly and still mishandle that situation. It may read the account before the hold is recorded, return a positive result and allow a later process to act on information that is no longer current. It may preserve the hold in the database but omit the reason from the operational queue. It may send a customer message that describes completion before settlement has actually occurred. These are different defects, although all can begin with a small change in the decision path.

A payment calculation reads inputs before an operator records a hold. The earlier calculation returns a positive result, but the payment must remain held and must not be sent for settlement. An authorised person must remove the hold before release can be reconsidered.

Figure 2. A calculation can be correct for the information it read and still be insufficient to authorise a payment. The engineering work must establish that an operational hold prevents release, including when the hold arrives during calculation. View the diagram at full size.

That leads to a more useful first piece of work than simply replacing a function. The team needs to follow an instruction from the information used to assess it through the decision, the relevant state change and the response seen by its consumers. It needs to establish how an operational hold affects that sequence and how an outdated calculation is prevented from authorising the next step. The work may touch several components of the new application because the behaviour crosses those components.

We do not have to implement every payment category before investigating this. We can choose a representative category and include the conditions needed to challenge the particular design. What matters is that the boundary is explained. Excluding an unusual payment type can be reasonable; excluding every corrected instruction would be a poor way to test a design whose main uncertainty concerns corrections.

The organisation should also decide which questions belong to engineering and which concern the service itself. Engineers can propose how to enforce a hold. They cannot decide that a hold no longer matters simply because removing it makes the first release easier. The work package needs to carry the approved meaning of the control, not merely a description of the code to produce.

Consequences That Extend Beyond the New Code

A useful plan follows both incorrect approvals and incorrect refusals. Allowing a payment to proceed when it should be held is an obvious concern. Referring legitimate instructions for manual review can also matter if it delays customers or creates more work than the operational team can handle. A fallback that sends everything to a queue needs an account of what happens to that queue, rather than an assumption that a person will absorb any increase.

The same applies to the scope of an initial release. A low-value payment category may reduce the consequence of one mistaken decision, but a sustained stream of such decisions can still create substantial exposure. A small percentage of traffic may also share an account-level limit or a common downstream service with the remaining traffic. The team needs to understand those connections before describing the population as isolated.

For our example, I would want the plan to state which instructions are eligible, which account and policy information they depend on, where the authoritative decision is recorded and which external actions remain disabled during verification. That tells engineers what the work is allowed to affect. It also gives operations something concrete to challenge: whether the proposed limits actually contain the failure the team is concerned about.

This does not require the same depth of scrutiny for every change. Updating the wording of an internal diagnostic message is different from changing the condition that releases a payment. Even that distinction depends on how the message is used; an automated consumer might interpret it as a status. The point of following the consequence is to make proportionate decisions, not to declare every alteration high risk.

Choosing Work That Resolves an Important Question

There are several credible places to start. A read-only reference-data capability could establish how the new platform handles identity, configuration, deployment and monitoring. A payment decision path could test whether the reconstructed rules and available data are sufficient. A controlled settlement integration could establish whether acknowledgements and retries can be reconciled. Their value depends on which uncertainty is currently preventing the team from making progress.

I would resist choosing the validator automatically just because it appears central to the example. If the team cannot yet deploy and observe anything in the target environment, that may be the immediate obstacle. Conversely, another polished demonstration of the platform will add little when the unresolved question is whether an operational correction is respected. The first work should address the assumption whose failure would otherwise cause significant redesign or delay.

The distinction is practical. Before committing substantial effort to a proposed interaction between decision-making and settlement, the team can exercise the uncertain behaviour in a controlled environment. It can examine a retry after an acknowledgement is lost, or a hold arriving while a calculation is running. Those results may confirm the design or show that it needs to change. Either outcome is useful before the same assumption is repeated throughout the replacement.

The work must nevertheless produce something the programme can use. A succession of exploratory exercises with no connection to the intended application is not a delivery strategy. A useful result might be an implemented decision path, a reproducible test of a disputed rule, a working integration contract or an operational procedure exercised with the people who will use it. Each should have a clear relationship to the application being built and the next commitment the team is considering.

Dependencies and Parallel Engineering Work

Repositories can still be useful for assigning work. They identify source ownership, build arrangements and places where engineers need to coordinate. The mistake is treating those technical boundaries as sufficient evidence that two workstreams can proceed independently. Separate repositories can depend on the same unresolved interpretation of a payment status, while two modules in one repository may be developed independently against a settled contract.

Suppose the new application needs to distinguish an instruction that has been accepted for processing from one whose settlement has been confirmed. The interface team, the notification team and the settlement integration all depend on that distinction. Allocating each to a different team does not remove the dependency. If each invents its own interpretation, the programme will discover the disagreement during integration, after it has been implemented several times.

I would resolve that meaning and establish representative examples early. The teams can then work in parallel on the interface, notifications and integration, checking their work against the same requirement. Where the contract remains provisional, that fact should be visible to the people relying on it. They can choose whether to explore with a temporary assumption or defer consequential implementation until the question is answered.

AI-assisted engineering makes this especially important. Several agents can produce large amounts of individually plausible code around an ambiguous interface. Their speed is useful when the contract is clear and their work can be integrated and examined. It is less useful when it multiplies incompatible interpretations. An engineer needs to decide what can be delegated independently and where the participants must share a settled decision before proceeding.

The intention is not to make all work sequential. It is to avoid paying for the same uncertainty several times. Parallel work should follow the dependencies in the behaviour and the design, with integration evidence returning early enough to influence what happens next.

Recovery Before the Application Takes Responsibility

The order of the work also depends on what recovery will require. While a candidate decision is being calculated without authority over the payment, stopping the comparison can leave the established service in control. That is a useful arrangement, provided the comparison itself cannot issue instructions, update authoritative records or overload a shared dependency. Shadow operation still needs engineering limits.

Once the new application accepts instructions or sends messages to settlement, returning to an earlier software version is a different proposition. The team has to account for what the new version has already done. Some instructions may be waiting locally, some may have been acknowledged externally and others may have an uncertain outcome because communication failed. A traffic switch does not resolve those states.

The programme therefore needs to develop recovery alongside the relevant behaviour. Engineers should be able to identify affected instructions, establish the authority responsible for each and decide whether the service can return to an earlier path or must recover forwards. A temporary adapter may help preserve a contract during introduction, but it needs an owner and a reason for eventual removal. Otherwise the new application can inherit another permanent dependency nobody intended to maintain.

Google's guidance on canarying releases describes evaluating a limited production deployment before proceeding more widely. That supports the idea of bounded exposure. It does not establish that a payment already sent can be undone. In our example, evaluating the release and recovering the business state are related responsibilities that need separate evidence.

The Work Engineers Can Delegate to Agents

An agent can help trace where a decision is used, identify candidate dependencies, prepare an implementation and generate cases that exercise a proposed boundary. It can also compare recorded outcomes and assemble the material an engineer needs to investigate a disagreement. This can make a thorough first piece of work more achievable, rather than requiring the team to choose something trivial because investigation is expensive.

The task should still state the intended outcome. Asking an agent to modernise the validation repository leaves it to infer what must remain true beyond that repository. Asking it to implement the agreed payment decision, preserve operational holds and demonstrate the relevant failure cases gives it a much better basis for useful work. The engineer should provide the authorised requirements, current source baseline and external contracts that support that request.

The same agent generating both the implementation and its tests can carry one mistaken assumption into both. For a consequential rule, expected outcomes need a basis outside the generated code: an approved requirement, a reviewed operational case or an independently established contract. The tests then challenge the implementation instead of merely describing what it already does.

A bounded task can still leave the agent considerable freedom over implementation. Engineers do not have to prescribe every edit. They do need to retain responsibility for requirements, acceptance and any increase in live authority. This becomes the immediate connection to the next series, which examines what software agents may decide and do within those boundaries.

What the Programme Should Be Able to Show Next

At the end of an early piece of work, I would want the team to show more than completed components. It should be able to explain which behaviour now works, which important assumption was examined, what the result allows it to attempt next and what remains unresolved. That does not replace delivery reporting. It makes a claim of progress more useful to the people deciding where to commit further effort.

For the payments replacement, a checked decision path might establish that operational holds survive concurrent calculation and that operators can explain the result. A later integration exercise might establish how an uncertain acknowledgement is reconciled without issuing a duplicate instruction. The programme can then make a better-informed decision about live responsibility. The application remains a new implementation throughout; the sequence concerns how engineers establish and introduce its required behaviour.

The supporting papers develop that work in three stages. 06.1, A small code change can have a large consequence, follows the payment decision beyond its function to establish the real scope of the change. 06.2, Choose the first slice for what it teaches you, compares possible starting points and the decisions their results would support. 06.3, Planning recovery before a new application changes live data, examines what happens after the replacement has begun to affect authoritative records and external systems.

These are also habits worth retaining after the first release. A later policy change, integration replacement or complete rebuild should begin with the same ability to identify affected behaviour, organise useful engineering work and examine its consequences. That is how the delivery plan supports the evergreen direction introduced in Series 05, rather than ending when the replacement goes live.


Editorial update, 2 November 2026: Added two explanatory figures to the existing payments example. The published reasoning and recommendations are unchanged.

The payments service, requirements and proposed checks in this paper are illustrative. They are not a customer case study or a report of measured delivery results. External references support the specific engineering practices attributed to them; the planning recommendations are developed through the example.

This paper is part of The Modernisation Control Papers, the first major sequence within The Harten Papers. Read the complete series on harten.io.