C4 architecture layers as plain text. For codebases maintained by agents.
C4 is the best architecture documentation standard for humans, but it is not good for agents. Agents work much better with text than with diagrams.
Refraction takes the C4 structure (System Context, Container, Component) and replaces every diagram with prose, lists, and tables. The hierarchy is the same. The format is plain markdown. Agents maintain the files as a side effect of normal development. Humans read at whatever altitude they need.
Structure
docs/
system.md (L1: system context)
containers/
[name].md (L2: one per container)
components/
[name].md (L3: one per component)
reference/ (optional)
[name].md
Three layers, each self-contained at its own level of abstraction, each linking downward only. A reference/ folder holds contract-level material (config schemas, protocol specs, API shapes) that doesn't belong in the architecture layers.
The layers
One file per project. What the system does, who it talks to, and what it deliberately doesn't do. An agent loads this for broad context. A human reads it to understand the project without reading code.
Required: Purpose, External actors, Container index with links, Constraints and non-goals.
Must be readable with no other context. No implementation details. Every container must be linked.
One file per separately deployable unit: a service, application, database, or background process. Shared infrastructure (auth, logging, feature flags) belongs in a platform.md container.
Required: Responsibility, Technology and deployment context, Interfaces (explicit direction), Component index with links, Key decisions.
Every external interface must be named. Cross-cutting concerns belong in platform.md. Every component must be linked.
One file per logical grouping that an architect would draw as a box. May span multiple source files or be a single class. Granularity test: if you'd explain it separately when onboarding a new developer, it's a component.
Required: Role, Interfaces (inputs/outputs/events), Code pointers, Constraints and decisions.
Code pointers are required: they bridge spec to implementation. No business logic in the docs; reference where to find it.
Level markers
Each file should declare its layer at the top as an HTML comment. The file path encodes the level, but agents often read docs as search results or pasted snippets where the path isn't visible. A marker costs nothing and prevents level confusion:
docs/system.md:
<!-- L1: System Context --> # My Project ...
docs/containers/auth.md:
<!-- L2: Container --> # Auth Service ...
docs/components/token-service.md:
<!-- L3: Component --> # Token Service ...
No diagrams
Refraction does not use diagrams: not Mermaid, not PlantUML, not ASCII art. Use prose, lists, and tables instead.
ASCII diagrams look useful but degrade quickly: agents produce them inconsistently, alignment breaks on edit, and they're harder to read than a well-written paragraph. If a relationship is worth documenting, it's worth describing in words. The constraint forces precision.
Agent workflow
The format works in both directions. Write the docs first and let the agent implement. Let the agent write the docs after a code change and review them yourself. Either way, the structure is clear enough for both sides to navigate and maintain it.
Agents load selectively: system.md for broad context, a container file when working in that service, a component file and its container file when working on a specific component. Never all files at once.
Why stop at L3
L4 in C4 is code, and the code is already there. A documentation layer that mirrors code at that resolution creates duplication and drift without adding signal. L3 code pointers are the bridge. L4 would be the code itself.
Example
docs/
system.md
containers/
api-gateway.md
auth.md
platform.md ← shared concerns
components/
routing.md
rate-limiter.md
token-service.md
user-store.md
logging.md
feature-flags.md
reference/
api-schema.md
auth-protocol.md
system.md links to all three containers. api-gateway.md describes its dependency on auth.md explicitly. auth.md references logging.md as a dependency without duplicating its documentation.
Claude Code skills
Four slash commands for working with Refraction in any project:
claude plugin install github:signalshell/refraction
/refraction:init: bootstrap docs from scratch by reading the codebase.
/refraction:sync: code changed; update docs to match.
/refraction:implement: docs changed; update code to match.
/refraction:check: find drift and determine which side needs updating.
sync and implement are two directions of the same workflow. The format works either way: write docs first and let the agent implement, or let the agent write docs and review them yourself.
github.com/signalshell/refraction
Refraction is a convention, not a tool. No install required. Use it as-is, or adapt it to your project's structure.
Built by Martin Sigloch with Tachikoma. · Documentation Standard