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.