In any system that lasts more than a few months, the same uncomfortable question arises: "why did we do it this way?". The person who made the decision is gone, the context has been lost, and the current team hesitates between honoring the choice or throwing it overboard without understanding it. Architectural governance exists to answer that question and to ensure technical coherence without becoming a bureaucratic brake. Traditionally, governance evoked heavy committees, documents hundreds of pages long, and a "chief architect" who approved everything. Today we seek the opposite: lightweight governance, distributed and based on decisions documented in a simple way. The flagship tool of this approach is the Architecture Decision Record (ADR). In this lesson we will look at what lightweight governance is, how to write ADRs with a template, how modern architecture committees work, and how to define standards that help rather than hinder.

Contents

  1. What architectural governance is
  2. Heavy vs. lightweight governance
  3. Architecture Decision Records (ADR)
  4. ADR template
  5. Complete ADR example
  6. Modern architecture committees
  7. Standards and guides (golden paths)
  8. Common Mistakes and Tips
  9. Exercises
  10. Conclusion

  1. What architectural governance is

Architectural governance is the set of practices that ensure an organization's technical decisions are coherent, aligned with business goals, and maintained over time. It covers three questions:

  • Who decides? How technical authority is distributed.
  • How is it decided? The process for making and documenting decisions.
  • How is compliance ensured? How it is verified that what was decided is respected.

The goal is not to control people, but to reduce the cost of coherence: so that a team does not reinvent the wheel, so that important decisions are not made lightly, and so that knowledge survives staff turnover. Good governance is invisible when it works and painful only when it is absent.

  1. Heavy vs. lightweight governance

Aspect Heavy governance (traditional) Lightweight governance (modern)
Authority Centralized in an architect/committee Distributed; teams with autonomy
Decisions Approved in advance by a body Made by whoever implements them, documented
Documentation Lengthy documents, often obsolete Short ADRs versioned with the code
Compliance Manual reviews, "gates" Automated (fitness functions, linters)
Speed Slow; the committee is a bottleneck Fast; the committee advises, does not block
Risk Decisions disconnected from reality Requires maturity and team culture

Lightweight governance does not mean "everyone does whatever they want." It means moving the decision to where the knowledge is (the team that builds), but requiring relevant decisions to be documented and verified. The committee shifts from gatekeeper to facilitator.

  1. Architecture Decision Records (ADR)

An Architecture Decision Record, an idea popularized by Michael Nygard in 2011, is a short document that captures one significant architectural decision: the context in which it was made, the decision itself, and its consequences. Key characteristics:

  • One per decision. It is not a master document, but a collection of small cards.
  • Immutable. An ADR is not edited once accepted; if the decision changes, a new one is written that supersedes the previous one (status "Superseded by ADR-00X").
  • Versioned with the code. It lives in the repository, usually in docs/adr/, so that it evolves alongside the system and is reviewed in pull requests.
  • Short. One or two pages. If you need more, it is probably several decisions.

What deserves an ADR? Decisions that are costly to reverse or that affect many: choosing an architectural style, a database, a communication protocol, an authentication policy, etc. Do not document the name of a variable with an ADR.

  1. ADR template

A minimalist and widely used template, in Markdown:

# ADR-001: <Short, imperative title of the decision>

## Status
Proposed | Accepted | Rejected | Obsolete | Superseded by ADR-00X

## Context
What situation or problem forces us to decide? Forces at play,
technical and business constraints, assumptions. Facts, not opinions.

## Decision
"We decided <X> in order to <objective>." A clear statement in the active voice.

## Consequences
Positive and negative outcomes of the decision. What becomes easier,
what becomes harder, what risks we take on, and what debt we generate.

## Alternatives considered
Other options evaluated and why they were discarded.

