Back to Blog

Architecture Decision Records: Tracking Every Critical Technical Choice with ADRs

TL;DR

Coomia DIPPublished on July 8, 202521 min read
Share this articleTwitter / X

Architecture Decision Records: Tracking Every Critical Technical Choice with ADRs

“

Series: S2 Architecture Overview · Article 15 | Level: Intermediate | Reading Time: 18 min

TL;DR

  • Architecture Decision Records (ADRs) are a lightweight documentation method for recording "why a particular technical decision was made." coomia-dip uses ADRs to systematically track every critical decision, from communication protocol selection (gRPC vs REST) to build tool selection (Gradle vs Maven).
  • A good ADR does not just document "what was chosen" -- more importantly, it documents "why other options were not chosen." Rejected alternatives and their rationale are crucial for future developers understanding the architectural context -- they answer the most commonly asked question: "why didn't we use X back then?"
  • ADRs are "living documents," not "historical archives." When changes in the technical landscape require modifying an original decision, the old ADR is not deleted but rather superseded by a new ADR that references it. This preserves the complete decision evolution chain.

#1. Introduction: The Forgotten "Why"

#1.1 The Question Every Project Faces

Throughout a software project's lifecycle, the most frequently asked question is not "how is this implemented?" (the code answers that), but "why was it implemented this way?"

Code
"Why use gRPC instead of REST for internal communication?"
"Why use Gradle instead of Maven for Java projects?"
"Why use Python instead of Java for Reasoning & Decision Layer?"
"Why use Kafka instead of RabbitMQ?"
"Why use Doris instead of ClickHouse?"

These questions are raised weekly by newly onboarded developers in the coomia-dip project. Without systematic documentation, the answer typically relies on "finding the person who was involved in the decision" -- and when that person leaves the team, this invaluable architectural context is lost forever.

#1.2 What Is an ADR

An ADR (Architecture Decision Record) is a lightweight, structured document format for recording significant architectural decisions. Each ADR contains:

  • Context: The situation and constraints faced when making the decision
  • Decision: What was ultimately chosen
  • Alternatives: Options considered but not selected, with rationale
  • Consequences: Positive and negative impacts of the decision

An ADR is not a design document, not a technical specification, not meeting minutes -- it is a distilled decision record, typically completable in 1-2 pages.

#1.3 coomia-dip ADR Practice

The coomia-dip project uses ADRs as one of its core architectural governance tools. In the project's CLAUDE.md, multiple technical red lines are effectively the enforcement results of key ADRs:

Code
No REST/JSON between internal services (must use gRPC)      → ADR-001
No Spring Boot for Reasoning & Decision Layer + Agent Runtime Layer (must use Python)               → ADR-003
No Maven for Java projects (must use Gradle)                 → ADR-005
No bypassing Ontology for direct DB access                   → ADR-007

Behind each red line is a complete ADR explaining the context, rationale, and trade-offs.

#2. ADR Template and Format

#2.1 coomia-dip ADR Template

coomia-dip uses the following standardized template:

Markdown
# ADR-{number}: {Decision Title}

## Status
{Proposed | Accepted | Deprecated | Superseded by ADR-XXX}

## Date
YYYY-MM-DD

## Context
{Describe the situation, constraints, and requirements at decision time}

## Decision
{Clearly state the decision made}

## Alternatives

### Option A: {Name}
- Pros: ...
- Cons: ...
- Reason not chosen: ...

### Option B: {Name}
- Pros: ...
- Cons: ...
- Reason not chosen: ...

## Consequences

### Positive
- ...

### Negative
- ...

### Risks and Mitigations
- Risk: ...
  Mitigation: ...

## References
- {Related links, documents, discussions}

#2.2 ADR Numbering Scheme

coomia-dip ADRs are grouped by domain:

RangeDomainExample
001-099Communication & ProtocolsADR-001 gRPC vs REST
100-199Data & StorageADR-101 Doris vs ClickHouse
200-299Compute & RuntimeADR-201 Python for Reasoning & Decision Layer
300-399Build & EngineeringADR-301 Gradle vs Maven
400-499Testing & QualityADR-401 Testcontainers
500-599Deployment & OperationsADR-501 Docker Compose
600-699Security & GovernanceADR-601 Ontology Forced Routing
700-799SDK & Developer ExperienceADR-701 Python SDK First

#3. Core ADR Deep Dive: Communication Protocol

#3.1 ADR-001: gRPC Over REST for Internal Communication

