Skip to main content

03.17Practice

Design docs, ADRs and C4 diagrams for AI coding agents

How AR Labs documents architecture so people and AI coding agents can read it: a design doc, one-page ADRs, and C4 diagrams kept as text.

On this page
  1. The problem it prevents
  2. Three artefacts, three gaps
  3. Rules for C4 diagrams
  4. Where the design record sits in the pipeline
  5. What we considered and did not adopt

Every system AR Labs builds is documented with three artefacts: a design document that tells the story of the system and why it is shaped as it is, architecture decision records that capture each significant choice on one page, and C4 diagrams that show the system at two zoom levels. Together they let a person or an AI agent understand a system without reading all of its code, which is why we keep them: an agent with no design record proposes patterns the system rejected months ago. The architecture overview explains how this record fits our wider approach.

The problem it prevents

Without a durable design record, architecture lives in conversation history and in whoever built it. Decisions are re-argued, agents propose patterns the system rejected months ago, and onboarding means reading everything. For AI coding agents the cost is direct: a campaign plan (the PRP for a large piece of work, before it is split into a tree of tasks) that has to restate the architecture every time is long, drifts out of date, and mixes design with implementation detail.

Three artefacts, three gaps

Artefact Answers Missing without it
Design document What is this system and why was it designed this way? No narrative, no alternatives considered, no non-goals
Architecture decision record (ADR) Why was this specific decision made? Decisions lost in chat, wikis and memory
C4 diagrams What does the system look like at each zoom level? No visual map

The design document follows the Google format, as described publicly by Malte Ubl: context and scope, goals and non-goals, the system design, alternatives considered, and cross-cutting concerns. Non-goals get particular weight: they name things that could reasonably be goals and are deliberately excluded, which stops scope creep before it starts. The document sits at the project root as DESIGN.md, is written for a technical reader with no project history, and is updated when the design changes, because a stale design doc misleads.

ADRs follow Michael Nygard's 2011 format: context, decision, consequences. One decision per record, one page per decision. Once accepted, an ADR is never edited; reversing a decision means writing a new ADR that supersedes the old one. Retroactive ADRs for decisions already made are welcome, since stating the context and consequences has value after the fact.

# ADR-004: SQLite for session persistence
 
Status: Accepted
 
## Context
Sessions live in memory and are lost on restart. One server, low write volume.
 
## Decision
Store sessions in SQLite on the application server.
 
## Consequences
Positive: no new service to run; survives restarts.
Negative: a second server would need a different store.

C4 diagrams, from Simon Brown's C4 model, show Level 1 (system context: the system as one box among its users and external systems) and Level 2 (containers: the applications and data stores inside it, with technology and protocols). We rarely draw Level 3 and do not draw Level 4 by hand, because it goes stale almost at once. The figure walks the four levels using our voice agent Salesbot: each panel opens the highlighted box of the panel before, from the system among its users down to the functions inside one component.

Four panels using Salesbot: system context, containers, components inside the voice server, and code, each zooming into the highlighted box of the panel before. Four panels, each zooming into one box of the panel before, using Salesbot as the example. Level 1, system context: a visitor uses Salesbot, which uses speech and language-model services. Level 2, containers: inside Salesbot are the web app, the voice server and the conversation store. Level 3, components: inside the voice server are the voice pipeline, the stage machine, the gate check and a background writer. Level 4, code: the functions behind the stage machine, such as recording a finding and checking whether a gate is complete. The lab draws levels 1 and 2 for every system, level 3 rarely, and never draws level 4 by hand. C4: four levels of zoom SIMON BROWN'S C4 MODEL · EACH LEVEL OPENS ONE BOX OF THE LEVEL BEFORE · EXAMPLE: SALESBOT FIGURE C4 ZOOM LEVELS DRAWN BY AR LABS SHEET 1 / 1 LEVEL 1 System context drawn for every system LEVEL 2 Containers drawn for every system LEVEL 3 Components drawn rarely LEVEL 4 Code never drawn by hand Visitor [Person] Salesbot [System] Speech + model [External] Web app [React] Voice server [Pipecat] Store [SQLite] Voice pipeline Stage machine Gate check Writer record_<gate>() merge into state gate_is_complete() every field set? confirm_findings() close the stage
Each C4 level opens one box of the level before; we draw levels 1 and 2 for every system.

Rules for C4 diagrams

  • Every box has a name, an explicit type, a technology (for containers and components) and a one-sentence responsibility.
  • Every line points one way and carries a label that reads as a sentence: "The web app makes API calls to the API using JSON over HTTPS." No bidirectional arrows, no bare "uses".
  • One zoom level per diagram; deployment detail goes on a separate deployment diagram.
  • Every diagram has a legend and a title stating its type and scope. Colour supports text and never carries meaning alone.

Diagrams are written as text in Structurizr DSL (a small language for describing C4 models), then validated and exported to Mermaid through a Structurizr server connected to the agent over the Model Context Protocol (MCP), so an agent can draft, check and render them without a drawing tool. A diagram skill loads these rules before any architecture diagram is created or edited, however small the change, because small edits made from memory are where the rules slip.

Where the design record sits in the pipeline

FIG. 01
flowchart LR
  G["Design interview"] --> D["Design record: DESIGN.md, ADRs, C4"]
  D --> P["PRP references it"]
  P --> R["Refine design after research"]
  R --> B["Build"]
  B --> C["Reconcile at container review"]
  C --> D

The design operation runs whenever new knowledge exists: after the design interview, after the research in the campaign plan (the PRP, described under spec-driven development), and at each container review, when a group of related tasks finishes and the walkthroughs of those tasks show what was actually built. The plan is the authority; the design record is the record. A change to the plan can send work back, but a change to the design record only brings the record up to date. Every revision lands as a diff that a person approves, and nothing rewrites the record unseen. Because the plan can point at the design record instead of restating it, plans stay short.

What we considered and did not adopt

arc42, an architecture template with twelve sections, carries too much overhead for a small team. An RFC (request for comments) process needs reviewers to comment, which a small practice does not have. The full BMAD method, a workflow built around role-based AI personas, is designed for greenfield product ideation rather than for documenting a system that already exists. The design doc, ADR and C4 combination covers each gap with little weight.