decree by example
Six scenarios follow one change — editing a file under src/auth/ — through its
whole life. Each runs real decree commands against a throwaway git corpus and prints
the real output. Nothing below is mocked; every block is captured from an actual run.
Each scenario ends on its own VALUE: line (what you gain) and HONESTY: line (where
decree refuses to overclaim). The exit code is the contract:
-
exit 1a finding you can gate CI on — a finding you can gate CI on: a conflict, a live overlap, dead governance. -
exit 0clean · advisory-only — clean, or advisory-only. Suggestions never block. -
exit 2config error — a config error, kept apart from findings on purpose.
You can run the whole arc yourself:
git clone https://github.com/doruksahin/decree && cd decreebash examples/run-all.shBefore you code
Section titled “Before you code”1 · Which decision explains this file?
Section titled “1 · Which decision explains this file?”Before editing src/auth/tokens.py, ask what governs it — and watch decree abstain on a
file nothing governs. exit 0 clean · advisory-only
── The corpus: one decision that governs the auth tokens file ──[index] rebuilding into .decree/index.sqlite[index] decisions=1 refs=0 governs=1 acs=0 commits=0[index] git_sync_ms=28✓ index rebuilt in 45ms
── Ask which decision governs the file you're about to touch ──
$ decree why src/auth/tokens.pysrc/auth/tokens.py — 1 governing decision
▸ SPEC-00000000000000000000000001 implemented 2026-05-10 exact JWT token storage governs: src/auth/tokens.py→ exit 0
$ decree why src/auth/tokens.py --json{ "query": "src/auth/tokens.py", "match_count": 1, "matches": [ { "decision_id": "SPEC-00000000000000000000000001", "type": "spec", "status": "implemented", "date": "2026-05-10", "title": "JWT token storage", "match_kind": "exact", "matched_path": "src/auth/tokens.py", "symbol": null } ]}→ exit 0
── The honesty beat: a file no decision governs ──
$ decree why src/auth/charge.pysrc/auth/charge.py — no governing decisions→ exit 0VALUE: git blame + grep + Slack archaeology → one command that returns the exact governing decision.HONESTY: why answers ONLY from declared 'governs:' frontmatter — never git, never semantic guessing.HONESTY: An empty result is a valid abstention (exit 0), not a failure. decree won't invent a decision.2 · Will my plan collide with a decision?
Section titled “2 · Will my plan collide with a decision?”Two decisions claim the same file, and the in-flight one has open acceptance criteria.
decree surfaces it at planning time, not in code review. exit 1 a finding you can gate CI on
── The corpus: two decisions claim the same file (one shipped, one in-flight) ──[index] rebuilding into .decree/index.sqlite[index] decisions=2 refs=0 governs=2 acs=2 commits=0[index] git_sync_ms=29✓ index rebuilt in 44ms
── Check the plan BEFORE coding (exit 1 = a finding you can gate CI on) ──
$ decree intent-check --plan Change token refresh storage --files src/auth/tokens.py[intent-check] exit 1: findings present (conflicts, live-session overlaps, or stale governance).Intent check — pre-PR governance map Plan: Change token refresh storage
Planned files (1): • src/auth/tokens.py
Governing decisions (2): ▸ SPEC-00000000000000000000000001 implemented exact governs src/auth/tokens.py JWT token storage ▸ SPEC-00000000000000000000000002 draft exact governs src/auth/tokens.py Token rotation policy
Stale governance (0): (none)
Unchecked acceptance criteria (2): ☐ SPEC-00000000000000000000000002 [Acceptance Criteria] Rotation job runs on schedule ☐ SPEC-00000000000000000000000002 [Acceptance Criteria] Old tokens revoked on rotation
Conflicts (1): ✗ src/auth/tokens.py: SPEC-00000000000000000000000001, SPEC-00000000000000000000000002
Live-session conflicts (0): (none)
Recommended actions (4): → update_spec_first [SPEC-00000000000000000000000002]: SPEC-00000000000000000000000002 (Token rotation policy) governs planned files and has unchecked acceptance criteria. Check off or amend ACs before implementing on top. → check_ac [SPEC-00000000000000000000000002]: SPEC-00000000000000000000000002 has an unchecked AC under 'Acceptance Criteria': Rotation job runs on schedule → check_ac [SPEC-00000000000000000000000002]: SPEC-00000000000000000000000002 has an unchecked AC under 'Acceptance Criteria': Old tokens revoked on rotation → resolve_conflict_first: src/auth/tokens.py is governed by SPEC-00000000000000000000000001, SPEC-00000000000000000000000002. Decide which decision is authoritative before implementing.→ exit 1VALUE: Discover a two-decision collision in code review (late) → see it at planning time: the conflict, the in-flight SPEC, its unchecked acceptance criteria, and a non-zero exit.HONESTY: intent-check reports the STRUCTURAL conflict (two decisions declare the path). It does NOT judge whether they truly contradict — that semantic call is the agent's/reviewer's job.While you code
Section titled “While you code”3 · Is another agent about to touch this same file?
Section titled “3 · Is another agent about to touch this same file?”Two agent sessions independently plan the same file. Given the other live session’s
planned paths, decree flags the overlap before either starts. exit 1 a finding you can gate CI on
── The corpus: one decision governing the contested file ──[index] rebuilding into .decree/index.sqlite[index] decisions=1 refs=0 governs=1 acs=0 commits=0[index] git_sync_ms=25✓ index rebuilt in 40ms
── This session plans tokens.py — we tell decree session-b also plans it ──
$ decree intent-check --plan Edit token storage --files src/auth/tokens.py --other-active-files {"session-b": ["src/auth/tokens.py"]}[intent-check] exit 1: findings present (conflicts, live-session overlaps, or stale governance).Intent check — pre-PR governance map Plan: Edit token storage
Planned files (1): • src/auth/tokens.py
Governing decisions (1): ▸ SPEC-00000000000000000000000001 implemented exact governs src/auth/tokens.py JWT token storage
Stale governance (0): (none)
Unchecked acceptance criteria (0): (none)
Conflicts (0): (none)
Live-session conflicts (1): ⇄ src/auth/tokens.py: also planned by session-b
Recommended actions (1): → isolate_session: src/auth/tokens.py is also planned by active session(s) session-b. Run in a dedicated worktree, or split this file out of one plan, before starting.→ exit 1VALUE: Two parallel agents edit the same file blind and you reconcile the wreck later → the live collision is flagged before either starts, with an 'isolate_session' recommendation (exit 1).HONESTY: decree owns NO session state. The caller supplies the other sessions' planned paths; decree only computes the overlap. It reports THAT two sessions claim the file, not who should win.After you code
Section titled “After you code”4 · Does this diff collide with governance?
Section titled “4 · Does this diff collide with governance?”The code is written and a diff exists. Before a human reviews, gate the diff against the
decision corpus — a deterministic, CI-shaped pass. exit 1 a finding you can gate CI on
── The corpus: same two decisions claiming src/auth/tokens.py ──[index] rebuilding into .decree/index.sqlite[index] decisions=2 refs=0 governs=2 acs=0 commits=0[index] git_sync_ms=32✓ index rebuilt in 46ms
── Make a change, then review the diff against governance (CI-shaped, exit 1) ──
$ decree intent-review --diff change.diff[intent-review] exit 1: findings present (conflicts or stale governance).Intent review — file:change.diff
Changed paths (1): • src/auth/tokens.py
Governing decisions (2): ▸ SPEC-00000000000000000000000001 implemented exact governs src/auth/tokens.py JWT token storage ▸ SPEC-00000000000000000000000002 draft exact governs src/auth/tokens.py Token rotation policy
Stale governance (0): (none)
Unchecked acceptance criteria (0): (none)
Conflicts (1): ✗ src/auth/tokens.py: SPEC-00000000000000000000000001, SPEC-00000000000000000000000002
Recommended actions (2): → resolve_conflict: src/auth/tokens.py is governed by SPEC-00000000000000000000000001, SPEC-00000000000000000000000002. Decide which decision is authoritative or supersede the others. → add_implements_trailer [SPEC-00000000000000000000000002]: Changes touch files governed by in-flight SPEC-00000000000000000000000002. Consider `decree commit --implements SPEC-00000000000000000000000002` so the commit links to the SPEC.→ exit 1VALUE: Governance review that depends on a human remembering every decision → a build gate that fails when a diff collides with the decision corpus.HONESTY: Reports structural intersection + conflict/stale findings; makes NO judgment about whether the change is correct. Exit 1 means 'a human/agent must look', not 'this is wrong'.Over time
Section titled “Over time”5 · Did the decision’s declared scope rot?
Section titled “5 · Did the decision’s declared scope rot?”Months in, a SPEC still claims a file no trailer-linked commit ever touched, while its
commits keep editing a helper it never declared. decree flags the dead governance (a
finding) and, separately, the suggested governance (advisory). exit 1 a finding you can gate CI on
── The corpus: a SPEC governing two files, with real trailer-linked history ──[index] rebuilding into .decree/index.sqlite[index] decisions=1 refs=0 governs=2 acs=0 commits=2[index] git_sync_ms=67✓ index rebuilt in 84ms
── Health: declared scope no commit touched (a finding, exit 1) + scope the code grew into (advisory) ──
$ decree healthStale decisions: none (all governed paths quiet).
Ungoverned hotspots: none above threshold.
Dead governance (declared governs paths no trailer-linked commit has touched):
SPEC-00000000000000000000000001 untouched by its 2 linked commit(s): src/auth/legacy_sso.py
Suggested governance (advisory — ungoverned files with a proposed owner; does not affect exit status):
SPEC-00000000000000000000000001 from 2 linked commit(s) touching 2 path(s): src/auth/helper.py (touched in 2 commits)
observed as of 2026-06-03T16:51:48+00:00; 0 decision(s) have no trailer-linked commits (governance unobservable).
Thresholds: --threshold-commits=10 --threshold-days=30→ exit 1VALUE: A decision's 'governs' list rots into fiction unnoticed → decree flags declared scope no trailer-linked commit ever touched (DEAD governance, exit 1) and, separately, scope the code grew into but never declared (SUGGESTED, advisory).HONESTY: Convention-bounded: the commit→decision link is the Implements: TRAILER convention, not a git guarantee — deterministic but not certain (needs 'decree commit' discipline).HONESTY: Asymmetry by design: DEAD is a finding (exit 1); SUGGESTED is advisory (exit 0, never feeds why()). A SPEC with zero trailered commits is reported 'unobserved, not dead' (fail-safe).While you code, governed
Section titled “While you code, governed”6 · Am I editing a file my decision doesn’t own?
Section titled “6 · Am I editing a file my decision doesn’t own?”In a governed session under a SPEC, you plan to edit a helper the SPEC’s own commits keep touching but never declared. decree nudges you to declare it — advisory, never blocking.
exit 0 clean · advisory-only
── The corpus: SPEC-…0001's own commits repeat-touch a helper it never declares ──[index] rebuilding into .decree/index.sqlite[index] decisions=1 refs=0 governs=1 acs=0 commits=2[index] git_sync_ms=65✓ index rebuilt in 78ms
── In a governed session under SPEC-…0001, planning to edit the helper (advisory, exit 0) ──
$ decree intent-check --plan edit auth helper --files src/auth/helper.py --under SPEC-00000000000000000000000001Intent check — pre-PR governance map Plan: edit auth helper
Planned files (1): • src/auth/helper.py
Governing decisions (0): (none — ungoverned plan)
Stale governance (0): (none)
Unchecked acceptance criteria (0): (none)
Conflicts (0): (none)
Live-session conflicts (0): (none)
Recommended actions (2): → add_governance: src/auth/helper.py has no governing decision. Consider writing a SPEC or amending an existing one's `governs:` list before starting. → declare_governs [SPEC-00000000000000000000000001]: SPEC-00000000000000000000000001's commits repeat-touch src/auth/helper.py, which is not in its `governs:`. Consider declaring it (advisory).→ exit 0VALUE: Governance scope drifts and you catch it in a quarterly audit → 'this file is yours in practice but undeclared' surfaces at the exact moment you touch it.HONESTY: Advisory by construction: declare_governs NEVER blocks (exit stays 0) and NEVER feeds why() — it is not a governance fact until a human adds it to 'governs:'. Squash-immune (needs commit_count >= 2).That’s the whole arc: before you code (why, intent-check), while you code
(parallel intent-check, governed --under), after you code (intent-review), and
over time (health). Each answer comes only from declared facts — and each scenario
names its own boundary. That asymmetry, finding versus advisory, is the point.
Start from the capabilities, or install decree and run the arc yourself.