# memrust - Doramagic AI Context Pack

> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。

## 充分原则

- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。
- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。

## 给宿主 AI 的使用方式

你正在读取 Doramagic 为 memrust 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。

## Claim 消费规则

- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。
- **事实最低状态**：`supported`
- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。
- `weak`：只能作为低置信度线索，必须要求用户继续核实。
- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。
- `unverified`：不得作为事实使用，应明确说证据不足。
- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。

## 它最适合谁

- **AI 研究者或研究型 Agent 构建者**：README 明确围绕研究、实验或论文工作流展开。 证据：`README.md` Claim：`clm_0002` supported 0.86
- **正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**：README 或插件配置提到多个宿主 AI。 证据：`README.md` Claim：`clm_0003` supported 0.86

## 它能做什么

- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md` Claim：`clm_0001` supported 0.86

## 怎么开始

- `pip install memrust          # Python` 证据：`README.md` Claim：`clm_0004` supported 0.86
- `npm install memrust-client   # TypeScript` 证据：`README.md` Claim：`clm_0005` supported 0.86
- `curl localhost:7700/v1/recall \` 证据：`README.md` Claim：`clm_0006` supported 0.86
- `claude mcp add memory -- memrust mcp --data-dir ~/.memrust --agent-id planner` 证据：`README.md` Claim：`clm_0007` supported 0.86
- `claude mcp add memory -- ./target/release/memrust mcp --data-dir ~/.memrust` 证据：`README.md` Claim：`clm_0008` supported 0.86
- `curl -X POST localhost:7700/v1/remember -H 'content-type: application/json' \` 证据：`README.md` Claim：`clm_0009` supported 0.86
- `curl -X POST localhost:7700/v1/recall -H 'content-type: application/json' \` 证据：`README.md` Claim：`clm_0010` supported 0.86
- `curl -X POST localhost:7700/v1/ingest -H 'content-type: application/json' \` 证据：`README.md` Claim：`clm_0011` supported 0.86
- `curl -X POST localhost:7700/v1/remember_batch -H 'content-type: application/json' \` 证据：`README.md` Claim：`clm_0012` supported 0.86

## 继续前判断卡

- **当前建议**：需要管理员/安全审批
- **为什么**：继续前可能涉及密钥、账号、外部服务或敏感上下文，建议先经过管理员或安全审批。

### 30 秒判断

- **现在怎么做**：需要管理员/安全审批
- **最小安全下一步**：先跑 Prompt Preview；若涉及凭证或企业环境，先审批再试装
- **先别相信**：真实输出质量不能在安装前相信。
- **继续会触碰**：命令执行、本地环境或项目文件、环境变量 / API Key

### 现在可以相信

- **适合人群线索：AI 研究者或研究型 Agent 构建者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86
- **适合人群线索：正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0003` supported 0.86
- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86
- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0004` supported 0.86

### 现在还不能相信

- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。
- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。
- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。
- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。
- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。
- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。
- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`README.md`

### 继续会触碰什么

- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`
- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`
- **环境变量 / API Key**：项目入口文档明确出现 API key、token、secret 或账号凭证配置。 原因：如果真实安装需要凭证，应先使用测试凭证并经过权限/合规判断。 证据：`README.md`
- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。

### 最小安全下一步

- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）
- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）
- **不要使用真实生产凭证**：环境变量/API key 一旦进入宿主或工具链，可能产生账号和合规风险。（适用：出现 API、TOKEN、KEY、SECRET 等环境线索时。）
- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）

### 退出方式

- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。
- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。
- **准备撤销测试 API key 或 token**：测试凭证泄露或误用时，可以快速止损。
- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。

## 哪些只能预览

- 解释项目适合谁和能做什么
- 基于项目文档演示典型对话流程
- 帮助用户判断是否值得安装或继续研究

## 哪些必须安装后验证

- 真实安装 Skill、插件或 CLI
- 执行脚本、修改本地文件或访问外部服务
- 验证真实输出质量、性能和兼容性

## 边界与风险判断卡

- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0013` inferred 0.45
- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0014` supported 0.86
- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。
- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。
- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。

## 开工前工作上下文

### 加载顺序

- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。
- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。
- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。
- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。
- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。

### 任务路由

- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86

### 上下文规模

- 文件总数：51
- 重要文件覆盖：40/51
- 证据索引条目：47
- 角色 / Skill 条目：5

### 证据不足时的处理

- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。
- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。
- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。
- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。

## Prompt Recipes

### 适配判断

- 目标：判断这个项目是否适合用户当前任务。
- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。

```text
请基于 memrust 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。
```

### 安装前体验

- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。
- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。

```text
请把 memrust 当作安装前体验资产，而不是已安装工具或真实运行环境。

请严格输出四段：
1. 先问我 3 个必要问题。
2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。
3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。
4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。

硬性边界：
- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。
- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。
- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。
- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。
- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。
- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。

