How-to guide

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

Command
pipx install "mneme-hq==0.10.0"

2. Write an ADR Mneme can protect

Save this as docs/adr/ADR-001-no-celery.md:

File · 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: accepted puts the ADR in the active set.
  • priority is 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 as Must not use the term "seamless". A single-term FORBID_DEPENDENCY line under a ## Constraints heading 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:

Command
mneme setup
Recorded output
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.

Command
mneme adr import docs/adr --memory .mneme/project_memory.json
Recorded output
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.
Command
mneme adr import docs/adr --memory .mneme/project_memory.json --apply
Recorded output
Wrote 1 decisions to .mneme/project_memory.json

Run

5. Audit the repository

Command
mneme audit --memory .mneme/project_memory.json --repo-root .
Recorded output
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

Command
mneme protect list --memory .mneme/project_memory.json
Recorded output
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:

Command
mneme protect validate ADR-001 --memory .mneme/project_memory.json
Recorded output
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

Command
mneme protect activate ADR-001 --memory .mneme/project_memory.json
Recorded output
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:

Command
mneme audit --memory .mneme/project_memory.json --repo-root .
Recorded output
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:

File · inputs/jobs_celery.py
from celery import Celery

app = Celery("jobs")
Command
mneme check --memory .mneme/project_memory.json \
  --input inputs/jobs_celery.py \
  --target-path workers/jobs.py \
  --query "edit to workers/jobs.py"
Recorded output
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:

File · inputs/jobs_pubsub.py
from google.cloud import pubsub_v1

publisher = pubsub_v1.PublisherClient()
Command
mneme check --memory .mneme/project_memory.json \
  --input inputs/jobs_pubsub.py \
  --target-path workers/jobs.py \
  --query "edit to workers/jobs.py"
Recorded output
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.

Command
mneme protect status ADR-001 --memory .mneme/project_memory.json
Recorded output
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:

Recorded output
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":

Recorded output
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

Recorded output
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:

Recorded output
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.

Command
mneme adr import docs/adr --memory .mneme/project_memory.json --apply --update-existing --preserve-protection ADR-001:FORBID_LITERAL:9e170833e847f7b3c7143e0d2be5d4b7
Recorded output
Wrote 1 decisions to .mneme/project_memory.json
Recorded output
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 celery as a whole, case-sensitive token, in any file you check except ADR-001's own file and the memory file. It does not match Celery, CELERY or celery_app. A document or comment that mentions celery as a word fails too. To limit a rule to certain paths, write it yourself with include_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_DEPENDENCY constraint. It never invents a rule from free prose.

Next