Let's review each section and why it matters:

  • Status: lets you know at a glance whether the decision is still in force. The typical flow is ProposedAccepted; later it may become Superseded.
  • Context: it is the most valuable part two years from now. It explains the forces that led to the decision. Without context, a correct decision looks arbitrary.
  • Decision: the concrete statement. In the active voice ("We decided to use PostgreSQL") so there is no ambiguity about what was chosen.
  • Consequences: honesty here is gold. Every decision has a cost; naming it prevents the future team from feeling deceived.
  • Alternatives considered: it demonstrates that thought was given. It prevents someone a year from now from proposing an option already discarded for good reasons.

  1. Complete ADR example

# ADR-007: Adopt asynchronous event-based communication between Orders and Billing

## Status
Accepted (2026-03-12)

## Context
The Billing module was invoked synchronously from Orders when
confirming a purchase. When Billing is slow or down, the order
confirmation fails, even though the payment has already been charged. During
campaign peaks we have seen timeouts and lost orders. The business demands that
confirming the order not depend on Billing's availability.

## Decision
We decided to decouple Orders and Billing via asynchronous events.
Orders will publish an `OrderConfirmed` event on a messaging broker
(RabbitMQ). Billing will consume it and generate the invoice in a deferred manner.

## Consequences
Positive:
- Confirming an order no longer depends on Billing: higher availability.
- Billing can process at its own pace and retry on failures.

Negative:
- The invoice is no longer immediate: eventual consistency. The customer will see
  "invoice in progress" for a few seconds.
- Operational complexity increases: the broker and the queues must be monitored.
- We need idempotency in Billing to avoid duplicating invoices if the
  event is redelivered.

## Alternatives considered
- Keep it synchronous with retries and a circuit breaker: reduces the problem but
  does not eliminate it; the confirmation remains coupled to Billing.
- Synchronous call with a short timeout and an internal queue: adds complexity without the
  guarantees of the broker.

Notice how the example applies the template with real data: the context narrates a concrete problem (timeouts during a campaign), the decision is unambiguous (events via RabbitMQ), and the consequences do not hide the cost (eventual consistency, the need for idempotency). Anyone who reads this two years from now will understand why Billing is asynchronous and will not try to "fix it" by making it synchronous.

  1. Modern architecture committees

The architecture committee has not disappeared, but it has changed its role. In the modern model it is usually organized as an ART (Architecture Review Team) or, more informally, an architecture guild:

  • Rotating composition: not just "architects," but senior engineers from various teams. It avoids the ivory tower and spreads knowledge.
  • Advisory function, not gatekeeping: it reviews proposed ADRs, provides a cross-cutting perspective, and detects overlaps or inconsistencies, but rarely blocks.
  • Lightweight cadence: short, frequent meetings, ideally over ADRs that are already written (you review a document, you do not improvise on a whiteboard).
  • Decisions by informed consensus: if there is no agreement, the team that bears the cost decides, recording it.
graph TD
    Equipo[Team proposes ADR] --> PR[Pull Request with the ADR]
    PR --> Guild[Architecture Guild reviews]
    Guild -->|comments| PR
    Guild -->|no significant objections| Acept[Status: Accepted]
    Acept --> Repo[(Repository docs/adr)]

The diagram's flow integrates governance into the development process: the ADR is proposed as a pull request, discussed like any code change, and, once approved, becomes versioned. Governance stops being a separate event and becomes part of daily work.

  1. Standards and guides (golden paths)

So that teams have autonomy without chaos, the organization defines standards and golden paths:

  • Standard: a rule that must be met ("every REST API exposes OpenAPI," "logs come out in JSON"). Ideally, verifiable automatically.
  • Golden path: the recommended and supported way to do something common (a microservice template, a ready-made CI/CD pipeline). It is not mandatory, but it is the easy path: whoever strays off it bears the cost.
  • Guide: a recommendation without obligation ("we prefer constructor injection").

The key is to distinguish what is mandatory and automatable from what is recommended. The more that can be verified with tools (linters, fitness functions, templates), the less you need to police by hand. A good standard is not documented in a PDF: it is codified in a check that fails the build if it is violated.

