[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-1955":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":23,"hasPages":25,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":29,"readmeContent":30,"aiSummary":31,"trendingCount":16,"starSnapshotCount":16,"syncStatus":17,"lastSyncTime":32,"discoverSource":33},1955,"mempal","ZhangHanDong\u002Fmempal","ZhangHanDong","AI Agent Memory","https:\u002F\u002Fzhanghandong.github.io\u002Fmempalace-book\u002Fen\u002Fch26-why-rewrite-in-rust.html",null,"Rust",161,21,1,9,0,2,4,19,6,4.03,"MIT License",false,"main",true,[27,28],"agent","memory-management","2026-06-12 02:00:35","# mempal\n\nProject memory for coding agents. Single binary, `cargo install mempal`, find past decisions with citations in seconds.\n\n## What It Does\n\n```\nAgent writes code → commits → mempal saves the decision context\nNext session (any agent) → mempal search → finds the decision with source citation\n```\n\n- **Hybrid search**: BM25 keyword matching + vector semantic search, merged via Reciprocal Rank Fusion\n- **Knowledge graph**: subject-predicate-object triples with temporal validity (valid_from\u002Fvalid_to)\n- **Cross-project tunnels**: automatic discovery when the same room appears in multiple wings\n- **Self-describing protocol**: MEMORY_PROTOCOL embedded in MCP ServerInfo teaches any agent how to use mempal — no system prompt configuration required\n- **Multilingual**: model2vec-rs (BGE-M3 distilled) as default embedder, zero native dependencies\n- **Single file**: everything lives in `~\u002F.mempal\u002Fpalace.db` (SQLite + sqlite-vec)\n\n## Quick Start\n\n```bash\ncargo install --path crates\u002Fmempal-cli --locked\n\nmempal init ~\u002Fcode\u002Fmyapp\nmempal ingest ~\u002Fcode\u002Fmyapp --wing myapp\nmempal search \"auth decision clerk\"\nmempal wake-up\n```\n\nWith REST support:\n\n```bash\ncargo install --path crates\u002Fmempal-cli --locked --features rest\n```\n\n## Configuration\n\nConfig at `~\u002F.mempal\u002Fconfig.toml` (optional, defaults work without it):\n\n```toml\ndb_path = \"~\u002F.mempal\u002Fpalace.db\"\n\n[embed]\nbackend = \"model2vec\"                          # default, zero native deps\n# model = \"minishlab\u002Fpotion-multilingual-128M\" # default multilingual model (1024d)\n```\n\nOther backends:\n\n```toml\n# Local ONNX (requires --features onnx)\n[embed]\nbackend = \"onnx\"\n\n# External API\n[embed]\nbackend = \"api\"\napi_endpoint = \"http:\u002F\u002Flocalhost:11434\u002Fapi\u002Fembeddings\"\napi_model = \"nomic-embed-text\"\n```\n\n## Commands\n\n| Command | Purpose |\n|---------|---------|\n| `mempal init \u003CDIR> [--dry-run]` | Infer wing\u002Frooms from project tree |\n| `mempal ingest \u003CDIR> --wing \u003CW> [--dry-run]` | Chunk, embed, and store |\n| `mempal search \u003CQUERY> [--wing W] [--room R] [--json]` | Hybrid search (BM25 + vector + RRF) |\n| `mempal wake-up [--format aaak]` | Context refresh, sorted by importance |\n| `mempal compress \u003CTEXT>` | AAAK format output |\n| `mempal delete \u003CDRAWER_ID>` | Soft-delete a drawer |\n| `mempal purge [--before TIMESTAMP]` | Permanently remove soft-deleted drawers |\n| `mempal kg add \u003CS> \u003CP> \u003CO>` | Add a knowledge graph triple |\n| `mempal kg query [--subject S] [--predicate P]` | Query triples |\n| `mempal kg timeline \u003CENTITY>` | Chronological view of an entity |\n| `mempal kg stats` | Knowledge graph statistics |\n| `mempal tunnels` | Cross-wing room links |\n| `mempal taxonomy list \u002F edit` | Manage routing keywords |\n| `mempal reindex` | Re-embed all drawers after model change |\n| `mempal status` | DB stats, schema version, scopes |\n| `mempal serve [--mcp]` | MCP server (+ REST with feature) |\n| `mempal cowork-install-hooks [--global-codex]` | Install UserPromptSubmit hooks for Claude Code (+ optional Codex merge) |\n| `mempal cowork-drain --target \u003Cclaude\\|codex>` | Drain inbox messages (for hook use; exits 0 on any failure) |\n| `mempal cowork-status --cwd \u003CPATH>` | Read-only view of both inboxes at `\u003CPATH>` |\n| `mempal fact-check [PATH\\|-] [--wing W] [--room R] [--now \u003CUNIX_SECS>]` | Offline contradiction check against KG triples + known entities |\n| `mempal bench longmemeval \u003CFILE>` | LongMemEval retrieval benchmark |\n\n## MCP Server (10 tools)\n\n`mempal serve --mcp` exposes these tools via Model Context Protocol:\n\n| Tool | Purpose |\n|------|---------|\n| `mempal_status` | State + protocol + AAAK spec (teaches agent on first call) |\n| `mempal_search` | Hybrid search with tunnel hints, citations, and AAAK-derived structured signals |\n| `mempal_ingest` | Store memories with optional importance (0-5) and dry_run; reports `lock_wait_ms` when concurrent ingest was observed |\n| `mempal_delete` | Soft-delete with audit trail |\n| `mempal_taxonomy` | List or edit routing keywords |\n| `mempal_kg` | Knowledge graph: add\u002Fquery\u002Finvalidate\u002Ftimeline\u002Fstats |\n| `mempal_tunnels` | Cross-wing room discovery |\n| `mempal_peek_partner` | Read partner agent's live session (Claude ↔ Codex), pure read, never writes |\n| `mempal_cowork_push` | Send a short handoff message to partner agent's inbox (at-next-submit delivery) |\n| `mempal_fact_check` | Offline contradiction detection vs KG triples + known entities (similar-name, relation mismatch, stale facts) |\n\nThe server embeds MEMORY_PROTOCOL (11 behavioral rules) in the MCP `initialize.instructions` field. Any MCP client learns the workflow automatically.\n\n## Memory Protocol\n\nmempal teaches agents these rules through self-description:\n\n0. **FIRST-TIME SETUP** — call `mempal_status` to discover wings before filtering\n1. **WAKE UP** — different clients have different pre-load mechanisms\n2. **VERIFY BEFORE ASSERTING** — search before stating project facts\n3. **QUERY WHEN UNCERTAIN** — search on \"why did we...\", \"last time we...\"\n3a. **TRANSLATE TO ENGLISH** — translate non-English queries before searching\n4. **SAVE AFTER DECISIONS** — persist rationale, not just outcomes\n5. **CITE EVERYTHING** — reference drawer_id and source_file\n5a. **KEEP A DIARY** — record behavioral observations in wing=\"agent-diary\"\n8. **PARTNER AWARENESS** — use `mempal_peek_partner` for live partner-agent session, not crystallized drawers\n9. **DECISION CAPTURE** — `mempal_ingest` is for firm decisions only; include partner input when peek informed the call\n10. **COWORK PUSH** — use `mempal_cowork_push` as the SEND primitive in the SEND\u002FREAD\u002FPERSIST triad; at-next-submit delivery, not real-time\n11. **VERIFY BEFORE INGEST** — call `mempal_fact_check` before persisting a decision that asserts entity relationships; it catches similar-name typos, relation mismatches against the KG, and stale facts with expired `valid_to`\n\n## Agent Cowork (P6 peek + P8 push)\n\nTwo coding agents (Claude Code and Codex) can collaborate on the same repo through a per-project inbox + hook-driven injection channel, on top of `mempal_peek_partner` (read live partner session) and `mempal_cowork_push` (send ephemeral handoff).\n\nInstall hooks once per repo (run at the repo root):\n\n```bash\nmempal cowork-install-hooks --global-codex\n```\n\nThis writes:\n\n- `.claude\u002Fhooks\u002Fuser-prompt-submit.sh` + merges a registration entry into `.claude\u002Fsettings.json` so Claude Code fires the hook on every user prompt.\n- `~\u002F.codex\u002Fhooks.json` UserPromptSubmit entry so Codex fires the same drain on every user prompt.\n\nThe `--global-codex` part is optional. The re-run is idempotent and self-heals stale\u002Fwrong drain entries — re-installing after a mempal upgrade is always safe.\n\nDelivery is **at-next-UserPromptSubmit**, not real-time: a push from Claude to Codex becomes visible only when the Codex user submits their next prompt, at which point the hook drains the inbox and prepends the message as `additionalContext` on that turn.\n\nCheck inbox state at any time without draining:\n\n```bash\nmempal cowork-status --cwd \"$PWD\"\n```\n\n### Known limitations\n\n- **Codex feature flag dependency**: Codex's hooks runtime is gated behind the `codex_hooks` feature flag (currently \"under development\" in shipped `codex-cli`). If the flag is off, Codex silently ignores `~\u002F.codex\u002Fhooks.json`. `install-hooks` detects this and prints a warning with the activation command: `codex features enable codex_hooks`.\n- **Two Claude-side artifacts**: Claude Code does not auto-discover hook scripts by filename. Both `.claude\u002Fhooks\u002Fuser-prompt-submit.sh` and the matching entry in `.claude\u002Fsettings.json` are required. `install-hooks` writes both; do not remove either by hand.\n- **TUI restart needed after config changes on the Codex side**: Codex reads `config.toml` + `hooks.json` at process startup only. After enabling the feature flag or running `install-hooks`, fully quit and relaunch the Codex TUI before expecting hooks to fire.\n- **MCP server re-spawn**: Claude Code spawns the mempal MCP server at client startup. After upgrading the mempal binary (`cargo install ...`), restart Claude Code so the MCP server respawns and exposes newly added tools like `mempal_cowork_push` or `mempal_fact_check`.\n- **Bidirectional scope**: `mempal_cowork_push` currently requires an MCP client identifying itself as `claude-code` or `codex` (or their aliases). Generic MCP clients cannot push because caller identity is required to fill the `from` field and enforce self-push rejection. This is by design for the Claude ↔ Codex pair.\n\n## Concurrent Ingest Safety (P9-B)\n\nTwo agents writing to the same source simultaneously used to be a TOCTOU race: both would pass the dedup check, both would insert, producing duplicate drawers or mismatched vectors. Since 0.4.0, `mempal_ingest` and `ingest_file_with_options` acquire a per-source advisory lock before entering the dedup + insert critical section.\n\n- Lock files live at `~\u002F.mempal\u002Flocks\u002F\u003C16-hex>.lock`, created lazily, released on guard drop.\n- 5 s timeout, 50 ms retry + jitter; `LockError::Timeout` surfaces as an `ingest` error.\n- Every non-dry-run response carries `lock_wait_ms: Option\u003Cu64>` so agents can detect contention.\n- Dry-run does not acquire the lock (no writes, no race).\n- Unix only in 0.4.0. On Windows the lock path is a no-op fallback; `LockFileEx` support is tracked for a follow-up.\n\n## Offline Fact Checking (P9-A)\n\n`mempal_fact_check` — and its CLI counterpart `mempal fact-check` — compare a text blob against the existing KG `triples` + the entity registry derived from recent drawers. It flags three issue classes, all deterministic and zero-LLM:\n\n| Issue | Trigger |\n|-------|---------|\n| `SimilarNameConflict` | Text mentions a name within Levenshtein distance ≤ 2 of a known entity, and the names are not equal. |\n| `RelationContradiction` | Text asserts a predicate (e.g. `brother_of`) that's in the incompatibility dictionary against an existing KG triple with the same `(subject, object)` endpoints. |\n| `StaleFact` | Text asserts a triple whose KG row has `valid_to \u003C now` (Unix seconds). |\n\nExtracted triples today cover three narrow patterns: \"X is Y's ROLE\", \"X works at \u002F for Y\", and \"X is [the|a|an] ROLE of Y\". Unknown sentence shapes are silently ignored, so the tool errs toward under-reporting rather than false positives.\n\nProtocol Rule 11 guides agents to run this before ingesting a decision that asserts entity relationships. See `specs\u002Fp9-fact-checker.spec.md` for the full contract.\n\n## Search Architecture\n\n```\nquery → BM25 (FTS5)     → ranked by keyword match\n      → Vector (sqlite-vec) → ranked by semantic similarity\n      → RRF Fusion (k=60)   → merged ranking\n      → Wing\u002FRoom filter     → scoped results\n      → Tunnel hints         → cross-project references\n```\n\n## Knowledge Graph\n\n```bash\nmempal kg add \"Kai\" \"recommends\" \"Clerk\"\nmempal kg add \"Clerk\" \"replaced\" \"Auth0\" --source-drawer drawer_xxx\nmempal kg timeline \"Kai\"\nmempal kg stats\n```\n\nTriples support temporal validity — relationships can be invalidated when they expire.\n\n## Agent Diary\n\nCross-session behavioral learning — agents record observations, lessons, and patterns:\n\n```bash\n# Search diary entries\nmempal search \"lesson\" --wing agent-diary\nmempal search \"pattern\" --wing agent-diary --room claude\n```\n\nDiary entries use the existing `mempal_ingest` tool with `wing=\"agent-diary\"` and `room=agent-name`. MEMORY_PROTOCOL Rule 5a teaches agents to write diary entries. Integrates with Claude Code's auto-dream for automatic memory consolidation.\n\n## Ingest Formats (5)\n\n| Format | Auto-detected by |\n|--------|-----------------|\n| Claude Code JSONL | `type` + `message` fields |\n| ChatGPT JSON | Array or `mapping` tree |\n| Codex CLI JSONL | `session_meta` + `event_msg` entries |\n| Slack DM JSON | `type: \"message\"` + `user` + `text` |\n| Plain text | Fallback |\n\n## AAAK Compression\n\nOutput-only format readable by any LLM without decoding:\n\n```bash\nmempal compress \"Kai recommended Clerk over Auth0 based on pricing and DX\"\n# V1|manual|compress|1744156800|cli\n# 0:KAI+CLK+AUT|kai_clerk_auth0|\"Kai recommended Clerk over Auth0...\"|★★★★|determ|DECISION\n```\n\nChinese text uses jieba-rs POS tagging for proper word segmentation.\n\n## Architecture\n\n| Crate | Responsibility |\n|-------|---------------|\n| `mempal-core` | Types, SQLite schema v4, taxonomy, triples |\n| `mempal-embed` | Embedder trait (model2vec default, ort optional) |\n| `mempal-ingest` | Format detection, normalization, chunking (5 formats) |\n| `mempal-search` | Hybrid search (BM25 + vector + RRF), routing, tunnels |\n| `mempal-aaak` | AAAK encode\u002Fdecode with BNF grammar + roundtrip tests |\n| `mempal-mcp` | MCP server (9 tools) |\n| `mempal-api` | Feature-gated REST API |\n| `mempal-cli` | CLI entrypoint |\n\nKey design choices:\n- **model2vec-rs** default embedder — zero native deps, multilingual (BGE-M3 distilled)\n- **ort (ONNX)** available behind `onnx` feature flag for max quality\n- **FTS5** for BM25 keyword search — synced via SQLite triggers\n- **Soft-delete** with audit trail — `mempal delete` + `mempal purge`\n- **Importance ranking** — drawers have 0-5 importance, wake-up sorts by importance\n- **Semantic dedup** — ingest warns (doesn't block) when similar content exists\n\n## Development\n\n```bash\ncargo test --workspace\ncargo test --workspace --all-features\ncargo clippy --workspace --all-targets --all-features -- -D warnings\ncargo fmt --all --check\n```\n\nAfter changing the embedding model, re-embed existing drawers:\n\n```bash\nmempal reindex\n```\n\n## Docs\n\n- Design: [`docs\u002Fspecs\u002F2026-04-08-mempal-design.md`](docs\u002Fspecs\u002F2026-04-08-mempal-design.md)\n- Usage guide: [`docs\u002Fusage.md`](docs\u002Fusage.md)\n- AAAK dialect: [`docs\u002Faaak-dialect.md`](docs\u002Faaak-dialect.md)\n- Specs (internal agent-spec contracts, on GitHub): \u003Chttps:\u002F\u002Fgithub.com\u002FZhangHanDong\u002Fmempal\u002Ftree\u002Fmain\u002Fspecs>\n- Plans (internal implementation plans, on GitHub): \u003Chttps:\u002F\u002Fgithub.com\u002FZhangHanDong\u002Fmempal\u002Ftree\u002Fmain\u002Fdocs\u002Fplans>\n- Benchmark: [`benchmarks\u002Flongmemeval_s_summary.md`](benchmarks\u002Flongmemeval_s_summary.md) — includes the older 384d baseline and the newer model2vec 256d run\n\n## Book: MemPalace — Reforging Memory in Rust\n\nmempal 的设计分析和完整技术叙事，收录在《MemPalace: AI 记忆的第一性原理》Part 10（第 26-30 章）：\n\n- [中文版](https:\u002F\u002Fzhanghandong.github.io\u002Fmempalace-book\u002Fch26-why-rewrite-in-rust.html)\n- [English](https:\u002F\u002Fzhanghandong.github.io\u002Fmempalace-book\u002Fen\u002Fch26-why-rewrite-in-rust.html)\n\n| 章节 | 内容 |\n|------|------|\n| 第 26 章 | 为什么用 Rust 重铸 — 触发点、重写判断、语言选择 |\n| 第 27 章 | 保留了什么、改变了什么 — 5 维度对比 + 架构图 |\n| 第 28 章 | 自描述协议 — MEMORY_PROTOCOL、7 条规则、agent 生命周期 |\n| 第 29 章 | 多 Agent 协作 — Claude↔Codex 接力、反模式发现、agent 日记 |\n| 第 30 章 | 诚实的差距 — benchmark 数据、6 个 gap |\n","mempal 是一个用于编码代理的记忆管理工具，旨在帮助开发者快速查找过去的决策及其引用。它通过结合BM25关键词匹配与向量语义搜索技术，并利用互惠排名融合算法来实现高效的信息检索。此外，mempal 构建了一个包含时间有效性的知识图谱，支持跨项目的自动发现功能，并采用自描述协议以简化使用流程。该项目适用于需要频繁回顾或复用代码决策的开发场景中，特别是当团队成员需要共享和理解项目历史时。mempal 仅依赖单一文件进行数据存储，极大地方便了用户的安装与维护工作。","2026-06-11 02:47:03","CREATED_QUERY"]