# How Codebase Memory Implements Architecture Decision Records (ADR) Management

> Explore Codebase Memory's ADR management system for creating, storing, and updating Architecture Decision Records using a CLI, HTTP API, or web UI for robust architecture documentation.

- Repository: [Martin Vogel/codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp)
- Tags: how-to-guide
- Published: 2026-07-08

---

**The ADR management system in Codebase Memory provides a full-featured subsystem for creating, storing, retrieving, and updating Architecture Decision Records in a SQLite-backed repository, complete with CLI, HTTP API, and web UI interfaces.**

Codebase Memory, an open-source project under `DeusData/codebase-memory-mcp`, embeds a complete Architecture Decision Records (ADR) management system directly into its analysis engine. Unlike external documentation tools, this system stores ADRs alongside code intelligence in a unified SQLite database, enabling programmatic access through C libraries, command-line tools, and REST endpoints.

## ADR Storage Architecture

The foundation of the ADR management system rests on a three-layer design that separates persistent storage from content processing and user interfaces.

### SQLite Storage Layer

ADRs persist in the `project_summaries` table, sharing the same transactional storage as other project-level metadata. The public C API, declared in [`src/store/store.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/store/store.h), exposes four core operations:

- **`cbm_store_adr_store`** – Inserts a new ADR or overwrites an existing record for a project
- **`cbm_store_adr_get`** – Retrieves the complete ADR content for a given project identifier
- **`cbm_store_adr_delete`** – Permanently removes an ADR from the database
- **`cbm_store_adr_update_sections`** – Performs partial updates to specific sections without rewriting the entire document

These functions operate on a `cbm_store_t` handle, ensuring ACID compliance across all ADR operations.

## ADR Content Processing

The system treats ADR content as structured markdown with strict schema validation, ensuring consistency across all architectural records.

### Parsing and Rendering Engine

In [`src/store/store.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/store/store.c), the **`cbm_adr_parse_sections`** function implements a line-by-line markdown parser that detects `##` headers and maps them to a `cbm_adr_sections_t` structure. This parser recognizes six canonical sections: `PURPOSE`, `STACK`, `ARCHITECTURE`, `PATTERNS`, `TRADEOFFS`, and `PHILOSOPHY`.

For output generation, **`cbm_adr_render`** reassembles the section map into canonical markdown, emitting required sections in standard order followed by any custom sections sorted alphabetically. This round-trip parsing ensures that partial updates maintain document integrity.

### Validation Rules

Before persistence, `cbm_adr_validate_content` verifies that all six required sections are present, while `cbm_adr_validate_section_keys` restricts section names to the allowed set. This schema enforcement prevents malformed ADRs from entering the codebase memory.

## User Interfaces for ADR Management

Codebase Memory exposes ADR functionality through three complementary interfaces, accommodating different workflows from automation to manual editing.

### CLI Command Interface

The `manage_adr` command, registered in [`src/mcp/mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/mcp.c), supports `mode='create'` and `mode='update'` actions that wrap the underlying store functions. This command also includes migration logic to import legacy file-based ADRs from [`.codebase-memory/adr.md`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory/adr.md) into the database store.

### HTTP API Endpoints

The HTTP server in [`src/ui/http_server.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/ui/http_server.c) provides RESTful access to ADR data:

- **`GET /api/adr?project={name}`** – Returns the stored ADR as JSON
- **`POST /api/adr`** – Creates or updates an ADR using a JSON body with `project` and `content` fields

These endpoints enable external tools and CI/CD pipelines to read and write architectural decisions programmatically.

### Web UI Component