# Example: a standard codified as a check in the CI pipeline
# "Every container image must declare a non-root user"
verify-non-root-user:
  stage: security
  script:
    - test "$(grep -c '^USER ' Dockerfile)" -ge 1 || (echo "Missing USER directive" && exit 1)

This snippet turns a security standard ("do not run as root") into a check that fails the build if the Dockerfile does not include a USER directive. It is executable governance: nobody has to remember the rule or review it by hand, because the pipeline enforces it. We will see this philosophy taken to the extreme in the next lesson on fitness functions.

  1. Common Mistakes and Tips

  • Documentation that nobody reads or maintains. A giant, obsolete wiki is worse than nothing. Prefer short ADRs versioned with the code.
  • Editing accepted ADRs. It breaks historical traceability. If the decision changes, write a new ADR that supersedes the previous one.
  • A committee that blocks everything. If every decision needs prior approval from a central body, delivery grinds to a halt. The committee advises; the team decides and documents.
  • Documenting trivial decisions. Reserve ADRs for decisions that are costly to reverse or that affect many. Do not document a date format with an ADR.
  • Standards only on paper. If a standard cannot be verified automatically, it will be violated silently. Codify it whenever you can.
  • Tip: number ADRs sequentially and never reuse numbers. The complete history, including rejected and superseded ones, is part of the value.

  1. Exercises

Exercise 1. Decide which of these decisions deserve an ADR and which do not: (a) choosing between REST and gRPC for service-to-service communication; (b) the name of the root package; (c) using JWT authentication; (d) the order of imports.

Exercise 2. Write an ADR following the template for this decision: "the team will use PostgreSQL as the main database instead of MongoDB." Invent a reasonable context.

Exercise 3. Your organization wants to guarantee that all services expose a /health endpoint. Would you frame it as a guide, a standard, or a golden path? How would you verify it?

Solutions

Solution 1. They deserve an ADR: (a) and (c), because they are decisions costly to reverse and affect all teams. They do not deserve an ADR: (b) and (d), which are trivial conventions; they go in a style guide or in the linter, not in an ADR.

Solution 2. (Example) Status: Accepted. Context: we need ACID transactions and strong relationships between orders, line items, and customers; the team is proficient in SQL and we do not foresee schemaless data. Decision: we decided to use PostgreSQL as the main database. Consequences: we gain referential integrity and transactions; we forgo MongoDB's schema flexibility and accept that highly variable data would require JSONB columns. Alternatives: MongoDB (discarded: we do not need a flexible schema and would lose easy multi-document transactions).

Solution 3. The best is a standard ("every service exposes /health") reinforced with a golden path (the service template already includes the endpoint, so meeting it is free). Verification is automated: a contract test in CI that starts the service and checks that /health responds with 200, failing the build if not.

  1. Conclusion

Modern architectural governance bets on being lightweight, distributed, and executable: moving decisions to the team that has the knowledge, documenting them with short, immutable ADRs versioned alongside the code, and turning the committee into an advisor rather than a gatekeeper. We have seen how to write ADRs with a template and a complete example, how architecture guilds operate, and how standards gain strength when they are codified into automatic checks instead of staying on paper. That last idea—verifying the architecture automatically—is the perfect bridge to the next lesson: Fitness Functions and Evolutionary Architecture, where we will learn to write tests that check that the architecture stays healthy as the system evolves.

Application Architecture Course

Module 1: Fundamentals of Application Architecture

Module 2: Design Principles and Tactics

Module 3: Architectural Styles and Patterns

Module 4: Distributed Architectures and Microservices

Module 5: Event-Driven Architectures and Messaging

Module 6: Domain-Driven Design (DDD)

Module 7: Data and Persistence

Module 8: Cloud Architecture and Deployment

Module 9: Quality, Security and Observability

Module 10: Evolution, Governance and Case Studies

© Copyright 2026. All rights reserved