Memora

Verifiable cognitive memory for personal vaults. Cite-or-it-didn't-happen.

Memora retrieves claims, not notes - atomic facts with source-span pointers, validity windows, and privacy bands. Every LLM citation is architecturally validated against your markdown. Hallucinations are caught structurally, not by trust.

See the architecture in motion


The problem

Personal AI memory tools, from RAG over Obsidian to second-brain wrappers, share one weakness: they retrieve notes and trust the LLM to quote them faithfully. When the LLM fabricates a meeting that didn't happen, puts words in someone's mouth, or cites a claim your notes don't contain, you have no architectural defense. You either catch the hallucination yourself, or you don't.

For a personal knowledge base with decisions and meeting notes, that is the wrong trust model.

How Memora differs

The atomic unit of memory is a claim, not a note. A claim is an extracted statement of fact with:

  • subject, predicate, object
  • source note + byte-range span
  • blake3 fingerprint of the source text
  • valid_from / valid_until temporal window
  • privacy band (public / private / secret)
  • provenance edges to source claims when synthesized

When the LLM answers, it cites claim ids. The validator re-reads the source span from your markdown, recomputes the fingerprint, and rejects citations that don't match. Hallucinated ids get stripped and the LLM is re-prompted with verified-only context. The citation contract is enforced by Rust types and span hashes, not by prompt obedience.

What you get

Verified citationsEvery claim_id in an answer is re-validated against the source span before reaching you. Hallucinations stripped.
Provenance + stalenessSynthesis claims point to sources. Edit a note, downstream syntheses are auto-marked stale.
Time-aware reasoningClaims have validity windows. "What was true in March" is queryable. Contradictions auto-supersede.
Per-claim privacyInline <!--privacy:secret-->...<!--/privacy--> markers. Secrets redacted at the wire boundary on cloud LLMs, type-system enforced.
Active challengerDaily background worker surfaces stale claims, contradictions, cross-region patterns, and frontier gaps in your world_map.md.
Hybrid retrievalBM25 + embedding + RRF fusion + Hebbian co-activation learning + spreading activation via wikilinks.
Local-firstSingle Rust binary. SQLite + HNSW. Works fully offline with Ollama.
Obsidian-nativePlain markdown vault with frontmatter. Open and edit in Obsidian alongside Memora.
MCP-nativeDrop into Claude Code, Cursor, or any MCP client over stdio.

Where to go next

Status

v0.1.26. Indexes 100-note vaults in 5 to 10 minutes with Claude Haiku for about $0.30. Local Ollama is supported. Vault sizes up to a few thousand notes are the target. Larger scales are unmeasured. The active challenger surfaces decisions, contradictions, stale dependencies, and open questions in every atlas.

Issues, edge cases, and design discussions welcome at github.com/radotsvetkov/memora/issues.

Quickstart (10 Minutes)

Verifiable cognitive memory for personal vaults. Cite-or-it-didn't-happen.

Memora retrieves claims, not notes - atomic facts with source-span pointers, validity windows, and privacy bands. Every LLM citation is architecturally validated against your markdown.

This walkthrough takes a determined user from install to first verified cited answer in about 10 minutes.

1) Install Memora

curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/radotsvetkov/memora/releases/latest/download/memora-cli-installer.sh | sh
What just happened

The installer places the Memora binaries on your system path (typically including memora and memora-mcp), so you can run CLI commands and expose MCP tools to clients without manual build steps.

2) Initialize a vault

memora init --vault ~/brain
What just happened

Memora created a vault scaffold with:

  • world_map.md (generated memory overview surface)
  • a sample semantic region folder
  • .memora/config.toml for local configuration and sidecar state

Your markdown vault stays human-readable and Obsidian-compatible from the start.

3) Add your first note manually

Create ~/brain/semantic/projects/drift/roadmap.md:

---
title: drift Serialization Decision
type: semantic
date: 2025-09-12
region: projects/drift
privacy: private
tags: [drift, serialization, architecture]
---

drift switched its serialization format from JSON to MessagePack in Q3.
Benchmarking showed a 3x throughput improvement.
Decision recorded in roadmap, retro, and review notes.
What just happened

You wrote plain markdown with frontmatter. No proprietary format is required. Memora will use this as extraction input and anchor future citations to precise source spans inside this file.

4) Index the vault

memora index --vault ~/brain
What just happened

Indexing runs a full pipeline:

  1. note metadata parsed and recorded
  2. claim extraction generates atomic claim candidates
  3. each stored claim is linked to source byte range and fingerprinted
  4. lexical and vector indexes are updated
  5. contradiction checks compare new/current claims and supersede older conflicts

The result is a queryable claim graph rather than a plain chunk index.

5) Ask your first query

memora query "What did we decide about drift's serialization format?" --vault ~/brain
What just happened

Memora retrieved claims, assembled model context, generated an answer, and validated cited claim ids against source spans before returning output. In the answer footer, citation entries correspond to claim ids that survived validation.

6) Add Claude Code MCP integration

Add one server entry to your MCP config:

{"mcpServers":{"memora":{"command":"/usr/local/bin/memora-mcp","env":{"MEMORA_VAULT":"/absolute/path/to/brain"}}}}
What just happened

Claude Code can now call Memora tools over stdio MCP. Instead of passing raw note chunks manually, you get memory-tool access with claim-aware retrieval and built-in citation validation behavior.

7) Ask the same question in Claude Code

