Documentation System Guide

Setting Up a Living Documentation System

A generalized, project-agnostic guide to structuring a docs/ folder and a root CLAUDE.md (or equivalent AI-assistant instruction file) so that a codebase stays legible to both humans and AI coding assistants as it grows. Distilled from a working example, with all project-specific names and concepts removed.

Introduction

Most repositories accumulate documentation in one of two failure modes: nothing gets written down, so every decision is re-litigated from scratch; or everything gets written down in one sprawling wiki page that nobody trusts is current. Both fail an AI coding assistant the same way they fail a new engineer — there is no reliable place to go to learn why the system looks the way it does before making a change to it.

This guide describes a folder layout that separates documentation by the kind of question it answers — not by feature, not by team, and not chronologically. Each folder answers one category of question ("why did we choose X over Y", "how does the system actually run", "what are we planning to build next") so that both a human and an AI assistant can navigate directly to the right altitude instead of reading everything.

It also describes a root CLAUDE.md — a single file that acts as the entry point and index into everything else, written for consumption by an AI coding assistant at the start of every session.

Guiding Principles

Separate the "why" from the "how"

Decisions (why we chose X) and architecture (how X currently works) rot at different rates. A decision record is a permanent, dated snapshot of reasoning at a point in time. An architecture doc must track the live system. Mixing them means one of the two goes stale silently.

One folder, one question

A reader (or an AI assistant) should be able to guess which folder to open just from the question they're asking — "why," "how does it run," "what's the plan," "how do I set this up," "what did we decide not to do (yet)." If a folder answers two unrelated questions, split it.

The index file is small and the details live elsewhere

CLAUDE.md should read like a table of contents with just enough summary to orient — one or two lines per linked doc, not the doc's content inlined. If the index file grows past a couple hundred lines of prose, content has leaked in that belongs in docs/.

Every doc is either "current" or explicitly dated

Architecture docs describe the system as it is now and get edited in place. Decision records are dated and immutable once accepted — superseding a decision means writing a new ADR that supersedes the old one, not silently editing the old one away.

Recommended Folder Tree

Start from this shape and drop what you don't need — a small project may only need architecture/, decisions/, and setup/.

docs/ ├── philosophy/ # optional — the worldview/principles behind the design (small teams often skip this) │ └── core.md ├── architecture/ # how the system currently works — living documents, edited in place │ ├── system-overview.md │ ├── key-concepts.md │ ├── tech-stack.md │ └── ... ├── design/ # feature designs, user-facing flows, UX patterns │ └── ... ├── decisions/ # ADRs — numbered, dated, immutable once accepted │ ├── 001-title-in-kebab-case.md │ ├── 002-title-in-kebab-case.md │ └── ... ├── specs/ # protocol / API / data-format / DSL specifications │ └── ... ├── dev-process/ # how work actually gets planned, built, and shipped │ ├── overview.md │ └── ... ├── setup/ # environment bootstrap and operational runbooks │ └── ... └── ideas/ # parking lot — out-of-scope follow-ups captured, not lost └── ...
Naming convention: use kebab-case filenames throughout (tech-stack.md, not TechStack.md) and number decisions/ files with a zero-padded, monotonically increasing prefix (001-, 002-, …) so directory listings sort chronologically.

Folder-by-Folder Guide

What belongs in each folder, what doesn't, and how to recognize when a doc is in the wrong place.

docs/philosophy/optional

The worldview and design principles that motivate the architecture — the "why does this project exist and why does it look the way it does" layer, one level above any single decision.

Contains
  • A core.md (or similarly named) document laying out the project's organizing principle and the reasoning that flows from it.
  • Deeper treatments of specific philosophical commitments that are load-bearing enough to warrant their own document (e.g., how the project thinks about a particular kind of ownership, safety, or user relationship).
Does not contain
  • Implementation detail, component diagrams, or anything that changes when the code changes — that belongs in architecture/.

Skip this folder entirely for projects without a strong opinionated worldview — most internal tools and CRUD apps don't need it. It earns its place when the "why" genuinely shapes many downstream technical choices and would otherwise get re-explained in every design doc.

docs/architecture/

How the system is put together right now. These are living documents — edited in place as the system evolves, not dated snapshots. This is usually the largest and most-read folder.