The React frontend includes ADR management through [`graph-ui/src/components/StatsTab.tsx`](https://github.com/DeusData/codebase-memory-mcp/blob/main/graph-ui/src/components/StatsTab.tsx), where an "ADR" button opens a modal interface for creating or editing records. This provides non-technical stakeholders with direct access to architectural documentation without requiring API calls or command-line usage.

## Working with ADRs in Code

The following examples demonstrate the C API for common ADR operations.

### Storing a New ADR

```c
const char *my_adr = 
    "## PURPOSE\n"

    "Explain why we choose SQLite.\n"
    "## STACK\n"

    "SQLite, libpq, …\n"
    "## ARCHITECTURE\n"

    "Single‑process DB.\n"
    "## PATTERNS\n"

    "Repository, DAO.\n"
    "## TRADEOFFS\n"

    "No clustering.\n"
    "## PHILOSOPHY\n"

    "Keep it simple.\n";

cbm_store_t *store = cbm_store_open("mydb.sqlite3");
int rc = cbm_store_adr_store(store, "my‑project", my_adr);
if (rc != CBM_STORE_OK) {
    fprintf(stderr, "Failed to store ADR: %s\n", cbm_store_errmsg(store));
}

```

### Retrieving an ADR

```c
cbm_adr_t adr = {0};
if (cbm_store_adr_get(store, "my‑project", &adr) == CBM_STORE_OK) {
    printf("ADR for %s:\n%s\n", adr.project, adr.content);
    cbm_store_adr_free(&adr);
}

```

### Updating Specific Sections

```c
const char *keys[]   = {"TRADEOFFS"};
const char *values[] = {"We give up clustering for simplicity."};
cbm_adr_t updated = {0};
int rc = cbm_store_adr_update_sections(store,
                                       "my‑project",
                                       keys, values, 1,
                                       &updated);
if (rc == CBM_STORE_OK) {
    printf("Updated ADR: %s\n", updated.content);
    cbm_store_adr_free(&updated);
}

```

### Using the HTTP API

```bash

# Get the ADR

curl -s "http://localhost:8080/api/adr?project=my-project" | jq .

# Update the ADR

curl -X POST http://localhost:8080/api/adr \
     -H "Content-Type: application/json" \
     -d '{"project":"my-project","content":"## PURPOSE\n…"}'

```

## Summary

- **Unified Storage**: ADRs live in the `project_summaries` table alongside other codebase metadata, accessible via `cbm_store_adr_*` functions in [`src/store/store.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/store/store.h).
- **Structured Content**: The system enforces six canonical sections (PURPOSE, STACK, ARCHITECTURE, PATTERNS, TRADEOFFS, PHILOSOPHY) through parsing and validation logic in [`src/store/store.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/store/store.c).
- **Multi-Modal Access**: Users interact with ADRs through the `manage_adr` CLI command, REST endpoints in [`src/ui/http_server.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/ui/http_server.c), or the React-based web interface.
- **Partial Updates**: The `cbm_store_adr_update_sections` function enables surgical modifications to specific sections without rewriting entire documents.

## Frequently Asked Questions

### What is the required format for ADR content in Codebase Memory?

ADR content must be valid markdown containing six specific sections marked with `##` headers: PURPOSE, STACK, ARCHITECTURE, PATTERNS, TRADEOFFS, and PHILOSOPHY. The `cbm_adr_parse_sections` function in [`src/store/store.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/store/store.c) validates this structure during storage operations, and `cbm_adr_render` ensures canonical ordering when retrieving records.

### How does the ADR management system handle legacy file-based records?

The `manage_adr` command in [`src/mcp/mcp.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/mcp.c) includes migration logic that automatically imports existing ADRs from [`.codebase-memory/adr.md`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory/adr.md) files into the SQLite database when running with `mode='create'`. This ensures historical architectural decisions are preserved when upgrading to newer versions of the tool.

### Can I update only one section of an ADR without rewriting the entire document?

Yes. The **`cbm_store_adr_update_sections`** function accepts arrays of section keys and values, allowing targeted updates to specific sections like TRADEOFFS or STACK while preserving all other content. This is particularly useful for automated tooling that needs to append decisions without parsing the full markdown document.

### Which database table stores ADR data in Codebase Memory?

ADRs are stored in the `project_summaries` table within the SQLite database, using the same storage layer as other project metadata. The `cbm_store_adr_store` and `cbm_store_adr_get` functions in [`src/store/store.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/store/store.h) provide the abstraction layer for reading and writing to this table.