Status: Accepted

Date: 2025-06-15

Context:

coomia-dip consists of 8 Layers, each an independent service or service group. These Layers require high-frequency, low-latency communication. The platform uses both Java (Control Layer + Data Layer) and Python (Reasoning & Decision Layer + Agent Runtime Layer), so the communication protocol must have cross-language capabilities.

Constraints to consider:

  1. Serialization compatibility between Java and Python
  2. Communication latency impact on derived property computation chains (see S2-07)
  3. Version management and backward compatibility of interface definitions
  4. Team learning costs and toolchain maturity

Decision:

All inter-service communication must use gRPC + Protobuf. REST/JSON is used only at the API gateway layer facing external users.

Alternatives:

Option A: REST + JSON

  • Pros: High team familiarity, rich debugging tools (Postman, curl), directly testable in browsers
  • Cons: JSON serialization/deserialization overhead is significant (4-5x slower than Protobuf); no strongly-typed interface definitions, cross-language compatibility depends on documentation rather than code; HTTP/1.1 creates one connection per request, no bidirectional streaming
  • Not chosen because: In high-frequency internal call scenarios (e.g., derived property cascade computation may trigger dozens of cross-Layer calls), JSON serialization overhead goes from negligible to a significant bottleneck

Option B: REST + Protobuf

  • Pros: Retains REST semantics while gaining Protobuf serialization benefits
  • Cons: Non-standard combination with limited toolchain support; still constrained by HTTP/1.1 connection model; code generation tools are less mature than the gRPC ecosystem
  • Not chosen because: A compromise between two worlds, lacking both REST's ecosystem advantage and gRPC's full capabilities

Option C: Apache Thrift

  • Pros: Similar IDL + code generation to gRPC, excellent performance
  • Cons: Less active community than gRPC; weaker streaming capabilities; poorer cloud-native ecosystem integration (Envoy, Istio) compared to gRPC
  • Not chosen because: gRPC has become the de facto standard for cloud-native communication; choosing Thrift would increase future infrastructure integration costs

Consequences:

Positive:

  • Cross-language interface compatibility is guaranteed by the Protobuf compiler, eliminating "documentation-code inconsistency" issues
  • 4-5x serialization performance improvement, reducing communication overhead in derived property cascade computation
  • Bidirectional streaming support provides native capability for real-time event pushing
  • Natural integration with the Kubernetes ecosystem (gRPC health checks, load balancing)

Negative:

  • Increased debugging difficulty -- gRPC uses a binary protocol, unlike JSON which can be viewed directly in a browser
  • Team learning curve -- need to learn Protobuf syntax and gRPC concepts
  • Toolchain requirements -- need to configure the protoc compiler and language-specific code generation plugins

Risks and Mitigations:

  • Risk: Debugging difficulty impacts development efficiency Mitigation: Introduce grpcurl and gRPC reflection API for a curl-like debugging experience; configure gRPC-Web proxy for development environments
  • Risk: Proto file changes cause cross-language incompatibility Mitigation: CI pipeline enforces dual-language compilation and contract tests (see S2-14)

#4. Core ADR Deep Dive: Technology Stack

#4.1 ADR-201: Python for Reasoning & Decision Layer + Agent Runtime Layer (Intelligence Layer)

Status: Accepted

Date: 2025-07-02

Context:

Reasoning & Decision Layer (Reasoning & Decision) and Agent Runtime Layer (Agent Runtime) need to handle:

  • Rule engine evaluation
  • Machine learning model inference
  • AI Agent orchestration
  • LLM API integration

The team needed to decide whether these two Layers should use Java (consistent with Control Layer + Data Layer) or Python.

Decision:

Reasoning & Decision Layer and Agent Runtime Layer must use Python 3.x + FastAPI. Spring Boot is prohibited.

Alternatives:

Option A: Java + Spring Boot

  • Pros: Unified technology stack with Control Layer + Data Layer, team has extensive Java experience, excellent JVM runtime performance
  • Cons: ML/AI ecosystem is far behind Python; integrating with PyTorch, Transformers, LangChain requires JNI or subprocess calls, adding complexity; virtually all new AI libraries and models provide Python SDKs first
  • Not chosen because: AI/ML is the core capability of Reasoning & Decision Layer + Agent Runtime Layer -- choosing Java means perpetually "chasing" the Python ecosystem rather than "leveraging" it