Typical documents
  • system-overview — a top-level diagram (component or sequence) and a walkthrough of how a request/event flows through the system.
  • key-concepts — the core abstractions/vocabulary of the codebase, defined once so every other doc can reference them by name instead of re-explaining.
  • tech-stack — technology choices and why, plus deployment/runtime topology.
  • One document per major subsystem (e.g., messaging/eventing, storage layer, auth/security model, observability, a significant external integration).
  • A code map, if the repo is large enough that "where does X live" is a recurring question.
Does not contain
  • The reasoning trail for why the architecture looks this way instead of some alternative — that belongs in decisions/. Architecture docs describe the winning state, not the debate.

docs/design/

Feature-level and user-facing design — concrete scenarios, interaction flows, and UX patterns, as opposed to system-internal architecture.

Typical documents
  • Interaction/user-flow docs written as concrete scenarios ("user does X, system responds Y") rather than abstract capability lists.
  • Cross-cutting design patterns used by multiple features (e.g., a shared orchestration or state-machine pattern reused across several feature areas).
  • Per-feature design docs for anything complex enough to need one before implementation starts.
Does not contain
  • Backend component wiring (→ architecture/) or the decision trail for why a design approach was picked over another (→ decisions/).

docs/decisions/

Architecture Decision Records (ADRs) — one file per significant, hard-to-reverse decision, capturing the context, the decision, the alternatives considered, and the consequences, at the time it was made. See the ADR template below.

What warrants an ADR
  • Choosing (or replacing) a core technology, protocol, or dependency.
  • A decision that would be expensive to reverse, or that a future contributor is likely to second-guess without the original context.
  • Anywhere you catch yourself explaining "we tried X first, but…" in a PR description — that reasoning belongs in an ADR instead, where it won't get lost.
Rules
  • Numbered sequentially, never renumbered or reused.
  • Immutable once Accepted — a changed decision gets a new ADR that supersedes the old one (update the old file's status, don't rewrite its content).
  • Don't mark an ADR Accepted while genuine open questions remain — use Proposed until they're resolved, even if the open questions look like "implementation details." A reader shouldn't have to guess whether "Accepted" means "fully settled" or "settled except for the parts we haven't figured out."

docs/specs/

Technical specifications: API contracts, wire/message formats, protocol definitions, DSL grammars — anything with a formal shape that other code or other teams need to implement against precisely.

Contains
  • Schema/contract definitions precise enough to implement against without reading source.
  • Protocol or state-machine specifications (e.g., a restricted workflow/DSL grammar).
Relationship to project-management tooling

Some teams also track higher-level "build specs" (phased implementation plans for a milestone) as issues in their project tracker rather than as files here. If you do that, say so explicitly in CLAUDE.md so it's clear docs/specs/ holds durable technical specifications, while the tracker holds time-bound delivery plans.

docs/dev-process/

How work actually gets planned, implemented, reviewed, and shipped in this repository — the meta-process, as distinct from what the software itself does.

Typical documents
  • overview — the end-to-end process from idea to merged code: stages, gates, who/what is responsible at each stage.
  • Any process automation you rely on (e.g., a scripted delivery pipeline, an autonomous or semi-autonomous agent workflow) — documented as a spec, including its failure modes and escalation paths.
  • Operational runbooks tied to the delivery process (branching conventions, environment promotion, backup/restore procedures).
Does not contain
  • Generic "how to run the app locally" instructions — put those in setup/ instead; keep this folder about process, not environment bootstrap.

docs/setup/

Practical, imperative runbooks for getting a working environment running — the "I just cloned this repo, now what" folder.

Typical documents
  • Prerequisite tooling and installation steps.
  • Launch/startup sequences for local development, with the exact commands to run.
  • Cloud/infra bootstrap docs (provisioning credentials, initial account setup) if the project needs external services.
Does not contain
  • Explanations of why the system is built this way — keep this folder purely operational and imperative; link out to architecture/ for the "why."

docs/ideas/

A parking lot for follow-up work identified during implementation but out of scope for the change at hand — so it's captured durably instead of living only in a PR comment or a Slack message that will be forgotten.