Prompt:

What did we decide about drift's serialization format?
What just happened

Claude Code routed the request through Memora MCP tools. The response surfaced with verified citations tied to your markdown-backed claims. If a citation fails validation, Memora strips/retries with verified-only context before returning.

  • Run memora watch --vault ~/brain in a dedicated terminal tab.
  • Add inline secret markers in mixed-sensitivity notes.
  • Check world_map.md after your next capture session.
  • Use memora_record_useful when a cited answer was especially helpful.

Troubleshooting basics

  • command not found: memora -> restart shell or verify installer path export.
  • No claims extracted -> confirm frontmatter + note content + successful indexing.
  • MCP tool unavailable -> verify memora-mcp path and MEMORA_VAULT value.
  • Sparse answers -> add more factual statements; reflection-only notes yield fewer claims by design.

Recommended Models

Memora makes two kinds of LLM calls. Extraction runs once per note and produces structured triples. Synthesis runs once per atlas and produces prose. Provider quality matters, especially for extraction.

This is what Memora was tuned against. Best balance of cost and quality.

[llm]
provider = "anthropic"
model = "claude-haiku-4-5-20251001"

Cost: about $0.30 to index a 100-note vault. Speed: 5 to 10 minutes with parallelism = 8.

Anthropic's free tier limits requests to 50 per minute. Add at least $5 of credit to reach Tier 1, or set parallelism = 1 to stay under the free limit.

OpenAI gpt-5-mini (alternative)

Comparable extraction quality at similar cost.

[llm]
provider = "openai"
model = "gpt-5-mini"

Local (Ollama)

Use this when local-only is a hard requirement.

[llm]
provider = "ollama"
model = "qwen2.5:32b-instruct-q5_K_M"

Honest assessment:

  • Qwen 14B is insufficient for production (hallucinates relationships, shallow triples).
  • Qwen 32B is acceptable but misses cross-region patterns.
  • Llama 70B can match Haiku quality with a large memory cost.
  • Below 32B parameters, atlas synthesis quality drops noticeably.

Embeddings run locally regardless of chat provider:

[embed]
provider = "ollama"
model = "nomic-embed-text"
dim = 768

Vault Conventions

Memora reads markdown notes from your vault and writes derived artifacts under .memora/.

Memora works with plain Obsidian-created notes that have no frontmatter. On first memora index or memora watch, it auto-fills any missing fields and prepends a YAML block while preserving your original note body byte-for-byte.

You can still provide and manage frontmatter manually. Memora applies a few quality-of-life normalizations while indexing:

  • region follows the note's folder path relative to the vault root.
  • updated follows the file mtime (second precision).
  • refs can optionally mirror detected wikilinks (configurable).
  • Invalid source / privacy enum values are normalized to defaults.
---
id: note-id
region: projects/drift
source: personal
privacy: private
created: 2026-04-01T00:00:00Z
updated: 2026-04-01T00:00:00Z
summary: "Short summary"
tags: [tag1, tag2]
refs: []
---

Example inferred frontmatter for an Obsidian note semantic/projects/drift/serialization-note.md:

---
id: serialization-note
region: projects/drift
source: personal
privacy: private
created: 2026-04-30T18:42:10Z
updated: 2026-04-30T18:42:10Z
summary: "drift switched from JSON to MessagePack after benchmarking"
tags: []
refs: []
---

Inline privacy markers

Use markers to narrow privacy to a sub-span:

This is public context.
<!--privacy:secret-->
Salary is 120k.
<!--/privacy-->

Claims extracted from secret spans are marked secret even when note privacy is broader.

