Most teams already document architectural decisions. The problem is that AI coding agents do not enforce them.
mneme adr import works with YAML-frontmatter ADRs and explicit ## Constraints sections — no rewriting required.
The problem this solves
Most teams have ADRs. They sit in docs/adr/, written in good faith, referenced in onboarding, and then quietly ignored by every AI coding agent that touches the codebase. The agent has no access to them, no enforcement against them, and no way to know when code it generates violates a decision the team already made.
mneme adr import closes that gap without requiring you to rewrite your ADRs or adopt a new format. Add a single section to flag machine-readable constraints, run the import, and those decisions enter the same enforcement pipeline as any other Mneme rule. Mneme catches the violation before it lands in review.
Step 1: add a Constraints section
ADR files need YAML frontmatter and an optional ## Constraints section. The rest of the body is free-form markdown and is preserved as rationale.
---
id: ADR-005
title: Brand vs Package Namespace Enforcement
status: accepted
priority: foundational
date: "2026-05-04"
scope: code
---
The package namespace is `mneme`. The brand name is "Mneme HQ".
These must never be conflated in code-bearing surfaces.
## Constraints
- FORBID_DEPENDENCY: MnemeHQ
- FORBID_PATH: site/use-cases/**/Mneme HQ*
YAML frontmatter is required. Nygard-style **Status:** Accepted headers are not parsed. Adding a 6-line frontmatter block per file is a one-time, scriptable conversion.
Three directive kinds are supported:
| Directive | What it does | Enforced by mneme check? |
|---|---|---|
| FORBID_DEPENDENCY: X | Stored as "no X" in decision constraints |
Yes — triggers WARN |
| FORBID_PATH: glob | Stored for visibility and audit | No (path enforcement is a follow-on) |
| REQUIRE_PATH: glob | Stored for visibility and audit | No (path enforcement is a follow-on) |
Unknown directive kinds raise a parse error rather than being silently dropped — a typo should not defeat governance.
Step 2: preview the import
Nothing is written during preview — safe to run on any codebase.
# dry-run: read-only preview
mneme adr import docs/adr --memory .mneme/project_memory.json
Output shows the active decision set and each parsed constraint:
ADR import preview
============================================================
Active set (4 ADRs):
[ADR-001] status=active
(no ## Constraints directives)
[ADR-005] status=active
constraint: no MnemeHQ
constraint: FORBID_PATH site/use-cases/**/Mneme HQ*
ADRs with status proposed, deprecated, or superseded are excluded from the active set. Explicit supersession via the supersedes frontmatter field is handled silently. Active-active contradictions (two accepted ADRs sharing the same scope, priority, and date) surface as diagnostics and block the apply step until resolved.
Step 3: apply the import
mneme adr import docs/adr --memory .mneme/project_memory.json --apply
The import writes atomically: the updated memory is serialized to a sibling temp file, then swapped in with os.replace(). A failed write leaves the original file intact. No backup files are created — the original is always recoverable from git history.
On success, the command reports what was written:
Wrote 4 decisions to .mneme/project_memory.json
Step 4: verify enforcement
Once imported, decisions enter the existing MemoryStore → DecisionRetriever → check_prompt pipeline without any changes to those components.
mneme check \
--memory .mneme/project_memory.json \
--input agent-output.py \
--query "Python package imports code namespace" \
--mode warn
If agent-output.py contains from MnemeHQ.memory_store import MemoryStore:
WARN [ADR-005] constraint "no MnemeHQ" -- trigger: mnemehq
Brand vs Package Namespace Enforcement
Result: WARN
The correct import path passes cleanly:
Result: PASS
Conflict handling
Same-id collision. If an incoming ADR id already exists in the target memory file's decisions[] array, the import refuses. Pass --update-existing to overwrite the existing entry in place.
Active-active contradiction. If two accepted ADRs share the same scope, priority, and date, the compiler cannot pick a winner deterministically. The import surfaces this as a diagnostic and refuses --apply unless --approve-conflicts is also passed. The fix is to edit the contradicting ADRs: mark one superseded, give one a higher priority, or give one a newer date.
Dogfooding
Mneme HQ enforces its own ADRs this way. The docs/adr/ directory in the public repo contains the team's architectural decisions, and ADR-005 (namespace enforcement) is imported into the project's live memory. When an AI-assisted task generates code using the wrong package namespace, Mneme catches it before it lands in review.
The runnable demo is at mneme-project-memory/examples/demo-adr-import.py in the repo. It imports the ADR corpus, applies it to a fresh memory file, and shows the WARN and PASS verdicts end-to-end.