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:

StatusMeaning

proposed

Decision proposed, not yet final

active

Current, valid decision

deprecated

Outdated, but not yet replaced

superseded

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 list

Output:

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.db

Shows 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-003

Output:

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

  1. Write the ADR file (e.g. docs/decisions/ADR-005-event-sourcing.md)

  2. Add an entry to specification.decisions

  3. Link affected elements/relationships with "decisions": ["ADR-005"]

  4. bausteinsicht validate — ensures that all referenced ADR IDs exist

bausteinsicht validate
# ✓ All ADR references are valid

Validate 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:

  • In the draw.io diagram you can see which elements have ADRs (→ CodeLens via LSP, Part 9)

  • bausteinsicht adr show displays the impact of a decision on the model

  • LLMs receive the complete decision context via bausteinsicht adr list --format json (→ Part 10)

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:

containers
context

Generated PlantUML diagrams via bausteinsicht export-diagram:

Diagram
Diagram

What Comes Next

Official documentation: User Manual · Tutorial on doctoolchain.org