This post continues from the tenth part. Architecture decisions often end up in Markdown files somewhere in the repository — and nobody remembers why the model looks the way it does. Bausteinsicht solves this: ADRs can be linked directly to elements and relationships in the model.
What are ADRs?
Architecture Decision Records (ADRs) document an architecture decision with context, options, and rationale. The format is intentionally lightweight — typically one short Markdown file per decision.
The problem: without direct linking, ADRs are isolated from the model. You can see in the diagram that an element exists, but not why it was designed that way.
Defining ADRs in the Specification
ADRs belong in specification.decisions in architecture.jsonc:
{
"specification": {
"decisions": [
{
"id": "ADR-001",
"title": "Monolith → Microservices Migration",
"status": "active",
"date": "2025-03-15",
"file": "docs/decisions/ADR-001-microservices.md"
},
{
"id": "ADR-002",
"title": "PostgreSQL as primary database",
"status": "active",
"date": "2025-03-20",
"file": "docs/decisions/ADR-002-postgresql.md"
},
{
"id": "ADR-003",
"title": "Auth via JWT instead of Sessions",
"status": "active",
"date": "2025-04-01",
"file": "docs/decisions/ADR-003-jwt-auth.md"
},
{
"id": "ADR-004",
"title": "REST API Gateway Pattern",
"status": "superseded",
"date": "2025-02-10",
"file": "docs/decisions/ADR-004-api-gateway.md"
}
]
}
}Possible status values:
| Status | Meaning |
|---|---|
| Decision proposed, not yet final |
| Current, valid decision |
| Outdated, but not yet replaced |
| Replaced by a newer ADR |
The file field points to the actual ADR file in the repository.
Bausteinsicht does not open it automatically — it is a pointer for developers and tools.
Linking ADRs to Elements
Each element can contain a decisions array with ADR IDs:
{
"model": {
"authservice": {
"kind": "service",
"title": "Auth Service",
"technology": "Go",
"decisions": ["ADR-003"]
},
"shop": {
"kind": "system",
"title": "Shop System",
"decisions": ["ADR-001"],
"children": {
"db": {
"kind": "database",
"title": "Shop DB",
"technology": "PostgreSQL",
"decisions": ["ADR-002"]
}
}
}
}
}Linking ADRs to Relationships
Relationships can also reference ADRs — for example when a decision concerns the communication architecture:
{
"relationships": [
{
"from": "shop.frontend",
"to": "authservice",
"label": "authenticate",
"decisions": ["ADR-003"]
}
]
}bausteinsicht adr list
Show all ADRs in the model:
bausteinsicht adr listOutput:
Decisions (4): ────────────────────────────────────────── ADR-001 ✓ Monolith → Microservices Migration Date: 2025-03-15 File: docs/decisions/ADR-001-microservices.md ADR-002 ✓ PostgreSQL als primäre Datenbank Date: 2025-03-20 File: docs/decisions/ADR-002-postgresql.md ADR-003 ✓ Auth via JWT statt Sessions Date: 2025-04-01 File: docs/decisions/ADR-003-jwt-auth.md ADR-004 ✗ REST API Gateway Pattern Date: 2025-02-10 File: docs/decisions/ADR-004-api-gateway.md
Status icons: ✓ active, ◯ proposed, ⚠ deprecated, ✗ superseded.
ADRs for a Specific Element
bausteinsicht adr list --element shop.dbShows only ADRs directly linked to shop.db.
JSON Output
bausteinsicht adr list --format json[
{
"id": "ADR-001",
"title": "Monolith → Microservices Migration",
"status": "active",
"date": "2025-03-15",
"file": "docs/decisions/ADR-001-microservices.md"
}
]bausteinsicht adr show
Details for a single ADR — including which elements and relationships reference it:
bausteinsicht adr show ADR-003Output:
ADR: ADR-003 ✓ ────────────────────────────────────────── Title: Auth via JWT statt Sessions Status: active Date: 2025-04-01 File: docs/decisions/ADR-003-jwt-auth.md Referenced by: - element: authservice - relationship: shop.frontend → authservice
This shows at a glance: this decision affects the Auth Service and the connection from the frontend to the Auth Service.
Typical ADR Workflow
Documenting a New Decision
Write the ADR file (e.g.
docs/decisions/ADR-005-event-sourcing.md)Add an entry to
specification.decisionsLink affected elements/relationships with
"decisions": ["ADR-005"]bausteinsicht validate— ensures that all referenced ADR IDs exist
bausteinsicht validate
# ✓ All ADR references are validValidate checks that all ADR IDs in decisions arrays are also defined in specification.decisions.
Superseding a Decision
When ADR-004 is superseded by ADR-007:
{
"id": "ADR-004",
"title": "REST API Gateway Pattern",
"status": "superseded",
"date": "2025-02-10",
"file": "docs/decisions/ADR-004-api-gateway.md"
},
{
"id": "ADR-007",
"title": "GraphQL Federation instead of REST Gateway",
"status": "active",
"date": "2025-07-01",
"file": "docs/decisions/ADR-007-graphql-federation.md"
}ADR-004 remains in the model — the superseded status indicates it is no longer valid.
This keeps the decision history traceable.
Why Directly in the Model Instead of Separate Tools?
ADR tools like adr-tools or Log4brains manage ADRs well — but they know nothing about the architecture model.
The linking in Bausteinsicht brings both together:
| Bausteinsicht stores only metadata (ID, title, status, date, path) — not the ADR content itself. The actual files remain in the repository; Bausteinsicht only references them. |
Example Model
The example for this part (elements and relationships with decisions references) is located at teil_11.jsonc.
This is what the result looks like in draw.io (bausteinsicht sync):
You can find the draw.io file here: teil_11.drawio
Generated PNG files via bausteinsicht export --image-format png:


Generated PlantUML diagrams via bausteinsicht export-diagram:
What Comes Next
Part 12: Overlay & Heatmap — Overlay external metrics like error rate or coverage onto architecture diagrams
Part 13: Graph Analysis — Uncover cycles and dependency patterns in the model graph
Official documentation: User Manual · Tutorial on doctoolchain.org