```

### 角色 / Skill 选择

- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。
- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。

```text
请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。
```

### 风险预检

- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。
- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。

```text
请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。
```

### 宿主 AI 开工指令

- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。
- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。

```text
请基于 memrust 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。
```

## 角色 / Skill 索引

- 共索引 5 个角色 / Skill / 项目文档条目。

- **memrust**（project_doc）：Memory infrastructure for AI agents — an agent-native memory engine, written in Rust. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`
- **Benchmarks**（project_doc）：Two scripts, both reproducible. Numbers in the project README came from these on an M-series MacBook — re-run them on your hardware before trusting any of it. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`benches/README.md`
- **memrust notebooks**（project_doc）：Three runnable notebooks. Everything installs with pip; the engine downloads as a single static binary no Rust toolchain needed . 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`notebooks/README.md`
- **memrust on HaluMem**（project_doc）：HaluMem https://github.com/MemTensor/HaluMem is an operation-level hallucination benchmark for agent memory systems. Instead of scoring a memory system end-to-end, it scores three stages separately — memory extraction , memory updating , and memory question answering — so a failure can be located rather than merely observed. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`benches/halumem/README.md`
- **Changelog**（project_doc）：- Optional extraction layer , behind --extractor openai and POST /v1/ingest . Hand it an exchange and a model distils durable facts out of it, so callers no longer have to decide what is worth remembering themselves. Off by default, and remember is untouched: with no extractor configured the write path has no model in it and nothing about the engine's behaviour changes. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CHANGELOG.md`

## 证据索引

- 共索引 47 条证据。