Option B: Python + Django

  • Pros: Django is Python's most mature web framework with powerful ORM
  • Cons: Django is a synchronous framework, async support (async views) was added later and feels non-native; Django's ORM is unused in coomia-dip (data access goes through the Ontology layer); framework is too heavy with many unused features
  • Not chosen because: FastAPI was designed async-first, perfectly matching the I/O-intensive nature of AI/ML workloads; Pydantic integration provides native data validation and serialization

Option C: Python + Flask

  • Pros: Lightweight and flexible, gentle learning curve
  • Cons: No built-in async support (requires Quart or ASGI adapter); no built-in data validation; no automatic OpenAPI documentation generation
  • Not chosen because: FastAPI is comprehensively superior to Flask in async performance, type safety, and API documentation

Consequences:

Positive:

  • Direct access to Python AI/ML ecosystem (PyTorch, Transformers, LangChain, etc.)
  • FastAPI's async-native support perfectly matches the high-latency nature of LLM API calls
  • Pydantic v2 provides runtime type validation, complementing Protobuf message formats
  • Easier to recruit AI/ML engineers -- Python is the lingua franca of the field

Negative:

  • Team needs to maintain two technology stacks (Java and Python) simultaneously
  • Python runtime performance is inferior to JVM (impacts CPU-intensive tasks)
  • Dependency management (pip/poetry) is less unified than Gradle
  • Two languages mean different code styles and best practices, requiring dual standards

#4.2 ADR-301: Gradle Over Maven for Java Builds

Status: Accepted

Date: 2025-06-20

Context:

coomia-dip Java projects (Control Layer and Data Layer) need a build tool. The project CLAUDE.md has already listed this as a technical red line:

Code
No Maven for Java projects (must use Gradle)

The technical rationale behind this red line needs to be documented.

Decision:

All Java projects must use Gradle 8.x for builds.

Alternatives:

Option A: Maven

  • Pros: Industry standard, convention over configuration, most Java developers are familiar with it, excellent IDE support
  • Cons: Verbose XML configuration, custom tasks require plugin authoring; weak incremental build capability -- nearly every build is a full build; slow multi-module project builds (2-3x slower than Gradle); inflexible, complex build requirements need extensive plugin configuration
  • Not chosen because: coomia-dip Control Layer and Data Layer are both multi-module projects (10+ submodules), and Maven's full-build model wastes significant time during daily development

Option B: Bazel

  • Pros: Open-sourced by Google, ultimate incremental builds and caching, multi-language support (unified Java + Python builds)
  • Cons: Extremely steep learning curve, configuration complexity far exceeds Gradle; Java ecosystem integration is inferior to Gradle (many libraries lack Bazel build rules); team has no Bazel experience
  • Not chosen because: Bazel's advantages materialize only in ultra-large-scale monorepos; coomia-dip's project scale is well served by Gradle

Consequences:

Positive:

  • Incremental builds reduce daily development build times from minutes to seconds
  • Kotlin DSL build.gradle.kts provides type-safe build configuration
  • Gradle has excellent Protobuf code generation plugin support (protobuf-gradle-plugin)
  • Good integration with Spring Boot and Quarkus Gradle plugins

Negative:

  • Some team members need to transition from Maven to Gradle
  • Gradle's flexibility sometimes leads to "a thousand ways to do the same thing"
  • Gradle Wrapper version management requires additional attention

#5. Core ADR Deep Dive: Data Storage

#5.1 ADR-101: Apache Doris as OLAP Engine

Status: Accepted

Date: 2025-07-10

Context:

