# ADR-[NNN]: [Short decision title in active voice]

> Detailed architecture decision record combining the decision description
> fields proposed by Jeff Tyree and Art Akerman (IEEE Software, 2005) with
> Olaf Zimmermann's Y-statement summary. Use it for decisions that are
> costly to reverse or that several teams depend on. For everyday
> decisions, the shorter ADR or MADR templates are enough.

<!--
Guidance: How to use this template
- Write the Y-statement (section 1) last, after the positions and argument
  are settled, then move it to the top so readers get the decision in one
  sentence.
- Record at least two positions, including the one you rejected. A record
  with a single option documents a choice, not a decision.
- Keep the record immutable once accepted. To change the decision, write a
  new ADR and mark this one "Superseded by ADR-[NNN]".
- Store ADRs next to the code or architecture documentation they govern,
  numbered sequentially.
-->

| Field | Value |
|---|---|
| ID | ADR-[NNN] |
| Title | [Short decision title] |
| Status | [Proposed / Accepted / Rejected / Deprecated / Superseded by ADR-NNN] |
| Group | [Architecture area, for example Integration, Data, Security, Platform] |
| Decision owner | [@name] |
| Deciders | [@name, @name] |
| Consulted | [@team-a, @security] |
| Informed | [@team-b, @operations] |
| Date proposed | YYYY-MM-DD |
| Date decided | YYYY-MM-DD |
| Review by | [YYYY-MM-DD or trigger, for example "when traffic exceeds 2,000 requests/s"] |

## 1. Summary (Y-statement)

<!-- Guidance: One sentence in the fixed six-part pattern. Name the rejected options and the downside you accept; that is what makes the statement useful later. -->