Contains
  • Short, informal notes: what the idea is, where it came from, and roughly how big it looks.
  • Deliberately low-ceremony — no fixed template, no status field. Promote an idea into a real ADR or design doc once someone commits to doing it.
Rule of thumb

Whenever a change surfaces an out-of-scope improvement worth doing later, write it here alongside the PR that surfaced it, not just in the PR description — PR descriptions get buried; this folder doesn't.

ADR Template

Use this shape for every file in docs/decisions/:

# ADR-NNN: <short, decision-shaped title>

**Status**: Proposed | Accepted | Superseded by ADR-XXX
**Date**: YYYY-MM-DD

## Context

What situation forced this decision? What were we doing before, and what changed
or what did we learn that made the previous approach worth revisiting?

## Decision

The decision itself, stated in one or two sentences, up front.

## Rationale

### Why the previous/rejected approach falls short
...

### Why this approach
...

### Alternatives considered
- **Alternative A** — what it offers, why it was rejected
- **Alternative B** — what it offers, why it was rejected

## Consequences

What changes as a direct result — code that gets retired, new maintenance burden
taken on, follow-up work created, anything that becomes easier or harder.
Keep Consequences honest about trade-offs, not just upside — "we now own this protocol ourselves, which means tailoring it to our needs but also maintaining it" reads very differently, and more usefully, six months later than a decision record that only lists benefits.

Writing a CLAUDE.md

