Guide / From the first decision onward

Give your next session
a memory of why.

Start with one real choice. Keep the reason and the rejected alternative. Then let the next session pick up where you left off.

Install dira

Homebrew is the quickest path on Apple Silicon Macs, Intel Macs, and Linux AMD64.

brew install kazi-org/tap/dira
dira --version

For Linux ARM64, or to install without Homebrew, download the matching archive from GitHub Releases. Each release includes macOS and Linux builds for ARM64 and AMD64, plus a checksums.txt file.

Build from source

Use the Go toolchain specified in go.mod.

git clone https://github.com/kazi-org/dira.git
cd dira
go build ./cmd/dira
./dira --help

A plain source build reports dev. Release binaries carry their release version. Put the binary on your PATH before configuring hooks.

Record your first decision

In your project directory, seed a ledger with a short interview. Choose workspace, then supply an intent, a constraint, and an open question. The interview writes all answers together; an incomplete interview leaves no partial ledger.

dira init --interview

Record a choice, the option you rejected, and the reason. This example creates dec-0001 in a fresh ledger:

dira log --kind decision --title "Use SQLite for local storage" \
  --alternative "PostgreSQL" \
  --why-not "Local storage must work offline without a database server" \
  --revisit-if "Multiple users need concurrent remote writes"

Now retrieve it and try a plan that repeats the rejected choice.

dira why SQLite
dira check "use PostgreSQL for local storage"
✗ conflicts with dec-0001
    rejected alternative: "PostgreSQL"
    why_not: Local storage must work offline without a database server
    revisit_if: Multiple users need concurrent remote writes
→ supersede dec-0001, or revise the plan

Output above is abridged. check exits with 2 for the conflict. Commit .dira/ alongside your code; its cache is derived data.

Matching is lexical. A result with no conflict means the matcher found none; it is not a proof that a plan has no semantic contradictions.

Connect your coding agent

The bundled integration targets Claude Code. Install its hooks and capture skill once:

dira install-hooks
dira install-skill

The hooks merge into ~/.claude/settings.json, preserving existing registrations. The skill is written under ~/.claude/skills/dira/. Start a new session in the repository to receive the brief.

EventWhat happens
SessionStartbrief --context --chain supplies decision context.
Stopsniff --stage --quiet stages candidate decisions.
PreCompactsniff --deep --stage --all preserves candidates before compaction.

Review is a separate step

dira distill

In an interactive terminal, confirm, ignore, edit, or undo a capture. Regex capture never invents a reason or accepts a decision. Confirmation marks a capture for semantic extraction; the entry stays staged until the session agent supplies its reasoning.

The PreCompact hook captures candidates, but its output alone does not guarantee completed semantic extraction. Check pending captures with distill. The hook configuration documents the delivery constraints.

For another agent, invoke the CLI directly and arrange for dira brief at session start and dira check before planning. The CLI has no model client; semantic work belongs to your agent session.

Recall the reasoning

dira brief
dira why SQLite
dira ui

brief summarizes blockers, active intents, and recent decisions in at most 1,500 tokens. why resolves an entry by ID, title, or tags and follows the reasoning chain. Search by the decision’s title, not just the name of a rejected alternative.

ui serves a read-only browser on localhost. See the same renderer in action in Dira’s own ledger.

Use check in your workflow

Run plans through dira check "your proposed plan" explicitly. The bundled capture hooks do not automatically gate plans.

check exit codeMeaning
0No conflict detected.
2A conflict with a settled decision.
1The check failed to run, including invalid arguments. Never treat this as a clean verdict.

Other commands generally use exit 2 for usage errors. Consult the command reference for each command’s contract.

Change direction without losing history

Decisions are allowed to change. First record a replacement with its own reasoning, then supersede the old decision. Use the IDs returned by your ledger:

dira supersede dec-0001 --with dec-0002 \
  --note "Requirements have changed"

The replacement gains a supersedes relationship and the old entry becomes superseded. Future checks consult the replacement. Both sides of the change remain in Git.

Bring existing ADRs

dira import docs/adr

Dira reports how many documents contain a rejected option with a reason before asking to write. Confirm interactively or pass --yes. Imported decisions are staged and carry the source filename and content hash.

If the corpus contains no reasoned rejections, dira offers to index it in the cache instead. It does not invent alternatives or turn every document into an enforceable decision.

Your files are the record

.dira/
├── config.toml      # Configuration
├── entries/         # Markdown + YAML frontmatter
│   ├── int-0001.md
│   └── dec-0001.md
└── cache/           # Derived SQLite; rebuildable

There are five entry kinds. Rejected alternatives are part of a decision, rather than a separate kind.

KindWhat it records
IntentWhat you are trying to make true.
DecisionA choice, its rejected alternatives, and their reasons.
QuestionSomething unresolved that may block work.
ConstraintA rule the work must respect.
NoteSupporting context.

Relationships connect entries. For example, a decision can derive_from an intent. See the exact edge names and validation rules in the entry schema.

dira reindex

The cache can be rebuilt from the entry files. Read, review, and diff the source with ordinary Git tools.

Connect context across projects

Declare parent ledgers in .dira/config.toml to organize personal, workspace, and repository context. dira brief --chain surfaces parent context; namespaced references connect entries across ledgers.

Parent context is read at runtime. Follow the tier and privacy rules when combining private context with public repositories.

Direction and execution

kazi checks whether a declared goal satisfies its acceptance predicates. Dira preserves why the goal matters and the choices behind it. Both work independently.

dira map

The map groups active intents and accepted decisions and reads execution status through kazi’s public JSON interface. If kazi is unavailable, the ledger groups still render with an explanation. Execution status is never stored in the ledger.

When something doesn’t look right

The hook cannot find dira

Verify dira --version in your shell and ensure the binary is on the PATH available to Claude Code. Start a new session after installing hooks.

A capture stays staged

Confirmation is not acceptance. The agent still needs to supply semantic reasoning. Review the queue with dira distill and consult the capture skill.

why cannot find my search

Try the entry’s exact ID, a word from its title, or a tag. The quick-start example uses dira why SQLite.

The command list differs

This website follows the source tree. Run dira --help for your installed binary and check release notes before upgrading.

Help make the record better

Dira is open source under the Apache License 2.0. Read the design document, explore the project’s decisions, or report a reproducible issue on GitHub.

sh hooks/install.sh
go test ./...

Run these from the source checkout before contributing. The tests include validation of Dira’s own ledger against its schema.