In the context of [functional or architectural context, for example "the
order service publishing events to five downstream consumers"], facing
[the concern or non-functional requirement, for example "the need for
at-least-once delivery without coupling release cycles"], we decided for
[the chosen option, for example "a transactional outbox with a managed
message broker"] and neglected [the rejected options, for example "direct
synchronous calls and a distributed two-phase commit"], to achieve [the
benefits, for example "independent deployability and no lost events"],
accepting that [the drawbacks, for example "consumers must be idempotent
and events arrive up to 5 s late"].

## 2. Issue

<!-- Guidance: Describe the architectural problem being addressed, why it must be decided now, and what happens if nothing is decided. -->

[Describe the issue. Example: "The order service currently calls the
invoicing, shipping and loyalty services synchronously. Any outage of a
downstream service blocks checkout; three incidents in Q2 caused 4.5 hours
of checkout downtime. Two new consumers are planned for next quarter,
which would make the coupling worse."]

## 3. Decision

<!-- Guidance: State the decision clearly and specifically, in active voice. Someone implementing it should know what to do. -->

[Example: "The order service will write domain events to an outbox table
in the same transaction as the order change. A relay process publishes
outbox rows to the managed message broker topic `orders.v1`. Downstream
services consume from their own subscriptions and must handle duplicate
events."]

## 4. Assumptions

<!-- Guidance: List the conditions you believe to be true that the decision relies on. If an assumption turns out false, the decision should be revisited. -->

| ID | Assumption | How it could be checked |
|---|---|---|
| AS-1 | *Example:* Peak event volume stays below 500 events/s for two years | Monthly capacity report |
| AS-2 | *Example:* The managed broker meets our 99.95% availability target | Provider SLA and incident history |
| AS-3 | *Example:* Consumers can tolerate up to 5 s delivery delay | Confirmed with consumer teams |
| [AS-n] | [Assumption] | [Check] |

## 5. Constraints

<!-- Guidance: Capture limits imposed by the environment that the decision must respect: standards, budgets, existing contracts, skills, regulation. -->

| ID | Constraint | Source |
|---|---|---|
| CO-1 | *Example:* Only managed services approved by the platform team may be used | Platform policy |
| CO-2 | *Example:* Order data must not leave the EU | Data protection policy |
| [CO-n] | [Constraint] | [Source] |

## 6. Positions

<!-- Guidance: Describe each option that was seriously considered, including the chosen one. Give each a fair, neutral description before evaluating. -->

| Position | Description | Pros | Cons |
|---|---|---|---|
| P1 | *Example:* Keep synchronous REST calls, add retries and circuit breakers | No new infrastructure; familiar | Checkout still depends on downstream availability; retries amplify load |
| P2 | *Example:* Transactional outbox and managed broker (chosen) | No lost events; consumers decoupled; new consumers need no producer change | New component to operate; eventual consistency; idempotent consumers required |
| P3 | *Example:* Distributed transaction across services | Strong consistency | Not supported by managed databases; poor availability; high complexity |
| [Pn] | [Description] | [Pros] | [Cons] |

## 7. Argument

<!-- Guidance: Explain why the chosen position wins against the criteria that matter, referencing assumptions and constraints. This is the heart of the record. -->

[Example: "Availability of checkout is the top quality goal (see quality
scenario QS-03). P1 cannot meet it because any downstream outage still
blocks the request path. P3 conflicts with constraint CO-1 and reduces
availability further. P2 removes downstream services from the checkout
path, satisfies CO-1 and CO-2 with the EU-hosted managed broker, and makes
adding consumers a change on the consumer side only. Its costs, operating
a relay and making consumers idempotent, are lower than one more hour of
checkout downtime per quarter."]

| Criterion | Weight | P1 | P2 | P3 |
|---|---|---|---|---|
| Checkout availability | 3 | 1 | 3 | 1 |
| Delivery guarantee | 2 | 2 | 3 | 3 |
| Operational effort | 2 | 3 | 2 | 1 |
| Fit with platform policy | 2 | 3 | 3 | 0 |
| **Weighted score** | | **19** | **25** | **11** |

## 8. Implications

<!-- Guidance: List what follows from the decision: work to do, new requirements, changes for other teams, training, follow-up decisions. -->

- [Example: Every consumer must deduplicate by event ID; the platform
  team publishes a shared library for this by YYYY-MM-DD.]
- [Example: Operations adds alerts on outbox backlog older than 60 s.]
- [Example: The event schema `orders.v1` becomes a public contract;
  breaking changes require a new topic version.]
- [Example: Reporting that relied on synchronous invoicing must accept a
  delay of up to 5 s.]

## 9. Related decisions

<!-- Guidance: Link decisions this one depends on, constrains, or supersedes. -->

| Decision | Relationship |
|---|---|
| *Example:* ADR-012 Adopt managed message broker | Depends on |
| *Example:* ADR-019 Event schema versioning | Constrains |
| [ADR-NNN] | [Depends on / Constrains / Supersedes / Superseded by / Related] |

## 10. Related requirements

<!-- Guidance: Trace the decision to the requirements or quality scenarios it serves, so it can be re-evaluated when they change. -->

| Requirement | How the decision addresses it |
|---|---|
| *Example:* QS-03 Checkout available during downstream outage | Downstream calls removed from checkout path |
| *Example:* NFR-07 No lost order events | Outbox written in the same transaction |
| [ID] | [How addressed] |

## 11. Related artifacts

<!-- Guidance: Point to the architecture views, designs, code and documents affected by or describing this decision. -->

| Artifact | Location | Change needed |
|---|---|---|
| *Example:* Container diagram | Architecture document section 4 | Add broker and relay |
| *Example:* Order service code | `services/orders/outbox` | New module |
| [Artifact] | [Location] | [Change] |

## 12. Related principles

<!-- Guidance: Name the architecture principles the decision applies or deviates from. A deviation needs a waiver reference. -->

| Principle | Applied or deviated | Note |
|---|---|---|
| *Example:* Prefer asynchronous integration between domains | Applied | |
| *Example:* Use managed services before self-hosting | Applied | Broker is a managed service |
| [Principle] | [Applied / Deviated, waiver ID] | [Note] |

## 13. Notes

<!-- Guidance: Record discussion history, open points raised during review, and the dates of review meetings. -->

| Date | Note | By |
|---|---|---|
| YYYY-MM-DD | *Example:* Security asked whether events contain personal data; confirmed only customer ID is included | @name |
| YYYY-MM-DD | [Note] | [@name] |

## Standard and licence note

Based on the architecture decision description template by Jeff Tyree
and Art Akerman ("Architecture Decisions: Demystifying Architecture",
IEEE Software 22(2), 2005) and the Y-statement format by Olaf Zimmermann.
This template is original text written for this collection and reproduces
no text from those publications. Template licence: MIT.
