Skip to content

decree

open source · deterministic · MIT

Your code outlives the reasons for it.

Humans forget which decision a file answers to. Agents never knew. decree keeps the decision attached to the code and checks every change against it — answering only from what's declared, and saying “no governing decisions” instead of guessing.

Terminal window
brew install doruksahin/decree/decree

Installs v3.2.1 from the decree Homebrew tap. Source installs are on Start here.

ask which decision governs a file
$ decree why src/auth/tokens.py
src/auth/tokens.py — 1 governing decision
▸ SPEC-00000000000000000000000001 implemented 2026-05-10 exact
JWT token storage
governs: src/auth/tokens.py
→ exit 0
…and when none does, it says so
$ decree why src/auth/charge.py
src/auth/charge.py — no governing decisions
→ exit 0
MIT & open source Python CLI, language-agnostic — governs paths, not your code decree governs its own code: 52 PRD/ADR/SPEC docs, 508/532 primary acceptance criteria, lint clean every terminal here is real captured output

Scenario You're about to edit src/auth/tokens.py. Why are tokens hashed, not encrypted?

Without decree

You don’t know. So you git blame, open three stale PRs, grep the wiki, and ping a teammate who left last quarter. Twenty minutes gone, and you’re still guessing whether your change is allowed.

With decree

One command returns the exact governing decision, attached to the file:

Terminal window
$ decree why src/auth/tokens.py
src/auth/tokens.py — 1 governing decision
▸ SPEC-00000000000000000000000001 implemented 2026-05-10 exact
JWT token storage
governs: src/auth/tokens.py
→ exit 0

VALUE The reason behind the code is one query away — not buried in chat history or a teammate’s memory.

HONESTY why answers only from declared governs:. If nothing governs the file, it says so. It will not invent a decision.

decree captures decisions as a chain and links each one to the code it governs:

decree runs in CI and in agent loops, so its verdict is the exit code — not prose someone has to read.

exit 1 a finding you can gate CI on a finding you can gate on: a conflict, a live overlap, dead governance.
exit 0 clean · advisory-only clean — or advisory-only. Suggestions never block.
exit 2 config error a config error, never a finding. The two are kept apart on purpose.

An LLM agent editing your code has no memory of the decisions it’s about to break. decree gives it a deterministic check to run before and after every edit — and the exit code gates the loop. The same checks are exposed over MCP (decree mcp serve: eight tools, identical JSON to the CLI) and project-local Codex/Claude skills installed by decree init --with-agents. For parallel work, a human orchestrator can refresh the read-only HTML board to inspect the sprint, then hand each worker agent one document ID. The agents stay on CLI/MCP: sprint move, decree ddd --doc, intent-check, intent-review, and sprint complete.

decree has no model and no temperature. The same corpus and the same diff produce the same answer, every run. It reads declared facts and computes structural overlap; where it reads git history (for drift signals), it labels the result advisory, never certain. It never asks a language model what your code probably means, and it never judges whether your change is correct, only whether it collides. That single boundary — answers only from what’s declared — is exactly what makes its output safe to gate CI on.

decree doesn’t replace git. It runs on top of it.

git tracks what changed — blame, log, and diff, as a content-addressed guarantee. decree tracks which decision that change has to honor, and checks whether it still does. git can show you that src/auth/tokens.py changed. It can’t tell you which decision that change must answer to, or whether your edit still aligns with it. decree maps the file to its governing decision from a declared governs: field, and gates the change that collides.

decree reads git history too — for advisory drift signals — but only as a convention, never as certainty. git guarantees which files a commit changed; the Implements: trailer that links a commit to a decision is a convention you write, not something git enforces. So those signals stay advisory by design.

Why decree, and not just a folder of ADRs?

Section titled “Why decree, and not just a folder of ADRs?”

You already write decisions in markdown. decree makes them queryable (governs: → file), enforceable (an exit-coded CI gate), and checkable over time (drift detection) — on top of the same files, for humans and agents both. It’s additive, not a replacement.

This isn’t a toy demo. decree manages its own decisions, and governs its own source:

decree, run against the decree repo
$ decree why src/decree/parser.py
src/decree/parser.py — 3 governing decisions
▸ SPEC-01KW1Z8TDZ6XZDV0G44KDSB92B implemented 2026-06-26 exact
Foldered Document Buckets and List CLI
governs: src/decree/parser.py
▸ SPEC-01KT22NMS0D19VMD8VPK4D2MNX implemented 2026-06-01 exact
Parallel-Safe Document Identity and Scoped Progress
governs: src/decree/parser.py
▸ SPEC-01KW1QJ27R175NVM8QNGW1FX8N draft 2026-06-26 exact
Sprint Ledger CLI and Validation
governs: src/decree/parser.py
→ exit 0

Its corpus is 48 PRD/ADR/SPEC docs at 497/521 primary acceptance criteria, lint clean — tracked by decree itself. See the full by-example walkthrough →