# A target architecture must explain its trade-offs

> Two designs for an eligibility service show how to compare independent releases, consistent decisions, recovery and operating costs, and explain what would justify choosing a different architecture.

Paper: 05.2
Published: 2026-10-23
Canonical: https://harten.io/papers/05-2-a-target-architecture-must-explain-its-trade-offs/

Cover illustration: [View the title image](https://harten.io/media/papers/covers/v1/05-2-a-target-architecture-must-explain-its-trade-offs.png?v=85dab3af860b). Illustrative cover artwork, not an application screenshot or a record of measured results.

## What This Paper Examines

Understanding an application can rule out weak architectural assumptions while still leaving several credible designs. This paper compares two ways to build a new eligibility service through the same policy change, authorised correction, demand peak and reporting failure. It examines what each design makes easier, what additional work it creates and which requirements neither may compromise. For the illustrative service, I would provisionally keep the core decision together, while treating independent rule deployment as a credible alternative that needs a demonstrated benefit. By the end, the reader should be able to explain a preferred design, its accepted disadvantages, the evidence still needed and the conditions that would justify revisiting it.

## Two Ways to Build the Replacement

Imagine an organisation replacing an application that decides whether people qualify for support. Applicants submit household-income information and supporting evidence. Staff can authorise corrections when new information arrives, and reporting uses the resulting decisions. A proposed policy change has revealed that the calculation, the case record and the correction process all contribute to the outcome an applicant receives.

In [Find the boundaries the system actually has](https://harten.io/papers/05-1-find-the-boundaries-the-system-actually-has/), I followed that investigation across three repositories and the operational work around them. It suggested that the eligibility decision needed clearer ownership, while reporting might be able to consume an agreed result separately. That is useful evidence for design. It does not establish that every responsibility involved in a decision must run in the same process.

The team is considering a new implementation, informed by the behaviour the organisation has agreed to preserve or change. It is free to choose different components, interfaces and data structures. Extracting the old calculation component is not a prerequisite. For this comparison, suppose one product team is responsible for the core eligibility service, with shared platform support. That is an assumption of the example, not something a source-code analysis could establish by itself.

The first option keeps rules, case state and authorised corrections within one modular decision application. Modules have explicit responsibilities, but they are deployed together. Public intake has its own boundary where its availability and workload justify it, and reporting consumes a controlled representation of completed decisions and later corrections.

The second option separates rule evaluation into an independently deployed service. The decision application still owns the authoritative case record and accepts or rejects the result of a calculation. It sends the rules service an identified set of inputs and the policy version to apply. The rules service returns a result with that context; it does not gain permission to overwrite the case simply because it completed a calculation. Intake and reporting have the same proposed boundaries as in the first option.

![Two candidate designs for a new eligibility service. Both have public intake, an authoritative decision owner and reporting. Option A evaluates rules inside the modular decision application. Option B calls an independently deployed, versioned rules service while retaining one owner of the case record.](/assets/papers/05-2-two-candidate-designs.svg)

*Two illustrative alternatives with the same business responsibility for the final decision. The comparison changes where rules run and are released, rather than assuming that a distributed design must allow several components to overwrite a case.* [View the diagram at full size](https://harten.io/assets/papers/05-2-two-candidate-designs.svg).

This gives us a more useful comparison than placing a well-designed modular application beside an unnecessarily fragmented alternative. A separate rules service could be valuable. It could support several applications, scale a demanding calculation independently or allow a team to release rules on its own schedule. The question is whether those benefits matter enough here to justify the additional interface, versioning and recovery work.

## Requirements That Every Option Must Satisfy

Before comparing advantages, the organisation needs to agree which outcomes both designs must provide. Suppose an authorised correction must not be silently lost when a background calculation finishes. A decision must also retain enough information to explain which evidence, policy and approved intervention produced it. Those are requirements of the service. A cheaper design cannot simply discard them because it scores well on other qualities.

The details need care. A case started under one policy may have to remain under that policy, or a later change may apply to it. The correct rule depends on the service being delivered. An architect or an agent cannot settle it by choosing whichever versioning arrangement is easier to implement. The business decision needs to come first, with uncertainty recorded where the responsible people have not yet resolved it.

Other requirements permit a choice within agreed limits. Reporting might be allowed to lag behind an operational decision, while the applicant must receive a reliable acknowledgement when their submission has been accepted. An internal calculation might pause during an outage if the organisation can still meet its decision deadline. Each statement needs a defined meaning and an owner who can accept its consequences. “Highly available” does not tell the engineering team whether a pending case is acceptable or whether a provisional result may be shown.

The Software Engineering Institute's [Architecture Tradeoff Analysis Method](https://www.sei.cmu.edu/library/the-architecture-tradeoff-analysis-method/) provides a useful basis for this kind of evaluation: examine candidate designs against competing quality attributes and identify their risks and trade-offs. I am applying that principle to an illustrative review here, rather than claiming to have performed a formal ATAM assessment.

For each important scenario, I would want the team to describe the condition, the required response and the measure by which it would judge that response. If the service must accept a particular peak volume, somebody must establish that volume and what “accepted” means. If reporting may lag, somebody must specify how long and what happens when that limit is exceeded. Missing measurements should remain questions to resolve, not become plausible numbers in a comparison table.

## An Authorised Correction During Recalculation

Take the difficult case from the earlier investigation. A background job begins recalculating eligibility using revision 17 of a case. While it runs, an analyst receives additional evidence and authorises a correction, producing revision 18. The calculation then returns a result based on the older information. For this scenario, assume the approved requirement is that the accepted correction must not be overwritten by that stale result.

In the modular design, the calculation and the case update are close together, but that proximity does not solve the problem automatically. A background worker can still read old data and write too late. The implementation needs to check that the case remains eligible for that result at the moment the result is committed. For example, it could make the update conditional on the case revision still matching the one evaluated. The check and update must be enforced together; checking first and writing later leaves the same race open.

If the revision has changed, the result cannot simply replace the newer state. The application follows the agreed rule for re-evaluation or review. It must retain enough context for an operator to understand why the earlier calculation was not applied. The design also has to distinguish an authorised correction to the inputs from an approved exception to the calculated outcome, because recalculating corrected inputs does not necessarily reproduce an exception decision.

The separate rules service can satisfy the same requirement. It evaluates the specified input revision under an identified policy version and returns the result to the decision owner. That owner performs the authoritative state check and decides whether the result can be recorded. A timeout, delayed response or repeated request must not make an older result acceptable. The interface therefore needs to preserve the input identity, policy version and request identity well enough to recognise what was evaluated and handle retries safely.

![A background calculation reads case revision 17. An analyst's authorised correction then creates revision 18. When the earlier calculation returns, the decision owner checks the revision atomically before committing, detects the mismatch and follows the approved re-evaluation or review route without overwriting the correction.](/assets/papers/05-2-correction-during-calculation.svg)

*An illustrative scenario that both architectures must pass. Keeping code together can make coordination simpler, but correctness still depends on an explicit update rule. Separating the calculation adds a network boundary without changing who may accept the final result.* [View the diagram at full size](https://harten.io/assets/papers/05-2-correction-during-calculation.svg).

This is why I would avoid saying that a consistent eligibility decision proves the whole capability must be one service. What it proves is that the decision needs a reliable owner and a defined consistency rule. Microsoft's [guidance on data considerations for microservices](https://learn.microsoft.com/en-us/azure/architecture/microservices/design/data-considerations) makes a related distinction: identify where strong consistency is required, where eventual consistency is acceptable and which service is authoritative. The location of a calculation is a further design choice.

For our team, evaluating rules locally may make the correction scenario easier to implement, inspect and support. The remote option may still justify its extra failure paths if it delivers a valuable independent capability. We need to compare those consequences, rather than treating either a process boundary or a shared database as proof that the requirement has been met.

## Independent Rule Changes and a Shared Contract

Now consider the benefit most likely to justify the separate service: changing rules without releasing the case application. We should establish what kind of change the organisation actually makes. A new income threshold might be a versioned policy configuration consumed by an existing evaluator. If the modular application supports that arrangement, the threshold may change without deploying new application code. A separate rules service would not be the only way to achieve that independence.

A different policy change may require information the application has never collected. Perhaps eligibility now depends on a new category of household income. Intake must collect it, evidence handling must describe it, the case record must retain it and operators must know how to correct it. Releasing the calculation independently does not remove those dependencies. The team still needs compatible contracts and a decision about cases that lack the new information.

There is nevertheless a strong case for separation when the circumstances support it. Suppose several services use a stable rule-evaluation contract, a dedicated team owns the evaluator, and frequent calculation changes do not alter the information its consumers provide. Independent deployment could then remove a real release bottleneck. The decision record should describe that bottleneck, the consumers affected and how compatibility will be maintained. It should also establish whether those consumers genuinely use the same policy meaning, rather than sharing similar-looking calculations that will later diverge.

An AI-assisted investigation can help compare policy changes with source changes, interface revisions and release records. It can prepare examples of changes that would cross the proposed boundary and ones that would stay inside it. But several repositories changing on the same day does not prove they had to change together. A reviewer still needs to distinguish business dependencies from a release process the replacement could improve.

For the illustrative service, we have not established a separate team, several consumers or a sustained need for independent evaluator releases. I would therefore keep that option open without claiming its principal benefit has already been demonstrated. The same discipline applies to the modular option: if every policy update still requires a large coordinated release, calling the code modular will not have solved the original problem.

## Peak Demand and an Unavailable Dependency

The next scenario concerns the people submitting applications. Suppose demand rises sharply near a deadline. The organisation needs to acknowledge accepted submissions reliably, while some decisions can be processed later. That may justify separating intake from decision processing in either design. It does not yet tell us that rule evaluation needs another deployment boundary of its own.

The team should measure where time and capacity are actually spent. Document uploads may dominate the intake path. A database query may limit throughput. The calculation itself may be inexpensive, or it may consume substantial processing time. Those findings lead to different interventions. Scaling a remote rules service will not repair a bottleneck caused by the decision application's own database.

A queue can absorb a temporary difference between arrival and processing rates, but the backlog still has to be cleared within the service's agreed limits. An acknowledgement also needs to mean something precise. If the interface says a submission has been accepted, the required information must be durably retained or its incomplete state clearly represented. Moving work into the background does not remove the obligation to account for it.

Now make the rules component unavailable. In the distributed option, intake might continue and cases could wait for evaluation, provided that delay is acceptable. The design needs a way to identify pending work, retry it safely and show operators when intervention is required. A failed call must not be mistaken for a policy refusal. In the modular option, a fault in the decision application may affect calculation and case management together, even if intake remains available. A separate evaluator could provide a useful degree of failure isolation that the team would otherwise have to establish within the application.

I would test both options against the same peak-load and recovery scenarios. A prototype should use representative calculations, data access and failure conditions, with enough detail to make the comparison meaningful. A fast response from a mocked dependency establishes very little about the real design. Equally, deliberately giving one option an unrealistic workload would only make the preferred result easier to obtain.

This is a useful place for agents to help build small experiments and exercise delayed responses, retries and recovery. Their reports should distinguish a measured result from a predicted one and state what was excluded. A successful prototype can reduce a particular uncertainty. It does not establish that the entire service meets its production requirements.

## Reporting After a Corrected Decision

Reporting provides another test because the preferred modular option is not free of distributed behaviour. Once it publishes results to a separate reporting capability, the team must account for a failure between recording a decision and making that decision available elsewhere. Keeping the core together does not remove that obligation.

Suppose the decision application accepts a correction but the reporting update is delayed. An operational screen may show the revised outcome while a management report still shows the earlier one. That may be acceptable for a defined period, or it may violate the purpose of a particular report. The organisation needs to distinguish those cases. A report used to monitor trends can have different freshness requirements from one used to authorise a consequential action.

The interface must represent later corrections as well as the first completed decision. Consumers need to know which revision they have received and what to do with a duplicate or an older update arriving after a newer one. Operators need to see when the reporting view has fallen behind and have a way to reconcile it. “We publish an event” is only the beginning of that explanation.

The [transactional outbox pattern described in AWS's guidance](https://docs.aws.amazon.com/prescriptive-guidance/latest/cloud-design-patterns/transactional-outbox.html) is one possible response to the database-and-message problem. The application records the state change and an intention to publish within the same local transaction, then delivers the message separately. Consumers still need to handle duplicates and ordering appropriately. This is an example of an implementation choice to evaluate, rather than a requirement to adopt that pattern or a particular cloud provider.

The important comparison is what happens to the service when reporting is delayed or unavailable. If decision processing can continue safely, the separation may provide useful isolation. If an operational approval depends on the report being current, that dependency must appear in the design. We cannot declare reporting independent by leaving the dependency out of the diagram.

## The Team That Has to Operate the Design

For this example, one product team owns the core service. That makes some of the benefits of separate deployment less immediate. The same people may still investigate a failed case across the evaluator, decision application and reporting consumer. They will need to understand which request succeeded, which result was accepted and whether a retry is safe. The number of services alone tells us little about how much work that requires.

The operating environment can change the answer. A mature platform may already provide deployment automation, monitoring, service identity and familiar recovery mechanisms. A separate evaluator may fit that environment with modest additional effort. In another organisation, the same design may require the application team to develop and support those arrangements itself. Managed infrastructure reduces some responsibilities, but the team still owns the meaning of a failed or repeated business operation.

The modular option has costs too. A release may include modules that did not change. Capacity may have to increase for the whole application when only one part needs it. A defect can affect a larger portion of the decision capability. Keeping that option manageable requires internal boundaries that developers and tools actually respect, with controlled access to state and tests that detect unintended dependencies. A module name in a folder is not sufficient.

I would compare delivery and operating costs over the period the organisation expects to use the design. That includes engineering effort, shared-platform charges, environments, diagnosis, security maintenance and recovery work, as well as infrastructure consumption. Where values are uncertain, ranges and their assumptions are more useful than a precise total. If a model supplies a number for support effort, the people expected to provide that support should be able to explain or challenge it.

The decision is partly organisational because people will absorb the consequences. A design that saves a release dependency but creates a support burden the organisation cannot sustain is a poor trade. A single deployable application that prevents several capable teams from making useful independent changes can be a poor trade for the opposite reason.

## Evidence That Would Change the Preferred Design

Given the assumptions of this example, I would start with a modular decision application and evaluate separate boundaries for intake and reporting. The correction scenario has one authoritative outcome, the core is owned by one team, and the benefit of a separately deployed evaluator has not yet been demonstrated. Keeping the core together offers a plausible way to reduce the coordination the team must implement and support. It remains a recommendation to test, rather than a result of a completed workload study.

I would change that recommendation if representative measurements showed that evaluation needed a substantially different capacity or availability arrangement, or if real consumers and ownership made independent releases valuable. The team might then keep case decisions under one owner while moving a stable evaluator behind a versioned contract. It would still have to demonstrate compatible policy changes, safe retries and recovery from interrupted requests.

Some evidence could challenge both designs. The organisation might discover that another application relies on an undocumented interpretation of a completed decision. Operations might identify a class of correction that requires a different approval process. Either could change the requirements before the team chooses where the code runs. That is why the comparison needs a route back to the approved behaviour, rather than only a list of technical advantages.

This also limits the value of an overall score. A weighted comparison can help a group discuss priorities, but a high average cannot compensate for failing a mandatory requirement. Nor does giving an unknown operating cost a numerical score make it known. I would separate requirements that must be satisfied from benefits the organisation can trade, then make the remaining judgement openly.

The people responsible for the service decide which disadvantages they are prepared to accept. Engineers should explain how the design produces those disadvantages and what could reduce them. The evidence should be strong enough for that decision, without pretending that all future demands can be known before implementation begins.

## A Decision Record the Next Team Can Use

The final diagram should be accompanied by an account of why the team chose it. The useful record is specific enough that a later engineer can distinguish an intentional compromise from an omission. It should also be honest about its status. A recommendation awaiting load tests is different from a decision approved after those tests have been reviewed.

For the illustrative service, the record might contain the following.

- **Working recommendation:** Keep rules, case state and authorised corrections in a new modular decision application, with separate intake and reporting boundaries where their requirements justify them.
- **Reason:** One team owns the core outcome. Local evaluation reduces the interface and recovery work needed to coordinate the current decision process.
- **Credible alternative:** A versioned rules service could provide independent releases, reuse or scaling while the decision application retains authority over case updates.
- **Accepted disadvantages:** Less deployment and scaling independence within the core, with a larger potential impact from an application failure.
- **Evidence still needed:** Representative workload and recovery results, confirmed reporting deadlines, and an agreed account of policy changes and correction handling.
- **Conditions for reconsideration:** Demonstrated evaluator bottlenecks, new consumers, changed team ownership or a sustained need for independent releases.

In a real decision record, the evidence entries would link to the actual requirements, measurements, reviewed examples and unresolved findings. The record would also identify who accepted the trade-offs and when. The example above is a worked illustration, not a claim that those investigations or approvals have happened.

I would retain the reasons for rejecting the alternative alongside the reasons for choosing the preferred design. If the next team later needs independent rule releases, it should be able to see whether that need was considered and outweighed by another constraint, or whether it simply did not exist at the time. That makes it easier to reconsider the decision without either defending the past automatically or assuming the earlier architects failed to understand the options.

## What an Engineering Agent Needs Before It Builds

These distinctions become particularly useful when an agent helps implement the replacement. If it receives only a target diagram, it may complete missing details according to the architecture pattern it recognises. It might introduce additional services because the interface looks reusable, or simplify a retry path because the normal case already passes. Either could alter a trade-off the organisation thought it had settled.

The agent needs the required behaviour, the chosen responsibilities and the reasons that consequential constraints exist. In our example, it needs to know that a calculation result cannot overwrite an accepted correction from a later case revision. It also needs to know that the decision owner remains authoritative if evaluation moves to another process. Those statements leave room for engineering choices while making the outcome that must be preserved explicit.

AI can help maintain the connection between requirements, proposed interfaces and test evidence. It can also compare alternatives more thoroughly than a team might have time to do manually. I would still challenge a comparison generated from one model's own assumptions. The scenarios should come from independently established requirements and operational review, and the test evidence should show what actually happened. A generated description of a recovery mechanism does not establish that a lost response or repeated request has been handled correctly.

Where implementation reveals a new dependency, the team should assess whether it changes the agreed outcome or an accepted trade-off. Routine choices within the design can proceed. A discovery that the supposedly independent rules service requires coordinated changes on every release deserves a review of the boundary. Faster implementation is useful, but it should not make an unsupported architectural assumption more expensive before anyone notices it.

## From the Target Design to the Live Service

For this eligibility service, the target is now something the team can explain through actual situations. It knows how an authorised correction affects an in-flight calculation, which policy changes might be independent, what can wait during an outage and how reporting receives a later decision. It can describe the disadvantages of keeping the core together and the evidence that would justify separating evaluation. The diagram records those choices; the supporting account lets someone challenge them.

The replacement can be designed and built independently of the old implementation, as I explored in [Architecture should be a consequence of evidence](https://harten.io/papers/05-architecture-should-be-a-consequence-of-evidence/). That freedom does not decide how live cases, historic records and operational authority will move. A coherent target can still be introduced through an unsafe transition if those responsibilities are left implicit.

The next paper, **05.3, The route to the target is part of the architecture**, examines that transfer. Depending on the service, it may involve a single rehearsed cutover or several controlled stages. The choice should follow the evidence about data, dependencies and recovery, just as the target architecture follows the behaviour and operating conditions it needs to support.

---

*This paper uses an illustrative eligibility-service scenario. Its versions, design assumptions and proposed checks are examples, not measured results or claims about a particular customer's application.*

*This paper is part of The Modernisation Control Papers, the first major sequence within The Harten Papers. [Read the complete series on harten.io](https://harten.io/papers/).*
