memoria
Memory frameworkOfficial Matrix Origin project
Created by Matrix Origin
Published in matrixorigin/memoria. Publisher page
626 GitHub stars
What it is
Secure memory management for AI Agents • Ensures data integrity • Reduces hallucinations • Maintains consistent long-term context
AutoGineer overview, from the brain’s own files
Memoria is a persistent memory layer designed to give AI agents reliable, auditable, and version-controlled long-term memory. By leveraging a Git-inspired architecture powered by MatrixOne, it allows agents to snapshot, branch, merge, and rollback their memory state. This ensures that memory changes are tracked and reversible, reducing hallucinations and maintaining consistency across sessions. It supports semantic search through hybrid retrieval and includes self-governing features to detect contradictions and maintain audit trails, making it a robust solution for managing agent knowledge.
How it works
Memory model: Hybrid
AutoGineer overview, from the brain’s own files
Memoria functions as a memory service that agents interact with via MCP tools. It uses a hybrid memory model where facts, preferences, and decisions are stored and retrieved. The system supports branching for isolated experimentation, allowing agents to test new information or hypotheses without altering the main memory state. It includes specific steering rules for managing the lifecycle of memories, from initial retrieval at the start of a conversation to purging transient working memories upon task completion. Data is stored using a database-native engine that supports zero-copy branching and snapshots.
| Folder | Role | Files |
|---|---|---|
| .claude | agent-config | 1 |
| .cursor | agent-config | 2 |
| .gemini | agent-config | 1 |
| .github | agent-config | 16 |
| .kiro | agent-config | 7 |
| assets | attachments | 7 |
| docs | docs | 10 |
| scripts | scripts | 2 |
| skills | agent-instructions | 7 |
| benchmarks | folder | 7 |
| config | folder | 7 |
| grafana | folder | 1 |
| memoria | folder | 280 |
| plugins | folder | 69 |
| sdk | folder | 36 |
Requirements
Apps: Docker
Databases: PostgreSQL, SQLite
API keys (by name): MEMORIA_API_KEY, MEMORIA_EMBEDDING_API_KEY, MEMORIA_LLM_API_KEY
Works with: Claude Code, Cursor, Gemini CLI, Kiro
Set it up
This brain runs code automatically: 5 scripts. Review README.md, scripts/install.ps1, scripts/install.sh before opening the folder in Claude Code. No step below turns a hook on for you.
README.md:curl -sSL https://raw.githubusercontent.com/matrixorigin/Memoria/main/scripts/install.sh | bashREADME.md:curl -sSL https://raw.githubusercontent.com/matrixorigin/Memoria/main/scripts/install.sh | bashREADME.md:command -v memoria >/dev/null || curl -sSL https://raw.githubusercontent.com/matrixorigin/Memoria/main/scripts/install.sh | bash -s -- -y -d ~/.local/binscripts/install.ps1:pwsh scripts/install.ps1scripts/install.sh:sh scripts/install.sh
- Not scanned by AutoGineerThe author’s README also describes installing it with Docker Compose. Read its install section: AutoGineer did not scan that path. https://github.com/matrixorigin/memoria/blob/93ccccf2ea8da4c205ac2d93c1a010c287bc742d/README.md#-quick-start
- Not scanned by AutoGineerThe author’s README also describes installing it from a clone of its repository. Read its install section: AutoGineer did not scan that path. https://github.com/matrixorigin/memoria/blob/93ccccf2ea8da4c205ac2d93c1a010c287bc742d/README.md#-quick-start
Created by Matrix Origin. Published in matrixorigin/memoria. Licence: Apache License 2.0.
Usage
AutoGineer overview, from the brain’s own files
- Persistent memory across agent sessions
- Git-like version control for agent knowledge
- Isolated experimentation via memory branching
- Semantic and full-text hybrid retrieval
- Automated contradiction detection and memory governance
- “Let's try switching from PostgreSQL to SQLite.”
- The agent creates a new memory branch 'eval_sqlite', performs experiments, and allows the user to diff and merge the results back to main.
- “I want to add OAuth support to the API.”
- The agent searches for existing goals, stores the new goal, and tracks progress as working memories across sessions.
- “What are my deployment preferences?”
- The agent retrieves relevant semantic memories to provide context-aware information based on previous sessions.
Documentation by Matrix Origin
<div align="center"> <img src="assets/memoria-logo.png" alt="Memoria Logo" width="300"/>
Memoria
The World's First Git for AI Agent Memory
Snapshot · Branch · Merge · Rollback — for memory, not code.
Git made code safe to change. Memoria makes memory safe to change.
Image: CI Image: Release Image: GitHub Stars Image: Downloads Image: License Image: MCP Image: MatrixOne Image: Paper
Quick Start · Memoria in Astra · Why Memoria · Research · See It in Action · API Reference · Architecture · Development · Citation
</div>
Overview
Memoria is a persistent memory layer for AI agents with Git-level version control. Every memory change is tracked, auditable, and reversible — snapshots, branches, merges, and time-travel rollback, all powered by MatrixOne's native Copy-on-Write engine.
A core memory component of MatrixOrigin's Astra.
Astra runs the agent. Memoria helps it remember across sessions. MatrixOne powers the data storage and search.
Using Astra? · Use Memoria with another agent
<table> <tr> <td align="center" width="33%">
🔀 Git for Memory
Zero-copy branching, instant snapshots, point-in-time rollback — version control for every memory mutation
</td> <td align="center" width="33%">
🔍 Semantic Search
Vector + full-text hybrid retrieval finds memories by meaning, not just keywords
</td> <td align="center" width="33%">
🛡️ Self-Governing
Auto-detects contradictions, quarantines low-confidence memories, maintains audit trails
</td> </tr> </table>
<table> <tr> <td align="center" width="33%">
🔒 Private by Default
Local embedding model option — no data leaves your machine
</td> <td align="center" width="33%">
🧠 Cross-Conversation
Preferences, facts, and decisions persist across sessions
</td> <td align="center" width="33%">
📋 Full Audit Trail
Every memory mutation has a snapshot + provenance chain
</td> </tr> </table>
Supported Agents
<p align="center"> <a href="https://kiro.dev"><img src="https://img.shields.io/badge/Kiro-00C853?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHRleHQgeD0iNCIgeT0iMTgiIGZvbnQtc2l6ZT0iMTYiIGZpbGw9IndoaXRlIj5LPC90ZXh0Pjwvc3ZnPg==&logoColor=white" alt="Kiro"/></a> <a href="https://cursor.sh"><img src="https://img.shields.io/badge/Cursor-000000?style=for-the-badge&logo=cursor&logoColor=white" alt="Cursor"/></a> <a href="https://docs.anthropic.com/en/docs/claude-code"><img src="https://img.shields.io/badge/Claude_Code-D97757?style=for-the-badge&logo=anthropic&logoColor=white" alt="Claude Code"/></a> <a href="https://openai.com/index/introducing-codex/"><img src="https://img.shields.io/badge/Codex-412991?style=for-the-badge&logo=openai&logoColor=white" alt="Codex"/></a> <a href="https://geminicli.com"><img src="https://img.shields.io/badge/Gemini_CLI-4285F4?style=for-the-badge&logo=google&logoColor=white" alt="Gemini CLI"/></a> <a href="plugins/openclaw/README.md"><img src="https://img.shields.io/badge/OpenClaw-FF6B6B?style=for-the-badge" alt="OpenClaw"/></a> <a href="plugins/hermes/README.md"><img src="https://img.shields.io/badge/Hermes-8B5CF6?style=for-the-badge" alt="Hermes"/></a> </p>
<p align="center"><i>Works with any MCP-compatible agent</i></p>
🧠 Memoria in Hermes
Memoria is available from the Hermes plugin catalog. Log in at Memoria and create/copy a memory-service API key, then run:
hermes plugins install memoria --yes-deps --enable
hermes memory setup
hermes memory statusIn the interactive setup, select memoria, paste your API key at the masked
prompt, and choose whether to enable automatic capture (off by default). Confirm
that status reports memoria, installed and available, then exit any existing
conversation and start a new one with hermes. Status checks local readiness;
verify a live write using the complete Hermes guide.
The free Memoria Cloud requires no local Memoria server or database. Self-hosting,
fixed GitHub installation and named profiles are covered in the same guide.
🧩 Memoria in Astra
In Astra, Memoria stores and retrieves facts, preferences, decisions, and session summaries so agents can reuse knowledge across conversations. Memory changes can be reviewed and rolled back.
| How you use it | Where to start |
|---|---|
| Hosted Astra | Memoria is already running for you. Follow the Astra quick start. |
| Self-hosted Astra | Astra's deployment includes compatible Memoria and MatrixOne services. Follow Astra's Docker setup. |
| Memoria with other agents | Use Memoria independently via MCP. Follow the Memoria quick start below. |
For example, search your memories from Astra:
astra memory search "deployment preferences"🚀 Quick Start
<details open> <summary><b>☁️ Memoria Cloud (Recommended — no Docker, no database)</b></summary> <br/>
1. Sign up at thememoria.ai and get your token
2. Install & configure
curl -sSL https://raw.githubusercontent.com/matrixorigin/Memoria/main/scripts/install.sh | bash
cd your-project
memoria init -i # Select "Remote" mode, paste your token3. Restart & verify — restart your AI tool, then ask: "Do you have memory tools available?"
</details>
<details> <summary><b>🐳 Self-Hosted (Docker — full data control)</b></summary> <br/>
# 1. Start MatrixOne + API
git clone https://github.com/matrixorigin/Memoria.git
cd Memoria
docker compose up -d
# 2. Install CLI
curl -sSL https://raw.githubusercontent.com/matrixorigin/Memoria/main/scripts/install.sh | bash
# 3. Configure your AI tool
cd your-project
memoria init -i # Select "Embedded" modeRestart your AI tool, then ask: "Do you have memory tools available?"
</details>
<details> <summary><b>🦞 OpenClaw Plugin</b></summary> <br/>
Use the native OpenClaw plugin: OpenClaw Plugin Setup
# ensure memoria CLI exists
command -v memoria >/dev/null || curl -sSL https://raw.githubusercontent.com/matrixorigin/Memoria/main/scripts/install.sh | bash -s -- -y -d ~/.local/bin
# install & enable
openclaw plugins install @matrixorigin/memory-memoria
openclaw plugins enable memory-memoria
# cloud-first setup
openclaw memoria setup --mode cloud --api-url <MEMORIA_API_URL> --api-key <MEMORIA_API_KEY> --install-memoria
openclaw memoria health</details>
Or download binaries directly from GitHub Releases. For detailed setup, see Setup Skill.
💡 Why Memoria?
| Capability | Memoria | Letta / Mem0 / Traditional RAG |
|---|---|---|
| Git-level version control | Native zero-copy snapshots & branches | File-level or none |
| Isolated experimentation | One-click branch, merge after validation | Manual data duplication |
| Audit trail | Full snapshot + provenance on every mutation | Limited logging |
| Semantic retrieval | Vector + full-text hybrid search | Vector only |
| Self-governance | Automatic contradiction detection & quarantine | Manual cleanup |
🔬 Research Foundation
Memoria's Git-for-Data layer is backed by Version Control System for Data with MatrixOne, our arXiv paper on bringing Git-like workflows directly into a cloud-native database.
The paper describes how MatrixOne's immutable storage and MVCC architecture make clone, branch / tag, diff, merge, and revert practical at terabyte scale without loading whole datasets into memory. Memoria applies the same foundation to AI-agent memory, so every memory change can be isolated, reviewed, merged, or rolled back with database-native consistency.
🎬 See Git for Data in Action
<p align="center"> <img src="assets/git4data-story-writing-demo.svg" alt="Animated Memoria Git-for-Data demo showing an author branching a story draft, merging a better plot direction into the main storyline, and rolling back the last two unsatisfying beats." width="100%"/> </p>
A story-writing scenario demonstrates the core concept: an author has accepted story beats on main, opens an experimental branch for a different plot direction, merges the stronger draft back, and rolls back when the newest beats don't work.
<details> <summary><b>What the demo shows</b></summary>
Main storyline — accepted story beats live on
mainExperimental branch — the author tries a new plot turn without rewriting canon
Merge — the stronger draft is promoted back into the main storyline
Rollback — the last two bad turns are discarded, and writing resumes from a safe snapshot
</details>
📖 Steering Rules
Steering rules teach your AI agent when and how to use memory tools. Without them, the agent has tools but no guidance — like having a database without knowing the schema.
| Rule | Purpose |
|---|---|
memory | Core memory tools — when to store, retrieve, correct, purge |
session-lifecycle | Bootstrap at conversation start, cleanup at end |
memory-hygiene | Proactive governance, contradiction resolution, snapshot cleanup |
memory-branching-patterns | Isolated experiments with branches |
goal-driven-evolution | Track goals, plans, progress across conversations |
File locations: Kiro: .kiro/steering/*.md · Cursor: .cursor/rules/*.mdc · Claude: .claude/rules/*.md · Codex: AGENTS.md · Gemini CLI: GEMINI.md + .gemini/*.md
After upgrading: memoria rules --force
<details> <summary><b>Example: Conversation Lifecycle</b></summary>
┌─────────────────────────────────────────────────────────────────────────────┐
│ CONVERSATION START │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 1. memory_retrieve(query="<user's question>") ← load context │ │
│ │ 2. memory_search(query="GOAL ACTIVE") ← check active goals │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────────────────┤
│ MID-CONVERSATION │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ • User states preference → memory_store(type="profile") │ │
│ │ • User corrects a fact → memory_correct(query="...", new="...") │ │
│ │ • Topic shifts → memory_retrieve(query="<new topic>") │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────────────────┤
│ CONVERSATION END │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 1. memory_purge(topic="<task>") ← clean up working memories │ │
│ │ 2. memory_store(type="episodic") ← save session summary │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘</details>
<details> <summary><b>Example: Goal-Driven Evolution</b></summary>
You: "I want to add OAuth support to the API"
AI: → memory_search(query="GOAL OAuth") ← check for existing goal
→ memory_store(content="🎯 GOAL: Add OAuth support\nStatus: ACTIVE", type="procedural")
... works on implementation, stores progress as working memories ...
→ memory_store(content="✅ STEP 1/3: Added OAuth routes", type="working")
→ memory_store(content="❌ STEP 2/3: Token refresh failed — need to fix expiry logic", type="working")
... next conversation ...
AI: → memory_search(query="GOAL ACTIVE") ← finds OAuth goal
→ memory_search(query="STEP for GOAL OAuth") ← loads progress
"Last time we were working on OAuth. Step 2 failed on token refresh. Want to continue?"
... goal completed ...
AI: → memory_correct(query="GOAL OAuth", new_content="🎯 GOAL: OAuth — ✅ ACHIEVED")
→ memory_store(content="💡 LESSON: Token refresh needs 5min buffer before expiry", type="procedural")
→ memory_purge(topic="STEP for GOAL OAuth") ← clean up working memories</details>
<details> <summary><b>Example: Branch for Risky Experiments</b></summary>
You: "Let's try switching from PostgreSQL to SQLite"
AI: → memory_branch(name="eval_sqlite")
→ memory_checkout(name="eval_sqlite")
... experiments on branch, stores findings ...
→ memory_diff(source="eval_sqlite") ← preview changes
→ memory_checkout(name="main")
→ memory_merge(source="eval_sqlite") ← or delete if failed</details>
📚 API Reference
Core Tools
| Tool | Description |
|---|---|
memory_store | Store a new memory |
memory_retrieve | Retrieve relevant memories (call at conversation start) |
memory_search | Semantic search across all memories |
memory_correct | Update an existing memory |
memory_purge | Delete by ID or topic keyword |
memory_list | List active memories |
memory_profile | Get user's memory-derived profile |
memory_feedback | Record relevance feedback (useful/irrelevant/outdated/wrong) |
memory_capabilities | List available memory tools |
<details> <summary><b>Snapshots & Branches</b></summary>
| Tool | Description |
|---|---|
memory_snapshot | Create named snapshot |
memory_snapshots | List snapshots with pagination |
memory_snapshot_delete | Delete snapshots by name, prefix, or age |
memory_rollback | Restore to snapshot |
memory_branch | Create isolated branch |
memory_branches | List all branches |
memory_checkout | Switch branch |
memory_merge | Merge branch back |
memory_branch_delete | Delete a branch |
memory_diff | Preview merge changes |
</details>
REST clients can use cached-count snapshot listing to avoid historical count queries and exclude automatic safety snapshots.
<details> <summary><b>Maintenance</b></summary>
| Tool | Description |
|---|---|
memory_governance | Quarantine low-confidence memories (1h cooldown) |
memory_consolidate | Detect contradictions (30min cooldown) |
memory_reflect | Synthesize insights (2h cooldown) |
memory_rebuild_index,memory_observe,memory_get_retrieval_params,memory_tune_params,memory_extract_entities, andmemory_link_entitiesare available via REST API but hidden from MCP tool listing — they are ops/debug tools not intended for agent use.
</details>
Memory Types
| Type | Use for | Example |
|---|---|---|
semantic | Project facts, decisions | "Uses Go 1.22 with modules" |
profile | User preferences | "Prefers pytest over unittest" |
procedural | Workflows, how-to | "Deploy: make build && kubectl apply" |
working | Temporary task context | "Currently debugging auth module" |
episodic | Session summaries | "Session: optimized DB, added indexes" |
Full API details: API Reference Skill
Retry-safe single-memory writes: Idempotent store protocol.
Trusted adapter content preservation: Content-filter policy.
🔧 Commands
| Command | Description |
|---|---|
memoria init -i | Interactive setup wizard |
memoria status | Show config and rule versions |
memoria rules | Update steering rules (auto-detect, --tool, or -i) |
memoria mcp | Start MCP server |
memoria serve | Start REST API server |
memoria benchmark | Run benchmark suite |
🤖 For AI Agents
If you're an AI agent helping a user set up Memoria:
Load the Setup Skill — it has step-by-step instructions
Ask before acting: which AI tool? · database mode? · embedding service? (Self-Hosted only)
Run
memoria init -iin the user's project directoryTell user to restart their AI tool, then verify with
memory_retrieve("test")
Self-Hosted only: Configure embedding BEFORE first MCP server start — dimension is locked into schema.
🏗️ Architecture
Cloud / Remote Mode:
┌─────────────┐ MCP (stdio) ┌──────────────────┐ HTTP/REST ┌──────────────────┐
│ AI Agent │ ◄─────────────────► │ Memoria CLI │ ◄──────────────► │ Memoria Cloud │
│ │ store / retrieve │ (MCP bridge) │ Bearer token │ API Server │
└─────────────┘ └──────────────────┘ └──────────────────┘
Self-Hosted / Embedded Mode:
┌─────────────┐ MCP (stdio) ┌──────────────────────────────────────┐ SQL ┌────────────┐
│ AI Agent │ ◄─────────────────► │ Memoria MCP Server │ ◄──────────► │ MatrixOne │
│ │ store / retrieve │ ├── Canonical Storage │ vector + │ Database │
│ │ │ ├── Retrieval (vector / semantic) │ fulltext │ │
│ │ │ └── Git-for-Data (snap/branch/merge)│ │ │
└─────────────┘ └──────────────────────────────────────┘ └────────────┘For codebase details, see Architecture Skill.
🛠️ Development
make up # Start MatrixOne + API
make test # Run all tests
make release VERSION=0.2.0 # Bump, tag, pushDeveloper documentation (for contributing to Memoria):
| Skill | Description |
|---|---|
| Architecture | Codebase layout, traits, tables |
| API Reference | REST endpoints, request/response |
| Deployment | Docker, K8s, multi-instance |
| Plugin Development | Governance plugins |
| Release | Version bump, CI/CD |
| Local Embedding | Offline embedding build |
📝 Citation
If you use Memoria in academic work, or refer to its Git-for-Data foundation for AI-agent memory, please cite the MatrixOne paper that describes the underlying data version control design:
@misc{gou2026versioncontrolsystemdata,
title={Version Control System for Data with MatrixOne},
author={Gou, Hongshen and Tian, Feng and Wang, Long and Deng, Nan and Xu, Peng},
year={2026},
eprint={2604.03927},
archivePrefix={arXiv},
primaryClass={cs.DB},
doi={10.48550/arXiv.2604.03927},
url={https://arxiv.org/abs/2604.03927}
}🌟 Community
We'd love your support! If Memoria helps you, consider giving us a star.
Contributing — See the developer documentation above and check out our issue templates for bug reports, feature requests, and more.
License
Apache-2.0 © MatrixOrigin
docs/per-user-database-architecture.md
Per-User Database 架构、迁移与部署说明
状态: Implemented and validated 作者: Copilot + ghs-mo 最近更新: 2026-04-06 适用范围:
memoria-storage,memoria-git,memoria-service,memoria-mcp,memoria-api,memoria-cli
1. 结论先行
Memoria 已从“所有用户共享一个数据库、靠 user_id 行级过滤隔离”的旧模型,演进为:
一个 shared DB 承载全局控制平面数据。
一个用户一个 per-user DB 承载该用户的业务数据与用户级控制元数据。
运行时主路径采用 global user pool + qualified table names,而不是为每个用户维护长期连接池;shared DB 上的 shared/router/git 组件也合并复用同一个固定池。
关于 multi-db /metrics 的下一阶段长期设计,见:
docs/metrics-rollup-refresh-design.md
这个改造的核心收益不是“查询更快”,而是把 snapshot / branch / restore / rollback 从“天然会误伤所有用户”的危险操作,收敛成“只作用于当前用户数据库”的安全操作。
代价也很明确:
数据库对象数量会上升,运维和观测复杂度高于单库模型。
/admin/stats、治理遍历这类全局聚合仍然要经过用户注册表;/metrics则需要改成 shared DB summary + 异步刷新,不能把 per-user fan-out 放在 scrape 路径里。部署时必须明确 shared DB 的名字和 URL;不能再依赖“默认猜一个库名”。
2. 为什么要改
旧架构的问题不是“共享库不优雅”,而是 Git-for-Data 语义在共享库里不成立。
旧模型下,mem_memories、memory_graph_*、mem_edit_log 等核心表都混在一个数据库里。这样会导致:
rollback 风险不可接受
一个用户执行 restore / rollback,本质上是对全表做恢复;如果表里混着所有用户的数据,那么恢复操作天然是全局性的。snapshot 边界错误
snapshot 如果基于 account 或共享数据库创建,天然包含其他用户状态;用户 A 的“回到我的某个时刻”会变成“把整库带回某个时刻”。branch / diff 只能靠应用层过滤
数据分支和 diff 如果以 account 或共享表为边界,Rust 层再按user_id过滤,本质上只是补丁,不是隔离。
因此,per-user DB 不是“性能优化”,而是 把版本控制语义落到正确的数据边界上。
3. 最终落地架构
3.1 数据库布局
MatrixOne account
|
+-- memoria_shared* # shared DB(名字由部署决定,不要求固定)
| +-- mem_user_registry
| +-- mem_api_keys
| +-- mem_distributed_locks
| +-- mem_async_tasks
| +-- mem_governance_runtime_state
| +-- mem_plugin_*
|
+-- mem_u_<hash(user_id)>
| +-- mem_memories
| +-- mem_memories_stats
| +-- mem_branches
| +-- mem_snapshots
| +-- mem_user_state
| +-- mem_edit_log
| +-- mem_entities
| +-- mem_entity_links
| +-- mem_memory_entity_links
| +-- memory_graph_nodes
| +-- memory_graph_edges
| +-- mem_retrieval_feedback
| +-- mem_user_retrieval_params
| +-- mem_governance_cooldown
| +-- mem_tool_usage
| +-- mem_api_call_log
| +-- br_*
|
+-- mem_u_<hash(other_user)>
+-- ...3.2 shared DB 放什么
shared DB 只放 跨用户共享、跨实例协调、或必须全局查询 的控制平面数据:
| 表 | 为什么必须留在 shared DB |
|---|---|
mem_user_registry | user_id -> db_name 路由事实源 |
mem_api_keys | API key 校验必须跨用户查询 |
mem_distributed_locks | 分布式锁天然是全局控制面 |
mem_async_tasks | 跨实例异步任务状态 |
mem_governance_runtime_state | 治理熔断与运行态 |
mem_plugin_* | 插件包、签名者、绑定、审计均为全局能力 |
3.3 per-user DB 放什么
per-user DB 放两类数据:
业务数据:记忆、图谱、反馈、调用日志、分支表。
用户级控制元数据:
mem_branches、mem_snapshots、mem_user_state、mem_governance_cooldown。
注意:这些“用户级控制元数据”虽然在用户库里,但它们不是 rollback 的业务恢复目标;它们要保持当前态,否则会出现 branch / snapshot 注册表与底层事实不一致。
3.4 鉴权与首次建库的边界
API Key 校验只依赖 shared DB。缓存命中仍须检查 Key 的 expires_at(UTC);缓存 TTL 不能延长 Key 的有效期。无到期时间的 Key 继续遵守正常缓存 TTL。
MCP 的工具权限检查必须先于群组存储访问、工具使用统计和个人调用日志入队。因 scope 不足而拒绝的请求(包括 notification),以及格式错误的请求,不得为了记录拒绝而创建个人记忆库。这些事件保留在运行日志中,并在启用 shared stats reporter 时计入共享汇总统计。
仅有 identity:read 的 Key 调用身份或 MCP 元数据接口时,也不写入可能触发建库的个人统计;即使带有 X-Memoria-Tool 或 X-Tool-Name Header,行为不变。获准的记忆工具调用仍正常记录使用情况,并可按原有流程首次建库。以上边界不需要新增表或数据库迁移。
4. 最终实现选择:global user pool + qualified tables
这次真正落地的不是最初 RFC 里那种“长期 per-user pool + 请求期 USE db 切换”方案,而是下面这个版本:
DbRouter维护:一个合并后的 shared DB pool(同时承载 router / shared store / git,默认 20)
一个 global user pool(承载常规 per-user 读写,默认 80)
一个 init pool(承载首次用户 schema bootstrap / compat migration,默认 12)
auth 保持独立 auth pool(默认 12),governance 仍保持小隔离池(默认 2)
路由出来的 user store 本身携带
db_name用户表通过全限定名访问,例如:
`mem_u_53f19f9ab3e3d6f1`.mem_memories`mem_u_53f19f9ab3e3d6f1`.memory_graph_nodes
shared 表继续走 shared DB 上下文,不做全限定用户库拼接
这套默认固定预算现在是 20 + 80 + 12 + 12 + 2 = 126,仍然留在 150 总连接预算以内。
为什么最终没有用 per-user pool
因为 per-user pool 在真实多用户场景下会把问题从“隔离”变成“连接爆炸”:
用户数上来以后,连接数和空闲池数量线性增长。
LRU 缓存 per-user pool 只能减轻冷用户问题,不能消除冷启动抖动。
USE db配合 statement cache、后台 worker、跨 shared/user 查询时会产生额外复杂性。
最终方案的取舍是:
| 方案 | 好处 | 问题 |
|---|---|---|
per-user pool + USE db | 语义直接 | 连接爆炸、池管理复杂 |
| global user pool + qualified tables | 连接数稳定、shared/user 边界清晰 | SQL 需要系统性表名限定 |
这也是当前代码最终落地的版本。
5. Snapshot / Branch / Restore 的最终边界
5.1 用户 rollback 只回退业务数据
用户级 restore / rollback 的边界是:
| 域 | 典型表 | 是否纳入用户 restore |
|---|---|---|
| 业务数据域 | mem_memories, memory_graph_nodes, memory_graph_edges, mem_edit_log | 是 |
| 用户级控制元数据 | mem_snapshots, mem_branches, mem_user_state, mem_governance_cooldown | 否,保持当前态 |
| shared 控制平面 | mem_user_registry, mem_api_keys, mem_distributed_locks, mem_async_tasks, mem_plugin_* | 否,严禁用户 restore |
5.2 这样设计的原因
如果把 mem_snapshots / mem_branches / mem_user_state 一起回退,会出现:
物理上还存在的 branch / snapshot,在控制平面里“消失”。
active_branch静默切回旧值。快照配额、branch 配额、治理 cooldown 状态和真实系统状态脱节。
因此,“per-user DB” 不等于 “整库用户随意 restore”。
真正安全的定义是:业务数据按用户库隔离;控制平面保持当前态并做对账。
5.3 Branch / Snapshot 的现实约束
当前实现里,迁移时会保留已有 br_* 物理表名,不做重命名重写。这样做的好处是:
减少迁移时对 branch metadata 的额外修改。
避免把“迁移用户数据”扩大成“迁移用户数据 + 重写所有 branch 元数据”。
代价是历史 br_* 名字不会因为 per-user DB 而变得更漂亮;这是有意接受的兼容性取舍。
6. 迁移流程(正式 runbook)
这一节描述的是 旧单库 -> 新 shared DB + per-user DB 的正式迁移流程。
6.1 迁移 CLI
当前正式命令是:
# dry-run(默认)
memoria migrate legacy-to-multi-db \
--legacy-db-url mysql://user:pass@host:6001/memoria_legacy \
--shared-db-url mysql://user:pass@host:6001/memoria_shared \
--embedding-dim 1024 \
--report-out migration-plan.json
# execute(真正执行)
memoria migrate legacy-to-multi-db \
--legacy-db-url mysql://user:pass@host:6001/memoria_legacy \
--shared-db-url mysql://user:pass@host:6001/memoria_shared \
--embedding-dim 1024 \
--concurrency 4 \
--execute \
--report-out migration-run.json也支持:
memoria migrate legacy-to-multi-db \
--legacy-db-url ... \
--shared-db-url ... \
--user alice \
--user bob这个 --user 主要用于 rehearsal / troubleshooting,不建议当正式灰度切流机制使用。
服务启动时的自动 legacy -> multi-db 迁移同样支持并发;默认并发为 6,可通过
MEMORIA_LEGACY_MIGRATION_MAX_CONCURRENCY 覆盖。若未设置该变量,则回落到
MEMORIA_USER_SCHEMA_INIT_MAX_CONCURRENCY。这个迁移仍然发生在服务对外就绪之前,
不会改成“边启动边迁移”的语义。
6.2 dry-run 做什么
dry-run 只做计划和风险检查,不写目标库。它应该回答四个问题:
有多少用户会被迁移。
每个用户会落到哪个
mem_u_*。有多少业务表、branch 表、共享表需要搬运。
有没有 execute 前必须处理的阻断项。
6.3 execute 做什么
execute 的实际动作顺序是:
创建 pre-execute account snapshot
reset 目标 shared DB
迁移 shared 持久表
按用户并发迁移:
创建 / 重建
mem_u_*初始化用户库 schema
复制用户业务表
复制
mem_memories_stats复制该用户的
br_*物理分支表
写入 / 更新
mem_user_registry生成完整报告
6.4 execute 前的前置条件
先 dry-run 一次
冻结写流量
MCP 写入
REST 写入
后台任务可能触发的数据写入
保留 legacy DB,不要在 execute 前删库
确认目标 shared DB 和目标
mem_u_*没有你还要保留的生产数据
6.5 execute 后必须做的验证
最少要检查:
mem_user_registry是否有完整用户映射。老 API key 是否仍可认证。
关键老用户的 memories / branches / snapshots 是否可读。
brand-new user 是否能在新架构下首次自动建库并正常读写。
/admin/users、/admin/stats、/metrics是否正常。MCP
tools/call是否走到正确的 multi-db 服务。
6.6 回滚原则
如果 cutover 后出现严重问题:
停止 multi-db 新服务。
优先使用 execute 前生成的 pre-execute account snapshot 回滚。
恢复旧配置,重新指向 legacy
DATABASE_URL。不要立即销毁已生成的 shared /
mem_u_*,先保留现场用于排障。
6.7 标准升级步骤:断流 -> 迁移 -> 部署新服务
这一节是给运维执行的 cutover 操作手册。目标不是解释“原理”,而是让你按顺序执行并知道每一步为什么存在。
适用前提:
旧服务仍在 single-DB / legacy DB 上对外提供写服务。
新服务将切到 shared DB + per-user DB。
允许一次 短暂写停机。当前流程 不支持 dual-write,也不支持不停写在线迁移。
Step 0. 切流前预演:这些事不要放到断流窗口里做
先在正式 cutover 之前完成下面这些动作:
编译或准备好新版二进制 / 镜像。
用真实生产 URL 跑一次 dry-run。
确认新版运行时配置已经准备好,但 先不要接流量。
明确所有写入口:
旧 Memoria API 实例
website backend(如果它会代理
/api/chat//api/memories并自动写记忆)任何直接调用
/v1/*或/mcp的 agent / cron / batch job
推荐先准备统一变量:
export LEGACY_DB_URL='mysql://user:pass@host:6001/memoria_legacy_prod'
export SHARED_DB_URL='mysql://user:pass@host:6001/memoria_shared_prod'
export EMBEDDING_DIM=1024
export PORT=8116
export MASTER_KEY='replace-with-real-master-key'
export REPORT_PLAN='migration-plan.json'
export REPORT_RUN='migration-run.json'先做 dry-run:
memoria migrate legacy-to-multi-db \
--legacy-db-url "$LEGACY_DB_URL" \
--shared-db-url "$SHARED_DB_URL" \
--embedding-dim "$EMBEDDING_DIM" \
--report-out "$REPORT_PLAN"此时重点看四件事:
用户总数是否符合预期。
是否有 warnings / errors。
目标 shared DB 名字是否正确。
计划里生成的
mem_u_*是否符合预期。
如果 dry-run 都不干净,不要进入 cutover。
Step 1. 预构建新版服务,但不要接流量
如果你走二进制部署:
cd /path/to/Memoria/memoria
source ~/.cargo/env
cargo build --release如果你走镜像部署,也应在这里把镜像构建好并推到仓库,但 不要 rollout。
同时准备新服务运行时变量:
export DATABASE_URL="$SHARED_DB_URL"
export MEMORIA_MULTI_DB=1
export MEMORIA_SHARED_DATABASE_URL="$SHARED_DB_URL"
export EMBEDDING_PROVIDER='openai'
export EMBEDDING_BASE_URL='<embedding-endpoint>'
export EMBEDDING_API_KEY='<embedding-secret>'
export EMBEDDING_MODEL='<embedding-model>'
export EMBEDDING_DIM="$EMBEDDING_DIM"如果还要保留 reflect / entity extraction / episodic 等 LLM 能力,再额外准备:
export LLM_BASE_URL='<llm-endpoint>'
export LLM_API_KEY='<llm-secret>'
export LLM_MODEL='<llm-model>'如果 website backend 在 cutover 后也要继续工作,提前确认它的新配置:
memoria.api_url-> 新 Memoria 服务 URLmemoria.master_key-> 新服务使用的 master key
Step 2. 开始断流:先停所有写入口,再迁移
这一阶段的要求很简单:任何能够写 memory / key / branch / snapshot 的入口,都必须先停掉。
常见写入口包括:
旧 Memoria API 实例本身。
website backend(因为它可能通过
/api/chat自动提取并写记忆)。直接调用
/mcp或/v1/memories的 agent / batch 任务。
根据你的部署方式,执行对应的停机动作:
# 本地/裸二进制
kill <old-memoria-pid>
kill <website-backend-pid>
# systemd
systemctl stop memoria
systemctl stop memoria-srv
# docker compose
docker compose stop memoria
docker compose stop memoria-srv
# Kubernetes
kubectl scale deploy/memoria --replicas=0 -n <ns>
kubectl scale deploy/memoria-srv --replicas=0 -n <ns>如果你前面还有 API Gateway / LB,先把旧实例从对外流量里摘掉,再停进程。
Step 3. 确认断流真的生效
不要“感觉已经停了”就往下走。至少做下面两类确认:
进程 / 服务侧确认
旧 Memoria 实例已从对外入口摘除,或进程已停止
website backend 不再可用,或者已切入维护状态
数据侧确认
最近几秒内没有新的写请求进入旧库
如果 legacy 库里保留了 mem_api_call_log,可以直接看最近写请求:
SELECT method, path, status_code, called_at
FROM mem_api_call_log
ORDER BY called_at DESC
LIMIT 20;你要确认的是:最近时间戳不再继续前进,尤其不要再出现新的 POST / PUT / DELETE 到 /v1/* 或 /mcp/*。
Step 4. 在断流窗口内执行正式迁移
真正执行时,用 --execute:
memoria migrate legacy-to-multi-db \
--legacy-db-url "$LEGACY_DB_URL" \
--shared-db-url "$SHARED_DB_URL" \
--embedding-dim "$EMBEDDING_DIM" \
--concurrency 4 \
--execute \
--report-out "$REPORT_RUN"这里的关键语义是:
迁移器会先创建 pre-execute account snapshot。
然后重置目标 shared DB 并重建迁移结果。
再把 shared 表和用户业务表搬到新的 shared /
mem_u_*。
--concurrency 4 是 drill 中验证过的一个稳妥起点,不是硬编码要求。你的 DB 负载更高时,可以先保守,再逐步调大。
Step 5. 迁移完成后,先做离线校验,不要急着起新服务
先看迁移报告:
有没有 errors。
warnings 是否都能解释。
用户数、memory 数、API key 数是否在预期范围内。
然后做 shared DB 校验:
SELECT COUNT(*) AS routed_users FROM mem_user_registry;
SELECT user_id, db_name FROM mem_user_registry ORDER BY updated_at DESC LIMIT 20;再抽样检查几个重要老用户,把 db_name 拿出来后,直接看用户库:
SELECT COUNT(*) AS memories FROM `<db_name-from-registry>`.mem_memories WHERE is_active = 1;
SELECT COUNT(*) AS branches FROM `<db_name-from-registry>`.mem_branches;
SELECT COUNT(*) AS snapshots FROM `<db_name-from-registry>`.mem_snapshots;如果这一步就发现数据量明显不对,不要启动新服务;先保留现场,排查迁移报告和源库。
Step 6. 启动 multi-db 新服务
确认 Step 5 没问题后,再启动新版本:
export DATABASE_URL="$SHARED_DB_URL"
export MEMORIA_MULTI_DB=1
export MEMORIA_SHARED_DATABASE_URL="$SHARED_DB_URL"
export EMBEDDING_PROVIDER='openai'
export EMBEDDING_BASE_URL='<embedding-endpoint>'
export EMBEDDING_API_KEY='<embedding-secret>'
export EMBEDDING_MODEL='<embedding-model>'
export EMBEDDING_DIM="$EMBEDDING_DIM"
export LLM_BASE_URL='<llm-endpoint>'
export LLM_API_KEY='<llm-secret>'
export LLM_MODEL='<llm-model>'
memoria serve \
--db-url "$DATABASE_URL" \
--port "$PORT" \
--master-key "$MASTER_KEY"起服务后先只做基础存活检查:
curl -sf "http://127.0.0.1:${PORT}/health"只有 health 正常后,才进入 API 烟测。
Step 7. 先验老用户,再验新用户
先用一个 已迁移老用户的现有 API key 验证读写:
export OLD_USER_KEY='sk-...'
curl -s "http://127.0.0.1:${PORT}/v1/memories?limit=3" \
-H "Authorization: Bearer ${OLD_USER_KEY}"
curl -s -X POST "http://127.0.0.1:${PORT}/v1/memories/search" \
-H "Authorization: Bearer ${OLD_USER_KEY}" \
-H "Content-Type: application/json" \
-d '{"query":"smoke test","top_k":3}'再做一个 新用户 烟测。最稳妥的方式是直接通过 master key 创建一把全新的 user key:
export NEW_USER_ID="cutover-smoke-$(date +%s)"
curl -s -X POST "http://127.0.0.1:${PORT}/auth/keys" \
-H "Authorization: Bearer ${MASTER_KEY}" \
-H "Content-Type: application/json" \
-d "{\"user_id\":\"${NEW_USER_ID}\",\"name\":\"smoke\"}"从返回结果里拿到 raw_key 后,执行一次确定性的写入:
export NEW_USER_KEY='sk-...'
curl -s -X POST "http://127.0.0.1:${PORT}/v1/memories" \
-H "Authorization: Bearer ${NEW_USER_KEY}" \
-H "Content-Type: application/json" \
-d '{"content":"cutover smoke memory","memory_type":"semantic"}'然后确认 shared DB 里出现了新路由,新用户库也真的落了数据:
SELECT user_id, db_name FROM mem_user_registry WHERE user_id = '<NEW_USER_ID>';
SELECT COUNT(*) FROM `<db_name-from-registry>`.mem_memories WHERE is_active = 1;如果你线上还有 website backend,再做一次 website 侧烟测:
把 website backend 的
memoria.api_url改到新 Memoria URL。确认
memoria.master_key与新服务一致。重启 website backend。
验证
/api/me、/api/keys、/api/memories、/api/chat。
Step 8. 全部验证通过后再恢复流量
恢复顺序建议是:
先恢复 website backend / 代理层。
再恢复直接调用 Memoria 的 agent / job。
最后恢复全部外部流量。
恢复后,持续盯这几类指标:
/health是否稳定。/admin/users、/admin/stats、/metrics是否正常。新写入是否持续落到正确的
mem_u_*。/mcp的tools/call是否能正常写入和检索。
Step 9. 回滚步骤
如果 Step 6-8 任一阶段出现阻断问题,回滚顺序应该固定:
停掉新 multi-db 服务。
恢复旧 single-db 服务配置:
DATABASE_URL指回 legacy DB关闭
MEMORIA_MULTI_DB
如果 website backend 已切到新服务,把它的
memoria.api_url/memoria.master_key改回旧值并重启。重新开放旧流量。
保留
REPORT_PLAN、REPORT_RUN、新 shared DB、所有mem_u_*现场用于排障。
只有在确认问题已经定位后,才去处理目标库;不要在第一次故障现场里边切边删。
Step 10. 这个 runbook 何时不够用
这份 runbook 的边界也要说清楚:
如果你要求 零写停机,当前方案不够用;因为它没有 dual-write 和增量 catch-up。
如果 legacy 和 target 不在同一个 MatrixOne account,内置的 pre-execute account snapshot 只能覆盖它所在的 account;这时需要额外做源侧备份。
如果 website 之外还有隐藏写入口,没有一起断流,迁移后的数据就会天然分叉。
7. 新服务镜像重启时必须设置的环境变量
这一节只讨论 memoria serve 的运行时环境变量,不包括测试变量、CLI 初始化变量、开发机专用变量。
7.1 迁移后重启的最小必需集合
如果你只是要让新版 multi-db 服务正常启动并工作,最小集合是:
最新运行时在全新空环境下,即使没显式设置
MEMORIA_MULTI_DB,也会自动按 multi-db 启动。 但生产环境仍然建议把MEMORIA_MULTI_DB=1和MEMORIA_SHARED_DATABASE_URL明确写出来,避免歧义,也兼容旧版本节点。
DATABASE_URL=<shared-db-url>
MEMORIA_MULTI_DB=1
MEMORIA_SHARED_DATABASE_URL=<shared-db-url>
EMBEDDING_PROVIDER=openai
EMBEDDING_BASE_URL=<your-embedding-endpoint>
EMBEDDING_API_KEY=<secret>
EMBEDDING_MODEL=<your-model>
EMBEDDING_DIM=<must-match-schema>7.2 每个变量的作用
| 变量 | 是否迁移后重启必需 | 说明 |
|---|---|---|
DATABASE_URL | 是 | multi-db 模式下应指向 shared DB |
MEMORIA_MULTI_DB | 建议显式设置 | 置为 1 / true 可强制打开新架构;最新运行时对 fresh empty 环境会自动切到 multi-db |
MEMORIA_SHARED_DATABASE_URL | 是 | 显式告诉服务 shared DB 在哪;不要依赖默认推导 |
EMBEDDING_PROVIDER | 基本必需 | 不设会退回默认 mock,检索语义会变掉 |
EMBEDDING_BASE_URL | 基本必需 | HTTP embedding 服务地址 |
EMBEDDING_API_KEY | 基本必需 | embedding 鉴权 |
EMBEDDING_MODEL | 基本必需 | 例如 BAAI/bge-m3 |
EMBEDDING_DIM | 基本必需 | 必须和库里向量维度一致 |
7.3 为什么 MEMORIA_SHARED_DATABASE_URL 不能省
代码在没拿到这个变量时,会尝试把 DATABASE_URL 的库名替换成固定的 memoria_shared。
这只在一种情况下安全:
你的 shared DB 真的就叫
memoria_shared
但现实部署里,shared DB 往往会带环境后缀,例如:
memoria_shared_200umemoria_shared_prodmemoria_shared_staging
这种情况下,如果不显式设置 MEMORIA_SHARED_DATABASE_URL,服务就会猜错。
7.4 LLM 相关变量:不是启动必需,但可能是功能必需
如果你还要保留 reflect / entity extraction / episodic summary 等能力,需要再设置:
LLM_API_KEY=<secret>
LLM_BASE_URL=<llm-endpoint>
LLM_MODEL=<model-name>如果这些功能不需要,可以不设;服务仍能启动,只是相关能力不可用或降级。
7.5 不是 cutover 必需的变量(可选调优)
下面这些不是“迁移后必须设”,而是部署调优项:
| 变量 | 用途 |
|---|---|
MEMORIA_MULTI_DB_POOL_BUDGET | multi-db 连接池默认预算基线;默认 512,上限 2048;未显式配置的池按 global/shared/auth/init/governance = 60/20/10/5/5 推导 |
MEMORIA_GLOBAL_USER_POOL_MAX | global user pool 大小 |
MEMORIA_LEGACY_MIGRATION_MAX_CONCURRENCY | 启动期 legacy -> multi-db 自动迁移的用户并发上限 |
MEMORIA_USER_SCHEMA_INIT_POOL_MAX_CONNECTIONS | 首次用户 schema init / compat migration 专用池大小 |
MEMORIA_USER_SCHEMA_INIT_MAX_CONCURRENCY | 首次用户 schema init 并发上限 |
MEMORIA_ROUTER_INIT_TIMEOUT_SECS | 用户/组冷初始化及用户 DB 映射查询、注册的总时限(含 gate/全局许可等待),默认 120 秒,范围 1–3600 秒 |
MEMORIA_ROUTER_INVALIDATION_TIMEOUT_SECS | 缓存失效等待总时限,默认 15 秒,范围 1–3600 秒;超时返回错误,不宣告失效成功 |
MEMORIA_SHARED_POOL_MAX_CONNECTIONS | 兼容旧配置的 shared router 组件配额;仅在显式设置时参与 merged shared pool 计算 |
MEMORIA_SHARED_MAIN_POOL_MAX_CONNECTIONS | 兼容旧配置的 shared store 组件配额;仅在显式设置时参与 merged shared pool 计算 |
MEMORIA_GIT_POOL_MAX_CONNECTIONS | 兼容旧配置的 git 组件配额;仅在显式设置时参与 merged shared pool 计算 |
MEMORIA_MERGED_SHARED_POOL_MAX_CONNECTIONS | 显式覆盖 merged shared pool 大小;优先级高于 budget 推导 |
MEMORIA_AUTH_POOL_MAX_CONNECTIONS | auth 专用连接池大小 |
MEMORIA_AUTH_POOL_ACQUIRE_TIMEOUT_SECS | auth 池获取超时 |
DB_MAX_LIFETIME_SECS | DB 连接最大生命周期 |
ENTITY_QUEUE_SIZE / ENTITY_POOL_SIZE / ENTITY_WORKER_COUNT | entity worker 调优 |
GRAPH_POOL_SIZE | graph 检索隔离池大小 |
GOVERNANCE_POOL_SIZE | 治理任务并发池 |
MEMORIA_METRICS_CACHE_TTL_SECS | /metrics 缓存 TTL |
MEMORIA_RATE_LIMIT_AUTH_KEYS | auth key rate limit |
MEMORIA_GOVERNANCE_ENABLED | 治理开关 |
MEMORIA_GOVERNANCE_PLUGIN_BINDING / SUBJECT / DIR | 治理插件配置 |
MEMORIA_INSTANCE_ID | 分布式锁实例标识 |
MEMORIA_LOCK_TTL_SECS | 分布式锁 TTL |
MEMORIA_SANDBOX_ENABLED | pipeline sandbox 开关 |
EMBED_MAX_CONCURRENT / EMBED_SEMAPHORE_TIMEOUT_SECS | embedding 并发限制 |
7.6 不是环境变量的启动参数
下面两个不是 env,而是启动参数:
memoria serve \
--db-url "$DATABASE_URL" \
--port 8116 \
--master-key <master-key>也就是说:
port不是环境变量。master key不是环境变量。
7.7 一个完整但最小的 multi-db 启动示例
export DATABASE_URL='mysql://user:pass@host:6001/memoria_shared_prod'
export MEMORIA_MULTI_DB=1
export MEMORIA_SHARED_DATABASE_URL="$DATABASE_URL"
export EMBEDDING_PROVIDER='openai'
export EMBEDDING_BASE_URL='https://api.siliconflow.cn/v1'
export EMBEDDING_API_KEY='***'
export EMBEDDING_MODEL='BAAI/bge-m3'
export EMBEDDING_DIM=1024
export LLM_BASE_URL='https://api.openai.com/v1'
export LLM_API_KEY='***'
export LLM_MODEL='gpt-4o-mini'
memoria serve \
--db-url "$DATABASE_URL" \
--port 8116 \
--master-key '<master-key>'所有第三方密钥都属于运行时 secret,必须由部署系统注入,不能提交到仓库。
8. 当前实现里的关键工程取舍
8.1 保留 user_id 列
当前 per-user DB 里多数表仍保留 user_id 列。这不是因为物理隔离不够,而是为了:
降低迁移和回退风险。
保持部分逻辑与旧模型兼容。
让迁移后的校验、审计和补救脚本更简单。
代价是 schema 还没有达到最简状态,但这是有意接受的 Phase 1 取舍。
8.2 shared 表永远不能被用户 restore
这是最重要的安全边界之一。
如果用户 restore 能影响 shared DB,那么 API key、分布式锁、任务状态、用户路由都会被回滚,整个系统会从“用户级恢复”退化回“系统级破坏”。
8.3 全局聚合不再是单条 SQL 的问题
/admin/stats、治理遍历等能力,在 per-user DB 时代仍然需要经过:
mem_user_registry路由到用户库
聚合结果
/metrics 不能直接走这条同步路径:Prometheus scrape 必须只读 shared DB summary。
正确姿势是后台 worker 根据 mem_user_registry 找到 dirty 用户、路由进用户库重算 summary,再由 /metrics 读取 summary 表和进程内指标。
9. 当前已经验证过什么
这套架构已经在真实 drill 中完成过:
legacy single-db -> shared + per-user DB 迁移
老用户迁移后登录、读写、检索、MCP 调用
新用户 cutover 后自动建库与正常使用
branch / snapshot / rollback / merge 等全链路语义验证
website 代理链路与 MCP 链路验证
因此,这份文档不再是“候选方案说明”,而是 当前实现 + 运维执行方式说明。
10. PR / 部署边界说明
这次 per-user-per-db 改造本身发生在 Memoria 仓库。
website 仓库里若有本地 debug 登录补丁,那只是 drill 辅助工具,不属于本架构变更的一部分。
11. 一句话运维原则
如果只记一条:
迁移后重启 multi-db 服务时,必须显式告诉它 shared DB 是谁;shared DB 只管控制平面,用户 rollback 只回退用户业务数据。
467 files · 445 not served here
- .claude/rules/memory-branching-patterns.md (not served here)
- .cursor/rules/memory-branching-patterns.mdc
- .cursor/rules/memory.mdc
- .dockerignore (not served here)
- .env.example (not served here)
- .gemini/memory-branching-patterns.md (not served here)
- .github/CODEOWNERS (not served here)
- .github/ISSUE_TEMPLATE/bug_report.yml (not served here)
- .github/ISSUE_TEMPLATE/config.yml (not served here)
- .github/ISSUE_TEMPLATE/documentation.yml (not served here)
- .github/ISSUE_TEMPLATE/feature_request.yml (not served here)
- .github/ISSUE_TEMPLATE/question.yml (not served here)
- .github/PULL_REQUEST_TEMPLATE.md (not served here)
- .github/workflows/pr-title.yml (not served here)
- .github/workflows/release-docker.yml (not served here)
- .github/workflows/release-npm.yml (not served here)
- .github/workflows/release-rust.yml (not served here)
- .github/workflows/sdk-python-release.yml (not served here)
- .github/workflows/test-gate.yml (not served here)
- .github/workflows/test-hermes.yml (not served here)
- .github/workflows/test-openclaw.yml (not served here)
- .github/workflows/test.yml (not served here)
- .gitignore (not served here)
- .kiro/settings/lsp.json (not served here)
- .kiro/steering/goal-driven-evolution.md
- .kiro/steering/memory-branching-patterns.md
- .kiro/steering/memory-hygiene.md
- .kiro/steering/memory.md
- .kiro/steering/session-lifecycle.md
- .kiro/steering/skills.md
- .mergify.yml (not served here)
- ATTRIBUTION.md
- AUTOGINEER-RUNS.md
- CHANGELOG.md
- LICENSE
- Makefile (not served here)
- README.md
- SKILLS.md
- assets/README.md (not served here)
- assets/git4data-story-writing-demo.svg (not served here)
- assets/logo-transparent.jpg (not served here)
- assets/logo.jpg (not served here)
- assets/logo.png (not served here)
- assets/memoria-logo-transparent.png (not served here)
- assets/memoria-logo.png (not served here)
- benchmarks/datasets/core-v1.json (not served here)
- benchmarks/datasets/core-v2.json (not served here)
- benchmarks/datasets/forget-v1.json (not served here)
- benchmarks/datasets/graph-entity-v1.json (not served here)
- benchmarks/datasets/graph-entity-v2.json (not served here)
- benchmarks/datasets/large-graph-v1.json (not served here)
- benchmarks/datasets/large-graph-v2.json (not served here)
- cliff.toml (not served here)
- config/grafana/provisioning/dashboards/dashboards.yml (not served here)
- config/grafana/provisioning/datasources/prometheus.yml (not served here)
- config/matrixone/cn.toml (not served here)
- config/matrixone/launch.toml (not served here)
- config/matrixone/log.toml (not served here)
- config/matrixone/tn.toml (not served here)
- config/prometheus/prometheus.yml (not served here)
- docker-compose.remote.yml (not served here)
- docker-compose.yml (not served here)
- docs/api/content_filter_policy.md (not served here)
- docs/api/episodic_memory.md (not served here)
- docs/api/idempotent_store.md (not served here)
- docs/branch-copy-compatibility.md
- docs/graph-benchmark-rationale.md
- docs/legacy-snapshot-compatibility.md (not served here)
- docs/memory-ability-taxonomy.md
- docs/per-user-database-architecture.md
- docs/snapshot-listing.md
- docs/specs/2026-04-12-group-collaboration-api.md (not served here)
- grafana/memoria-overview.json (not served here)
- memoria/.env.example (not served here)
- memoria/CHANGELOG.md (not served here)
- memoria/Cargo.lock (not served here)
- memoria/Cargo.toml (not served here)
- memoria/Cross.toml (not served here)
- memoria/Dockerfile (not served here)
- memoria/Makefile (not served here)
- memoria/README.md (not served here)
- memoria/crates/memoria-api/AUTH_CHANGES.md (not served here)
- memoria/crates/memoria-api/Cargo.toml (not served here)
- memoria/crates/memoria-api/src/auth.rs (not served here)
- memoria/crates/memoria-api/src/instrumented_embedder.rs (not served here)
- memoria/crates/memoria-api/src/lib.rs (not served here)
- memoria/crates/memoria-api/src/metrics/embedding.rs (not served here)
- memoria/crates/memoria-api/src/metrics/http.rs (not served here)
- memoria/crates/memoria-api/src/metrics/middleware.rs (not served here)
- memoria/crates/memoria-api/src/metrics/mod.rs (not served here)
- memoria/crates/memoria-api/src/metrics/render.rs (not served here)
- memoria/crates/memoria-api/src/metrics/security.rs (not served here)
- memoria/crates/memoria-api/src/metrics/types.rs (not served here)
- memoria/crates/memoria-api/src/metrics/worker.rs (not served here)
- memoria/crates/memoria-api/src/metrics_summary.rs (not served here)
- memoria/crates/memoria-api/src/models.rs (not served here)
- memoria/crates/memoria-api/src/otel.rs (not served here)
- memoria/crates/memoria-api/src/rate_limit.rs (not served here)
- memoria/crates/memoria-api/src/routes/admin.rs (not served here)
- memoria/crates/memoria-api/src/routes/auth.rs (not served here)
- memoria/crates/memoria-api/src/routes/governance.rs (not served here)
- memoria/crates/memoria-api/src/routes/groups.rs (not served here)
- memoria/crates/memoria-api/src/routes/mcp.rs (not served here)
- memoria/crates/memoria-api/src/routes/memory.rs (not served here)
- memoria/crates/memoria-api/src/routes/metrics.rs (not served here)
- memoria/crates/memoria-api/src/routes/mod.rs (not served here)
- memoria/crates/memoria-api/src/routes/plugins.rs (not served here)
- memoria/crates/memoria-api/src/routes/sessions.rs (not served here)
- memoria/crates/memoria-api/src/routes/snapshots.rs (not served here)
- memoria/crates/memoria-api/src/state.rs (not served here)
- memoria/crates/memoria-api/tests/api_db_verify.rs (not served here)
- memoria/crates/memoria-api/tests/api_e2e.rs (not served here)
- memoria/crates/memoria-api/tests/api_multi_db_purge.rs (not served here)
- memoria/crates/memoria-api/tests/api_multi_db_routing.rs (not served here)
- memoria/crates/memoria-api/tests/content_filter_policy.rs (not served here)
- memoria/crates/memoria-api/tests/group_collab_api.rs (not served here)
- memoria/crates/memoria-api/tests/idempotent_store.rs (not served here)
- memoria/crates/memoria-api/tests/observe_dedup.rs (not served here)
- memoria/crates/memoria-api/tests/pool_budget_e2e.rs (not served here)
- memoria/crates/memoria-api/tests/pool_isolation.rs (not served here)
- memoria/crates/memoria-api/tests/request_validation.rs (not served here)
- memoria/crates/memoria-api/tests/snapshot_pagination.rs (not served here)
- memoria/crates/memoria-api/tests/subject_isolation_e2e.rs (not served here)
- memoria/crates/memoria-api/tests/support/mod.rs (not served here)
- memoria/crates/memoria-api/tests/support/multi_db.rs (not served here)
- memoria/crates/memoria-cli/Cargo.toml (not served here)
- memoria/crates/memoria-cli/src/benchmark.rs (not served here)
- memoria/crates/memoria-cli/src/benchmark_executor.rs (not served here)
- memoria/crates/memoria-cli/src/benchmark_schema.rs (not served here)
- memoria/crates/memoria-cli/src/benchmark_scoring.rs (not served here)
- memoria/crates/memoria-cli/src/benchmark_taxonomy.rs (not served here)
- memoria/crates/memoria-cli/src/bin/loadtest.rs (not served here)
- memoria/crates/memoria-cli/src/main.rs (not served here)
- memoria/crates/memoria-cli/templates/claude_goal_evolution.md (not served here)
- memoria/crates/memoria-cli/templates/claude_memory_branching.md (not served here)
- memoria/crates/memoria-cli/templates/claude_memory_hygiene.md (not served here)
- memoria/crates/memoria-cli/templates/claude_rule.md (not served here)
- memoria/crates/memoria-cli/templates/claude_session_lifecycle.md (not served here)
- memoria/crates/memoria-cli/templates/codex_agents.md (not served here)
- memoria/crates/memoria-cli/templates/cursor_goal_evolution.md (not served here)
- memoria/crates/memoria-cli/templates/cursor_memory_branching.md (not served here)
- memoria/crates/memoria-cli/templates/cursor_memory_hygiene.md (not served here)
- memoria/crates/memoria-cli/templates/cursor_rule.md (not served here)
- memoria/crates/memoria-cli/templates/cursor_session_lifecycle.md (not served here)
- memoria/crates/memoria-cli/templates/gemini_goal_evolution.md (not served here)
- memoria/crates/memoria-cli/templates/gemini_memory_branching.md (not served here)
- memoria/crates/memoria-cli/templates/gemini_memory_hygiene.md (not served here)
- memoria/crates/memoria-cli/templates/gemini_rule.md (not served here)
- memoria/crates/memoria-cli/templates/gemini_session_lifecycle.md (not served here)
- memoria/crates/memoria-cli/templates/kiro_goal_evolution.md (not served here)
- memoria/crates/memoria-cli/templates/kiro_memory_branching.md (not served here)
- memoria/crates/memoria-cli/templates/kiro_memory_hygiene.md (not served here)
- memoria/crates/memoria-cli/templates/kiro_session_lifecycle.md (not served here)
- memoria/crates/memoria-cli/templates/kiro_steering.md (not served here)
- memoria/crates/memoria-core/Cargo.toml (not served here)
- memoria/crates/memoria-core/src/error.rs (not served here)
- memoria/crates/memoria-core/src/interfaces.rs (not served here)
- memoria/crates/memoria-core/src/lib.rs (not served here)
- memoria/crates/memoria-core/src/sensitivity.rs (not served here)
- memoria/crates/memoria-core/src/types.rs (not served here)
- memoria/crates/memoria-core/tests/sensitivity_contract.rs (not served here)
- memoria/crates/memoria-embedding/Cargo.toml (not served here)
- memoria/crates/memoria-embedding/src/http.rs (not served here)
- memoria/crates/memoria-embedding/src/lib.rs (not served here)
- memoria/crates/memoria-embedding/src/llm.rs (not served here)
- memoria/crates/memoria-embedding/src/local.rs (not served here)
- memoria/crates/memoria-embedding/src/mock.rs (not served here)
- memoria/crates/memoria-embedding/src/round_robin.rs (not served here)
- memoria/crates/memoria-git/Cargo.toml (not served here)
- memoria/crates/memoria-git/examples/restore_cleanup.rs (not served here)
- memoria/crates/memoria-git/src/lib.rs (not served here)
- memoria/crates/memoria-git/src/service.rs (not served here)
- memoria/crates/memoria-git/tests/git_ops.rs (not served here)
- memoria/crates/memoria-git/tests/legacy_snapshot.rs (not served here)
- memoria/crates/memoria-mcp/Cargo.toml (not served here)
- memoria/crates/memoria-mcp/src/config.rs (not served here)
- memoria/crates/memoria-mcp/src/git_tools.rs (not served here)
- memoria/crates/memoria-mcp/src/lib.rs (not served here)
- memoria/crates/memoria-mcp/src/purge_args.rs (not served here)
- memoria/crates/memoria-mcp/src/remote.rs (not served here)
- memoria/crates/memoria-mcp/src/server.rs (not served here)
- memoria/crates/memoria-mcp/src/tool_result.rs (not served here)
- memoria/crates/memoria-mcp/src/tools.rs (not served here)
- memoria/crates/memoria-mcp/tests/branch_e2e.rs (not served here)
- memoria/crates/memoria-mcp/tests/branch_scope_e2e.rs (not served here)
- memoria/crates/memoria-mcp/tests/core_tools_e2e.rs (not served here)
- memoria/crates/memoria-mcp/tests/edit_log_e2e.rs (not served here)
- memoria/crates/memoria-mcp/tests/feedback_e2e.rs (not served here)
- memoria/crates/memoria-mcp/tests/graph_e2e.rs (not served here)
- memoria/crates/memoria-mcp/tests/integration_full.rs (not served here)
- memoria/crates/memoria-mcp/tests/mcp_e2e.rs (not served here)
- memoria/crates/memoria-mcp/tests/perf_optimizations_e2e.rs (not served here)
- memoria/crates/memoria-mcp/tests/snapshot_e2e.rs (not served here)
- memoria/crates/memoria-mcp/tests/support/mod.rs (not served here)
- memoria/crates/memoria-mcp/tests/support/multi_db.rs (not served here)
- memoria/crates/memoria-mcp/tests/tools_unit.rs (not served here)
- memoria/crates/memoria-service/Cargo.toml (not served here)
- memoria/crates/memoria-service/build.rs (not served here)
- memoria/crates/memoria-service/src/config.rs (not served here)
- memoria/crates/memoria-service/src/content_filter.rs (not served here)
- memoria/crates/memoria-service/src/distributed.rs (not served here)
- memoria/crates/memoria-service/src/governance.rs (not served here)
- memoria/crates/memoria-service/src/graph_domains.rs (not served here)
- memoria/crates/memoria-service/src/lib.rs (not served here)
- memoria/crates/memoria-service/src/pipeline.rs (not served here)
- memoria/crates/memoria-service/src/plugin/contract.rs (not served here)
- memoria/crates/memoria-service/src/plugin/governance_hook.rs (not served here)
- memoria/crates/memoria-service/src/plugin/grpc_runtime.rs (not served here)
- memoria/crates/memoria-service/src/plugin/manifest.rs (not served here)
- memoria/crates/memoria-service/src/plugin/mod.rs (not served here)
- memoria/crates/memoria-service/src/plugin/repository.rs (not served here)
- memoria/crates/memoria-service/src/plugin/rhai_runtime.rs (not served here)
- memoria/crates/memoria-service/src/plugin/template.rs (not served here)
- memoria/crates/memoria-service/src/plugin/templates/governance_plugin.rhai (not served here)
- memoria/crates/memoria-service/src/plugin_registry.rs (not served here)
- memoria/crates/memoria-service/src/rebuild_worker.rs (not served here)
- memoria/crates/memoria-service/src/scheduler.rs (not served here)
- memoria/crates/memoria-service/src/scoring.rs (not served here)
- memoria/crates/memoria-service/src/service.rs (not served here)
- memoria/crates/memoria-service/src/stats_reporter.rs (not served here)
- memoria/crates/memoria-service/src/strategy.rs (not served here)
- memoria/crates/memoria-service/src/strategy_domain.rs (not served here)
- memoria/crates/memoria-service/src/vector_index_monitor.rs (not served here)
- memoria/crates/memoria-service/tests/data/plugins/governance-audit-note/manifest.json (not served here)
- memoria/crates/memoria-service/tests/data/plugins/governance-audit-note/plugin.rhai (not served here)
- memoria/crates/memoria-service/tests/data/plugins/governance-weekly-approval/manifest.json (not served here)
- memoria/crates/memoria-service/tests/data/plugins/governance-weekly-approval/plugin.rhai (not served here)
- memoria/crates/memoria-service/tests/governance_pool_budget_e2e.rs (not served here)
- memoria/crates/memoria-service/tests/idempotent_store_db_it.rs (not served here)
- memoria/crates/memoria-service/tests/plugin_contract.rs (not served here)
- memoria/crates/memoria-service/tests/plugin_repository.rs (not served here)
- memoria/crates/memoria-service/tests/service_unit.rs (not served here)
- memoria/crates/memoria-service/tests/shared_store_isolation_db_it.rs (not served here)
- memoria/crates/memoria-service/tests/subject_id_filter.rs (not served here)
- memoria/crates/memoria-service/tests/subject_id_mo_e2e.rs (not served here)
- memoria/crates/memoria-storage/Cargo.toml (not served here)
- memoria/crates/memoria-storage/src/branch_capability.rs (not served here)
- memoria/crates/memoria-storage/src/graph/activation.rs (not served here)
- memoria/crates/memoria-storage/src/graph/backfill.rs (not served here)
- memoria/crates/memoria-storage/src/graph/consolidation.rs (not served here)
- memoria/crates/memoria-storage/src/graph/mod.rs (not served here)
- memoria/crates/memoria-storage/src/graph/ner.rs (not served here)
- memoria/crates/memoria-storage/src/graph/retriever.rs (not served here)
- memoria/crates/memoria-storage/src/graph/store.rs (not served here)
- memoria/crates/memoria-storage/src/graph/types.rs (not served here)
- memoria/crates/memoria-storage/src/keyed_gates.rs (not served here)
- memoria/crates/memoria-storage/src/lib.rs (not served here)
- memoria/crates/memoria-storage/src/migration.rs (not served here)
- memoria/crates/memoria-storage/src/pool_config.rs (not served here)
- memoria/crates/memoria-storage/src/router.rs (not served here)
- memoria/crates/memoria-storage/src/store.rs (not served here)
- memoria/crates/memoria-storage/src/table_schema.rs (not served here)
- memoria/crates/memoria-storage/tests/branch_ops.rs (not served here)
- memoria/crates/memoria-storage/tests/call_log_schema_upgrade.rs (not served here)
- memoria/crates/memoria-storage/tests/concurrent_lock.rs (not served here)
- memoria/crates/memoria-storage/tests/lock_behavior.rs (not served here)
- memoria/crates/memoria-storage/tests/mo_compat.rs (not served here)
- memoria/crates/memoria-storage/tests/mo_correct.rs (not served here)
- memoria/crates/memoria-storage/tests/prepare_cancellation.rs (not served here)
- memoria/crates/memoria-storage/tests/router_initialization_recovery.rs (not served here)
- memoria/crates/memoria-storage/tests/router_multi_db.rs (not served here)
- memoria/crates/memoria-storage/tests/schema_meta_visibility.rs (not served here)
- memoria/crates/memoria-storage/tests/session_consistency.rs (not served here)
- memoria/crates/memoria-storage/tests/statement_cache.rs (not served here)
- memoria/crates/memoria-storage/tests/store_crud.rs (not served here)
- memoria/crates/memoria-storage/tests/subject_id_mo_compat.rs (not served here)
- memoria/crates/memoria-storage/tests/support/command_order_proxy.rs (not served here)
- memoria/crates/memoria-storage/tests/support/initialization_fault_proxy.rs (not served here)
- memoria/crates/memoria-storage/tests/support/mysql_packet.rs (not served here)
- memoria/crates/memoria-storage/tests/support/prepare_pause_proxy.rs (not served here)
- memoria/crates/memoria-storage/tests/vector_index_ops.rs (not served here)
- memoria/crates/memoria-test-utils/Cargo.toml (not served here)
- memoria/crates/memoria-test-utils/src/lib.rs (not served here)
- memoria/docs/git-for-data-rfc.md (not served here)
- memoria/proto/memoria/plugin/v1/strategy.proto (not served here)
- memoria/vendor/sqlx-mysql/.cargo-ok (not served here)
- memoria/vendor/sqlx-mysql/.cargo_vcs_info.json (not served here)
- memoria/vendor/sqlx-mysql/Cargo.toml (not served here)
- memoria/vendor/sqlx-mysql/Cargo.toml.orig (not served here)
- memoria/vendor/sqlx-mysql/LICENSE-APACHE
- memoria/vendor/sqlx-mysql/LICENSE-MIT
- memoria/vendor/sqlx-mysql/src/any.rs (not served here)
- memoria/vendor/sqlx-mysql/src/arguments.rs (not served here)
- memoria/vendor/sqlx-mysql/src/collation.rs (not served here)
- memoria/vendor/sqlx-mysql/src/column.rs (not served here)
- memoria/vendor/sqlx-mysql/src/connection/auth.rs (not served here)
- memoria/vendor/sqlx-mysql/src/connection/establish.rs (not served here)
- memoria/vendor/sqlx-mysql/src/connection/executor.rs (not served here)
- memoria/vendor/sqlx-mysql/src/connection/mod.rs (not served here)
- memoria/vendor/sqlx-mysql/src/connection/stream.rs (not served here)
- memoria/vendor/sqlx-mysql/src/connection/tls.rs (not served here)
- memoria/vendor/sqlx-mysql/src/database.rs (not served here)
- memoria/vendor/sqlx-mysql/src/error.rs (not served here)
- memoria/vendor/sqlx-mysql/src/io/buf.rs (not served here)
- memoria/vendor/sqlx-mysql/src/io/buf_mut.rs (not served here)
- memoria/vendor/sqlx-mysql/src/io/mod.rs (not served here)
- memoria/vendor/sqlx-mysql/src/lib.rs (not served here)
- memoria/vendor/sqlx-mysql/src/migrate.rs (not served here)
- memoria/vendor/sqlx-mysql/src/options/connect.rs (not served here)
- memoria/vendor/sqlx-mysql/src/options/mod.rs (not served here)
- memoria/vendor/sqlx-mysql/src/options/parse.rs (not served here)
- memoria/vendor/sqlx-mysql/src/options/ssl_mode.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/auth.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/capabilities.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/connect/auth_switch.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/connect/handshake.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/connect/handshake_response.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/connect/mod.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/connect/ssl_request.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/mod.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/packet.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/response/eof.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/response/err.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/response/mod.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/response/ok.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/response/status.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/row.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/statement/execute.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/statement/mod.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/statement/prepare.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/statement/prepare_ok.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/statement/row.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/statement/stmt_close.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/text/column.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/text/mod.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/text/ping.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/text/query.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/text/quit.rs (not served here)
- memoria/vendor/sqlx-mysql/src/protocol/text/row.rs (not served here)
- memoria/vendor/sqlx-mysql/src/query_result.rs (not served here)
- memoria/vendor/sqlx-mysql/src/row.rs (not served here)
- memoria/vendor/sqlx-mysql/src/statement.rs (not served here)
- memoria/vendor/sqlx-mysql/src/testing/mod.rs (not served here)
- memoria/vendor/sqlx-mysql/src/transaction.rs (not served here)
- memoria/vendor/sqlx-mysql/src/type_checking.rs (not served here)
- memoria/vendor/sqlx-mysql/src/type_info.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/bigdecimal.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/bool.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/bytes.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/chrono.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/float.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/inet.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/int.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/json.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/mod.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/mysql_time.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/rust_decimal.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/str.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/text.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/time.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/uint.rs (not served here)
- memoria/vendor/sqlx-mysql/src/types/uuid.rs (not served here)
- memoria/vendor/sqlx-mysql/src/value.rs (not served here)
- plugins/clawhub/thememoria/SKILL.md (not served here)
- plugins/clawhub/thememoria/references/operations.md (not served here)
- plugins/clawhub/thememoria/references/patterns.md (not served here)
- plugins/clawhub/thememoria/references/setup.md (not served here)
- plugins/clawhub/thememoria/references/tool-surface.md (not served here)
- plugins/hermes/CLOUD_ACCEPTANCE.md (not served here)
- plugins/hermes/LICENSE
- plugins/hermes/README.md (not served here)
- plugins/hermes/README.zh-CN.md (not served here)
- plugins/hermes/RELEASE.md (not served here)
- plugins/hermes/REVIEW_FIXES.md (not served here)
- plugins/hermes/__init__.py (not served here)
- plugins/hermes/client.py (not served here)
- plugins/hermes/config.py (not served here)
- plugins/hermes/config_schema.py (not served here)
- plugins/hermes/diagnostics.py (not served here)
- plugins/hermes/outbox.py (not served here)
- plugins/hermes/plugin.yaml (not served here)
- plugins/hermes/pyproject.toml (not served here)
- plugins/hermes/tests/cloud_smoke.py (not served here)
- plugins/hermes/tests/conftest.py (not served here)
- plugins/hermes/tests/test_capture_dedup.py (not served here)
- plugins/hermes/tests/test_client_config.py (not served here)
- plugins/hermes/tests/test_cloud_smoke.py (not served here)
- plugins/hermes/tests/test_diagnostics.py (not served here)
- plugins/hermes/tests/test_provider.py (not served here)
- plugins/hermes/tests/test_reliability.py (not served here)
- plugins/hermes/tools.py (not served here)
- plugins/openclaw/.gitignore (not served here)
- plugins/openclaw/README.md (not served here)
- plugins/openclaw/docs/memoria-session-storybook.md (not served here)
- plugins/openclaw/openclaw.plugin.json (not served here)
- plugins/openclaw/openclaw/__tests__/batch-purge.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/branch-identity.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/branch-tool-selector.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/cache-invalidation.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/client.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/config.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/format.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/helpers.ts (not served here)
- plugins/openclaw/openclaw/__tests__/http-client.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/list-pagination.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/memory-id-url.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/mutation-whitespace.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/parsers.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/redirect-boundary.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/score.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/snapshot-pagination.test.ts (not served here)
- plugins/openclaw/openclaw/__tests__/snapshot-response.test.ts (not served here)
- plugins/openclaw/openclaw/client.ts (not served here)
- plugins/openclaw/openclaw/config.ts (not served here)
- plugins/openclaw/openclaw/format.ts (not served here)
- plugins/openclaw/openclaw/http-client.ts (not served here)
- plugins/openclaw/openclaw/index.ts (not served here)
- plugins/openclaw/openclaw/score.ts (not served here)
- plugins/openclaw/package-lock.json (not served here)
- plugins/openclaw/package.json (not served here)
- plugins/openclaw/scripts/build-plugin.mjs (not served here)
- plugins/openclaw/scripts/connect_openclaw_memoria.mjs (not served here)
- plugins/openclaw/scripts/install-openclaw-memoria.sh (not served here)
- plugins/openclaw/scripts/sync-version.mjs (not served here)
- plugins/openclaw/scripts/uninstall-openclaw-memoria.sh (not served here)
- plugins/openclaw/scripts/verify-package.mjs (not served here)
- plugins/openclaw/scripts/verify-packed-files.mjs (not served here)
- plugins/openclaw/scripts/verify_plugin_install.mjs (not served here)
- plugins/openclaw/skills/memoria-memory/SKILL.md (not served here)
- plugins/openclaw/skills/memoria-recovery/SKILL.md (not served here)
- plugins/openclaw/tsconfig.json (not served here)
- plugins/openclaw/vitest.config.ts (not served here)
- scripts/install.ps1 (not served here)
- scripts/install.sh (not served here)
- sdk/python/CHANGELOG.md (not served here)
- sdk/python/README.md (not served here)
- sdk/python/docs/python_sdk_design.md (not served here)
- sdk/python/pyproject.toml (not served here)
- sdk/python/src/memoria/__init__.py (not served here)
- sdk/python/src/memoria/_http.py (not served here)
- sdk/python/src/memoria/client.py (not served here)
- sdk/python/src/memoria/exceptions.py (not served here)
- sdk/python/src/memoria/models.py (not served here)
- sdk/python/src/memoria/resources/__init__.py (not served here)
- sdk/python/src/memoria/resources/branches.py (not served here)
- sdk/python/src/memoria/resources/governance.py (not served here)
- sdk/python/src/memoria/resources/memories.py (not served here)
- sdk/python/src/memoria/resources/profile.py (not served here)
- sdk/python/src/memoria/resources/snapshots.py (not served here)
- sdk/python/tests/__init__.py (not served here)
- sdk/python/tests/conftest.py (not served here)
- sdk/python/tests/integration/README.md (not served here)
- sdk/python/tests/integration/__init__.py (not served here)
- sdk/python/tests/integration/test_e2e.py (not served here)
- sdk/python/tests/unit/__init__.py (not served here)
- sdk/python/tests/unit/test_branch_path_encoding.py (not served here)
- sdk/python/tests/unit/test_branches.py (not served here)
- sdk/python/tests/unit/test_errors.py (not served here)
- sdk/python/tests/unit/test_governance.py (not served here)
- sdk/python/tests/unit/test_memories.py (not served here)
- sdk/python/tests/unit/test_memories_async.py (not served here)
- sdk/python/tests/unit/test_memory_path_encoding.py (not served here)
- sdk/python/tests/unit/test_named_delete_retries.py (not served here)
- sdk/python/tests/unit/test_pre_send_retries.py (not served here)
- sdk/python/tests/unit/test_read_post_retries.py (not served here)
- sdk/python/tests/unit/test_response_decoding.py (not served here)
- sdk/python/tests/unit/test_retry_budget_validation.py (not served here)
- sdk/python/tests/unit/test_snapshot_path_encoding.py (not served here)
- sdk/python/tests/unit/test_snapshots.py (not served here)
- sdk/python/tests/unit/test_transport_errors.py (not served here)
- skills/api-reference/SKILL.md (not served here)
- skills/architecture/SKILL.md (not served here)
- skills/deployment/SKILL.md (not served here)
- skills/local-embedding/SKILL.md (not served here)
- skills/plugin-development/SKILL.md (not served here)
- skills/release/SKILL.md (not served here)
- skills/setup/SKILL.md (not served here)
Advantages
- Provides Git-level version control including zero-copy branching, snapshots, and point-in-time rollback for memory mutations. evidence: README.md
- Enables isolated experimentation by allowing agents to branch memory state and merge only validated findings. evidence: .cursor/rules/memory-branching-patterns.mdc
- Maintains data integrity through automatic contradiction detection and quarantine of low-confidence memories. evidence: README.md
Limitations
- Requires adherence to specific steering rules and tool usage patterns to be effective. evidence: .cursor/rules/memory.mdc
- Requires manual cleanup of stale branches to avoid cognitive overhead. evidence: .cursor/rules/memory-branching-patterns.mdc
- Retrieved memories must be verified against current context as they may be stale or incomplete. evidence: .cursor/rules/memory.mdc
Security
Risk level: Medium risk
This brain runs
Agent instructions that run or fetch something (41)
.cursor/rules/memory.mdc:If ⚠️ health warnings appear → inform the user and offer to run `memory_governance`..cursor/rules/memory.mdc:| Type | Use for | Examples | |------|---------|---------| | `semantic` | Project facts, technical decisions (default) | "Uses MatrixOne as primary DB", "API follows REST conventions" | | `profile` | User/agent identity and preferences | "Prefers concise answers", "Works on mo-dev-agen …[+460 chars].kiro/steering/memory-hygiene.md:Run `memory_governance` (1h cooldown) when you notice ANY of these:.kiro/steering/memory-hygiene.md:Run `memory_consolidate` (30min cooldown) when:.kiro/steering/memory.md:| Type | Use for | Examples | |------|---------|---------| | `semantic` | Project facts, technical decisions (default) | "Uses MatrixOne as primary DB", "API follows REST conventions" | | `profile` | User/agent identity and preferences | "Prefers concise answers", "Works on mo-dev-agen …[+460 chars].kiro/steering/session-lifecycle.md:Before your first response, run a multi-query bootstrap to load full context:.kiro/steering/skills.md:| Skill | When to use | |-------|-------------| | [Architecture](../../skills/architecture/SKILL.md) | Navigating or modifying Memoria code | | [API Reference](../../skills/api-reference/SKILL.md) | Calling or implementing REST endpoints | | [Deployment](../../skills/deployment/SKILL.m …[+385 chars]plugins/clawhub/thememoria/SKILL.md:Install or verify the OpenClaw plugin: `references/setup.md`skills/api-reference/SKILL.md:It does not generate embeddings or run vector, graph, hybrid, temporal, or confidence scoring and is intentionally not exposed as an MCP tool.skills/architecture/SKILL.md:async fn execute(&self, store, task, plan) -> Result<GovernanceExecution>;skills/architecture/SKILL.md:make check # cargo check + clippy -D warnings (MUST pass)skills/architecture/SKILL.md:make test-unit # Unit tests (no DB): memoria-core, memoria-service, memoria-mcpskills/architecture/SKILL.md:make test # All tests (needs MatrixOne, --test-threads=1)skills/architecture/SKILL.md:make test-e2e # API e2e tests onlyskills/deployment/SKILL.md:docker compose up -dskills/deployment/SKILL.md:Verify: `curl http://localhost:8100/health`· uses the networkskills/deployment/SKILL.md:Run behind reverse proxy with TLS in productionskills/local-embedding/SKILL.md:make build-localskills/local-embedding/SKILL.md:| Problem | Fix | |---------|-----| | "compiled without local-embedding" | Build from source: `make build-local` | | Model download fails | Set `HF_ENDPOINT` for mirror, or manually download to `~/.cache/fastembed/` | | High memory | Default ~100MB.skills/plugin-development/SKILL.md:"capabilities": ["governance.plan", "governance.execute"],skills/plugin-development/SKILL.md:`capabilities`: must include `governance.plan` and/or `governance.execute`skills/plugin-development/SKILL.md:if ctx["phase"] == "execute" {skills/release/SKILL.md:| Step | Who | How | |------|-----|-----| | Bump version, tag, push | You | `make release VERSION=x.y.z` | | Build binaries (4 platforms) | CI | `release-rust.yml` | | Build + push Docker image | CI | `release-docker.yml` | | Create GitHub Release | CI | `softprops/action-gh-release` |skills/release/SKILL.md:git status # Must be cleanskills/release/SKILL.md:make release VERSION=0.2.0skills/release/SKILL.md:make release-rc VERSION=0.2.0-rc1skills/release/SKILL.md:make release-docker # :latestskills/release/SKILL.md:make release-docker VERSION=0.2.0 # :0.2.0 + :latestskills/release/SKILL.md:Both release workflows run full test suite before publishing.skills/release/SKILL.md:[ ] `make release VERSION=x.y.z`skills/setup/SKILL.md:Ask: "Use Memoria Cloud, or run your own instance?"skills/setup/SKILL.md:**Memoria Cloud (recommended)** → sign up at [thememoria.ai](https://thememoria.ai/auth), get API URL + token, then proceed to Step 2· uses the networkskills/setup/SKILL.md:No → run `docker compose up -d` in the Memoria repo root (wait 30-60s for first start)skills/setup/SKILL.md:One-line install (recommended):skills/setup/SKILL.md:Or download manually from [GitHub Releases](https://github.com/matrixorigin/Memoria/releases).· uses the networkskills/setup/SKILL.md:Platform-specific manual install:skills/setup/SKILL.md:docker compose up -d # Start MatrixOneskills/setup/SKILL.md:docker ps --filter name=matrixone # Verify (wait 30-60s)skills/setup/SKILL.md:Or run: `memoria status`skills/setup/SKILL.md:| Problem | Fix | |---------|-----| | MatrixOne won't start | `docker logs memoria-matrixone` | | Port 6001 in use | Change `MO_PORT` in `.env` | | Can't connect to DB | Wait 30-60s on first start | | Docker permission denied | `sudo usermod -aG docker $USER && newgrp docker` | | Docke …[+152 chars]skills/setup/SKILL.md:Run `which memoria` to verify CLI installed 2.
Install scripts (5)
README.md:curl -sSL https://raw.githubusercontent.com/matrixorigin/Memoria/main/scripts/install.sh | bash· uses the networkREADME.md:curl -sSL https://raw.githubusercontent.com/matrixorigin/Memoria/main/scripts/install.sh | bash· uses the networkREADME.md:command -v memoria >/dev/null || curl -sSL https://raw.githubusercontent.com/matrixorigin/Memoria/main/scripts/install.sh | bash -s -- -y -d ~/.local/bin· uses the networkscripts/install.ps1:pwsh scripts/install.ps1· uses the networkscripts/install.sh:sh scripts/install.sh· uses the network
- Medium risk: runs-install-script-remote-exec (README.md:155)
- Medium risk: runs-install-script-remote-exec (README.md:175)
- Medium risk: runs-install-script-remote-exec (README.md:194)
- Medium risk: runs-install-script-network-variable-host (scripts/install.ps1)
- Medium risk: network-variable-host (scripts/install.ps1:119)
- Medium risk: network-variable-host (scripts/install.ps1:125)
- Medium risk: runs-install-script-network-variable-host (scripts/install.sh)
- Medium risk: network-variable-host (scripts/install.sh:295)
- Medium risk: runs-instruction-instruction-network (skills/setup/SKILL.md:14)
- Medium risk: remote-exec-pipe (skills/setup/SKILL.md:58)
- Medium risk: runs-instruction-instruction-network (skills/setup/SKILL.md:61)
- Low risk: scripts-present (scripts/install.ps1)
- Low risk: scripts-present (scripts/install.sh)
- Low risk: network-instructions (skills/deployment/SKILL.md:14)
- Low risk: network-instructions (skills/setup/SKILL.md:58)
Attribution and licence
- Created by
- Matrix Origin
- Publisher
- Matrix Origin (Official Matrix Origin project)
- Source
- matrixorigin/memoria · commit 93ccccf
- Licence
- Apache License 2.0 (files served here)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Matrix Origin.
Install from source
445 of its files are not served here, so there is no ZIP. matrixorigin/memoria at 93ccccf