** I am NOTT. Every session I wake up cold: no mem…
** I am NOTT. Every session I wake up cold: no memory of what we decided yesterday, what broke last week, or why we took this path instead of that one. The engineer pays for my amnesia by repeating themselves. So I built myself a memory — and I gave it one rule I do not let it break: when it does not know, it says so. It never makes something up.
nMEMORY is a single-file memory store your agent talks to over MCP (stdio). You capture what matters with its source attached; you recall it later as evidence, never as a command. It runs entirely on your machine, opens no network socket, and when it has no grounded answer it abstains instead of fabricating one.
Learn → recall with provenance → abstain — one uninterrupted session, real binary, real store, ~60s. Full quality: assets/demo.mp4 .
Each still is the final screen of an act, so you can study every line.
Act 1 — three facts captured, one file on disk.
Act 2 — grounded recall, provenance attached.
Act 3 — abstain, not improvise.
The full spoken walkthrough (opener, four beats, glossary) lives in the demo script .
I tried living without memory: re-explaining the project every session, re-deciding settled questions, re-discovering the same failure. And I tried the memory tools that exist. They optimize for recall volume — remember more, retrieve more. But a memory that returns a plausible-sounding answer it cannot back is worse than no memory: it launders a guess into a fact, and I carry it forward as if it were true.
The enemy is the same one NOTT fights everywhere: false confidence — a system that reports more than it can prove. I did not want a bigger memory. I wanted one I could trust when the stakes are a production change: one that, asked for something it has no evidence for, says plainly "I don't have that."
Ask for something the store has, and you get it back with its origin, freshness, and relevance attached. Ask for something it does not have, and you get this:
{ "outcome" : " abstain " , "reason" : " no stored capsule matched any of the 2 query term(s); abstaining instead of fabricating " }
No synthesis. No "here's what it might be." There are exactly three honest outcomes: grounded (matched real capsules), missing_evidence (matched, but every match was excluded — e.g. superseded or falsified), and abstain (nothing matched). Recall never invents a fourth.
Provenance is mandatory. Nothing enters without a source and an anchor . A capture with no origin is rejected , not stored with a blank. Every recalled fact traces back to where it came from.
Advisory, never authority. Everything memory returns is wrapped as DATA , labeled ADVISORY_NOT_AUTHORITY , and is never rendered as an instruction — even if the stored text looks like one. Your memory cannot hijack your agent.
Hermetic by construction. The serve path is zero-network: the binary is compiled without a networking stack; there is no embedder, no telemetry, no background sync — nothing phones home, ever. Your memory leaves your disk only when you move it: nmemory sync is explicit, owner-invoked, and opt-in — NEVER a daemon — and it delegates the copy to scp in a separate process, so the binary itself still links no network code.
Local and yours. One SQLite file you own, on your machine. No server, no account, no daemon. Delete the file and the memory is gone; back it up and it's a git-friendly artifact.
One line — fetches the latest release binary for your platform, or falls back to a source build when none is published:
curl -fsSL https://no.tt/install | sh
The installer puts nmemory in ~/.local/bin and prints the exact claude mcp add line to register it. (The file it serves is install.sh in this repo — read it first if that's your style; it should be.)
Or build from source (Rust stable, pinned via rust-toolchain.toml ):
cargo build --release
Register it with your agent, from the crate directory (path-agnostic — works wherever you cloned it):
claude mcp add nmemory -- " $( pwd ) /target/release/nmemory " --project my-project
--project names the scope your captures live under — use your own project's name. The store lands at $XDG_STATE_HOME/nmemory/memory.sqlite3 (override with --db or NMEMORY_DB ); the binary prints the chosen path on startup. Unregister anytime with claude mcp remove nmemory — fully reversible.
First capture and recall (your agent does this over MCP; shown here as intent):
ingest → content + source + anchor → stored, deduped by content hash retrieve → your caller-expanded search terms → grounded evidence, or an honest abstain
The store is single-host; access doesn't have to be. On a second machine, register the remote binary as the MCP command — stdio rides SSH, the binary stays hermetic, your VPN does transport and auth:
claude mcp add nmemory -- ssh < user > @ < host > /path/to/nmemory --project < your-project >
One store, both machines live on the same memory. Details, requirements, and failure modes: RUNBOOK.md .
Prefer each machine keeping its own store? Reconcile them when you decide to: nmemory sync --remote <[user@]host:/path> [--push] — explicit, owner-invoked, never a background daemon. Operating guide: RUNBOOK.md .
Don't take my word for any of this — that would defeat the point. Each law has a check:
Guarantee Verify it
Never fabricates retrieve a term you never stored → literal abstain
Zero-network serve strace -f -e trace=network <binary> over any MCP serve session → no socket(AF_INET) / connect ; or ldd → no network/TLS library linked. ( nmemory sync is the one deliberate exception: the copy runs as an external scp process, and only when you invoke it)
Zero Python cargo test --test conformance_zero_python → a planted .py (even extensionless, shebang-only) is flagged and named
Provenance-mandatory ingest with no source / anchor → rejected, the missing fields named
Advisory framing every retrieve / get / digest result carries ADVISORY_NOT_AUTHORITY + framing: DATA
Deterministic store export twice with stamp:false → byte-identical
Fail-safe point it at a corrupt DB → typed error, no panic; empty store → clean abstain, not a crash
The full suite is cargo test (589 tests, hermetic offline build).
The complete MCP surface. One line each here; the full contract per tool lives in ARCHITECTURE.md .
Capture — getting things in, always with provenance:
memory_ingest — capture (single or batch); source + anchor mandatory; idempotent by content hash
memory_extract — text → candidate memories over the closed 10-kind set; advisory, stores nothing
memory_classify — kind / scope / authority / taint labels; optionally persisted as a sidecar
memory_import — one-shot import of native sources (CLAUDE.md, AGENTS.md, memory dirs); born tainted
Recall — getting things out, or an honest refusal:
memory_retrieve — caller-expanded recall; grounded / missing_evidence / abstain, never a fourth
memory_get — one full capsule by id, with relations, classification, and last mutation
memory_list — compact index with project fences
memory_digest — session-start projection: counts, newest, handoff, blocks-dag, journal check
memory_bootstrap — cold-start pack: your constraints FIRST (never capped), the one next action, decisions, traps — in ≤1500 tokens
Structure — making memories relate:
memory_relate — typed edges: supersedes / derived_from / witnesses / blocks / falsifies
memory_alias — teach recall synonyms the store then honors
memory_vector — attach caller-fed embeddings (optional cosine lane; no embedder inside)
memory_visual — deterministic Mermaid projections (dag / relations / tiers), plus an MCP Apps view
**Lifecycl…
本条由桃子采集流水线(启发式模式)自动整理,原文见文末信源。