Install Mneme and activate your first protection
Install the Mneme command-line tool with pipx and run mneme setup. Import an architecture decision record (ADR), and the audit tells you whether Mneme can protect it. Then validate and activate that one rule, and mneme check starts failing code that breaks the decision.
You’ll end up with: Mneme installed in a repository, one ADR turned into an active FORBID_LITERAL rule, an audit that reports the decision as Protected, and a mneme check that fails when code reintroduces the banned library.
Goal
An ADR is a short Markdown file that records one architecture decision and why it was made. Mneme reads ADRs and can turn some of them into rules it checks code against. Installing Mneme does not turn any rule on: mneme setup runs in setup mode, which prepares the repository and blocks nothing. Enforcement starts only when you activate a rule for a specific decision. This guide takes one ADR from a fresh install to an active, verified rule.
These terms come up throughout:
- Memory file:
.mneme/project_memory.json, where Mneme stores your compiled decisions and their rules. - Mneme-ready: the audit found a decision with a clear, checkable intent and a rule Mneme could install for it, but no rule is installed yet.
- Protected: the audit observes enforcement for the decision. In this guide, that is an installed rule.
- Requires modelling and Guidance: the other two audit tiers. Requires modelling means a checkable intent with no rule Mneme can derive yet; Guidance means a decision that is advice rather than a checkable rule.
FORBID_LITERAL: the rule type this guide installs. It fails a check when a file contains a given token.
Prerequisites
- Python 3.11 or newer, and pipx.
- A git repository. An existing project works; create a
docs/adr/directory if it doesn't have one. - No coding agent and no continuous integration (CI) setup. Later guides add both.
Configure
1. Install the command-line tool
pipx install "mneme-hq==0.10.0"
2. Write an ADR Mneme can protect
Save this as docs/adr/ADR-001-no-celery.md:
docs/adr/ADR-001-no-celery.md--- id: ADR-001 title: No Celery status: accepted priority: foundational date: "2026-10-01" scope: workers --- Background jobs run on the managed Pub/Sub queue. Celery was retired after the 2026 queue incident, and reintroducing it brings back a broker the team no longer operates.
status: acceptedputs the ADR in the active set.priorityis required. The import stops without it (see Troubleshooting).- The title No Celery is what makes this ADR Mneme-ready. The audit reads an imported ADR's title, and when the title names one banned term it can propose a rule for that term.
- Two title shapes work: a
No <one term>headline, or a title that bans a quoted term, such asMust not use the term "seamless". A single-termFORBID_DEPENDENCYline under a## Constraintsheading works too. Any other wording stays Requires modelling until you write the rule yourself, as Turn an ADR into an enforceable decision shows.
3. Run setup
From the repository root:
mneme setup
Mneme setup Repository OK repo (<tmp>/repo) Project memory Created <tmp>/repo/.mneme/project_memory.json Architecture baseline Not connected (no audit reference provided) Integrations None detected Protection readiness Protected: 0 Mneme-ready: 0 Requires modelling: 0 Guidance: 0 Enforcement Not enabled Initial check OK (0 decisions) | ADR diagnostics: 1 (warn-only) Mneme is installed in setup mode.
Setup creates the memory file and reports what it found, including one warn-only ADR diagnostic for the ADR from step 2. Enforcement: Not enabled is expected: setup never installs a rule, a hook or a CI check.
4. Preview, then apply the import
Without --apply, the import writes nothing. The preview exits with code 1 and says the ADR "will be imported for retrieval only". That means the ADR has no rule yet, so for now Mneme can only show it to agents as context. Nothing is wrong: activation adds the rule in step 8.
mneme adr import docs/adr --memory .mneme/project_memory.json
ADR import preview
============================================================
Active set (1 ADRs):
[ADR-001] status=active
(no supported ## Constraints directives)
Retrieval-only ADR warnings:
- ADR-001 yields 0 mechanically enforceable rules; it will be imported for retrieval only. Add an enforceable directive such as FORBID_LITERAL under ## Constraints to make enforcement explicit.
mneme adr import docs/adr --memory .mneme/project_memory.json --apply
Wrote 1 decisions to .mneme/project_memory.json
Run
5. Audit the repository
mneme audit --memory .mneme/project_memory.json --repo-root .
Architecture Protection Audit
============================================================
Decisions discovered: 1
Protection-relevant: 1
Current Protection: 0.0%
Protection Gap: 100.0%
Protected today: 0
Mneme-ready: 1
Requires modelling: 0
Guidance-only: 0
Per-decision breakdown:
[mneme_ready] ADR-001: No Celery
guardrail: FORBID_LITERAL: celery
ADR-001 is Mneme-ready. The audit read the title No Celery and names the rule it would install: FORBID_LITERAL: celery.
6. List the activation candidates
mneme protect list --memory .mneme/project_memory.json
Protection activation candidates
============================================================
Protected: 0 Mneme-ready: 1 Requires modelling: 0 Guidance: 0
Candidates: 1
[1] ADR-001: No Celery
source: <tmp>/repo/docs/adr/ADR-001-no-celery.md
guardrail: FORBID_LITERAL: celery
rule to install: FORBID_LITERAL "celery"
applies to: global applicability (canonical policy sources exempt)
enforcement: FORBID_LITERAL fails on an exact case-sensitive match, enforced independently of retrieval score; canonical policy sources are exempt (ADR-019/ADR-020)
Validate before activating: mneme protect validate <decision-id>
Activate (explicit): mneme protect activate <decision-id>
Read the applies to line before you go on. This rule applies to every file you check except ADR-001's own file and the memory file, which the output calls "canonical policy sources". ADR numbers in Mneme's own output, such as ADR-019 here, refer to Mneme's design records, not to yours.
7. Validate the rule
Validation runs four checks on the proposed rule and changes nothing:
mneme protect validate ADR-001 --memory .mneme/project_memory.json
Validating proposed protection for [ADR-001]
decision: No Celery
proposal: FORBID_LITERAL "celery"
checks:
PASS prohibited_detected: input containing 'celery' is a typed FAIL
PASS permitted_allowed: permitted input without 'celery' is not blocked
PASS path_scope_respected: artifact path enforced=True, canonical policy source exempt=True
PASS unrelated_paths_unaffected: unrelated artifact path enforced=True, permitted content blocked=False
Result: VALID
Validation never activates protection.
8. Activate it
mneme protect activate ADR-001 --memory .mneme/project_memory.json
Protection activated and verified: [ADR-001] (rule installed) rule: FORBID_LITERAL "celery" verification: canonical assessment reports protected Re-run `mneme audit` to observe the new Protected decision.
Activation adds the rule to ADR-001's current version in the memory file, switches the project out of setup mode, then re-runs the audit's assessment for ADR-001 to confirm it is now Protected.
Expected result
The audit now counts ADR-001 as Protected:
mneme audit --memory .mneme/project_memory.json --repo-root .
Architecture Protection Audit
============================================================
Decisions discovered: 1
Protection-relevant: 1
Current Protection: 100.0%
Protection Gap: 0.0%
Protected today: 1
Mneme-ready: 0
Requires modelling: 0
Guidance-only: 0
Per-decision breakdown:
[protected] ADR-001: No Celery
guardrail: FORBID_LITERAL: celery
And the rule is live. To test it, save a worker that brings Celery back. Any location works; this guide uses inputs/jobs_celery.py:
inputs/jobs_celery.pyfrom celery import Celery
app = Celery("jobs")
mneme check --memory .mneme/project_memory.json \ --input inputs/jobs_celery.py \ --target-path workers/jobs.py \ --query "edit to workers/jobs.py"
FAIL [ADR-001] FORBID_LITERAL "celery" -- trigger: celery
No Celery
path: workers/jobs.py
Result: FAIL
--input is the file to check. --target-path is the path that content would have in the repository, here a worker module. --query describes the change; Mneme uses it to choose which decisions to show as guidance, and checks typed rules such as this one either way. The check fails with exit code 2.
The same worker written against Pub/Sub, saved as inputs/jobs_pubsub.py, passes with exit code 0:
inputs/jobs_pubsub.pyfrom google.cloud import pubsub_v1 publisher = pubsub_v1.PublisherClient()
mneme check --memory .mneme/project_memory.json \ --input inputs/jobs_pubsub.py \ --target-path workers/jobs.py \ --query "edit to workers/jobs.py"
Result: PASS
Evidence
mneme protect status shows one decision's tier, its rule and whether the rule is installed. Nothing in it is stored separately; Mneme derives it from the memory file each time.
mneme protect status ADR-001 --memory .mneme/project_memory.json
Decision [ADR-001] No Celery lifecycle status: active protection tier: protected guardrail: FORBID_LITERAL: celery evidence: verified rule installed: yes
Commit .mneme/project_memory.json with the ADR. The installed rule lives in that file. The agent hooks and CI checks in the next guides read it, so they enforce every rule installed in it.
Troubleshooting
The import stops with missing required field 'priority'
The import crashes with a Python traceback. The last line names the file and the missing field:
mneme.adr_schema.ADRValidationError: ADR validation failed with 1 error(s): troubleshooting/no-priority/ADR-001-no-celery.md: missing required field 'priority'
Add priority: foundational (or another priority) to the ADR's frontmatter and import again.
The audit says Requires modelling, and there are no candidates
The ADR's intent is clear to a person, but the title doesn't name a single banned term, so Mneme won't guess a rule. This ADR is titled "Request handlers must not import the database client":
Protection activation candidates ============================================================ Protected: 0 Mneme-ready: 0 Requires modelling: 1 Guidance: 0 Candidates: 0 (no activation candidates)
Either retitle it in one of the shapes from step 2, or write the rule yourself in a ## Constraints section, as Turn an ADR into an enforceable decision shows.
Already Protected when you activate again
Already Protected: [ADR-001] already Protected under the canonical assessment Nothing to activate.
Activation is idempotent. Running it twice never installs a second copy of the rule.
Re-importing an edited ADR is refused
After you edit an activated ADR and re-import it with --update-existing, the import stops with exit code 2:
ERROR: ADR import refused while evolving 'ADR-001': decision 'ADR-001': version evolution would drop protection/legacy_unknown bindings ['ADR-001:FORBID_LITERAL:9e170833e847f7b3c7143e0d2be5d4b7']; pass --preserve-protection or --release-protection for each (ADR-030 §9a)
The activated rule lives in the memory file, not in the ADR, so a new version of the ADR would drop it. (ADR-030 in the message is one of Mneme's own design records.) Mneme refuses rather than switch protection off silently. Say what you want: --preserve-protection with the rule id from the message keeps the rule, and --release-protection drops it.
mneme adr import docs/adr --memory .mneme/project_memory.json --apply --update-existing --preserve-protection ADR-001:FORBID_LITERAL:9e170833e847f7b3c7143e0d2be5d4b7
Wrote 1 decisions to .mneme/project_memory.json
Decision [ADR-001] No Celery lifecycle status: active protection tier: protected guardrail: FORBID_LITERAL: celery evidence: verified rule installed: yes
Limits
- The installed rule matches
celeryas a whole, case-sensitive token, in any file you check except ADR-001's own file and the memory file. It does not matchCelery,CELERYorcelery_app. A document or comment that mentionsceleryas a word fails too. To limit a rule to certain paths, write it yourself withinclude_paths, as in Turn an ADR into an enforceable decision. - Activation installs one rule for one decision. It doesn't start any agent hook or CI job. Until you add those, the rule runs only when you call
mneme check. - The audit derives a rule only from the title shapes in step 2 or a single-term
FORBID_DEPENDENCYconstraint. It never invents a rule from free prose.