Derived files

  • world_map.md
  • <region>/_atlas.md
  • <region>/_index.md
  • .memora/config.toml
  • .memora/memora.db
  • .memora/vectors/*
  • .memora/last_challenger.json
  • .memora/watch.lock (present while memora watch is running)

Derived markdown can be regenerated and should not be edited as source-of-truth notes.

Frontmatter config knobs

In .memora/config.toml:

[frontmatter]
refs_mode = "sync_from_wikilinks" # or "manual"
  • sync_from_wikilinks: keep refs aligned to [[wikilinks]] in body.
  • manual: never auto-rewrite refs.

Obsidian Properties Template

Use this template in Obsidian so source and privacy are always visible and quick to edit.

Suggested property options

  • source: personal, reference, derived
  • privacy: public, private, secret

Recommended defaults:

  • source: personal
  • privacy: private

Example note template

---
id: "{{title}}"
region: default
source: personal
privacy: private
created: 2026-01-01T00:00:00Z
updated: 2026-01-01T00:00:00Z
summary: ""
tags: []
refs: []
---

Notes

  • Memora keeps timestamps in second precision (...T12:34:56Z).
  • If frontmatter.refs_mode = "sync_from_wikilinks", refs is rewritten from body wikilinks.
  • Invalid source / privacy values are normalized to personal / private.

Obsidian + Memora Daily Driver Guide

Verifiable cognitive memory for personal vaults. Cite-or-it-didn't-happen.

Memora retrieves claims, not notes - atomic facts with source-span pointers, validity windows, and privacy bands. Every LLM citation is architecturally validated against your markdown.

This guide is for Obsidian users who want Memora as a local-first memory backend while using Claude Code as the conversational interface.

What this guide assumes

  • You already keep (or want to keep) a markdown vault.
  • You want to preserve prose as prose, not force everything into rigid fields.
  • You want model answers that are grounded in verifiable source spans.
  • You want a practical workflow you can run daily with minimal friction.

Use a structure that keeps note intent clear and lets Memora infer context.

~/brain/
  episodic/
    meeting-2025-q3-arch.md
    2025-10-design-review.md
  semantic/
    projects/
      drift/
        roadmap.md
        serialization-strategy-2025-q3.md
      drift-bench/
        benchmark-language-notes.md
    people/
      sarah.md
      james.md
      priya.md
  procedural/
    release-checklist.md
    incident-playbook.md
  world_map.md
  .memora/
    config.toml
    state.db
    logs/

Why these folders

  • episodic/ for dated observations, meetings, and journals.
  • semantic/<region>/ for durable facts and reference knowledge by domain.
  • procedural/ for repeatable processes, checklists, runbooks.

This layout is not a hard requirement. It is a practical default that helps both human navigation and memory extraction.

.memora/ sidecar and git

Keep .memora/ out of your notes repository unless you explicitly want derived state tracked. Typical .gitignore entry:

.memora/

Your markdown remains the durable, user-owned artifact; .memora/ is generated state for indexing, embeddings, and runtime metadata.

Frontmatter Spec

Memora reads frontmatter for classification, temporal cues, and privacy defaults.

  • type: episodic | semantic | procedural
  • date: ISO date (YYYY-MM-DD) for primary event/authoring context
  • region: short domain label (for semantic grouping)
  • privacy: public | private | secret

Optional fields

  • tags: array of topical labels
  • status: draft | active | archived
  • valid_from, valid_until: explicit claim window hints for extraction
  • source: external provenance hint (book, meeting, URL, etc.)
  • confidence: self-assessed confidence marker for nuanced material

Full frontmatter example

---
title: drift Serialization Decision
type: semantic
date: 2025-09-12
region: projects/drift
privacy: private
tags: [drift, serialization, architecture]
status: active
valid_from: 2025-09-12
valid_until:
source: leadership-sync
confidence: medium
---

Notes on strictness

Memora can still extract claims from imperfect notes. The frontmatter spec is a quality lever, not a binary gate. Missing optional fields reduce structure but do not block indexing.

Inline Privacy Marker Syntax

Use inline markers when only part of a note is sensitive.

This project update is broadly shareable.

<!--privacy:secret-->
The account number is 4451-XX and pending legal review details are in draft.
<!--/privacy-->

Action items remain public.

Supported marker levels:

  • public
  • private
  • secret

How inheritance works

Claim privacy is the strictest of:

  1. note frontmatter privacy
  2. inline marker privacy (if present)

So if note privacy is private and inline section is secret, extracted claims from that section become secret.

world_map.md: What It Is

world_map.md is a generated overview of your current memory topology and review signals. It is not your canonical writing surface; it is a maintenance and situation-awareness artifact.

Typical sections include:

  • active regions and note density
  • recently superseded claims
  • stale derivative hotspots
  • contradiction clusters
  • frontier gaps (thinly connected domains)
  • "Today's review" block from the challenger run

When Memora rewrites it

Memora updates world_map.md during indexing/watch cycles when:

  • enough new claims enter the graph
  • contradiction/staleness landscape changes
  • scheduled daily challenger run executes

You can edit this file manually, but treat generated sections as ephemeral.

Reading "Today's review"

The challenger writes concise operational prompts, such as:

  • "q4-rollout-plan depends on serialization-strategy-2024, now superseded."
  • "drift-bench language disagreement: rust vs go."
  • "drift backpressure strategy is still pending decision."

Read this section as a queue for targeted note maintenance, not as an alarm log.

Daily Driver Workflow

This five-step loop is optimized for consistency, not perfection.

1) Capture in Obsidian (or via memora_capture)

Write naturally in Obsidian: meeting outcomes, decisions, reflections, plans. If you are already in Claude Code and want quick capture, use memora_capture to append a session note directly to the vault.

Guideline: prefer fast capture over over-structuring. Frontmatter and markers can be refined afterward.

2) Run memora watch in a terminal tab

Keep one terminal running:

memora watch --vault ~/brain

The watch loop handles:

  • file change detection
  • indexing and extraction
  • contradiction checks and supersession updates
  • atlas/consolidation updates
  • daily challenger pass

This is the background "memory maintenance engine." You keep writing; Memora keeps the claim graph current.

3) Ask questions in Claude Code

Use Claude Code with Memora MCP configured. Ask normal questions:

  • "What did the team decide about drift's serialization format?"
  • "What changed in deployment strategy this month?"
  • "Which assumptions in product strategy were superseded?"

Memora-backed responses include claim citations that are validated before display.

4) Reinforce useful retrievals with memora_record_useful

When a cited answer is useful, mark it:

  • this feeds Q-value style reinforcement for retrieval policy
  • high-value paths become easier to prioritize in future ranking

You are effectively training the memory prioritization loop with low-friction feedback from real usage.

5) Review world_map.md regularly

Open the "Today's review" section every day or two. Act on one or two items:

  • resolve contradictions where intent changed
  • refresh stale syntheses after major note edits
  • fill frontier gaps by capturing missing context

Small, regular interventions are better than monthly cleanup marathons.

Claims vs Prose: What Goes Where

This distinction matters because Memora extracts claims from prose, but not every sentence should be forced into atomic-fact style.

Put in claims (naturally, through prose that contains facts)

  • explicit decisions ("We chose X over Y.")
  • commitments ("Deadline moved to May 10.")
  • stable descriptors ("Service A depends on Service B.")
  • measurable observations ("Error rate rose after deployment.")

Leave as prose

  • reflections and uncertainty exploration
  • narrative context and emotional processing
  • rough ideation where assertions are intentionally fluid
  • personal meaning-making that is not a stable factual statement

Both are valuable. Reflection-heavy notes may yield fewer extracted claims, and that is expected. The goal is not maximal claim density; the goal is faithful memory with usable evidence.

Practical writing pattern

A useful balance:

  1. write free-form reflection first
  2. include a short "Decisions / Facts" section when relevant
  3. keep sensitive lines wrapped with inline markers when needed

This gives Memora clear extraction anchors while preserving narrative richness.

Privacy Practice: Frontmatter vs Inline Markers

Use the privacy tools intentionally by granularity.

Use frontmatter privacy: secret when

  • the whole note is sensitive
  • sharing any part externally is inappropriate
  • the note is primarily credentials, legal details, or private health data

Use inline markers when

  • most of the note is shareable but a few passages are sensitive
  • you want one note to hold both operational and confidential details
  • you need surgical redaction without splitting files unnaturally

Operational rule of thumb

  • whole-note sensitivity -> frontmatter
  • partial sensitivity -> inline markers

This keeps notes readable while preserving strict outbound redaction behavior.

Querying Expectations in Practice

When you ask a question, expect three outcomes:

  1. Verified answer with citations (normal path)
  2. Answer with fewer citations because some were invalidated and stripped
  3. Retry-constrained answer generated from verified-only context

If a claim citation cannot be validated against source span fingerprint, it does not pass through as-is. This is central to Memora's trust model.

Maintenance Habits That Keep Quality High

  • Keep frontmatter consistent in newly created notes.
  • Prefer one fact per sentence for high-signal decisions and commitments.
  • Re-index after major refactors or bulk note moves.
  • Resolve challenger-highlighted contradiction clusters early.
  • Keep vault paths stable when possible; large path churn can increase stale maintenance overhead.

Common Pitfalls

  • Over-optimizing templates too early: start with a minimal frontmatter set.
  • Ignoring stale flags: stale does not mean wrong, but it does mean review.
  • Using secret everywhere: overuse reduces model utility; mark surgically.
  • Treating world_map.md as canonical prose: it is generated maintenance output, not your long-form notebook.

Minimal Setup Checklist

  • Vault created and initialized with Memora
  • .memora/ gitignored
  • Frontmatter defaults chosen
  • memora watch running in one terminal tab
  • MCP integration configured for Claude Code
  • First verified cited query completed
  • First world_map.md review done

Closing

Obsidian remains your writing environment. Memora adds a verifiable memory layer that tracks claim provenance, temporal validity, privacy boundaries, and citation integrity. Used daily, the combination gives you both narrative freedom and evidence-backed recall: write naturally, query confidently, and review memory health through world_map.md.

Memora Architecture Deep Dive

Verifiable cognitive memory for personal vaults. Cite-or-it-didn't-happen.

Memora retrieves claims, not notes - atomic facts with source-span pointers, validity windows, and privacy bands. Every LLM citation is architecturally validated against your markdown.

This document describes the concrete system design in four layers:

  1. Note Graph (vault and markdown substrate)
  2. Claim Graph (typed factual representation)
  3. Retrieval and Validation (query-time execution)
  4. Agent Interfaces (MCP tools and client integration)

The goal is not to maximize retrieval throughput at all costs. The goal is to make unsupported claims difficult to surface and easy to detect.

Layered System Diagram

+--------------------------------------------------------------------------+
| Layer 4: Agent Interfaces (MCP over stdio)                               |
|  memora_query_cited | memora_capture | memora_stale_claims | challenger  |
+--------------------------------------------------------------------------+
                                  |
                                  v
+--------------------------------------------------------------------------+
| Layer 3: Retrieval + Validation                                          |
|  Hybrid retrieval (BM25 + vector + RRF)                                  |
|  Spreading activation over links/edges                                   |
|  Privacy filter + typed prompt builder                                   |
|  Citation validator (span re-read + fingerprint recompute + retry)       |
+--------------------------------------------------------------------------+
                                  |
                                  v
+--------------------------------------------------------------------------+
| Layer 2: Claim Graph (SQLite + edge model)                               |
|  claim(subject,predicate,object,span,fingerprint,time,privacy,status)    |
|  edges: entails | contradicts | supersedes | derives | co_occurs         |
|  provenance DAG + stale propagation                                      |
+--------------------------------------------------------------------------+
                                  |
                                  v
+--------------------------------------------------------------------------+
| Layer 1: Note Graph (Obsidian vault + watcher)                           |
|  markdown notes + frontmatter + inline privacy markers                   |
|  file events -> parse -> extraction jobs                                 |
+--------------------------------------------------------------------------+

Design Principles

Memora uses a narrow set of invariants:

  • Claims are addressable units. All downstream reasoning references claim ids, not free text snippets.
  • Source spans are mandatory. Every extracted claim stores a byte range into a specific markdown file.
  • Fingerprints are mandatory. A blake3 hash over the exact source span is captured at extraction and checked at validation time.
  • Validity is explicit. Claims can become historical (valid_until) without disappearing from history.
  • Privacy is monotonic. A claim can only move toward stricter visibility when inherited or overridden.

These rules are enforced in the data model and request pipeline, not only by prompts or post-hoc heuristics.

Layer 1: Note Graph

The Note Graph is the user-owned vault. Memora does not replace it and does not rewrite user prose as a primary persistence strategy. Notes remain markdown files editable in Obsidian or any text editor.

1.1 Vault as source of truth

Memora treats the vault as canonical for natural language content. Derived state is stored in .memora/ and the local database; the authoritative prose remains in markdown.

Input channels into this layer:

  • manual note edits in Obsidian
  • captured notes from MCP tools (for example memora_capture)
  • file-level moves, renames, and deletions

1.2 Structural parsing

Each note is parsed for:

  • frontmatter fields (type, date, region, privacy, tags, status, etc.)
  • body sections
  • inline privacy markers: <!--privacy:secret--> ... <!--/privacy-->

The parser outputs typed segments with byte offsets. These byte offsets are the backbone for source-span references in claims.

1.3 Incremental change detection

A watcher detects modified files and schedules extraction jobs. The queue keeps work bounded and avoids full re-indexing for every keystroke. Hash-based change detection ensures unchanged notes are skipped.

1.4 Why this layer matters

Most memory systems jump directly from note chunks to retrieval. Memora adds a formal extraction boundary so claims can carry strict provenance. This boundary is what makes downstream citation checks deterministic.

Layer 2: Claim Graph

The Claim Graph is the core memory model. A claim has typed fields and graph relations to other claims.

2.1 Claim schema

Core fields:

  • subject, predicate, object
  • source_note
  • source_span_start, source_span_end (byte offsets)
  • span_fingerprint (blake3)
  • valid_from, valid_until
  • privacy_band (public, private, secret)
  • lifecycle flags (current, superseded, stale, etc.)

This schema separates statement identity from rendering text. The same concept can be tracked across time with explicit supersession edges rather than silent overwrite.

2.2 Edge model

Memora stores directional, typed edges:

  • entails
  • contradicts
  • supersedes
  • derives
  • co_occurs

Edges support both retrieval-time context expansion and maintenance-time staleness propagation.

2.3 Storage strategy

Primary persistence is SQLite:

  • relational tables for claims and edges
  • FTS5 index for lexical retrieval
  • JSON1-compatible metadata fields for structured payloads

Embeddings are stored for semantic retrieval and indexed with HNSW. This allows hybrid retrieval while keeping the memory model local-first.

2.4 Provenance and stale propagation

Synthesis claims store provenance links to source claims (derives). If any source becomes invalid or superseded, dependent syntheses are marked stale.

This stale bit is not an error state. It is a review signal: the synthesis might still be useful, but it should be revalidated against current inputs.

Layer 3: Retrieval and Validation

This layer is where query-time guarantees are enforced.

3.1 Retrieval cascade

Retrieval is not a single query operation. It is a staged cascade:

  1. lexical retrieval from FTS5 (BM25-style scoring)
  2. vector retrieval from HNSW embeddings
  3. reciprocal-rank fusion (RRF)
  4. graph expansion via co-activation and spreading activation
  5. privacy filtering
  6. prompt context assembly

The output is a ranked claim set, not note paragraphs.

3.2 Citation validator

The validator checks every claim id cited by the model:

  1. fetch claim row by id
  2. open source markdown note
  3. read exact byte span
  4. recompute blake3 fingerprint
  5. compare to stored fingerprint

If any citation fails (missing id, span mismatch, fingerprint mismatch), that citation is rejected. Depending on tool mode, rejected citations are stripped and the model is retried using verified-only context.

3.3 Retry semantics

Retry is scoped and deterministic:

  • first pass: full retrieved context
  • validation pass: verify cited ids and spans
  • fallback pass: re-prompt with only validated claim context

This avoids silently passing unverifiable citations through to the user.

3.4 Temporal and contradiction awareness

Retrieval defaults to currently valid claims. Historical queries can include time filters to reconstruct prior states without flattening history.

Contradictions are represented explicitly and alter validity windows rather than deleting data. That keeps historical trails auditable.

Layer 4: Agent Interfaces

Memora exposes capabilities through MCP over stdio. Clients query tools instead of linking to private internals.

4.1 Tool surface

Representative interfaces include:

  • cited query tool for validated responses
  • capture tools for episodic logging
  • contradiction and stale-claim inspection tools
  • challenger outputs for periodic review

Tool responses are shaped around claim ids and provenance so clients can show evidence, not just summaries.

4.2 Why MCP boundary matters

The interface layer keeps guarantees portable across clients. A user can switch between environments without changing citation behavior because validation lives inside Memora, not in client-specific prompt templates.

4.3 Failure mode handling

If external model output includes invalid citations, Memora handles that inside the pipeline. The client receives either verified results or explicit failure signals, not a hidden downgrade.

Claim Lifecycle Walk-through

This is a concrete path for one statement from note to cited answer.

  1. User writes text in semantic/projects/drift/roadmap.md: "drift switched serialization from JSON to MessagePack after throughput benchmarks."
  2. Watcher detects file change and schedules extraction.
  3. Extractor emits claim candidate: drift | uses_serialization | messagepack.
  4. Source span recorded as byte offsets into the markdown file.
  5. Fingerprint computed over that exact span and stored in claim row.
  6. Claim indexed in FTS and embedding index; edges updated as needed.
  7. User asks query through an MCP client.
  8. Retrieval returns ranked claim set including this claim id.
  9. Model drafts answer and cites [claim:abc123].
  10. Validator re-opens source note, slices stored byte range, recomputes blake3, and confirms it matches stored fingerprint.
  11. Citation marked verified and answer is returned.
  12. User sees output with verified citations that map back to source text.

If step 10 fails, citation is removed and the retry path runs on verified-only claims.

Contradiction Handling Walk-through

Contradictions are a first-class maintenance event.

  1. A new claim arrives: drift-bench | uses_language | go.
  2. System fetches candidate claims with matching subject/predicate and current validity windows.
  3. Contradiction judge evaluates pairs (new, candidate) for conflict, such as go vs rust.
  4. If conflict is confirmed:
    • older claim receives valid_until = new.valid_from (or event timestamp)
    • supersedes edge is written (new -> old)
    • contradicts edge is written for explainability
  5. Derivative claims linked to the older claim are marked stale.
  6. Challenger later surfaces stale derivatives for review/regeneration.

Two properties are intentional:

  • old data is retained for historical reasoning
  • current reasoning can exclude superseded claims by default

Privacy Redaction Walk-through

Privacy is applied during extraction and enforced before prompt construction.

  1. Parser reads note-level frontmatter privacy.
  2. Parser reads inline privacy markers in body spans.
  3. Each extracted claim receives privacy = max(note_level, inline_level).
  4. Query pipeline applies privacy filter before prompt assembly.
  5. Prompt builder accepts typed claim wrappers that distinguish:
    • local-safe claims
    • redacted claims for cloud transport
  6. For cloud model calls, secret claims are transformed:
    • subject preserved
    • predicate, object replaced with [redacted]
  7. Non-redacted secret claims are rejected by type constraints and cannot enter outbound model payload construction.

This architecture turns privacy from a policy suggestion into a compile-time and runtime boundary.

Five Differentiators

1) Architectural citation enforcement

Most systems ask the model to cite correctly and then trust it. Memora stores source spans and fingerprints at extraction time, then verifies cited ids by re-reading markdown at response time. This allows deterministic rejection of invalid citations and a retry path constrained to verified context.

2) Claim-first memory model

The memory primitive is an atomic claim, not a note chunk. Claims carry temporal state, privacy, provenance, and edges. That enables operations like supersession, stale propagation, and relation-aware retrieval that are difficult to represent when the only unit is free text.

3) Time-aware contradiction handling

Contradictions are modeled as graph relations with validity window updates. New claims can supersede old ones without deleting history. Queries can target either the current world state or historical states, and stale derivatives can be identified explicitly.

4) Per-claim privacy with typed redaction

Privacy is resolved at claim level using note metadata plus inline marker overrides. Secret claims can still contribute structurally while restricting outbound content. Cloud-bound payloads enforce redaction before model transport, which is stronger than relying on operators to remember manual filtering.

5) Active challenger loop

Memora runs a periodic challenger that inspects stale dependencies, contradictions, and sparsely connected frontier areas. This is not just retrieval: it is maintenance of memory integrity over time. The result is a continuously reviewable world map instead of a static index.

What We Do Not Do

  • Not a faster RAG benchmark story: Memora's primary claim is architectural verifiability. Benchmark speed/latency comparisons against other systems are not published here.
  • Not a multimodal memory store yet: current substrate is markdown-first with structured metadata; rich multimodal ingestion is future work.
  • Not federated multi-vault reasoning yet: primary target is one personal vault and its sidecar state.
  • Not a research-agent framework: Memora is a memory engine and interface layer, not an autonomous planner for open-ended web research.

Operational Notes

  • Local-first operation works offline with local model backends.
  • Derived state is reproducible from vault content plus config.
  • Citation verification depends on byte-accurate spans; manual file rewrites are expected and handled through re-indexing.
  • Claims may be skipped when extraction confidence or structure is insufficient; absence of a claim does not imply absence of prose.

Closing

Memora is engineered around a strict contract: if an answer cites your notes, the citation must survive structural checks against the source text. The system is intentionally conservative where trust boundaries are involved, and that conservatism is what enables personal-memory workflows where incorrect citations are treated as system errors, not normal behavior.

Citation Protocol

Memora treats citations as verifiable references to claim IDs.

Claim marker format

LLM responses use [claim:<id>].

Example:

drift switched to MessagePack for serialization [claim:drf75a1c9e10b2aa]

Verification steps

  1. Parse claim markers from LLM output.
  2. Resolve each claim ID from SQLite.
  3. Resolve note path and byte span.
  4. Re-read source span from markdown body.
  5. Recompute BLAKE3 fingerprint.
  6. Optionally verify quote overlap.

Status values

  • verified
  • unverified (claim missing)
  • fingerprint_mismatch (source changed)
  • quote_mismatch (marker quote unsupported)

Verified answer semantics

clean_text is rewritten to keep only statements supported by verified claim markers.

This means "verified" in Memora is an architectural property (data + hash + span), not a prompt instruction.

For example, a verified claim can point to semantic/projects/drift/roadmap.md with a span that captures the MessagePack decision text.

Architectural Comparison

Verifiable cognitive memory for personal vaults. Cite-or-it-didn't-happen.

Memora retrieves claims, not notes - atomic facts with source-span pointers, validity windows, and privacy bands. Every LLM citation is architecturally validated against your markdown.

This document compares memory architectures, not benchmark performance.

Scope and framing

The systems below are useful in different contexts, and several have influenced how practitioners think about personal knowledge tooling. The comparison here focuses on one narrow question:

How does each system model memory when an LLM answer needs to be grounded in a user's personal notes?

For each system, we look at:

  • primary unit of retrieval
  • citation mechanism
  • temporal state handling
  • privacy boundaries
  • synthesis staleness handling
  • where Memora diverges

1) Traditional RAG over Obsidian

One-sentence description: Index markdown notes into chunks, retrieve top-k chunks with keyword/vector search, and pass those chunks to the model as context.

Architectural primitive

The core primitive is a chunk of note text (often overlapping windows). Metadata may include file path, heading, tags, or timestamps, but chunk text is still the object supplied directly to the model.

Citations

Usually prompt-level citation guidance. The prompt asks the model to cite notes or quote excerpts, but the pipeline often does not perform a strict post-generation verification of every cited identifier against immutable spans.

Temporal reasoning

Typically weak. Some setups use file modified time as a recency signal, which is helpful for ranking but not equivalent to claim-level validity windows. Temporal queries often degrade into "newer chunks rank higher."

Privacy handling

Commonly note-level or folder-level segregation (for example separate sensitive folders excluded from indexing). Fine-grained within-note redaction is possible, but usually depends on conventions, not typed enforcement.

Synthesis staleness

Rarely modeled explicitly. If a synthesis answer from last week depends on notes that changed today, the system does not track that dependency graph by default.

Where Memora diverges

Memora extracts atomic claims with source byte spans and fingerprints. The model cites claim ids; citations are verified against markdown spans before output is accepted. Contradictions and supersession update claim validity windows, and derived claims can be marked stale when their dependencies change.

2) LLM Wiki (Karpathy pattern)

One-sentence description: Curated wiki-style notes are maintained and queried through model prompts, with emphasis on human-maintained pages and summaries.

Architectural primitive

The primitive is generally the wiki page / full note rather than atomic factual units. Retrieval can be simple grep-like search, embedding search, or manual page curation.

Citations

Again mostly prompt-level trust. The model is asked to reference sections or pages, but strict claim-id-to-span validation is typically outside scope.

Temporal reasoning

Usually manual. Edits update the page narrative, but there is no built-in claim-level time window model unless custom logic is added.

Privacy handling

Mostly repository-level or file-level policies. Fine-grained secret redaction can be done procedurally, but not usually via a typed claim transport boundary.

Synthesis staleness

Not tracked as a first-class graph concern in the base pattern. If summaries depend on old sections, freshness is largely a human maintenance task.

Where Memora diverges

Memora keeps note prose but converts factual content into explicit claim records with provenance edges. Staleness becomes computable (derives edges + stale marks) and contradiction handling updates validity windows instead of relying on manual page rewrites.

3) Ori-Mnemos

One-sentence description: A memory-oriented framework focused on organizing and recalling information from accumulated user interactions.

Architectural primitive

Typically event/memory entries or chunk-like artifacts depending on deployment. The unit is still generally larger and less strictly typed than subject-predicate- object claims with immutable source spans.

Citations

In most practical setups, citations are either absent or generated via prompt conventions. There is limited evidence of mandatory span-hash validation against source markdown at answer time.

Temporal reasoning

Temporal metadata may exist at entry level, but claim-level supersession and contradiction windows are not generally the default mechanism.

Privacy handling

Commonly policy/config driven at source or collection level. Per-claim typed redaction at model boundary is not the typical baseline.

Synthesis staleness

Dependency-tracked stale propagation is not usually central. Refresh behavior is often periodic re-summarization rather than DAG-aware invalidation.

Where Memora diverges

Memora's core divergence is strict verifiability: every claim maps to a source span with fingerprint, and cited ids are validated structurally. Temporal changes are represented as supersession edges and validity updates, not only recency.

4) MDEMG

One-sentence description: A memory graph style approach that structures knowledge for retrieval and agent use across sessions.

Architectural primitive

Graph nodes often represent memories/documents/entities, with varying granularity and schema. The primitive can be richer than flat chunks, but is not necessarily anchored to byte-accurate spans in user markdown.

Citations

Often graph-aware retrieval with model-mediated explanation. Citation guarantees are typically semantic/prompt level, not strict span-hash contracts.

Temporal reasoning

Some graph memory systems include timestamps or recency weighting, but explicit valid_from/valid_until per atomic claim with contradiction-based supersession is uncommon as a default.

Privacy handling

Depends on deployment policy and node metadata. Fine-grained transport redaction for secret fragments is usually custom rather than enforced by a dedicated typed pipeline.

Synthesis staleness

Graph updates may occur, but "this derived claim is stale because one ancestor was superseded" is not universally enforced without additional logic.

Where Memora diverges

Memora combines graph edges with strict source anchoring and citation validation. It treats provenance and stale propagation as standard maintenance behavior, not optional add-ons.

5) Vanilla Obsidian + Claude Code (no memory layer)

One-sentence description: Use Obsidian as note storage and ask questions in Claude Code directly, without a dedicated extraction/claim memory engine.

Architectural primitive

The primitive is whatever context is manually selected or searched at runtime: files, snippets, or ad hoc passages. There is no persistent claim graph.

Citations

Citations depend on what the model is prompted to provide and what context was manually supplied. Verification is user-driven rather than architecturally enforced.

Temporal reasoning

Handled manually by inspecting timestamps, file history, or narrative context. No built-in claim-level temporal windows or supersession semantics.

Privacy handling

Relies on user judgment and workspace boundaries. There is no dedicated claim privacy lattice with mandatory redaction at model transport boundaries.

Synthesis staleness

Not tracked by default. If prior synthesis depended on now-edited notes, there is no automatic stale marker.

Where Memora diverges

Memora adds a dedicated memory backend between vault and model: claim extraction, provenance, contradiction handling, stale propagation, and citation verification. The user still owns markdown, but verification does not depend on manual checking for every answer.

Summary Matrix

DimensionRAG over ObsidianLLM WikiOri-MnemosMDEMGObsidian + Claude CodeMemora
Atomic unitchunkspages/notesmemory entriesgraph nodes/memoriesad hoc snippetsatomic claims
Citation modelprompt-levelprompt-levelprompt-level/variessemantic/prompt-levelmanual/prompt-levelarchitectural validation
Temporal modelrecency-biasedmanual editsentry timestampsrecency/metadatamanualvalidity windows + supersession
Privacy modelfolder/note policyfile policypolicy/configmetadata/policymanualper-claim + typed redaction
Staleness trackingusually noneusually nonelimitedlimited/customnoneprovenance DAG + stale flags

Final note on benchmarking

This is an architectural comparison, not a performance comparison. Memora has not been run in published head-to-head benchmarks against these systems. The distinctions here are about memory modeling, citation guarantees, temporal representation, and privacy boundaries, not claims about retrieval speed or quality rankings.

MCP Tools

All tools return JSON payloads.

memora_query

Input:

{"query":"What did the team decide about drift's serialization format?","k":5}

Output:

{"hits":[{"id":"note-1","summary":"drift moved to MessagePack in Q3","region":"projects/drift","score":0.12,"snippet":"..."}],"regions_used":["projects/drift"]}

memora_query_cited

Input:

{"query":"What did the team decide about drift's serialization format?","k":5}

Output:

{"clean_text":"drift switched from JSON to MessagePack [claim:drf75a1c9e10b2aa]","verified_count":1,"checks":[{"claim_id":"drf75a1c9e10b2aa","status":"verified"}]}

memora_get_note

Input: {"id":"note-1"}

Output keys: id, region, summary, body, tags, refs, wikilinks, hebbian_neighbors

memora_get_atlas

Input: {"region":"projects/drift"}

Output keys: region, atlas_markdown, note_count

memora_get_world_map

Input: {}

Output: {"markdown":"# World Map ..."}

memora_neighbors

Input: {"id":"note-1","top_n":5}

Output keys: hebbian, wikilinks

memora_record_useful

Input: {"query_id":"...","useful_ids":["note-a","note-b"]}

Output: {"ok":true}

memora_capture

Input:

{"region":"inbox","summary":"Quick capture","body":"...", "tags":["inbox"], "privacy":"private"}

Output: {"id":"note-...","path":"inbox/note-....md"}

memora_consolidate

Input: {"scope":"all"} or {"scope":"region:work/projects"}

Output keys: regions_rebuilt, notes_moved

memora_verify_claim

Input: {"claim_id":"abcd1234"}

Output keys: exists, span_intact, current_text

memora_stale_claims

Input: {}

Output: array of stale claim rows.

memora_contradictions

Input: {"subject":"drift-bench"} (optional)

Output: array of contradiction rows.

memora_challenge

Input: {}

Output: ChallengerReport JSON.

memora_decisions

Input: {}

Output: [{id,title,decided_on,status}]

License

Apache 2.0 only. See LICENSE.

Why Apache 2.0

Personal memory infrastructure should be portable, forkable, and embeddable without surprise. Apache 2.0 was chosen specifically because:

  • It's permissive without being a free-for-all. Companies and individuals can build on Memora - wrappers, internal forks, MCP integrations, distribution bundles - without infecting their own license. That matters for adoption inside organizations where copyleft would be a non-starter.

  • It includes an explicit patent grant. Contributors who hold patents cannot retroactively assert them against downstream users of the code they contributed to. For a tool whose differentiators (claim graph, span fingerprint, citation validator) sit close to active patent thickets in the LLM tooling space, the explicit grant is non-negotiable.

  • It survives M&A. A future Memora acquirer cannot revoke the license on existing releases. Once Apache 2.0 is published, it stays Apache 2.0 for that version, forever.

  • It's compatible with the rest of the Rust ecosystem. Most Cargo crates are MIT or Apache 2.0 dual-licensed; choosing Apache 2.0 lets us depend on them without friction and lets others depend on us symmetrically.

What Apache 2.0 means in practice

You can:

  • Use Memora commercially.
  • Modify Memora and distribute the modifications (under Apache 2.0).
  • Patent your own improvements while keeping Memora's grant intact.
  • Bundle Memora into a closed-source product, as long as you preserve the notice file and don't claim Memora endorsement.
  • Run Memora on private vaults, internal infrastructure, or air-gapped systems without contacting anyone.

You must:

  • Include a copy of the Apache 2.0 license with any redistribution.
  • Preserve copyright, patent, trademark, and attribution notices.
  • State significant changes if you redistribute modified versions.
  • Not use the Memora name or logo to imply endorsement of a fork without permission.

SPDX identifier

SPDX-License-Identifier: Apache-2.0

Full text

See LICENSE in the repository root for the canonical Apache 2.0 text.