intent-check — catch a collision before you write a line
decree intent-check --plan … --files … is the pre-code planning guard. You
describe the change in a sentence and name the files it will touch, and decree tells you
which decisions stand in the way — before you have written a single line.
Scenario You're about to change how src/auth/tokens.py stores refresh tokens.
Without decree
You write the change, push the branch, and open a PR. Only in review does a teammate notice that two decisions claim that file — one shipped, one still in-flight with open acceptance criteria. You found out too late, after the work was done.
With decree
One command, run against the plan, surfaces the collision at planning time:
$ 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
Block now (1): ✗ resolve_conflict_first: src/auth/tokens.py is governed by SPEC-00000000000000000000000001, SPEC-00000000000000000000000002. Decide which decision is authoritative before implementing.
Clean later (3): ~ 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
Recommended next command: decree intent-check --under SPEC-00000000000000000000000001 --plan "..." --files ... (name the authoritative decision; treat the other governors as contextual)
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 The two-decision collision, the in-flight SPEC, and its unchecked acceptance criteria show up before you code — not in a review comment after.
HONESTY intent-check reports the structural conflict — two decisions declare the same path. It does not judge whether they truly contradict; that semantic call is the agent’s or reviewer’s job.
How it works
Section titled “How it works”Give intent-check a plan summary and the files the plan will touch. It reports the decisions that govern those files, which of them are stale, which acceptance criteria are still unchecked, and any structural conflicts — two decisions claiming the same path. All of it lands before a diff exists, so you adjust the plan instead of unwinding code.
Every finding carries a class, so an agent can act without guessing:
blocking_findings (a real collision), advisory_findings (surfaced — proceed and note
them), and corpus_hygiene_findings (you’re editing a decree document itself). Planned
files are split into source, corpus, and generated — so refining a SPEC’s own
design is never mistaken for ungoverned code. The human report leads with a Block now /
Clean later summary and one recommended next command. The classes are additive and the
exit code is unchanged: they inform the decision, they don’t gate it.
Run it
Section titled “Run it”Two decisions declare src/auth/tokens.py. The in-flight one has unchecked acceptance
criteria. intent-check leads with Block now (the conflict) and Clean later (the
unchecked criteria), then one recommended next command.
$ 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
Block now (1): ✗ resolve_conflict_first: src/auth/tokens.py is governed by SPEC-00000000000000000000000001, SPEC-00000000000000000000000002. Decide which decision is authoritative before implementing.
Clean later (3): ~ 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
Recommended next command: decree intent-check --under SPEC-00000000000000000000000001 --plan "..." --files ... (name the authoritative decision; treat the other governors as contextual)
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 1The plan touches a SPEC’s own markdown and a new helper. Neither is a blocker: the
self-edit is corpus maintenance, the new file an advisory add_governance. Both
land under Clean later and the check exits exit 0 clean · advisory-only — editing a
decision document is no longer mistaken for ungoverned code.
$ decree intent-check --plan Refine the SPEC and add a helper --files decree/spec/spec-00000000000000000000000001-token-storage.md src/auth/helper.pyIntent check — pre-PR governance map Plan: Refine the SPEC and add a helper
Block now (0): (none)
Clean later (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. ~ corpus_maintenance [decree/spec/spec-00000000000000000000000001-token-storage.md]: decree/spec/spec-00000000000000000000000001-token-storage.md is a decree document; run `decree lint` (and `decree index rebuild` after governs:/frontmatter edits) — no governance needed.
Recommended next command: Proceed; address the advisory / corpus-hygiene items when convenient.
Planned files (2): • decree/spec/spec-00000000000000000000000001-token-storage.md • 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 (1): → add_governance: src/auth/helper.py has no governing decision. Consider writing a SPEC or amending an existing one's `governs:` list before starting.→ exit 0--other-active-files takes a JSON map of other session ids to the paths they plan to
touch. A planned file that overlaps a live session surfaces as a live-session conflict
with an isolate_session recommendation.
$ 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
Block now (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.
Clean later (0): (none)
Recommended next command: Run in a dedicated worktree, or split the overlapping file out of one plan, before starting.
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 1decree owns no session state. You supply the other sessions’ planned paths; decree only computes the overlap. It reports that two sessions claim the file — not who should win.
Work under your active decision
Section titled “Work under your active decision”A hot file often belongs to more than one decision over time — a first slice, an evolution,
a shared contract. Reported flat, that reads as a conflict every time. Pass
--under SPEC-… and intent-check frames the report around the decision you’re working under:
$ decree intent-check --plan Change token refresh storage --files src/auth/tokens.py --under SPEC-00000000000000000000000001[intent-check] exit 1: findings present (conflicts, live-session overlaps, or stale governance).Intent check — pre-PR governance map Plan: Change token refresh storage
Block now (1): ✗ resolve_conflict_first: src/auth/tokens.py is governed by SPEC-00000000000000000000000001, SPEC-00000000000000000000000002. Decide which decision is authoritative before implementing.
Clean later (3): ~ 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
Recommended next command: Proceed under SPEC-00000000000000000000000001; the other governors are contextual — resolve only if their acceptance criteria contradict your plan.
Active decision: SPEC-00000000000000000000000001 Owned files (1): src/auth/tokens.py Contextual overlaps (1): ~ src/auth/tokens.py — also governed by SPEC-00000000000000000000000002 (context, not a contradiction)
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 1The Active decision block spells out the frame — what your decision owns, which
other governors are contextual, and any path it does not own (a real
contradiction) — and the recommended next command guides you to proceed under it. The same
three keys (owned_files, contextual_overlaps, contradictions) are in the --json
output for programmatic consumers.
VALUE ”Work under SPEC-…01; treat SPEC-…02 as context” is a call an agent can make deterministically — instead of stopping on every hot file two decisions happen to share.
A separate advisory, directory_overlaps, surfaces co-governance the exact-path conflict
query can’t see: a file owned by one decision exactly and another via a directory
governs: entry. It’s advisory — it never flips the exit code.
When you’d reach for this
Section titled “When you’d reach for this”- Before an agent starts implementing — hand it the governing decisions and conflicts as deterministic context, not a guess.
- Before opening a PR — gate CI on a clean plan so collisions surface at planning time, not in review.
- When two agents or people might touch the same file — pass their planned paths and catch the live overlap before either writes a line.
Flags & exit codes
Section titled “Flags & exit codes”intent-check exits exit 1 a finding you can gate CI on on a blocking finding — structural conflicts,
live-session overlaps, or stale governance — exit 0 clean · advisory-only when the plan is clean
or has only advisory / corpus-hygiene findings, and exit 2 config error on a config
error, such as an invalid --under id. The blocking_findings / advisory_findings /
corpus_hygiene_findings classes and the --under framing keys are additive: they never
change the exit code.
All flags
| Flag | What it does |
|------|--------------|
| --plan TEXT | One-sentence to one-paragraph description of the planned change. |
| --files PATH [PATH ...] | One or more repo-relative paths the plan will touch. |
| --other-active-files JSON | JSON map of other active session ids to the paths they plan to touch, e.g. '{"session-b": ["src/foo.py"]}'. Planned files overlapping a live session surface as live-session conflicts. |
| --under ID | Active decision id. Frames the report around it — owned_files, contextual_overlaps, contradictions — and surfaces the advisory governs_gaps its own commits repeat-touch (≥2) but it doesn’t declare. Invalid id exits 2. |
| --json | Emit JSON for programmatic consumers. |
| --project PATH | Operate on the project at this path (default: cwd). |
| --with-abstention | Route governance lookups through the calibrated method. |
| --target-precision P | Desired precision floor for non-abstain responses. |
Next: intent-review — gate the diff after you code.