Getting started
Install it, create a project, and work through the loop it is built around — find something to do, take it, finish it.
Install
A prebuilt binary, with no Rust toolchain needed:
curl -fsSL https://raw.githubusercontent.com/oddurs/cairn/main/install.sh | sh
It detects your platform, verifies the release checksum and installs to
~/.local/bin. Homebrew takes three commands, because recent versions require
third-party taps to be trusted explicitly:
brew tap oddurs/cairn
brew trust oddurs/cairn
brew install cairn
From source, cargo install --git https://github.com/oddurs/cairn cairn-md.
Create a project
$ cairn init
created cairn.toml
created cairn/items/
That writes the schema and the directory items live in. Run it at the root of a repository — items are meant to be committed alongside the code they describe.
cairn init --preset minimal --bare starts from a small schema without example
items. The default writes a fully commented schema to adapt to your project.
The loop
Four commands carry the day-to-day. Everything else is machinery underneath them.
ID PRIORITY STATUS MILESTONE TITLE
0003 p0 in progress v0.1 Support OAuth login
0005 p1 planned v0.1 Board shears on narrow terminals
0006 p2 backlog v0.2 Document the export format
3 ready · 1 in progress · 1 blockedWork that is genuinely startable. Anything waiting on unfinished work is excluded, and what is already under way comes first — the most useful next action is usually finishing something.
claimed 0003 Support OAuth login
you · doing · cairn/items/0003-support-oauth-login.mdTakes the top-ranked unclaimed item, writes your name into it, and prints its body so work can begin. It refuses an item somebody else holds, and one that is blocked.
Then record what you learned and finish:
$ cairn note 3 "Chose the authorization code flow; implicit is deprecated."
$ cairn close 3
3, 0003 and the project’s own rendering all name the same item.
cairn note appends to the item under a dated heading. A status records what
was decided; a note records why, which is the difference between a backlog and a
list of things nobody remembers rejecting.
next excludes unfinished dependencies; it does not decide which ideas your
project has approved. If your schema uses planned for selected work, scope an
agent’s claim with cairn claim --next --filter 'status=planned'.
Harrow is the optional terminal counterpart. Run it beside an editor or agent to watch the same backlog and make interactive decisions. It reads the files directly and delegates changes to Cairn.
What gets written down
An item is a Markdown file, and that is the whole storage format.
---
id: 3
uid: 00000003-0000-4000-8000-000000000003
title: Support OAuth login
type: feature
status: doing
milestone: v0.1
assignee: you
claimed: 2026-09-05
created: 2026-09-05
updated: 2026-09-05
priority: p0
---
## Problem
## Proposal
## Acceptance criteria
- [ ]Everything above the closing --- is checked against the schema. The body is
yours; conventions such as acceptance checkboxes and proposals let tools help
you work it. Edit the file in your editor or from the command line — both keep
working, and changing a title normally renames the file to match.
The generated roadmap
ROADMAP.md is built from the items, and rebuilt whenever one changes. Never
edit it by hand.
$ cairn render
wrote ROADMAP.md 14 items
cairn: cairn/items/0009-bad.md:4: unknown status `nope`
failed: 1 error(s), 0 warning(s) across 7 item(s)cairn check --render --strict belongs in continuous integration. It validates every item against the schema and proves the committed roadmap still matches them, which is what stops a roadmap from quietly becoming fiction.
Where to go next
- The schema — item types, statuses, fields and milestones, and why status categories matter.
- Agents — serving the backlog over MCP, and the loop an agent follows.
- Durability — what happens on a crash, a merge, or two people writing at once.