CLAUDE.md (or your assistant's equivalent instruction file) is loaded at the start of every AI-assisted session in the repository. Treat it as the front door: an index into docs/, a statement of non-negotiable working rules, and enough project context that the assistant doesn't need to re-derive the basics from source every time.

Section-by-Section

SectionPurpose
Project OverviewWhat the project is, in a couple of sentences, plus its core philosophy/principles as a short bulleted list if the project has strong opinions worth stating up front.
Documentation StructureA one-line description of what each docs/ subfolder contains, plus — critically — a one-line summary per file inside decisions/ as the ADR list grows. This is the single most valuable section for an assistant: it turns "go read 15 files" into "here's the two-sentence version, follow the link if you need more."
Key ConceptsThe project's core vocabulary defined in one place, each term linked to where it's elaborated in architecture/. Prevents every session from re-deriving terminology from scratch.
Architecture (summary)A short summary of runtime topology, major subsystems, and security posture — each with a link to the full doc. Summarize, don't duplicate.
Working Directory / Environment ConventionsHard operational rules that are easy to violate by default and expensive when violated — e.g., "always run commands from the repo root," "this is a worktree, not a parent checkout." State these as imperative rules, not narrative.
Build & DevelopmentThe concrete toolchain: language/runtime version, package manager, container tooling, migration tooling, and the couple of scripts that start/stop everything.
Development ProcessA short pointer to dev-process/overview.md plus the stage list inline if it's short enough to scan at a glance.
TestingTest runner and how to invoke it. If test commands are still being figured out, say so explicitly rather than leaving the section silently absent.
Project StructureA shallow directory tree of the actual repo (not the docs folder) with a one-line purpose per top-level directory.
Deferred DecisionsAn explicit, honestly-maintained list of "we know this is unresolved." See below — this section matters more than it looks.
Why "Deferred Decisions" earns its place: an AI assistant without a source of truth for "what's still undecided" will confidently invent an answer when asked about it, because a plausible-sounding answer is *available* even when no real one exists. An explicit, maintained list of open areas gives the assistant permission to say "this is designed but not yet implemented" or "this is genuinely undecided" instead of fabricating a specific mechanism. Update it every time something moves from deferred to designed.

Style Rules

  • Index, don't inline. If you're pasting more than a paragraph of an existing doc's content into CLAUDE.md, link to the doc instead and summarize in one line.
  • State rules imperatively. "Always run commands from the primary working directory" reads and is followed more reliably than a paragraph explaining why worktrees can be confusing.
  • Prefix true overrides with IMPORTANT. Reserve this for the handful of rules that should win over an assistant's default instincts (e.g., "never squash-merge," "never delete without confirming"). Overusing it dilutes the signal.
  • Cross-reference ADRs inline. When a section of CLAUDE.md summarizes a decision, link the ADR that made it (see ADR-004) so the reasoning trail is one click away instead of assumed.
  • Keep it current on every merge that changes structure. A stale CLAUDE.md is worse than a short one — it actively misdirects. Treat "update CLAUDE.md" as part of the definition of done for any change that adds a new subsystem, ADR, or process stage.
  • Prefer plain prose over emoji and heavy formatting. This file gets parsed by an LLM at the start of every session — clarity and scanability matter more than visual flourish.

Skeleton Template

# CLAUDE.md

Guidance for AI coding assistants working in this repository.

## Project Overview

<One to three sentences: what this project is and who it's for.>

### Core Philosophy   (optional — only if the project has strong opinions)

- <Principle 1, stated as a stance, not a feature>
- <Principle 2>

## Documentation Structure

Detailed docs live in `docs/`:

- `docs/architecture/` — how the system currently works
  - `system-overview.md` — top-level diagram and walkthrough
  - `key-concepts.md` — core abstractions and vocabulary
  - ...
- `docs/design/` — feature and UX design
- `docs/decisions/` — ADRs (one-line summary per file; grows as decisions accrue)
  - `001-<slug>.md` — <one-line takeaway>
  - `002-<slug>.md` — <one-line takeaway>
- `docs/specs/` — technical specifications
- `docs/dev-process/` — how work is planned, built, and shipped
- `docs/setup/` — environment bootstrap and runbooks
- `docs/ideas/` — captured out-of-scope follow-ups

## Key Concepts

See `docs/architecture/key-concepts.md` for full definitions.

- **<Term>**: <one-line definition>
- **<Term>**: <one-line definition>

## Architecture

<Short summary — runtime topology, major subsystems, security posture —
each pointing to its doc in `docs/architecture/`.>

## Working Directory / Environment Conventions

- <Hard rule 1>
- <Hard rule 2>

## Build & Development

- <Language/runtime + version>
- <Package manager and key commands>
- <How to start/stop the local environment>

## Development Process

See `docs/dev-process/overview.md`. <Stage list if short enough to scan.>

## Testing

<Test runner and invocation. State explicitly if this is still TBD.>

## Project Structure

```
src/     — <one-line purpose>
tests/   — <one-line purpose>
docs/    — architecture, design, specs, decisions, process documentation
...
```

## Deferred Decisions

Explicitly unresolved areas — update as items move from deferred to designed:

- <Area> — <what's decided so far, what's still open>

Bootstrap Checklist

Steps to stand this up from scratch in a new project.

  1. Create docs/architecture/, docs/decisions/, and docs/setup/ first — these three cover most projects' immediate needs. Add design/, specs/, dev-process/, ideas/, and philosophy/ only once you have real content for them; an empty folder signals structure without substance.
  2. Write docs/architecture/key-concepts.md and system-overview.md early — before the codebase grows past the point where one person can describe it from memory.
  3. Retroactively write ADRs for the two or three decisions you've already made that would be expensive to reverse, even if they weren't documented at the time. Backfilling early is far cheaper than backfilling after the reasoning is forgotten.
  4. Write CLAUDE.md last, once there's at least a little real content to index — an index into empty folders is not useful. Use the skeleton template above.
  5. Add a repo-structure section to CLAUDE.md reflecting the actual top-level directories, not an aspirational layout.
  6. Add the "Deferred Decisions" section immediately, even if it's short — it's easiest to keep honest if it exists from the start rather than being added after the assistant has already fabricated a few answers.

Keeping It Alive

Do

  • Update CLAUDE.md's documentation index in the same PR that adds a new ADR or architecture doc.
  • Move an item out of "Deferred Decisions" the moment it's actually designed — don't let the list go stale in the optimistic direction either.
  • Write the ADR during the work that makes the decision, not after — the alternatives-considered section degrades fast from memory.
  • Let architecture docs drift toward the code by editing them in the same PR that changes the behavior they describe.

Avoid

  • Editing an Accepted ADR's content after the fact — supersede it with a new one instead.
  • Letting docs/ideas/ become a second backlog system — it's a capture point, not a tracker; promote or discard, don't let it accumulate indefinitely.
  • Duplicating the same explanation across CLAUDE.md and a docs/ file — pick one owner per fact and link to it everywhere else.
  • Treating docs/setup/ as a place to explain design rationale — keep it purely imperative so it stays skimmable under time pressure.