coomia-dip needs an OLAP engine to support:

  • Large-scale analytical queries
  • Materialized views (ComputationCoordinator's MATERIALIZED mode)
  • Real-time data ingestion and near-real-time queries
  • SQL compatibility (lower learning curve)

Decision:

Use Apache Doris as the platform's primary OLAP engine.

Alternatives:

Option A: ClickHouse

  • Pros: Exceptional single-table query performance, high columnar storage compression, active community
  • Cons: Poor multi-table JOIN performance (coomia-dip's relationship queries are frequent); limited materialized view functionality; weak distributed transaction support; real-time updates (UPSERT) require ReplacingMergeTree engine with brief data inconsistency windows
  • Not chosen because: coomia-dip's Ontology queries frequently involve multi-table JOINs for object relationships, which is ClickHouse's weak point

Option B: Apache Druid

  • Pros: Strong real-time ingestion, excellent time-series queries
  • Cons: Incomplete SQL support; no standard UPDATE/DELETE; high operational complexity (multiple node types); weak materialized view capabilities
  • Not chosen because: coomia-dip is not a purely time-series analytics scenario; full SQL semantics are required

Option C: StarRocks

  • Pros: Architecture similar to Doris, slightly better in performance benchmarks, strong materialized views
  • Cons: Commercially driven, community edition has feature limitations; domestic user community is less active than Doris; long-term direction influenced by commercial strategy
  • Not chosen because: Doris as an Apache Top-Level Project has more open community governance and better long-term sustainability

Consequences:

Positive:

  • MySQL-compatible SQL syntax lowers team learning costs
  • Materialized view functionality directly supports ComputationCoordinator's MATERIALIZED mode
  • Real-time ingestion + near-real-time queries satisfy most derived property computation needs
  • Apache Foundation project status ensures open-source sustainability

Negative:

  • Doris's ecosystem (connectors, tools) is less rich than ClickHouse's
  • Not as performant as ClickHouse in extreme performance scenarios (but coomia-dip's query patterns are not extreme)
  • Need to monitor Doris version upgrade compatibility

#6. Core ADR Deep Dive: Architecture Patterns

#6.1 ADR-601: Mandatory Ontology Routing

Status: Accepted

Date: 2025-06-25

Context:

The project CLAUDE.md technical red line:

Code
No bypassing Ontology for direct database access

This red line requires all data access to go through OntologyRuntimeService, even though this means additional gRPC call overhead (2-5ms). The complete context of this decision needs to be documented.

Decision:

All service data reads and writes must go through OntologyRuntimeService's gRPC interface. Direct database connections from any service are prohibited.

Rationale (see S2-04 Ontology Kernel article for details):

  1. Unified permission checking: The Ontology layer performs permission validation on every operation; direct DB access bypasses the permission system
  2. Schema validation: The Ontology layer guarantees all writes conform to ObjectType-defined constraints
  3. Audit trail: Every operation automatically generates audit logs; direct DB access creates "untraceable" data changes
  4. Event publishing: Data changes automatically trigger CDC events; direct DB access causes derived properties to miss cascade updates

Rejected Alternative:

"Allow read-only direct access" -- it was proposed to allow direct DB connections for read-only scenarios to improve query performance. Rejected because:

  • Read-only queries still require permission checking
  • Read-only queries also need audit records
  • Once a "read-only direct" exception is opened, it quickly evolves into "write-direct too"
  • 2-5ms Ontology overhead is acceptable for most scenarios

#7. ADR Lifecycle Management

#7.1 ADR Status Transitions

Code
Proposed
  │
  ├── Team discussion & technical review
  │
  ├── Accepted
  │       │
  │       ├── Environment changes / new requirements
  │       │
  │       └── Superseded (by ADR-XXX)
  │               │
  │               └── New ADR references old ADR
  │
  └── Rejected
          │
          └── Rejection reasons documented (equally valuable)

#7.2 When to Create an ADR

Not every technical decision needs an ADR. coomia-dip uses these criteria:

Needs ADRDoes Not Need ADR
Choosing a database or message queueChoosing a log format
Choosing a communication protocolChoosing code indentation style
Choosing a programming languageChoosing variable naming convention
Defining security architecture patternsChoosing a specific encryption algorithm
Changing system boundariesRefactoring internal implementation details

Simple rule: If someone will ask "why" about this decision in 6 months, write an ADR.

#7.3 ADR Update Policy

Once an ADR is accepted, its body should not be modified (it records the decision context "at that time"). If changes are needed, create a new ADR:

Markdown
# ADR-102: Migrating from Doris to Doris + Iceberg Hybrid Architecture

## Status
Accepted (supersedes the "Doris as sole OLAP engine" portion of ADR-101)

## Context
ADR-101 chose Doris as the sole OLAP engine. After 6 months of operation,
cold data storage in Doris proved too expensive. Iceberg needs to be
introduced as a cold data storage layer...

#8. ADRs and Project Red Lines

#8.1 Red Lines = ADR Enforcement

Every technical red line in coomia-dip's CLAUDE.md corresponds to one or more ADRs:

Technical Red LineCorresponding ADRCore Rationale
No internal REST communicationADR-001Performance + cross-language type safety
No Spring Boot for Reasoning & Decision Layer + Agent Runtime LayerADR-201AI/ML ecosystem compatibility
No MavenADR-301Incremental build efficiency
No bypassing OntologyADR-601Permissions + audit + events
No as anyADR-702Type safety
No empty catch blocksADR-401Debuggability

#8.2 Red Line Exception Process

If a developer encounters a genuinely special scenario requiring a red line exception, it must go through this process:

Code
1. Submit a "Red Line Exception ADR"
   ├─ Explain why the red line must be crossed
   ├─ Describe the scope of impact
   └─ Propose mitigation measures

2. Architecture Review
   ├─ At least 2 Senior reviewers
   └─ Document review conclusions

3. If Approved
   ├─ Record the "scoped" exception in the ADR
   ├─ Set checkpoints (is the exception still necessary?)
   └─ Notify relevant Layer owners

#9. Team Collaboration Value of ADRs

#9.1 New Member Onboarding

For developers newly joining coomia-dip, ADRs are among the most effective onboarding materials. By reading the core ADRs, new members can understand within 2-3 hours:

  • Why these technologies were chosen over alternatives
  • What alternatives were historically considered
  • The trade-offs and compromises in each key decision
  • Which constraints can be challenged and which are immovable

#9.2 Cross-Team Alignment

In coomia-dip's multi-Layer architecture, different teams own different Layers. ADRs ensure all teams stay aligned on critical technical decisions:

Code
Control Layer team: "We want to expose a new interface via REST"
    → Check ADR-001 → Understand why gRPC is required
    → If special needs exist → Submit an exception ADR

Reasoning & Decision Layer team: "We want to rewrite performance-critical paths in Go"
    → Check ADR-201 → Understand why Python was chosen
    → If performance needs are legitimate → Submit new ADR evaluating Go adoption feasibility

#9.3 Technical Debt Management

The "negative consequences" and "risks" recorded in ADRs serve as an early warning system for technical debt. Teams can periodically review ADR predictions:

Code
ADR-001's predicted risk: "Debugging difficulty impacts development efficiency"
    → 6-month review → Debugging pain points did materialize
    → Mitigated by introducing grpcurl + gRPC reflection
    → Recorded in ADR-001's "retrospective" section

#10. ADR Anti-Patterns

#10.1 Common Anti-Patterns

Anti-PatternDescriptionConsequence
Retroactive writingADR written months after decision was implementedContext is lost, alternatives incompletely recalled
Over-detailedADR becomes a 20-page design documentNobody wants to read or write them
Missing alternativesOnly records "what was chosen" not "what else was considered"Future developers cannot understand decision context
Non-actionable"We should consider performance"Not a concrete, actionable decision
Never revisitedADR is filed and forgottenDecision may be outdated but nobody knows
Stealth editingDirectly modifying accepted ADR bodyBreaks the decision history chain

#10.2 Qualities of a Good ADR

A high-quality ADR should enable a reader 6 months later to understand within 5 minutes:

  1. What problem was faced (Context)
  2. What was decided (Decision -- summarized in one sentence)
  3. Why alternatives were not chosen (Alternatives -- the most valuable section)
  4. What costs must be borne (Consequences -- honest about negative impacts)

#11. ADR Toolchain

#11.1 Storage and Organization

coomia-dip stores ADRs as part of the code repository:

Code
docs/
└── adr/
    ├── README.md                    ← ADR index
    ├── templates/
    │   └── adr-template.md          ← Standard template
    ├── 001-grpc-over-rest.md
    ├── 101-doris-as-olap.md
    ├── 201-python-for-intelligence.md
    ├── 301-gradle-over-maven.md
    ├── 401-testing-pyramid.md
    ├── 501-docker-compose-deployment.md
    ├── 601-ontology-routing.md
    └── 701-python-sdk-first.md

#11.2 ADR and Git Integration

ADR changes follow the same version control process as code:

  • ADR creation and modification are submitted via PRs
  • PRs require at least 2 reviewer approvals
  • Post-merge, recorded via commit messages (using appropriate prefixes)
Code
add: ADR-102 Doris + Iceberg hybrid storage architecture decision

#11.3 Automated Indexing

The CI pipeline includes an automation script that regenerates the README.md index on every ADR change:

Python
# scripts/generate_adr_index.py
def generate_index(adr_dir: str) -> str:
    """Scan ADR directory and generate Markdown index"""
    adrs = []
    for path in sorted(Path(adr_dir).glob("*.md")):
        if path.name in ("README.md", "adr-template.md"):
            continue
        title = extract_title(path)
        status = extract_status(path)
        date = extract_date(path)
        adrs.append(f"| [{path.stem}]({path.name}) | {title} | {status} | {date} |")

    header = "| ADR | Title | Status | Date |\n|-----|-------|--------|------|\n"
    return header + "\n".join(adrs)

#12. ADRs and Architecture Evolution

#12.1 Decision Chain Tracking

ADRs form "decision chains" through cross-references:

Code
ADR-001 (gRPC internal communication)
    │
    ├── ADR-002 (Protobuf Schema management)
    │       └── ADR-003 (Proto files mono-repo management)
    │
    └── ADR-004 (gRPC streaming for event pushing)
            └── ADR-005 (Kafka as event backbone → replacing gRPC streaming)

ADR-101 (Doris as OLAP)
    │
    └── ADR-102 (Doris + Iceberg hybrid → supersedes part of ADR-101)

#12.2 Architecture Evolution Traceability

Through ADR chains, one can clearly see how the architecture evolved step by step:

Code
2025-06: ADR-001 → Choose gRPC for internal communication
2025-07: ADR-004 → Consider gRPC streaming for event pushing
2025-08: ADR-005 → Discover gRPC streaming unsuitable for large-scale events, switch to Kafka
2025-09: ADR-006 → Build 7 event roles on Kafka (see S2-06)

This evolution chain answers "why Kafka is used for event pushing instead of gRPC streaming" -- because ADR-004 tried it, and ADR-005 documented why it was abandoned.

#13. Comparison with Palantir Foundry

DimensionPalantir Foundrycoomia-dip
Decision recordsInternal technical memos (closed source)ADR public documents (code repository)
Decision trackingConfluence + JIRAGit version control + Markdown
Technical red linesInternal specification documentsCLAUDE.md + ADRs
New hire onboardingMentorship + internal trainingADR self-service reading + mentorship
Decision updatesDocument update notificationsPR approval + Git history
Architecture governanceArchitecture review committeeADR submission + peer review

As an open-source project, coomia-dip's ADR transparency is a core advantage. Any contributor can read the complete decision history and understand "why," not just see "what."

#14. Practical Recommendations

#14.1 Start Writing ADRs from Day One

Do not wait until the project "stabilizes" to start writing ADRs. The most valuable decisions typically occur early in the project, and early context is the most easily forgotten.

#14.2 Keep It Lightweight

An ADR should not exceed 2 pages. If it is growing too long, design documentation and decision records may be getting mixed together. ADRs only record "decisions" -- design details belong in other documents.

#14.3 Alternatives Are the Most Valuable Section

Spend more time writing "why not X" than "why Y." "Chose Y" is a visible fact in the code, but "why not X" is tacit knowledge that exists only in the decision-maker's mind.

#14.4 Review Regularly

Spend 1-2 hours each quarter reviewing existing ADRs:

  • Which decisions' negative consequences have materialized?
  • Which alternatives have become more attractive now?
  • Which ADRs need follow-up ADRs to course-correct?

#Key Takeaways

  1. The core of an ADR is not "what was chosen" but "why other options were not chosen." The code itself is the best documentation of "what was chosen," but "why" exists only in decision-makers' minds. When decision-makers leave the team, this critical context is lost forever. coomia-dip converts tacit knowledge into explicit documentation through its ADR system, ensuring every technical red line has traceable decision backing.

  2. ADRs are "living documents," not "historical archives" -- old decisions are not deleted but superseded by new ones. This chain structure preserves complete decision evolution history. When someone asks "why did we switch from gRPC streaming to Kafka for event pushing," the ADR chain clearly records the complete attempt, problem, and change process.

  3. Technical red lines must be backed by ADRs; otherwise it is "dictation" rather than "governance." Every technical red line in coomia-dip's CLAUDE.md corresponds to an ADR that developers can read to understand "why this red line exists." If there is a legitimate reason to cross a red line, an exception ADR can be submitted for team review. This mechanism balances architectural consistency with flexibility.

“

Series Retrospective: The S2 Architecture Overview series concludes here. From Article 1's Layered Architecture to Article 15's Architecture Decision Records, we have comprehensively presented coomia-dip's architectural design philosophy, technology selection rationale, and engineering practices. We hope these articles help readers understand not just "what coomia-dip is" but "why coomia-dip is the way it is."

Tags: #adr #architecture-decision-record #technical-governance #red-line #grpc #gradle #python #doris #ontology #decision-tracking #coomia-dip