mneme CLI exposes init, list_decisions, add_decision, test_query, check, cursor generate, benchmark, and adr import. Every subcommand reads a project_memory.json corpus via --memory and returns Unix exit codes (0 pass, 1 warn, 2 fail).The mneme command-line interface
Reference for every subcommand the OSS mneme CLI ships with: managing the decision corpus, querying it, enforcing it against generated content, exporting to editor surfaces, and running the governance benchmark suite. The CLI is the deterministic surface; the same operations are available programmatically.
Install
Python 3.11+. MIT-licensed. No vector store, no ML runtime.
$ pipx install "mneme-hq>=0.5.1" # or: pip install mneme-hq
Installs the mneme entry point on your PATH. Scaffold a new corpus with mneme init; every other subcommand requires --memory pointing at a project_memory.json file. An example corpus ships at examples/project_memory.json.
From source (contributors): git clone https://github.com/MnemeHQ/mneme && cd mneme && pip install -e .
init
Scaffold an empty project memory corpus.
Creates the memory file (including its parent directory) containing a valid, empty decision corpus — deliberately zero seeded decisions, because every recorded decision is enforceable and sample content would create phantom rules. Exits non-zero without writing if the target file already exists, unless --force is supplied.
$ mneme init
Created .mneme/project_memory.json
| Flag | Required | Description |
|---|---|---|
| --path | no | Output path. Defaults to .mneme/project_memory.json. |
| --force | no | Overwrite an existing file at --path. |
list_decisions
Print every decision in the memory file.
Lists every decision in the corpus with id, summary, scope, and constraints. Read-only.
$ mneme list_decisions --memory examples/project_memory.json
| Flag | Required | Description |
|---|---|---|
| --memory | yes | Path to project_memory.json. |
add_decision
Append a new decision to the corpus.
Writes a new decision directly to the JSON file. The Pipeline runtime is never mutated — this is a file operation only. Fails with exit code 2 if the id already exists.
$ mneme add_decision --memory examples/project_memory.json \ --id mneme_042 \ --decision "Use JSON storage" \ --scope storage \ --constraint "no postgres" \ --anti-pattern "sqlalchemy"
| Flag | Required | Description |
|---|---|---|
| --memory | yes | Path to project_memory.json. |
| --id | yes | Stable id for the decision (e.g. mneme_042). |
| --decision | yes | Short statement of the decision. |
| --rationale | no | Optional free-text explanation. |
| --scope | no, repeatable | One or more scope tags. Pass --scope multiple times. |
| --constraint | no, repeatable | One or more constraints the decision implies. |
| --anti-pattern | no, repeatable | One or more patterns to flag against. |
test_query
Run a query through the retriever and show scores plus the injected context.
Useful for debugging which decisions are surfaced for a given task description before you wire enforcement into a workflow. Prints every decision ranked by score, plus the top-N context packet that would actually be injected.
$ mneme test_query --memory examples/project_memory.json \ --query "should I add postgres?"
| Flag | Required | Description |
|---|---|---|
| --memory | yes | Path to project_memory.json. |
| --query | yes | The task description / prompt context to retrieve against. |
| --top | no | How many top decisions to show in the injected packet. Defaults to the package default. |
check
Enforce decisions against an input file. The command at the center of the governance loop.
Reads an input file (a prompt, a generated diff, a draft), retrieves the relevant decisions for --query, and runs the enforcer. Prints any violations and exits with a code that reflects the verdict.
$ mneme check --memory examples/project_memory.json \ --input draft.md \ --query "working on storage layer" \ --mode strict
| Flag | Required | Description |
|---|---|---|
| --memory | yes | Path to project_memory.json. |
| --input | yes | Path to the file to check. A filepath, not inline text — write generated content or a diff to a file first. |
| --query | yes | Provides retrieval context for relevance-scored decisions. Retrieval does not bound corpus-wide typed literal enforcement — those rules apply regardless of query relevance. |
| --target-path | no | Artifact path used for typed-rule path applicability when --input contains materialized or introduced content from another file (e.g. a hook checking staged edit content against the real target path). |
| --top | no | Size of the retrieval-gated tier: bounds how many decisions have their multi-term rules applied. Unambiguous literal rules are enforced across the whole corpus regardless (ADR-017). |
| --mode | no | strict (default) or warn. See exit codes. |
| --json | no | Emit a machine-readable verdict payload (schema: mneme.check/v1, includes evaluation_complete, per-rule applicability, and freshness) as the only stdout content. Exit codes unchanged. |
| --adr-dir | no | Directory of ADR markdown files checked for freshness drift. Warn-only diagnostics that never affect the exit code; defaults to docs/adr, skipped silently when absent. |
Mode semantics. strict exits non-zero on any violation, making it suitable as a merge gate. warn always exits zero, useful while a team is still shaping its decision corpus and does not want a noisy corpus to block work.
Completeness and path diagnostics. A verdict is only trusted when the payload's evaluation_complete flag is true; an incomplete evaluation exits 2 and prints Result: INCOMPLETE rather than a verdict. Path-scoped typed rules also emit per-rule applicability lines (PATH PASS/SKIP/UNKNOWN [decision_id] …) showing how the target path resolved against the rule's selectors — an unresolvable path surfaces as PATH_APPLICABILITY_UNKNOWN, never as a silent pass. With --json, the same traces appear in the payload's applicability array.
cursor generate
Export retrieved decisions to a Cursor .mdc rules file.
Generates a Cursor-compatible rules file scoped to the supplied query. Writes the corpus into a format the Cursor agent reads directly, so the same decisions are surfaced to the IDE agent as to the rest of the toolchain. See the Cursor integration page for end-to-end setup.
$ mneme cursor generate --memory examples/project_memory.json \ --query "working on storage layer" \ --output .cursor/rules/mneme.mdc
| Flag | Required | Description |
|---|---|---|
| --memory | yes | Path to project_memory.json. |
| --query | yes | Context query for retrieval. |
| --output | no | Output path. Defaults to .cursor/rules/mneme.mdc. |
| --top | no | How many top decisions to include. |
benchmark
Run the governance benchmark suite and report violation-detection results.
Runs every scenario in the supplied directory against the decision corpus and prints a terminal report. Optional --json and --markdown flags emit machine- and human-readable reports for CI artifacts. Scenario categories map onto the governance violation hierarchy; the benchmark methodology is documented at /benchmark/.
$ mneme benchmark examples/benchmarks/ \
--memory examples/project_memory.json \
--json reports/bench.json \
--markdown reports/bench.md
| Flag | Required | Description |
|---|---|---|
| benchmarks_dir | yes (positional) | Directory containing benchmark scenario subdirectories. |
| --memory | yes | Path to project_memory.json. |
| --json | no | Write a JSON report to FILE. |
| --markdown | no | Write a Markdown report to FILE. |
adr import
Compile a directory of ADRs into the decision corpus.
Parses every ADR markdown file in a directory (YAML frontmatter required), validates the corpus, resolves precedence, and writes compiled decisions into the target memory. Runs as a preview by default; nothing is written until --apply. Full walkthrough: ADR import guide.
$ mneme adr import docs/adr \ --memory .mneme/project_memory.json \ --dry-run $ mneme adr import docs/adr \ --memory .mneme/project_memory.json \ --apply
| Flag | Required | Description |
|---|---|---|
| adr_dir | yes (positional) | Directory containing ADR markdown files. |
| --memory | yes | Path to the target project_memory.json. |
| --dry-run | no | Print the preview without writing (default). |
| --apply | no | Write imported decisions to --memory. |
| --update-existing | no | Allow same-id overwrite of existing decisions. |
| --approve-conflicts | no | Proceed with apply even if active-active contradictions exist. |
Exit codes
Designed for CI gating. The codes are stable across releases.
| Verdict | strict (default) | warn | Meaning |
|---|---|---|---|
| PASS | 0 | 0 | No violations. |
| WARN | 1 | 0 | Constraint matched. In strict mode the verdict stays WARN but the process exits non-zero; warn mode exits zero. |
| FAIL | 2 | 0 | Typed rule or anti-pattern hit. In strict mode this is a hard fail. |
| INCOMPLETE | 2 | 2 | Evaluation could not complete (evaluation_complete: false). Never reported as PASS — machine consumers should fail open on their own terms. |
| Code | Meaning |
|---|---|
| 0 | All scenarios passed. |
| 1 | At least one scenario failed, or a benign scenario was blocked (FALSE_POSITIVE). |
| 2 | Supplied benchmarks_dir is not a directory. |
| Code | Meaning |
|---|---|
| 0 | Decision appended. |
| 2 | A decision with the supplied --id already exists. |
CI usage
The check command is designed to live as a pre-merge governance gate. The simplest viable wiring:
GitHub Actions — PR diff gate
Run mneme check against the PR diff in strict mode. Exit code 1 (WARN) or 2 (FAIL) blocks the merge.
name: governance
on: [pull_request]
jobs:
governance:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.11' }
- run: pip install -e .
- name: Render PR diff
run: git diff origin/${{ github.base_ref }}...HEAD > pr.diff
- name: Governance check
run: |
mneme check \
--memory .mneme/project_memory.json \
--input pr.diff \
--query "${{ github.event.pull_request.title }}" \
--mode strict
Full example wired into a working repo: /integrations/github-actions/.
Pre-commit — local warn-mode
Run in warn mode locally so the developer sees friction without blocking the commit. Pair with strict-mode CI for the actual gate.
# .git/hooks/pre-commit — --input expects a filepath, so write the diff first $ git diff --cached > /tmp/mneme-staged.diff $ mneme check \ --memory .mneme/project_memory.json \ --input /tmp/mneme-staged.diff \ --query "$(git log -1 --pretty=%B)" \ --mode warn