The Modernisation Control Papers — 05.1
Find the boundaries the system actually has
Why an eligibility service might have three repositories, what a policy change reveals about their dependencies, and how engineers can use that evidence to choose boundaries for a new application.

What This Paper Examines
Separate repositories can make code easier to organise without making the business process easier to change. This paper follows an illustrative household-income policy change through an eligibility service to examine where those two things differ. It considers why the original separation may have made sense, how AI can help trace dependencies, and what engineers still need to establish with the people who own and operate the service. The provisional conclusion is that rules, case state and authorised corrections may belong together in the replacement, while reporting may support a separate boundary. By the end, the reader should be able to explain what would justify keeping or changing an inherited boundary, and what evidence a new design still needs.
Why the Service Might Have Three Repositories
Imagine an eligibility service that helps an organisation decide whether an applicant qualifies for support, partly by assessing household income. Its code sits in three repositories, each holding a separately managed part of the source and its change history. One contains the public-facing application, another the calculation component, and the third reporting. Each has its own build, and different people have contributed over the years. This is an illustrative scenario, but there are plausible reasons why a team might have organised the work this way.
The original developers may have wanted to separate concerns. Changes to application screens could be reviewed without disturbing specialist calculation code, while the people producing reports could work to a different schedule. Different technologies or supplier responsibilities might also have made separate repositories useful. We should establish which of those reasons actually applied through architecture records, release history and conversations with the people involved. The repository layout alone cannot tell us why the decision was made, whether it achieved its purpose or whether the same constraints still apply.
The starting arrangement in this illustrative service. Reasons for the original separation remain questions to investigate; the three source repositories do not, by themselves, establish three independently deployable services. View the diagram at full size.
Now the modernisation team is considering how to design a replacement. Giving the calculation its own service seems reasonable: it already has a name and a recognisable purpose. A proposed household-income policy change provides a way to examine that boundary. The policy team needs to understand how the revised threshold will affect applications already in progress as well as new ones, and following one case takes the developers beyond the calculation repository.
The public application validates part of the income data before the calculation runs. A stored procedure derives a value saved against the case, reporting uses its own view of that value, and an overnight process revisits certain decisions. When applicants provide information late, an operations team can correct cases through an administrative screen. These responsibilities may be sensibly separated in the code while still needing coordination to produce a consistent eligibility outcome. The investigation must establish where that coordination is necessary and where it is a consequence of the old implementation.
In the Series 05 flagship, Architecture should be a consequence of evidence, I examined how understanding the existing service can change the design of a new application. Here I want to follow one boundary decision far enough to explain it. Which responsibilities can change independently, which need to stay consistent as part of the same decision, and how much of the original separation should influence the replacement?
The Policy Change That Reaches Beyond the Calculation Component
Suppose the new policy changes the income threshold for a particular category of application. An engineer updates the calculation and its unit tests, then asks whether the work is finished. The answer depends on several things the calculation component cannot decide on its own.
The public application may reject an income figure that the new policy permits. A reporting view may use a derived value that no longer has the same meaning. The overnight process may recalculate an open case using the wrong version of the policy. An authorised correction made yesterday may need to remain valid, or it may need to be reconsidered under the revised rule. Those questions have different technical locations, but they all concern how the organisation reaches and records an eligibility decision.
I would follow one example case through the whole process rather than assuming that matching names in different codebases mean the same thing. Start with the information the applicant provides and find the point at which it is accepted. Trace where it is validated, transformed and stored, and what other data is used to calculate the result. Then follow the decision into reporting, scheduled processing and exception handling. If the rule changes while a case remains open, find out which component determines the policy version that applies and how an earlier result is corrected.
Illustrative responsibilities affected by the income-policy change. Repository boundaries identify source locations; the same decision also depends on stored data, scheduled processing and authorised corrections. View the diagram at full size.
This is a useful role for an AI-assisted investigator. An agent can search multiple repositories, trace callers and data references, connect stored procedures to application code and identify jobs that read or update the same values. Instead of an engineer manually assembling scattered references, it can present an initial map of the relevant paths with citations to the actual source. That reduces the time spent finding the material and gives the team more of the application to examine before choosing an architecture.
But I would distinguish a confirmed dependency from an interpretation of what that dependency means. Finding two functions that reference the same income field does not establish that they implement the same rule. The functions may apply different policy versions or serve different operational purposes. Equally, the absence of a reference in the scanned repositories does not prove that an external consumer or manual process does not exist. A reliable investigation needs to show what was observed, what is inferred from it and which questions still require evidence from elsewhere.
By the end of that investigation, the team may know much more about the income rule without having chosen a service boundary. That is useful progress. We have established the responsibilities that any future design must account for, rather than making the future design inherit the location of the legacy code.
Shared Data and the Ownership of an Eligibility Decision
The database introduces another complication. The three repositories appear separate in source control, but that does not tell us which components are allowed to change the same case. The public application creates the record, the calculation updates derived values, reporting reads from the operational schema and the overnight job may update the outcome again. An operations analyst can also intervene through an administrative route.
If we put the calculation behind a new API and leave all those writing arrangements unchanged, little may have been gained. The new service still depends on an existing schema whose fields carry obligations for other parts of the system. A change to the meaning of a stored result may force coordinated releases elsewhere. Two pieces of software may both believe they are entitled to change a decision, with no agreed rule for resolving competing writes.
Consider an open case whose income was corrected by operations just before the nightly recalculation begins. If the overnight job overwrites that correction, which result should the applicant see in the morning? The right answer is not determined by which process ran last unless the organisation has deliberately authorised that rule. It may depend on whether the correction was approved, what new evidence it represents and which policy version applies to the case. The future application needs to represent those decisions clearly.
An illustrative conflict between an authorised correction and scheduled recalculation. Business owners need to establish which outcome is required and why; execution order alone does not supply that authority. View the diagram at full size.
This is the point where I would stop treating the shared table as merely a technical dependency. Finding several writers should prompt us to check who owns the decision and how conflicting updates are handled. The organisation may already have a rule that the code does not express clearly. We need to know which action creates the authoritative eligibility outcome, what can legitimately change that outcome, which information reporting is entitled to consume and how an incorrect or incomplete decision is recovered.
An agent can help identify reads, writes, transactions and data lineage, especially where the relevant operations are scattered across languages and stored procedures. It can also propose a simpler data model for a replacement. But it cannot establish from a table definition alone whether a late operations correction outranks a scheduled recalculation. That requires the approved business rule and evidence of how the organisation handles contested cases.
The new system does not have to keep the old database or its update sequence. It does need an explicit account of the decision's state and authority. Once those requirements are clear, the engineering team can consider keeping the decision and its corrections together, or accepting the additional consistency and recovery work that a distributed design would introduce.
The Decisions Made Outside the Application
The manual corrections are worth investigating separately because they are particularly easy to underestimate. A source-code analysis might find a small administration feature, a script that changes a case record and perhaps a spreadsheet used to track unresolved applications. It may group those artefacts under operations and conclude that exception handling can be modernised independently from the eligibility rules.
Now speak to the people who use them. An analyst may explain that an applicant's evidence sometimes arrives after an automated decision has been recorded. Another may describe cases started under an earlier policy, where the timing of a change determines the outcome. Some exceptions may be legitimate features of the service; others may be workarounds for a defect that should not be reproduced. There may be different practices between teams, and those differences themselves need to be resolved before they become requirements.
Imagine that a case has failed the automated income calculation because supporting evidence was unavailable. An analyst later reviews the evidence and authorises the case to proceed. If the replacement places corrections in a separate service without a reliable way to update the authoritative decision, the applicant could receive a refusal even though the organisation has approved the correction. Reporting might record the automated result while the operational team believes it has settled the case.
The technical implementation of those corrections can change completely in a greenfield replacement. We may decide that a new case-management workflow should replace the spreadsheet and administrative scripts. We might also find that a former workaround is no longer necessary. But the responsibility for making, authorising and recording the corrected decision must have an explicit place in the new application.
This is one of the pitfalls of allowing an AI-generated component map to settle the architecture too early. The model may group files accurately according to their code dependencies and still miss the relationship between a human decision and the case it changes. The absence of that relationship in the model's evidence should lead to further investigation, not a confident conclusion that exception handling is independent.
Reporting Has Different Dependencies From the Decision
As the team follows the same eligibility case, reporting begins to look different from the calculation and correction work. Reporting largely consumes decisions once they have been completed. It needs the right result, the relevant policy context and a reliable account of any later authorised change, but it does not ordinarily need to take part in the transaction that makes the decision.
That distinction matters when the organisation asks for new reports or changes the way completed cases are analysed. A new reporting view might be developed without altering the rules that determine eligibility. Reporting workloads may also have different scaling needs and a different tolerance for delay. An agreed, well-defined representation of the completed decision could therefore let reporting evolve independently from the application that creates it.
We should test that assumption rather than simply giving reporting its own box. A statutory or operational report may have a deadline that places stricter limits on delay than an ordinary management dashboard. Some consumers may rely on a case being final only after reconciliation. Historic reports may need to preserve the meaning of a decision under the policy that applied when it was made. Those constraints belong in the specification for the reporting interface.
If we can show that reporting can consume a stable, authoritative result without participating in the decision itself, that is a credible boundary for a new system. It may be implemented through an event, a read model or another suitable interface. The mechanism is a design choice. What matters is whether reporting can change and recover from failure without forcing unnecessary changes to the decision capability.
The distinction is not that reporting happens to be easier code to extract. We are considering where responsibilities can be separated in a newly designed application. In this case, reporting's requirements may permit separation while rules, case state and authorised corrections still need closer coordination.
What AI Can Establish About Candidate Boundaries
There is a practical difference between asking an agent to propose services from a repository tree and asking it to investigate how one business change affects an estate. The first can produce a plausible decomposition quickly. The second gives the team material against which candidate boundaries can be examined.
For our income-rule change, I would want the AI-assisted analysis to identify the source locations involved, the shared records they touch, the consumers of the eligibility result and the release dependencies that can be established from the available history. I would also want it to show gaps: interfaces outside the analysed scope, dynamic behaviour not resolved by static inspection, and operational actions for which no authoritative description exists. A reviewer should be able to follow those findings back to the source or the relevant operational evidence. Where architecture decisions and release records are available, an agent can also help recover the reasons recorded for an earlier separation. It must distinguish those records from a plausible explanation inferred from the code layout.
There is value in asking the agent to test competing hypotheses. Suppose we propose that rules evaluation can be released without changing case state or reporting. The agent can find recent changes to the calculation, inspect whether the same changes affected validation or persistence, and prepare representative scenarios that exercise the boundary. It can help an engineer see how a rule change propagates. If the evidence contradicts the proposed independence, the investigation has done something useful even though it has not generated the architecture we first expected.
The limitations need to stay visible. A change history may be incomplete, and several repositories may have been updated together for reasons unrelated to the business rule. A model can mistake correlation for a necessary dependency, or overlook a runtime interaction that the source code does not make obvious. It can also generate tests that confirm its own proposed separation because both the design and the tests share the same incorrect assumptions. Independent behavioural requirements and operational review are therefore needed to challenge the results.
AI reduces the effort involved in gathering and comparing evidence. It does not turn service decomposition into a calculation with one correct answer. A meaningful boundary is ultimately justified by the behaviour, data consistency, ownership, operational recovery and rate of change the organisation needs.
Evidence That Two Capabilities Can Change Independently
Once the team has a few candidate boundaries, I would examine what happens when a real change is made. Take the next household-income threshold change. If rules evaluation were a genuinely independent capability, could it be changed and tested without requiring another team to alter how case state is recorded? Could reporting continue to consume a stable result? Would an operations analyst be able to understand and correct an unusual case without coordinating a release of several services?
The existing application's change history can provide clues, but it is not the final design requirement. Two repositories may always have been released together because the old platform made independent deployment difficult. Conversely, two components may have separate pipelines while depending on one undocumented manual process. We need to distinguish unavoidable behavioural coupling from constraints imposed by the implementation we are replacing.
For the future application, I would describe the expected independence in concrete terms. For example, reporting can be changed without changing the rule that decides a case, provided it continues consuming the approved decision record. The eligibility calculation may require a coordinated change with case state and correction handling because those responsibilities together produce one authoritative outcome. If the organisation later wants independent rule deployment, the design will need explicit versioning and consistency controls sufficient to make that safe.
Those statements can be challenged through prototypes, representative scenarios and an account of who operates the capability when it fails. An agent may help produce a candidate interface and test the normal and failure paths. Engineers and business owners can then examine whether the claimed independence survives an actual policy change and an exceptional case, rather than accepting a boundary because the drawing looks clean.
Illustrative tests of a candidate reporting boundary. Separation becomes credible when reporting preserves the meaning of a decision, receives authorised changes and recovers within agreed constraints. The team would run and review these checks before approving the boundary. View the diagram at full size.
If separation creates more coordination than it removes, the organisation should be able to say so. The purpose of finding boundaries is to design an application that can be changed and operated effectively, not to maximise the number of services.
Choosing Boundaries for a New Eligibility Application
In this illustrative investigation, the findings would support considering the eligibility decision, case state and authorised corrections as one closely related capability. Reporting has a different relationship to that decision, and public intake may have distinct availability and scaling needs. Those are candidate boundaries that deserve consideration in the greenfield target.
The distinction from traditional component-by-component modernisation is important. We do not have to extract the old calculation repository, recreate its stored procedures or carry forward the reporting schema before building the replacement. We can use the legacy system to recover what eligibility decisions must mean, who is entitled to change them, which downstream information must remain available and what conditions the new system must handle. Then we can design those responsibilities as part of a new implementation, with architecture chosen for the required behaviour rather than the inherited file structure.
This brings us back to the three repositories. Their original separation may have helped people manage different kinds of work, and some of those reasons may still matter. Public-facing changes can still benefit from a clear interface to the decision process. Reporting can still need a different delivery schedule. What the income-rule investigation challenges is the assumption that the calculation repository already contains everything needed to make and correct an eligibility decision. It gives the team a reason to reconsider that boundary without dismissing the original separation of concerns.
For a real replacement, I would compare the original rationale with the requirements we have now. A continuing need for separate teams, technologies or deployment schedules should influence the design. A restriction imposed by an obsolete platform may no longer need to shape it. Merely merging the repositories would not resolve competing updates to a case or establish who may change the outcome. Equally, keeping three repositories would not prevent the team from defining those responsibilities more clearly. Where the source is maintained, what is deployed together and who owns the decision are related choices, but one does not settle the others.
For this example, I would initially keep rules, case state and authorised corrections within one cohesive decision capability, with an agreed interface supplying outcomes and later authorised changes to reporting. That could be implemented as a modular application with clear internal responsibilities. If independent rule deployment is a present requirement, the design needs explicit versioning, consistency and recovery arrangements sufficient to support it. We can then compare whether that independence provides enough operational benefit to justify the additional work.
This does not claim that the first design is final or that a greenfield replacement is always appropriate. The quality of the decision depends on the evidence available and the organisation's constraints. We may discover another external dependency, a policy exception that needs more investigation or a case-recovery requirement that changes the grouping. Those findings should remain visible rather than disappearing when we draw the target architecture.
For agentic engineering, this gives the implementation agents a much stronger starting point. They can build a different application, explore interfaces and verify scenarios against the approved requirements, without silently inheriting the boundaries of the code they analysed. The team retains responsibility for deciding which capabilities belong together and why, with enough supporting evidence to revise that choice when necessary.
That brings us to the next question. There may be several architectures that satisfy the required behaviour, including more distributed designs that offer genuine advantages in some organisations. In 05.2, A target architecture must explain its trade-offs, I examine how to compare those alternatives and record the reasons for the chosen design.
This paper uses an illustrative eligibility-service scenario, not a claim about a particular customer's application.
The DORA material on loosely coupled teams and the Software Engineering Institute's Architecture Tradeoff Analysis Method provide useful external reference points for independence and architectural trade-offs.
This paper is part of The Modernisation Control Papers, the first major sequence within The Harten Papers. Read the complete series on harten.io.