Software architecture refers to the blueprint of a software system: what foundational principles apply, what constraints must be adhered to, and what decisions must be made. These decisions can be divided into two categories: immutable Type 1 decisions with a major impact and revisable Type 2 decisions. A living architecture defends itself, for example through measurable KPIs, fitness functions, and automated tests.
Key Takeaways
- Architecture documents that exist only in a wiki do not defend themselves: Only when ADRs and fitness functions are made automatically verifiable do they actively protect the architecture from violations.
- Type-1 decisions, such as the choice between a monolith and microservices, are virtually impossible to reverse in practice and must therefore be defined within a clear framework of justification and defended over the long term.
- Type-2 decisions, such as the choice of logging framework, can and should change if team feedback or metrics suggest otherwise, because their impact does not jeopardize the architecture.
- Architecture committees should discuss only Type 1 decisions, because Type 2 topics block evolution in that setting—evolution that the team could easily allow through direct discussion.
- AI can help make soft architectural rules technically verifiable: It can detect, within context, whether a catch block is logged but in the process discloses sensitive data such as credit card numbers.
Architecture Becomes Outdated the Moment It’s Fully Defined
A software architecture describes how a system should be built: what’s important, what constraints apply, and what to keep in mind. It’s the blueprint, several levels above the code. It’s precisely this plan that often lags behind reality.
Architectural planning takes days, weeks, sometimes months. Meanwhile, the product, software, and requirements continue to evolve. In a strict waterfall model, this is less noticeable because the environment remains relatively stable. As soon as a team works agilely and requirements change, a carefully crafted architecture runs the risk of missing the mark when it comes to actual needs.
This isn’t an argument against architecture work, but rather one for finding the right balance. Spending too much time deliberating can mean clinging to requirements that no longer exist in that form. The challenge lies in balancing stability against adaptability.
Why Early Architectural Decisions Shape Testing
Performance and security must be tested early on because they depend on the architecture. If you start too late, you’ll have to shake up fundamental structures—and that gets expensive.
This creates a balancing act. On one hand, there are decisions that have a major impact on the system and on quality characteristics—decisions that can hardly be reversed later on. On the other hand, there is the desire to remain flexible enough to respond to changes. The real challenge lies in addressing both at the same time.
The solution lies in making a distinction: Which decision is a cornerstone that must be defended? And which one, while necessary, can be revised without major consequences?
Separating Type 1 and Type 2 Decisions
Jeff Bezos’ analogy provides a simple framework. A Type 2 decision is a door through which you can walk back. A Type 1 decision is a door that slams shut behind you: the wall is too high; you can’t go back.
For every architectural decision, it’s worth asking at the outset which category it falls into. This determines how much thought it deserves and how much effort it will take later to defend the decision.
A classic Type 1 example is the choice between microservices architecture and a monolith. In theory, you can move from a monolith to microservices simply by breaking it down. In practice, it’s not that simple. The reverse approach—merging microservices back into a single unit via copy-paste—also sounds feasible but proves difficult to implement.
What’s important is the relief this brings: if there are good reasons for a monolith, that’s fine. Microservices aren’t mandatory. They come with their own drawbacks, such as a lot of minor details to manage between services. The key is that the choice is well-founded and sustained throughout the application’s lifecycle.
The logging framework is the counterexample. At some point, a choice must be made, but if it turns out after eight weeks that it isn’t a good fit, you replace it. The system keeps running; there’s no fundamental change. You’re allowed to make decisions like this and then change your mind later.
| Type 1 | Type 2 | |
|---|---|---|
| Reversibility | practically none | at any time |
| Example | Microservices vs. monolith, hyperscaler lock-in | Logging framework |
| Effort required to think through | high | moderate |
| Where to decide | Board, with management backing | within the team |
| Documentation | watertight | keep it concise |
There’s a limit to building generically
Replaceability comes at a cost, and at a certain point, that cost tips over into overengineering. With logging, you’d have to make a lot of mistakes for it not to be replaced. Other areas can only be kept generic enough to keep the choice open indefinitely with considerable effort.
Anyone who makes everything as generic as possible ends up building a massively overengineered system—and for reasons that serve no one. The more open a section is kept, the fewer concrete guidelines there are for implementation. Then developers lack examples.
Moreover, some supposed Type 1 decisions can be broken down into Type 2 decisions as soon as a suitable pattern exists. If there’s a clean pattern in place, the specific implementation doesn’t really matter.
The Cloud Question Depends on Strategy, Not Just the Architect
The architect alone does not determine how much leeway a decision has. The choice of hyperscaler illustrates this. If the choice is open, the architect has a wide range of options. If the company specifies a major hyperscaler, the direction is set.
If the directive includes the addendum “keep the system generic anyway,” the classification shifts. Committing to a single hyperscaler is actually a Type 1 decision. Those who build cloud-native systems tie themselves less tightly to a provider and regain flexibility.
If, on the other hand, provider-specific services are deeply integrated into the system, it’s clearly a Type 1 decision. You can’t move away from that hyperscaler—at least not with reasonable effort. Transformations are possible, but the effort involved becomes enormous.
An Architecture That Defends Itself
Architecture documentation only works if it extends beyond the page. ARC42 templates, C4, and ADRs are the right tools for capturing ideas without getting bogged down. An ADR on its own, stored in a wiki that no one looks at, won’t accomplish anything.
The goal is documentation that defends itself when someone violates it. It should set off a red light: “The idea you have here violates what has been established.”
The amount of effort required varies depending on the type. Type-1 decisions require clear, robust documentation, and everyone on the project should be familiar with it. For Type-2 decisions, documentation can be more concise, and you should assume that not everyone on the team is familiar with them.
If I can set up my ADRs so that they can defend themselves when they’re violated—or at least trigger a red light—then someone will come by and realize: Think this through again. — Ralf Enderle
How Architecture Becomes Testable
An architecture defends itself as soon as its criteria are translated into a testable form. “The architecture should be high-performing” is nice, but worthless as long as it isn’t turned into KPIs that can be used for testing.
The key is linking the KPIs to the underlying decisions. For example, microservices are chosen to scale per service and maintain a certain level of performance. It is precisely these goals that become metrics. If a test fails, a light comes on and signals that something is wrong.
Fitness Functions, a concept by Neil Ford, translate hard architectural criteria into a technically verifiable form. The criteria feel rigid on paper but become flexible enough during testing to be technically grasped.
Where AI Provides Additional Context in Testing
AI complements technical checks in cases where pure rule-based checks fail to capture the intent behind a rule. For example: Every catch block should appear in the log so that you can respond to production errors. Regular expressions can be used to verify that a log statement follows a catch block. The regular expression does not specify what is logged there.
If you also describe why this logging is important, AI can interpret the surrounding context. In the context of a credit card payment, it can recognize that the error log might contain the credit card number. A regular expression would not detect this.
This check does not provide 100% certainty. AI systems don’t wake up in the same mood every day. But there’s no reason to forego the additional safeguards this provides.
Architectural Decisions Belong Where They Have an Impact
An overarching board that reviews architecture every few weeks and contributes ideas runs the risk of discussing matters far removed from the reality of software development. Here, too, the distinction between decision types helps. Type-1 decisions belong in such a forum because they require management’s endorsement.
Discussing Type-2 decisions in large meetings is a waste of time. Doing so means debating issues with no impact and hindering the evolution that would otherwise happen effortlessly, instead of addressing the difficult issues. These decisions belong within the team.
If the team determines during the retrospective that a Type-2 decision isn’t working after a few weeks, they change it. It’s designed precisely for that—with minimal impact. Why defend a decision that’s easy to change? Clinging to it means missing out on easy evolution.
What Tester Should Demand from Architects
Tester shouldn’t just ask what the architecture looks like, but how it translates into testable factors. The key request to the architect is: Think about how your architecture manifests itself in KPIs—in soft or hard factors that can be tested.
This question gives rise to a shared goal: ensuring that the architecture chosen for good reasons is actually followed and not violated. Fitness functions are one way to achieve this; AI-supported context checks are another.
Many teams already have an ongoing architecture process. This can be adapted. A retrospective is a good place to raise the question of whether the current approach supports the right decisions and approves the right ones.


