🪨 Cairn [](#license) [](./CAIRN.md)

August 13, 2026 · View on GitHub

Tool-free convention that keeps, beside your code, a living spec of what the system does now plus a dated log of how it got there, readable by any agent, human or AI.

A cairn marks the trail and is built from every stone laid before it. Cairn does the same for a codebase: a description of what the system does today, standing on an honest record of every change that got it there.


Cairn is a language- and tool-agnostic convention for keeping three things beside your code:

  • spec: the current truth, what the system does today.
  • changes: reviewable proposals for in-flight work, written before code.
  • log: an honest, dated history of what has landed.

It is plain Markdown and a discipline. No runtime, no package manager, no mandatory CLI. Any agent, human or AI, that can read and write text can follow it. The formal contract lives in CAIRN.md, and the step-by-step procedure in GUIDE.md.

The idea in one minute

Most projects keep a journal: a retrospective, append-only record (changelogs, commits, "done" notes). A journal is honest, because history cannot rot. But it makes every reader replay the whole thing to figure out the present.

Cairn adds the two things a journal lacks:

  1. a spec, the journal folded forward into one current-truth document, so no replay is needed.
  2. a change, written and reviewed before the work, so intent can be checked before code exists.

The spec is the only artifact that can go stale, so Cairn has exactly one forcing rule:

A change that affects behaviour is not done until its delta has been folded into the spec and an entry has been appended to the log.

That single rule is the same step a spec tool would automate, and it is what keeps the spec alive.

Layout

<root>/
  cairn/
    spec/        # current truth, one file per capability
    changes/     # in-flight proposals (proposal.md + tasks.md + optional delta.md)
    log/         # dated history, one file per landed change

The root is discovered by walking up to the nearest cairn/ directory or cairn.toml, just like git finds .git. One root per repo, and a monorepo may have one per package (nearest wins). Cairn defaults to a dedicated cairn/ directory rather than docs/, which is already owned by documentation generators. The location is configurable in cairn.toml.

Adopting Cairn

  1. Drop the activation stanza into your agent's always-loaded instructions. Copy AGENTS.md into your repo, with the thin per-tool pointers below.
  2. Create a cairn/ directory with empty spec/, changes/, and log/, or run impl/bash/init.
  3. That is it. From the next prompt on, a Cairn-aware agent proposes, implements, folds the spec, and logs, by default and with no command.

Per-tool activation

All of these point at the same AGENTS.md, so there is one source of truth:

ToolFileContent
portableAGENTS.mdthe stanza
Claude CodeCLAUDE.md@AGENTS.md
Cursor.cursor/rules/cairn.mdcpointer
GitHub Copilot.github/copilot-instructions.mdpointer

Enforcement (optional)

  • Claude Code: a Stop hook in the repo's .claude/settings.json runs the verifier in-loop and nudges the agent to fix violations before finishing.
  • Any tool, any author: a git pre-commit hook (hooks/pre-commit, enabled with git config core.hooksPath hooks) runs the verifier and blocks non-conformant commits.

Both invoke an optional reference port. A Cairn-aware agent that checks by reading needs neither.

Tooling

Cairn needs no tooling. You create and check a structure by reading the rules, and the friendly walkthrough is in GUIDE.md. Any tooling is optional and read-only. The write side, authoring correct specs, deltas, and log entries, is judgement-heavy and stays with the author. The read side is mechanical, so anyone can build reporters in any language: a status view, a log view, a spec view, a timeline renderer, a conformance verifier. The fixed frontmatter, predictable paths, and literal delta headings are what make those readers trivial.

Optional reference ports live under impl/, one folder per language, none required. The bash port is two small scoped scripts:

A companion Claude Code skill (.claude/skills/cairn) carries the authoring procedure so it stays out of always-loaded context.

Prior art

Cairn owes its core structure to OpenSpec. From it, Cairn borrows the split between specs (current truth) and changes (proposals carrying a delta), and, closely, the delta grammar (## ADDED / MODIFIED / REMOVED Requirements, ### Requirement:, #### Scenario:).

Cairn diverges deliberately in a few ways. History is promoted to a first-class, dated, immutable log rather than an archive. There is no required runtime, and tooling is read-only in any language, where OpenSpec ships a Node CLI. The root is discovered by walk-up and its location is configurable, rather than a fixed directory. Activation is delivered through always-loaded agent instructions plus optional hooks, so it applies by default across tools. The root-discovery convention itself echoes git, .editorconfig (root = true), and lockfile-based project roots.

Status

Early and living. The spec is at v0.1.0 (draft) and will be refined. This repository dogfoods Cairn on itself, see cairn/. Feedback and adopters welcome.

Contributing

See CAIRN.md for the formal specification. Discussion, issues, and alternative-language ports are all welcome.

Alternatives

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.