Refraction

Layered architecture docs in plain text. For teams of humans and agents.

v1.1

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 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)
  specs/
    [name].md            (L4: behavioral and algorithm specs)
  ops/
    [name].md            (build, release, deploy, install, runtime)
  external/
    [name].md            (one per external system)

Every file is linked from at least one other file. Starting from system.md and following links, the entire documentation is navigable. No orphan files.

The ops/ and external/ folders are not numbered layers; they hold supporting material that doesn't describe architecture.

The layers

L1
System Context
docs/system.md

What the system does, who uses it, what it talks to, what it deliberately doesn't do. One file per project. Must link to every container.

L2
Container
docs/containers/[name].md

One file per separately deployable or runnable unit. Shared infrastructure belongs in platform.md. Must name every external interface explicitly, and link to every component.

L3
Component
docs/components/[name].md

One file per logical grouping within a container. Granularity rule: if you'd explain it separately when onboarding a new developer, it's a component.

L4
Spec
docs/specs/[name].md

Detailed behavioral specs: algorithms, protocols, interaction models. A spec is not owned by any single component; multiple components may link to the same spec.

Ops

docs/ops/[name].md

Operational concerns that don't describe architecture. Common types:

  • Build: prerequisites, commands, output artifacts
  • Release: version scheme, publish steps, distribution
  • Deploy: target environment, deployment process, configuration
  • Install: end-user installation and upgrade
  • Runtime: system dependencies, configuration, state

Create only the files that apply to your project. Name them freely.

External

docs/external/[name].md

One file per external system with significant API surface. Document what the system is, the specific calls and patterns you use, constraints and limits, and a link to official docs. Create a file when you have real API surface to document. Passing references don't need a file.

Markers

Each file declares its layer at the top as an HTML comment. The file path encodes the layer, but agents read docs as snippets without path context:

<!-- L1: System Context -->
<!-- L2: Container -->
<!-- L3: Component -->
<!-- L4: Spec -->
<!-- Ops -->
<!-- External -->

No diagrams

Refraction does not use diagrams (not Mermaid, not PlantUML, not ASCII art). Use prose, lists, tables, and code blocks instead.

Diagrams degrade quickly: agents produce them inconsistently, alignment breaks on edit, and a well-written paragraph conveys the same information more reliably.

Project reference

Every project using Refraction includes this line near the top of system.md:

Documentation follows the [Refraction documentation standard v1.1](https://signalshell.com/refraction/v1.1).

Agent workflow

Agents load only what they need: 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, a spec when implementing a specific behavior, an external file when writing integration code, an ops file when building or deploying. Never all files at once.

Granularity heuristics

New container (L2): deploys independently, has its own data store, or communicates via a network boundary.

New component (L3): you'd explain it separately to a new developer, or an architect would draw it as a distinct box.

New spec (L4): behavior too detailed for L3 without bloating it, applies to multiple components, or you'd write a separate design doc for it.

New ops file: a distinct operational concern worth documenting for the people who build, run, or ship the project.

New external file: real API surface to document: specific endpoints, parameters, constraints.

Keep as a mention: a single well-named thing with no interesting decisions, or its interface is obvious from its container's interface.

Example

docs/
  system.md
  containers/
    api-gateway.md
    auth.md
    platform.md          ← shared infrastructure
  components/
    routing.md
    rate-limiter.md
    token-service.md     ← code pointers: src/auth/token.go
    user-store.md
  specs/
    auth-protocol.md     ← linked from token-service and api-gateway
    rate-limit-algorithm.md
  ops/
    build.md
    deploy.md
  external/
    stripe.md
    sendgrid.md

system.md links to every container. Each container links to every component it owns. auth-protocol.md is linked from both token-service.md and api-gateway.md; specs are shared, not owned.

Why

No diagrams. Diagrams degrade quickly: agents produce them inconsistently, alignment breaks on edit, and a well-written paragraph conveys the same information more reliably. The constraint forces precision.

Four layers. There is meaningful ground between "this component exists and here are its key decisions" and "here is the source code." Behavioral specs, algorithms, and wire protocols need a home that isn't bloating L3 and isn't the code itself.

Specs are shared, not owned. Cross-cutting behavior is common. A security protocol may be implemented by three components; all three should link to the same spec rather than duplicating it.

Code pointers. Docs should be grounded in the codebase. File paths and module names let agents and humans navigate from a doc directly to the implementation without searching. Use them wherever they help, most naturally at L3 and L4.

Agent-as-maintainer. Documentation rots because maintenance is a human tax. Making agents responsible keeps docs in sync as a side effect of the commit workflow.

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.

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