- **memrust**（documentation）：Memory infrastructure for AI agents — an agent-native memory engine, written in Rust. 证据：`README.md`
- **Benchmarks**（documentation）：Two scripts, both reproducible. Numbers in the project README came from these on an M-series MacBook — re-run them on your hardware before trusting any of it. 证据：`benches/README.md`
- **memrust notebooks**（documentation）：Three runnable notebooks. Everything installs with pip; the engine downloads as a single static binary no Rust toolchain needed . 证据：`notebooks/README.md`
- **memrust on HaluMem**（documentation）：HaluMem https://github.com/MemTensor/HaluMem is an operation-level hallucination benchmark for agent memory systems. Instead of scoring a memory system end-to-end, it scores three stages separately — memory extraction , memory updating , and memory question answering — so a failure can be located rather than merely observed. 证据：`benches/halumem/README.md`
- **Package**（package_manifest）：{ "name": "memrust-client", "version": "0.6.1", "description": "Zero-dependency TypeScript client for the memrust agent memory engine", "license": "Apache-2.0", "type": "module", "main": "./dist/index.js", "types": "./dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" } }, "files": "dist", "src" , "scripts": { "build": "tsc -p .", "prepublishOnly": "npm run build" }, "devDependencies": { "typescript": "^5.6.0" }, "engines": { "node": " =18" } } 证据：`sdks/typescript/package.json`
- **License**（source_file）：Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ 证据：`LICENSE`
- **Changelog**（documentation）：- Optional extraction layer , behind --extractor openai and POST /v1/ingest . Hand it an exchange and a model distils durable facts out of it, so callers no longer have to decide what is worth remembering themselves. Off by default, and remember is untouched: with no extractor configured the write path has no model in it and nothing about the engine's behaviour changes. 证据：`CHANGELOG.md`
- **.dockerignore**（source_file）：target /target memrust-data .git .env .env. sdks assets 证据：`.dockerignore`
- **Cargo**（source_file）：package name = "memrust" version = "0.6.1" edition = "2021" description = "Agent-native memory engine: hybrid retrieval HNSW + BM25 + entity graph + recency behind remember/recall/forget, with HTTP and MCP interfaces" license = "Apache-2.0" repository = "https://github.com/AIAnytime/memrust" readme = "README.md" keywords = "ai", "agents", "memory", "vector-search", "mcp" categories = "database-implementations", "data-structures" exclude = "assets/", "control-plane/", "notebooks/", ".github/", "sdks/", "Dockerfile", ".dockerignore", 证据：`Cargo.toml`
- **Embed**（source_file）：use std::collections::hash map::DefaultHasher; ⋮---- use std::time::Duration; ⋮---- use crate::index::text::tokenize; use crate::index::vector::normalize; ⋮---- pub trait Embedder: Send + Sync { ⋮---- fn embed batch &self, texts: & &str - Result { texts.iter .map t self.embed t .collect ⋮---- fn embed query &self, text: &str - Result { self.embed text ⋮---- pub struct HashEmbedder { ⋮---- impl HashEmbedder { pub fn new dim: usize - Self { ⋮---- fn bump &self, v: &mut f32 , feature: &str, weight: f32 { ⋮---- feature.hash &mut h ; let hash = h.finish ; ⋮---- impl Embedder for HashEmbedder { fn dim &self - usize { ⋮---- fn embed &self, text: &str - Result { let mut v = vec! 0.0f32; self.dim ;… 证据：`src/embed.rs`
- **Engine**（source_file）：use std::path::Path; ⋮---- use serde json::json; use uuid::Uuid; ⋮---- use crate::index::text::Bm25Index; ⋮---- use crate::rerank::Reranker; ⋮---- fn is expired record: &MemoryRecord, now: i64 - bool { record.expires at.is some and t t f32 { ⋮---- pub struct IngestPlan { ⋮---- fn check request req: &RememberRequest - Result { if req.text.trim .is empty { bail! "memory text must not be empty" ; ⋮---- bail! "created at must be a positive Unix timestamp in milliseconds, got {ts}" ; ⋮---- bail! ⋮---- Ok ⋮---- fn visible to record: &MemoryRecord, as agent: Option - bool { ⋮---- record.agent id.is none record.agent id.as deref == Some agent ⋮---- struct CheckpointRef { ⋮---- struct CheckpointOwne… 证据：`src/engine.rs`
- **Lib**（source_file）：pub mod embed; pub mod engine; pub mod extract; pub mod index; pub mod rerank; pub mod server; pub mod store; pub mod summarize; pub mod types; ⋮---- pub use engine::MemoryEngine; 证据：`src/lib.rs`
- **Main**（source_file）：use std::path::PathBuf; use std::sync::Arc; ⋮---- use memrust::engine::MemoryEngine; use memrust::extract::LlmExtractor; ⋮---- use memrust::rerank::LlmReranker; ⋮---- fn build summarizer args: & String - Result { match flag args, "--summarizer", "extract" .as str { "extract" = Ok Box::new ExtractiveSummarizer::default , ⋮---- let url = flag args, "--summarizer-url", "https://api.openai.com/v1" ; let model = flag args, "--summarizer-model", "gpt-4o-mini" ; ⋮---- .or else std::env::var "OPENAI API KEY" .unwrap or default ; Ok Box::new RemoteSummarizer::openai compatible ⋮---- other = bail! "unknown summarizer '{other}' expected extract or openai " , ⋮---- fn numeric flag args: & String , name… 证据：`src/main.rs`
- **Rerank**（source_file）：use std::time::Duration; ⋮---- pub trait Reranker: Send + Sync { ⋮---- pub struct LlmReranker { ⋮---- impl LlmReranker { pub fn openai compatible base url: &str, model: &str, api key: &str - Self { ⋮---- url: format! "{}/chat/completions", base url.trim end matches '/' , model: model.to string , api key: api key.to string , ⋮---- .timeout Duration::from secs 60 .build , ⋮---- impl Reranker for LlmReranker { fn rerank &self, query: &str, docs: & &str - Result { if docs.is empty { return Ok Vec::new ; ⋮---- .iter .enumerate .map i, d format! "{}. {d}", i + 1 ⋮---- .join "\n" ; let mut req = self.agent.post &self.url ; if !self.api key.is empty { req = req.set "authorization", &format! "Bearer… 证据：`src/rerank.rs`
- **Summarize**（source_file）：use std::time::Duration; ⋮---- use crate::index::text::tokenize; ⋮---- pub trait Summarizer: Send + Sync { ⋮---- pub struct ExtractiveSummarizer { ⋮---- impl Default for ExtractiveSummarizer { fn default - Self { ⋮---- impl Summarizer for ExtractiveSummarizer { fn summarize &self, memories: & &str - Result { if memories.is empty { bail! "nothing to summarize" ; ⋮---- .iter .map m { let tokens = tokenize m ; let set = tokens.iter .cloned .collect ; ⋮---- .collect ; ⋮---- df.entry t.as str .or insert 0 += 1; ⋮---- .enumerate .map i, tokens, set { let mass: f32 = set.iter .map t df t.as str as f32 .sum ; mass / tokens.len as f32 + 3.0 , i ⋮---- scored.sort by a, b b.0.total cmp &a.0 ; ⋮---- le… 证据：`src/summarize.rs`
- **Types**（source_file）：use uuid::Uuid; ⋮---- pub enum MemoryKind { ⋮---- pub enum Visibility { ⋮---- pub struct MemoryRecord { ⋮---- pub struct RememberRequest { ⋮---- pub enum RecallStrategy { ⋮---- impl RecallStrategy { ⋮---- pub fn weights self - f32, f32, f32, f32 { ⋮---- pub struct MemoryFilter { ⋮---- impl MemoryFilter { ⋮---- pub fn is empty &self - bool { self.kinds.is empty && self.tags.is empty && self.session id.is none && self.agent id.is none && self.since.is none && self.until.is none ⋮---- pub fn matches &self, rec: &MemoryRecord - bool { if !self.kinds.is empty && !self.kinds.contains &rec.kind { ⋮---- if rec.session id.as deref != Some s.as str { ⋮---- if rec.agent id.as deref != Some a.as str {… 证据：`src/types.rs`
- **The conversation's own time, so recency decays from when the turn**（source_file）：MEMRUST URL = os.getenv "MEMRUST URL", "http://127.0.0.1:7801" ⋮---- TEMPLATE MEMRUST = """Memories for user {user id}: ⋮---- def post path: str, body: dict, namespace: str, timeout: float = 120.0 - dict ⋮---- req = urllib.request.Request last = None ⋮---- last = e ⋮---- DATE FORMAT = "%b %d, %Y, %H:%M:%S" ⋮---- def to unix ms stamp: str ⋮---- dt = datetime.strptime stamp, DATE FORMAT .replace tzinfo=timezone.utc ⋮---- def add dialogue namespace: str, turns: list, session idx: int - float ⋮---- items = ⋮---- The conversation's own time, so recency decays from when the turn happened rather than from when this import ran. ⋮---- items = {k: v for k, v in it.items if v is not None} for it in it… 证据：`benches/halumem/eval_memrust.py`
- **-- core API ----------------------------------------------------------**（source_file）：all = "MemrustClient", "MemrustError" version = "0.6.1" ⋮---- class MemrustError RuntimeError ⋮---- def clean d: dict str, Any - dict str, Any ⋮---- class MemrustClient ⋮---- def request self, method: str, path: str, body: Optional dict = None - dict ⋮---- headers = {"content-type": "application/json"} ⋮---- req = urllib.request.Request ⋮---- -- core API ---------------------------------------------------------- ⋮---- def health self - dict ⋮---- """Engine stats: memory counts, index sizes, WAL tail length.""" ⋮---- body = clean ⋮---- def remember batch self, items: list dict - list dict ⋮---- stamped = ⋮---- item = dict item ⋮---- def forget self, memory id: str - bool ⋮---- def run lifecy… 证据：`sdks/python/memrust.py`
- **Pyproject**（source_file）：build-system requires = "setuptools =61" build-backend = "setuptools.build meta" 证据：`sdks/python/pyproject.toml`
- **Index**（source_file）：export type MemoryKind = "episodic" "semantic" "working" "reflection" "tool call" "procedural"; ⋮---- export type RecallStrategy = "balanced" "semantic" "lexical" "recent" "relational"; ⋮---- export type Visibility = "private" "shared"; ⋮---- export interface MemoryRecord { id: string; kind: MemoryKind; text: string; created at: number; importance: number; expires at?: number; sources?: string ; entities?: string ; tags?: string ; session id?: string; agent id?: string; visibility: Visibility; metadata?: unknown; } ⋮---- export interface RecallSignals { vector: number; lexical: number; graph: number; recency: number; importance: number; rerank: number; } ⋮---- export interface RecallHit { r… 证据：`sdks/typescript/src/index.ts`
- **Graph**（source_file）：use uuid::Uuid; ⋮---- fn is stopword w: &str - bool { STOPWORDS.contains &w.to lowercase .as str ⋮---- pub fn extract entities text: &str, tags: & String - Vec { ⋮---- let key = e.to lowercase ; if key.len = 2 && seen.insert key.clone && out.len = text.split whitespace .collect ; ⋮---- .iter .map w w.trim matches c: char !c.is alphanumeric && c != '-' .collect ; ⋮---- let mut chars = w.chars ; match chars.next { Some c if c.is uppercase = chars.all c c.is lowercase c.is numeric , ⋮---- while i = 3 { push w.to string ; ⋮---- if w.len = 2 && w.len bool { self.entity records.is empty ⋮---- pub fn entity count &self - usize { self.entity records.len ⋮---- pub fn top entities &self, limit: usize… 证据：`src/index/graph.rs`
- **Mod**（source_file）：pub mod graph; pub mod text; pub mod vector; 证据：`src/index/mod.rs`
- **Text**（source_file）：use std::collections::HashMap; ⋮---- pub fn tokenize text: &str - Vec { text.to lowercase .split c: char !c.is alphanumeric .filter t !t.is empty .map t t.to string .collect ⋮---- pub struct Bm25Index { ⋮---- impl Default for Bm25Index { fn default - Self { ⋮---- impl Bm25Index { pub fn new - Self { ⋮---- pub fn len &self - usize { ⋮---- pub fn is empty &self - bool { ⋮---- pub fn add &mut self, text: &str - usize { let id = self.doc len.len ; let tokens = tokenize text ; ⋮---- tf.entry t.clone .or insert 0 += 1; ⋮---- self.postings.entry term .or default .push id, freq ; ⋮---- self.doc len.push tokens.len as u32 ; self.deleted.push false ; ⋮---- self.live len += tokens.len as u64; ⋮---- pu… 证据：`src/index/text.rs`
- **derive Debug, Serialize, Deserialize**（source_file）：use std::cmp::Reverse; ⋮---- struct Ord32 f32 ; ⋮---- impl Eq for Ord32 {} impl PartialOrd for Ord32 { fn partial cmp &self, other: &Self - Option { Some self.cmp other ⋮---- impl Ord for Ord32 { fn cmp &self, other: &Self - std::cmp::Ordering { self.0.total cmp &other.0 ⋮---- pub fn normalize v: &mut f32 { let norm = v.iter .map x x x .sum:: .sqrt ; ⋮---- for x in v.iter mut { ⋮---- pub fn dot a: & f32 , b: & f32 - f32 { let n = a.len .min b.len ; ⋮---- acc l = a i + l .mul add b i + l , acc l ; ⋮---- let mut sum: f32 = acc.iter .sum ; ⋮---- fn dot codes q: & f32 , codes: & u8 - f32 { let n = q.len .min codes.len ; ⋮---- acc l = q i + l .mul add codes i + l as f32, acc l ; ⋮---- fn dist f3… 证据：`src/index/vector.rs`
- **toast {**（source_file）：memrust dashboard // Apply the saved theme before first paint so there is no flash. try { var t = localStorage.getItem "memrust-theme" ; if t document.documentElement.setAttribute "data-theme", t ; } catch e {} / Light and dark are each selected against their own surface, not auto-inverted. Both signal palettes pass the categorical checks lightness band, chroma floor, CVD separation, normal-vision floor . Two light slots sit under 3:1 contrast, which is why every signal track carries a visible name and numeric value — identity never rests on color alone. / :root { color-scheme: light; --page: f5f5f3; --surface: ffffff; --surface-2: f1f0ed; --border: e0dfda; --text: 16160f; --text-2: 52514e;… 证据：`src/server/dashboard.html`
- **Http**（source_file）：use std::sync::Arc; ⋮---- use axum::middleware::Next; ⋮---- use serde::Deserialize; use serde json::json; use uuid::Uuid; ⋮---- fn without embedding mut record: MemoryRecord - MemoryRecord { ⋮---- pub struct AppState { ⋮---- type Rejection = StatusCode, String ; ⋮---- impl AppState { ⋮---- fn resolve &self, headers: &HeaderMap - Result { let namespace = extract namespace headers ; if self.auth.enabled { let presented = extract key headers .ok or ⋮---- .to string , ⋮---- .authenticate &presented .ok or StatusCode::UNAUTHORIZED, "invalid API key".to string ?; if !key.may access &namespace { return Err ⋮---- format! "this key is not scoped to namespace '{namespace}'" , ⋮---- .get or create &na… 证据：`src/server/http.rs`
- **Mcp**（source_file）：use uuid::Uuid; ⋮---- use crate::engine::MemoryEngine; ⋮---- type Shared = Arc ; ⋮---- pub fn run engine: Shared, agent id: Option - anyhow::Result { ⋮---- for line in stdin.lock .lines { ⋮---- if line.trim .is empty { ⋮---- let Some id = msg.get "id" .cloned else { ⋮---- let method = msg.get "method" .and then Value::as str .unwrap or "" ; let params = msg.get "params" .cloned .unwrap or Value::Null ; ⋮---- "initialize" = Ok json! { ⋮---- "ping" = Ok json! {} , "tools/list" = Ok tools list , "tools/call" = tools call &engine, &params, agent id.as deref , = Err -32601, format! "method not found: {method}" , ⋮---- Ok result = json! { "jsonrpc": "2.0", "id": id, "result": result } , Err code,… 证据：`src/server/mcp.rs`
- **default**（source_file）：use std::collections::HashMap; ⋮---- use std::time::Instant; ⋮---- use crate::server::tenancy::Registry; ⋮---- struct Histogram { counts: u64; BUCKETS.len , ⋮---- impl Histogram { fn record &mut self, seconds: f64 { ⋮---- for i, edge in BUCKETS.iter .enumerate { ⋮---- pub struct Metrics { ⋮---- impl Default for Metrics { fn default - Self { ⋮---- impl Metrics { pub fn new - Self { ⋮---- pub fn record &self, route: &str, status: u16, seconds: f64 { ⋮---- .lock .expect "metrics lock" .entry route.to string , status .or insert 0 += 1; ⋮---- .entry route.to string .or default .record seconds ; ⋮---- self.unauthorized.fetch add 1, Ordering::Relaxed ; ⋮---- pub fn render &self, registry: &Registr… 证据：`src/server/metrics.rs`
- **Mod**（source_file）：pub mod http; pub mod mcp; pub mod metrics; pub mod tenancy; 证据：`src/server/mod.rs`
- **Tenancy**（source_file）：use std::collections::HashMap; use std::path::PathBuf; ⋮---- use crate::embed::Embedder; use crate::engine::MemoryEngine; use crate::index::vector::HnswConfig; use crate::extract::Extractor; use crate::rerank::Reranker; use crate::summarize::Summarizer; use crate::types::LifecycleConfig; ⋮---- pub type MakeEmbedder = Box Result + Send + Sync ; pub type MakeSummarizer = Box Result + Send + Sync ; pub type MakeReranker = Box Box + Send + Sync ; ⋮---- pub type MakeExtractor = Box Arc + Send + Sync ; ⋮---- pub struct EngineFactory { ⋮---- pub struct Namespace { ⋮---- pub struct Registry { ⋮---- impl Registry { pub fn new root: PathBuf, factory: EngineFactory - Self { let legacy root = root.join… 证据：`src/server/tenancy.rs`
- **Test E2E**（source_file）：BASE = os.environ.get "MEMRUST URL", "http://127.0.0.1:7700" ⋮---- planner = MemrustClient BASE, agent id="planner" researcher = MemrustClient BASE, agent id="researcher" operator = MemrustClient BASE ⋮---- seen = h "record" "text" for h in researcher.recall "Initech pricing strategy" ⋮---- seen = h "record" "text" for h in planner.recall "Initech pricing strategy" ⋮---- hits = operator.recall "Initech pricing", top k=5 ⋮---- records = operator.remember batch ⋮---- snap = operator.snapshot "ops" ⋮---- stats = operator.health ⋮---- victim = records 0 "id" 证据：`sdks/python/test_e2e.py`
- **Pilot Qa Score**（structured_config）：{ "overall score": { "frame": "memrust", "qa num": 164, "qa valid num": 164, "correct qa ratio": { "all": 0.7621951219512195, "valid": 0.7621951219512195 }, "hallucination qa ratio": { "all": 0.13414634146341464, "valid": 0.13414634146341464 }, "omission qa ratio": { "all": 0.10365853658536585, "valid": 0.10365853658536585 }, "by question type": { "Basic Fact Recall": { "n": 40, "correct": 0.8, "hallucination": 0.1, "omission": 0.1 }, "Dynamic Update": { "n": 6, "correct": 0.3333, "hallucination": 0.3333, "omission": 0.3333 }, "Generalization & Application": { "n": 31, "correct": 0.6129, "hallucination": 0.2258, "omission": 0.1613 }, "Memory Boundary": { "n": 39, "correct": 0.8462, "halluci… 证据：`benches/halumem/pilot_qa_score.json`
- **Tsconfig**（structured_config）：{ "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "lib": "ES2022", "DOM" , "strict": true, "declaration": true, "outDir": "dist", "skipLibCheck": true }, "include": "src" } 证据：`sdks/typescript/tsconfig.json`
- **Commercial control plane — licensing undecided, see control-plane/LICENSE**（source_file）：/target /memrust-data .env .env. .wal checkpoint.json sdks/typescript/dist sdks/typescript/node modules sdks/python/dist pycache / /target-linux /memrust-bin /memory- .DS Store .egg-info/ .pdf bench-results.json bench-agent-recall.json bench-agent-embeddings.npz memrust-investor-deck.pptx DECK NOTES.md build deck.py .deck-dash.png startup ecosystem database.xlsx startup ecosystem csv/ STARTUP ECOSYSTEM SUMMARY.md build db.py 证据：`.gitignore`
- **Build stage**（source_file）：Build stage Pinned to bookworm to match the runtime stage: the default rust:slim tag has moved to trixie, whose glibc is newer than bookworm's, and the binary then fails to start with GLIBC 2.39 not found . FROM rust:1.96-slim-bookworm AS build WORKDIR /app Build dependencies against a stub first so they stay cached when only the sources change — a rebuild after editing src/ skips recompiling the tree. COPY Cargo.toml Cargo.lock ./ RUN mkdir -p src && echo "fn main {}" src/main.rs \ && echo "" src/lib.rs \ && cargo build --release \ && rm -rf src COPY src ./src Touch so cargo notices the real sources are newer than the stub artifacts. RUN touch src/main.rs src/lib.rs && cargo build --release 证据：`Dockerfile`
- **Agent Recall**（source_file）：TOP K = 5 ⋮---- CACHE = "bench-agent-embeddings.npz" SERVICES = "Orion", "Meridian", "Atlas", "Vertex", "Halcyon", "Cobalt" TEAMS = "billing", "search", "mobile", "platform", "growth" ⋮---- def corpus seed: int = 7 ⋮---- rng = random.Random seed ⋮---- ticket = f"INC-{90000 + i 7}" text = f"Incident {ticket}: the {svc} service returned stale results " ⋮---- paraphrases = ⋮---- def hit rate results: dict str, list int , probes, kind: str - float ⋮---- subset = p for p in probes if p "kind" == kind hits = sum 1 for p in subset if p "answer" in results p "query" :TOP K ⋮---- def run vector engine name, build, search, memories, probes, vecs, qvecs ⋮---- out = {p "query" : search qvecs i for i, p… 证据：`benches/agent_recall.py`
- **Concurrency**（source_file）：def conn ⋮---- def post c, path, payload ⋮---- def ingest vecs ⋮---- c = conn ⋮---- def reader qs, stop, out ⋮---- i = 0 ⋮---- t = time.perf counter ⋮---- def writer vecs, stop, out ⋮---- def run threads: int, with writer: bool, qs, vecs ⋮---- workers = threading.Thread target=reader, args= qs, stop, lats for in range threads ⋮---- t0 = time.perf counter ⋮---- elapsed = time.perf counter - t0 ⋮---- flat = x for l in lats for x in l ⋮---- def main ⋮---- rng = np.random.default rng 0 vecs = rng.normal size= N, DIM .astype np.float32 ⋮---- qs = vecs :200 ⋮---- base = None ⋮---- r = run threads, False, qs, vecs base = base or r "qps" ⋮---- r = run 4, True, qs, vecs 证据：`benches/concurrency.py`
- **Favicon**（source_file）： 证据：`docs/favicon.svg`
- **Index**（source_file）：memrust — memory infrastructure for AI agents { "@context": "https://schema.org", "@graph": { "@type": "WebSite", "url": "https://aianytime.github.io/memrust/", "name": "memrust", "description": "Memory infrastructure for AI agents. One endpoint Claude Code, Cursor, Codex, LangGraph and CrewAI all share — hybrid retrieval over vectors, keywords, an entity graph and recency, with every result explaining why it surfaced.", "inLanguage": "en", "publisher": { "@type": "Organization", "name": "memrust" } }, { "@type": "SoftwareApplication", "name": "memrust", "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Database", "operatingSystem": "Linux, macOS, Windows", "url": "h… 证据：`docs/index.html`
- **memrust**（source_file）：Memory infrastructure for AI agents. An agent-native memory engine written in Rust that answers "what do I know about this?" rather than "which vectors are nearest?" — exposed through remember / recall / forget, retrievable over four fused signals, and reachable by any MCP client so every agent shares one memory. Apache-2.0, single binary, no external search dependencies. 证据：`docs/llms.txt`
- **memrust — https://aianytime.github.io/memrust/**（source_file）：memrust — https://aianytime.github.io/memrust/ Everything here is public documentation and marketing. Nothing is gated, nothing is user data, so everything is crawlable. 证据：`docs/robots.txt`
- **Sitemap**（source_file）：https://aianytime.github.io/memrust/ 2026-07-29 weekly 1.0 https://aianytime.github.io/memrust/docs/ 2026-07-29 weekly 0.9 https://aianytime.github.io/memrust/llms.txt 2026-07-29 monthly 0.5 证据：`docs/sitemap.xml`
- **01 Quickstart**（source_file）：{ "cells": { "cell type": "markdown", "id": "cell-1", "metadata": {}, "source": " memrust \u2014 quickstart\n", "\n", " Memory infrastructure for AI agents. memrust is an agent-native memory\n", "engine written in Rust: hybrid retrieval vector + BM25 + entity graph +\n", "recency behind a remember / recall / forget API, where every result\n", "explains why it surfaced with a per-signal score breakdown.\n", "\n", "This notebook gets you from zero to recall in about two minutes:\n", "\n", "1. install the Python SDK and start the engine\n", "2. remember a few memories\n", "3. recall them \u2014 and read the signal breakdown\n", "4. see the strategies lexical for exact IDs, relational for the e… 证据：`notebooks/01_quickstart.ipynb`
- **02 Rag With Embeddings**（source_file）：{ "cells": { "cell type": "markdown", "id": "cell-16", "metadata": {}, "source": " memrust \u2014 RAG with real embeddings\n", "\n", "This notebook builds a complete retrieval pipeline on memrust:\n", "\n", "1. embed documents with BGE-large-en-v1.5 1024-dim, a production-grade\n", " retrieval model via sentence-transformers\n", "2. store text + vectors in memrust remember batch \u2014 bulk ingest \n", "3. hybrid retrieval: semantic vectors + BM25 + entity graph, fused, explained\n", "4. RAG : ground an LLM answer in recalled memories OpenAI key optional \n", "5. memory lifecycle: TTL expiry, consolidation, snapshot/restore\n", "\n", "memrust supports embeddings three ways: a built-in OpenA… 证据：`notebooks/02_rag_with_embeddings.ipynb`
- **03 Pdf Rag Agents**（source_file）：{ "cells": { "cell type": "markdown", "id": "cell-35", "metadata": {}, "source": " memrust \u2014 PDF RAG with a LangGraph agent\n", "\n", "The full pipeline, end to end:\n", "\n", "1. load a real PDF with pypdf \"Attention Is All You Need\" and chunk it\n", "2. embed with BGE-large-en-v1.5 1024-dim \u2014 or swap in OpenAI embeddings\n", "3. store chunks + vectors in memrust\n", "4. build a LangGraph retrieve\u2192generate RAG agent over memrust\n", "5. the agent writes back : reflections and episodic traces of what it did\n", "6. the whole memory feature set: multi-agent private/shared visibility,\n", " working-memory TTLs, consolidation, entity graph, snapshots, checkpoints" }, { "cell t… 证据：`notebooks/03_pdf_rag_agents.ipynb`
- **Extract**（source_file）：use std::time::Duration; ⋮---- use crate::types::MemoryKind; ⋮---- pub struct Turn { ⋮---- pub struct Candidate { ⋮---- pub trait Extractor: Send + Sync { ⋮---- fn superseded by &self, fact: &str, existing: & String - Result { Ok Vec::new ⋮---- pub struct LlmExtractor { ⋮---- impl LlmExtractor { pub fn openai compatible base url: &str, model: &str, api key: &str - Self { ⋮---- url: format! "{}/chat/completions", base url.trim end matches '/' , model: model.to string , api key: api key.to string , ⋮---- .timeout Duration::from secs 120 .build , ⋮---- fn chat &self, system: &str, user: String - Result { let mut req = self.agent.post &self.url ; if !self.api key.is empty { req = req.set "autho… 证据：`src/extract.rs`
- **Store**（source_file）：use serde::de::DeserializeOwned; ⋮---- use uuid::Uuid; ⋮---- use crate::types::MemoryRecord; ⋮---- pub enum WalOp { ⋮---- pub struct Wal { ⋮---- impl Wal { pub fn open dir: &Path - Result { ⋮---- .with context format! "creating data dir {}", dir.display ?; let path = dir.join "memory.wal" ; ⋮---- if path.exists { ⋮---- for i, line in reader.lines .enumerate { ⋮---- if line.trim .is empty { ⋮---- Ok op = ops.push op , ⋮---- eprintln! "memrust: skipping unreadable WAL line {}: {e}", i + 1 ; ⋮---- let file = OpenOptions::new .create true .append true .open &path ?; Ok ⋮---- pub fn append batch &mut self, ops: & WalOp - Result { if ops.is empty { return Ok ; ⋮---- buf.push str &serde json::to s… 证据：`src/store.rs`

## 宿主 AI 必须遵守的规则

- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`README.md`, `benches/README.md`, `notebooks/README.md`
- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`README.md`, `benches/README.md`, `notebooks/README.md`

## 用户开工前应该回答的问题

- 你准备在哪个宿主 AI 或本地环境中使用它？
- 你只是想先体验工作流，还是准备真实安装？
- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？

## 验收标准

- 所有能力声明都能回指到 evidence_refs 中的文件路径。
- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。
- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。

---

## Doramagic Context Augmentation

下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。

## Human Manual 骨架

使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。

宿主 AI 硬性规则：
- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。
- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。
- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。

- **项目概述与核心价值**：importance `high`
  - source_paths: README.md, Cargo.toml, CHANGELOG.md
- **混合检索架构与信号融合**：importance `high`
  - source_paths: src/engine.rs, src/index/vector.rs, src/index/text.rs, src/index/graph.rs, src/index/mod.rs
- **存储引擎与持久化机制**：importance `high`
  - source_paths: src/store.rs, src/types.rs, src/lib.rs, src/main.rs
- **内存生命周期与多智能体可见性**：importance `high`
  - source_paths: src/engine.rs, src/summarize.rs, src/types.rs
- **命名空间与 API 密钥**：importance `high`
  - source_paths: src/server/tenancy.rs, src/server/mod.rs, src/main.rs
- **HTTP API 与 Web 仪表盘**：importance `high`
  - source_paths: src/server/http.rs, src/server/dashboard.html, src/types.rs
- **MCP 服务器与多语言 SDK**：importance `high`
  - source_paths: src/server/mcp.rs, sdks/python/memrust.py, sdks/python/pyproject.toml, sdks/python/test_e2e.py, sdks/typescript/src/index.ts
- **部署、可观测性与嵌入模型集成**：importance `high`
  - source_paths: Dockerfile, .dockerignore, src/server/metrics.rs, src/embed.rs, src/summarize.rs

## Repo Inspection Evidence / 源码检查证据

- repo_clone_verified: true
- repo_inspection_verified: true
- repo_commit: `a45b624dcf487e94ba142e686219c5c747ff534c`
- inspected_files: `Dockerfile`, `README.md`

宿主 AI 硬性规则：
- 没有 repo_clone_verified=true 时，不得声称已经读过源码。
- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。
- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。

## Doramagic Pitfall Constraints / 踩坑约束

这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。

### Constraint 1: 依赖 Docker 环境

- Trigger: 安装/运行入口包含 Docker 命令：docker run -p 7700:7700 -v memrust-data:/data aianytime/memrust # Client SDKs pip install memrust # Python npm install memrust-client
- Host AI rule: 标注 Docker 前置条件，并提供非 Docker 路径或失败提示。
- Why it matters: 非工程用户可能没有 Docker，启动成本明显增加。
- Evidence: identity.distribution | https://github.com/AIAnytime/memrust | docker run -p 7700:7700 -v memrust-data:/data aianytime/memrust # Client SDKs pip install memrust # Python npm install memrust-client
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 2: 可能修改宿主 AI 配置

- Trigger: 项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。
- Host AI rule: 列出会写入的配置文件、目录和卸载/回滚步骤。
- Why it matters: 安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。
- Evidence: capability.host_targets | https://github.com/AIAnytime/memrust | host_targets=mcp_host, claude_code, claude, cursor, gemini_cli, chatgpt
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 3: 能力判断依赖假设

- Trigger: README/documentation is current enough for a first validation pass.
- Host AI rule: 将假设转成下游验证清单。
- Why it matters: 假设不成立时，用户拿不到承诺的能力。
- Evidence: capability.assumptions | https://github.com/AIAnytime/memrust | README/documentation is current enough for a first validation pass.
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 4: 维护活跃度未知

- Trigger: 未记录 last_activity_observed。
- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。
- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- Evidence: evidence.maintainer_signals | https://github.com/AIAnytime/memrust | last_activity_observed missing
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

- Trigger: no_demo
- Evidence: downstream_validation.risk_items | https://github.com/AIAnytime/memrust | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 6: 存在评分风险

- Trigger: no_demo
- Why it matters: 风险会影响是否适合普通用户安装。
- Evidence: risks.scoring_risks | https://github.com/AIAnytime/memrust | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 7: issue/PR 响应质量未知

- Trigger: issue_or_pr_quality=unknown。
- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。
- Why it matters: 用户无法判断遇到问题后是否有人维护。
- Evidence: evidence.maintainer_signals | https://github.com/AIAnytime/memrust | issue_or_pr_quality=unknown
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 8: 发布节奏不明确

- Trigger: release_recency=unknown。
- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。
- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。
- Evidence: evidence.maintainer_signals | https://github.com/AIAnytime/memrust | release_recency=unknown
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。
