{
  "markdown": "<div align=\"center\">\n  <img src=\".github/banner.png\" alt=\"Perseus Vault — Persistent Memory. Encrypted, local-first, one portable file.\" width=\"100%\">\n</div>\n\n# Perseus Vault\n\n<!-- mcp-name: io.github.Perseus-Computing-LLC/perseus-vault -->\n\n> **Persistent, encrypted memory for AI agents. One Rust binary, one file, no cloud.**\n\n[![Build and Test](https://img.shields.io/github/actions/workflow/status/Perseus-Computing-LLC/perseus-vault/test.yml)](https://github.com/Perseus-Computing-LLC/perseus-vault/actions/workflows/test.yml)\n[![License: MIT](https://img.shields.io/github/license/Perseus-Computing-LLC/perseus-vault)](./LICENSE)\n[![Release](https://img.shields.io/github/v/release/Perseus-Computing-LLC/perseus-vault)](https://github.com/Perseus-Computing-LLC/perseus-vault/releases)\n[![Glama](https://glama.ai/mcp/servers/Perseus-Computing-LLC/perseus-vault/badge)](https://glama.ai/mcp/servers/Perseus-Computing-LLC/perseus-vault)\n[![LangGraph](https://img.shields.io/badge/integrations-LangGraph-blue)](integrations/langgraph/)\n[![CrewAI](https://img.shields.io/badge/integrations-CrewAI-orange)](integrations/crewai/)\n[![AutoGen](https://img.shields.io/badge/integrations-AutoGen-purple)](integrations/autogen/)\n\n**Published on** [Official MCP Registry](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.Perseus-Computing-LLC/perseus-vault) · [Glama](https://glama.ai/mcp/servers/Perseus-Computing-LLC/perseus-vault) · [mcpservers.org](https://mcpservers.org/servers/perseus-computing-llc/perseus-vault) · [Docker (GHCR)](https://github.com/Perseus-Computing-LLC/perseus-vault/pkgs/container/perseus-vault)\n\nGive your agents memory that survives the session, so they stop re-deriving what they\nalready learned and stop repeating past mistakes. Hybrid recall (BM25 + dense + RRF),\nbi-temporal history, and **AES-256-GCM** at rest are exposed through a canonical MCP\nsurface that works with any host. The exact v2.23.2 `--no-default-features` snapshot\npublished in the [versioned API reference](https://perseus.observer/vault/mcp-reference/)\ncontains **175 unique canonical tools**; counts are release/profile-specific and are\nalso recorded in the published [`metadata.json`](https://perseus.observer/vault/mcp-reference/metadata.json).\n\nThe source-checked LongMemEval claim is the fully offline **session-level recall**\nmeasurement in [`benchmark/longmemeval/`](benchmark/longmemeval/README.md): on the public\n`_s` split (500 questions, 23,867 sessions), the committed hybrid path reaches\n**83.2% recall@1, 98.8% recall@5, 99.8% recall@10, and 0.8949 MRR** against\n`answer_session_ids`. It is judge-free and uses the real binary with bundled local\nembeddings; it is a retrieval metric, **not end-to-end QA accuracy**. The exact\nreport, harness, and reproduction command are documented in that directory.\n\n[Perseus Context Engine](https://github.com/Perseus-Computing-LLC/perseus) resolves the present; [Perseus Ledger](https://github.com/Perseus-Computing-LLC/ledger) records the evidence. Vault is the durable-memory layer between them.\n\n**One binary. One file. No Docker. No Postgres. No cloud.** Local-first, air-gap ready, MIT.\n\n## One-Line Install\n\n```bash\ncurl -sSf https://raw.githubusercontent.com/Perseus-Computing-LLC/perseus-vault/main/scripts/install.sh | sh\n```\n\nThat's it. Perseus Vault is installed to `~/.local/bin/perseus-vault`. Start it:\n\n```bash\nperseus-vault serve --db ~/.perseus-vault/data/perseus-vault.db\n```\n\n> **Encryption is enabled automatically for the default installation.** The first\n> run creates `~/.perseus-vault/secret.key` with owner-only permissions and an\n> encrypted database canary. Back up that key: it cannot be recovered. Explicit\n> `--encryption-key` paths remain supported, and existing plaintext databases are\n> preserved for migration with `perseus-vault init --rekey`. Use `doctor` to\n> inspect the actual on-disk state.\n\n> **macOS note (Apple Silicon).** A freshly built or copied binary is\n> SIGKILLed on first run (`Killed: 9`, no other output) by the OS binary\n> policy — even with no quarantine attribute. The one-line installer and the\n> `bootstrap.sh` build-from-source installer ad-hoc code-sign Perseus Vault for\n> you. If you build the binary yourself, sign it once **after each rebuild**:\n>\n> ```bash\n> cargo build --release\n> cp target/release/perseus-vault ~/.local/bin/perseus-vault\n> codesign --force --sign - ~/.local/bin/perseus-vault   # required on Apple Silicon; fixes \"Killed: 9\"\n> ```\n>\n> `--force` re-signs an already-signed binary (needed after every rebuild); the\n> step is harmless on Intel macOS and unnecessary on Linux/Windows.\n\nThen wire your MCP client(s) — and the full recall/capture loop — in one command:\n\n```bash\nperseus-vault install-client --hooks --rules\n```\n\nThis autodetects Claude Code / Codex / Cursor (pass `--client <name>` for\nclaude-desktop, hermes, windsurf, vscode, zed, or generic; `--all-detected`\nwires every detected client), merges the MCP server registration into the\nclient's config without clobbering anything (a `.bak-perseus` backup is\nwritten first), points every client at **one shared memory database**,\nregisters the session lifecycle hooks (recall injection on SessionStart,\nhygiene on session end — the `docs/lifecycle-hooks.md` contract), and appends\nthe memory usage rules to `CLAUDE.md`/`AGENTS.md`. Re-running is a no-op; add\n`--dry-run` to preview every file it would touch.\n\nOr connect any MCP host by hand (Claude Desktop, Cursor, Hermes Agent, Perseus, etc.):\n\n```json\n{\n  \"mcpServers\": {\n    \"perseus-vault\": {\n      \"command\": \"perseus-vault\",\n      \"args\": [\"serve\", \"--db\", \"~/.perseus-vault/data/perseus-vault.db\"]\n    }\n  }\n}\n```\n\n## For Agents: Connect Over MCP\n\nWhen the primary consumer is an agent, the interface is **MCP** — the agent\nadopts the Vault through its MCP client, and no per-machine CLI install is\nneeded beyond running the server itself:\n\n```bash\n# 1. Run the server (one line)\nperseus-vault serve --db ~/.perseus-vault/data/perseus-vault.db &\n\n# 2. Register it in the agent's MCP client config\n#    { \"mcpServers\": { \"perseus-vault\": {\n#        \"command\": \"perseus-vault\",\n#        \"args\": [\"serve\", \"--db\", \"~/.perseus-vault/data/perseus-vault.db\"] } } }\n\n# 3. Verify the agent-facing surface\nperseus-vault doctor\n```\n\n`perseus-vault install-client --hooks --rules` wires the whole\nrecall/capture loop for Claude Code / Codex / Cursor / Hermes in one command.\nFor the agent-facing capability map — which tool does which job, and the\nplanning-boundary pattern — see\n[docs/integration/agent-adoption.md](docs/integration/agent-adoption.md).\nFor the cross-tier architecture and evaluator boundary, see the\n[Evaluator Guide](docs/EVALUATOR_GUIDE.md).\n\n## 30-Second Quickstart\n\n```bash\n# Start Perseus Vault\nperseus-vault serve --db memory.db &\nsleep 1\n\n# Remember a fact (via MCP JSON-RPC on stdio)\necho '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"perseus_vault_remember\",\"arguments\":{\"category\":\"demo\",\"key\":\"hello\",\"body_json\":\"{\\\"text\\\":\\\"Hello from Perseus Vault!\\\"}\"}}}' | perseus-vault serve --db memory.db\n\n# Search for it\necho '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"perseus_vault_recall\",\"arguments\":{\"query\":\"Hello\"}}}' | perseus-vault serve --db memory.db\n```\n\n## Memory model and operational boundaries\n\nPerseus Vault keeps three planes distinct:\n\n- **Implicit working context** is the host's current prompt, transcript, and any\n  context block a client chooses to inject. It is ephemeral and host-owned; it\n  is not persisted merely because Vault returned it.\n- **Explicit durable memory** is written by an explicit\n  `perseus_vault_remember`, `perseus_vault_capture`, `write`, or `capture`\n  operation. The Vault server owns the SQLite record, history, journal, decay,\n  archive, and purge lifecycle.\n- **Derived projections** include consolidated or synthesized records and\n  exported Markdown. They carry provenance, but they are not a replacement for\n  the durable source records and may need separate cleanup.\n\n`perseus-vault prepare` and `perseus_vault_context` read durable records to\nproduce a bounded, task-relevant **active working context**. This is a rolling\nsnapshot, not a background write or a promise that the client will retain it:\nrefresh it when the task changes, and do not treat prompt text as durable memory\nunless an explicit capture/write operation succeeds. Recall-first output is\nbudgeted (1500 characters by default, 6000 for large-window hosts, or an\nexplicit `max_context_chars`); the `always_on` set is capped at five. See\n[retention and context semantics](docs/retention.md).\n\nLifecycle hooks and client installers are optional orchestration. They request\nserver-owned recall, capture, maintenance, and refresh work; they do not become\na second store or change retention policy. If the server or a hook is\nunavailable, continue the task without injected memory and surface the degraded\nstate. A host integration may have an explicitly configured local fallback, but\nthat fallback must be labeled local-only and must not be presented as durable\nVault recall; a failed explicit write must never be reported as persisted. For\nupgrade/recovery steps, use the\n[upgrade and migration playbook](docs/migration/upgrade-playbook.md).\n\n## Works With Every MCP Client\n\nPerseus Vault is a standard MCP **stdio** server — the same `perseus-vault serve` command works\neverywhere. Run `perseus-vault doctor` to validate your install and print this matrix locally.\n\n| Client | Status | Config | \n|---|---|---|\n| Claude Desktop | ✅ | `claude_desktop_config.json` |\n| Claude Code / Hermes | ✅ | `.mcp.json` / `config.yaml` |\n| Cursor | ✅ | `.cursor/mcp.json` |\n| Windsurf | ✅ | `mcp_config.json` |\n| VS Code + Continue.dev | ✅ | `config.json` |\n| Zed | ✅ | `settings.json` |\n| Codex CLI | ✅ | `~/.codex/config.toml` |\n\nCopy-paste config snippets for each: **[docs/clients/](docs/clients/)**.\n\nThen wire the **recall → work → capture → consolidate** loop to your client's\nsession events (SessionStart/Stop hooks for Claude Code, Codex, and Cursor,\nplus a portable AGENTS.md fallback): **[docs/lifecycle-hooks.md](docs/lifecycle-hooks.md)**.\n\nComposing with a memory washer (CoalWash) and a runtime output compactor\n(Noisegate) for end-to-end context-budget control:\n**[docs/integration/context-budget-stack.md](docs/integration/context-budget-stack.md)**.\n\nAuditing what the Vault remembers, from where, and under which authority:\n**[docs/evidence-chain-guidance.md](docs/evidence-chain-guidance.md)** — evidence chains,\nwrite-time provenance tags, and continuous attestation for durable memory.\n\n## Memory banks (per-client isolation, one profile)\n\nAgency running 50 clients with the same playbook? Don't duplicate profiles —\ndesignate the **memory bank** per project and keep one Hermes profile, one\nVault, and one shared skill library:\n\n```markdown\n# .hermes.md\nmemory_bank: acme-seo            # name → deterministic workspace hash\nmemory_bank_workspace: <64-hex>  # optional explicit workspace override\n```\n\nThe [Hermes memory provider](https://github.com/Perseus-Computing-LLC/hermes-plugin-perseus-vault)\n(`hermes plugins install Perseus-Computing-LLC/hermes-plugin-perseus-vault`)\nresolves the bank once per session and scopes every Vault read and write —\nprefetch recall, `perseus_recall` / `perseus_remember` / `perseus_forget`,\nsession-end capture — to a dedicated workspace. Bank names map\ndeterministically (`sha256(\"memory-bank:\" + name)`), so every instance\npointing at the same name addresses the same workspace with no registry to\nmaintain. Workspaces are first-class on the server: scoped maintenance, dedup\nisolation between banks, and per-workspace authority manifests. Discovery\nmirrors Hermes project-context rules (nearest `.hermes.md` wins, bounded at\nthe git root); a context file without a directive means no bank — the\nconfigured workspace stays in effect.\n\n## Why Perseus Vault\n\nPerseus Vault is designed to be MCP-native, local-first, zero-dependency, and\nagent-first.\n\n### LongMemEval retrieval (offline, judge-free)\n\nThe current public measurement is the reproducible retrieval lane in\n[`benchmark/longmemeval/`](benchmark/longmemeval/README.md), not the deprecated\nLLM-answer-and-judge experiment. It drives the real binary over MCP stdio and\nchecks whether a gold evidence session appears in the requested rank window,\nusing LongMemEval's `answer_session_ids` on the public `_s` split.\n\nThe committed report covers 500 questions and 23,867 ingested sessions:\n\n| path | recall@1 | recall@3 | recall@5 | recall@10 | MRR |\n|---|---:|---:|---:|---:|---:|\n| keyword only (`fts5`) | 4.2% | 12.2% | 19.2% | 33.6% | 0.1069 |\n| dense | 75.8% | 88.0% | 91.8% | 96.0% | 0.8296 |\n| **hybrid (RRF)** | **83.2%** | **96.6%** | **98.8%** | **99.8%** | **0.8949** |\n\nThese are session-level retrieval metrics: offline, judge-free, and not\nend-to-end QA accuracy. Reproduce the exact source-checked report with the\ncommands in the benchmark README; the committed artifact is\n[`report-currentmain-2026-08-16.json`](benchmark/longmemeval/report-currentmain-2026-08-16.json).\nThe deprecated [`benchmarks/LONG_MEM_EVAL.md`](benchmarks/LONG_MEM_EVAL.md)\nexplains why the earlier model/judge numbers are not used as public claims.\n\n### LOCOMO (mem0's own harness)\n\nMeasured on mem0's own LOCOMO harness ([our fork](https://github.com/Perseus-Computing-LLC/memory-benchmarks)), not ours — cats 1–4, 1,540q, top-200, gpt-5 answerer + judge:\n\n| Engine | Overall | Single | Temporal | Multi | Open-domain |\n|---|---|---|---|---|---|\n| **Perseus Vault 2.20.2** | **87.9%** | 89.1 | 92.2 | 85.1 | 70.8 |\n| Mem0 Platform Starter | 82.2% | 85.0 | 82.9 | 78.0 | 67.7 |\n| Zep Cloud Flex | 33.8% | 36.9 | 6.9 | 50.0 | 49.0 |\n\nCat-5 adversarial (446q): Perseus 63.5, Mem0 55.6, Zep 49.8. Our Mem0 measurement is 9.4pts below their published file (judge/platform drift — disclosed). [Full leaderboard →](https://github.com/Perseus-Computing-LLC/memory-benchmarks)\n\n### Bi-temporal time-travel (three-axis)\n\nOur strongest structural differentiator — full **SQL:2011 bi-temporal** history\n(transaction-time *and* valid-time) — measured against a reproducible,\n**fully offline** gauntlet. It drives the real shipped binary over MCP stdio\nthrough the hard cases single-axis competitors get wrong (retroactive\ncorrections, proactive future-dated facts, out-of-order arrival, belief-vs-truth\ndivergence, closed periods):\n\n| Axis | Question it answers | Checks | Pass |\n|---|---|---|---|\n| **valid-time** (`valid_at`) | \"what was true in the world at T\" | 10 | 10 |\n| **transaction-time** (`as_of`) | \"what did we believe at T\" | 1 | 1 |\n| **bi-temporal** (`bitemporal`) | \"as of belief at T, what was true at V\" | 2 | 2 |\n| **Total** | | **13** | **13 (100%)** |\n\nReproduce with a single command (no API key, no network, no LLM):\n\n```bash\ncargo build --release\npython benchmark/temporal/gauntlet.py --bin target/release/perseus-vault\n```\n\nThe PASS/FAIL verdicts are deterministic (wall-clock timestamps vary, verdicts\ndo not), so a correct build re-runs to an identical `signature_sha256`. The\ncommitted [`gauntlet_report.json`](benchmark/temporal/gauntlet_report.json) is\nthe reference. [Methodology & dataset →](benchmark/temporal/README.md)\n\n### Comparison Matrix\n\n| | Perseus Vault | Mem0 | Letta | Zep |\n|---|---|---|---|---|\n| **Deployment** | Single binary | Cloud + self-host | Docker/Postgres | Docker/Neo4j |\n| **Dependencies** | None (SQLite embedded) | Python + vector DB | Postgres + Python | Neo4j + Go (Graphiti) |\n| **MCP-Native** | ✅ Versioned canonical MCP surface | ❌ Not MCP-native | ❌ Not MCP-native | ❌ Not MCP-native |\n| **Offline/Local** | ✅ Fully local | Cloud-dependent | Docker needed | Docker needed |\n| **Encryption** | AES-256-GCM ✅ | ❌ | ❌ | ❌ |\n| **Hybrid Search** | BM25 + Dense + RRF | Vector only | Vector only | Vector + Graph |\n| **Entity Lifecycle** | Decay + Promote + Archive | ❌ | ❌ | ❌ |\n| **Entity Graph** | Link + Traverse | ❌ | ❌ | ✅ |\n| **Journal Audit Trail** | ✅ Immutable | ❌ | ❌ | ❌ |\n| **State Management** | ✅ Key-value + TTL | ❌ | ❌ | ❌ |\n| **MCP Tools** | Versioned; [public API reference](https://perseus.observer/vault/mcp-reference/) | 5 | 8 | 0 |\n| **License** | MIT | Apache 2.0 | Apache 2.0 | Apache 2.0 |\n\n[Full comparison: Perseus Vault vs Mem0 →](docs/comparison/perseus-vault-vs-mem0.md)\n[vs Letta →](docs/comparison/perseus-vault-vs-letta.md)\n[vs Zep →](docs/comparison/perseus-vault-vs-zep.md)\n\n### Stress Test: 100K Entities\n\nPerseus Vault handles sustained test workloads on modest hardware. The numbers\nbelow are from the committed artifact\n[`benchmark/scale/report.json`](benchmark/scale/report.json): the real release\nbinary driven over MCP stdio (one persistent process per corpus size), AMD64\n16-core, Windows 11, every write durable before the next is sent.\n\n| Metric | 10K | 100K |\n|---|---|---|\n| **Write throughput, sustained (MCP stdio)** | 479 docs/s | 40 docs/s |\n| **Hybrid recall p50** | 19.03 ms | 79.73 ms |\n| **FTS5 recall p50** | 3.14 ms | 15.67 ms |\n\nFull percentiles, `as_of` point lookups, temporal recall, and cold-start\nnumbers are in [`benchmark/scale/`](benchmark/scale/README.md).\n\nRun it yourself: `python benchmark/scale/run.py`\n\n### Recall Accuracy at Scale: Keyword Collapses, Hybrid Holds\n\nSpeed is table stakes — the question that matters for agent memory is *does the\nright memory actually surface?* Measured on distinct-content corpora (first-party,\nreproducible; see [`benchmark/lambda/`](benchmark/lambda/)), recall@k by mode:\n\n**100,000 entities** (1×H100, `nomic-embed-text` on Ollama):\n\n| recall@k | keyword (BM25/FTS5) | dense | **hybrid (RRF)** |\n|---|---|---|---|\n| @1 | 0.003 | 0.680 | **0.785** |\n| @5 | 0.015 | 0.859 | **1.000** |\n| @10 | 0.029 | 0.899 | **1.000** |\n\nAt 100K entities, hybrid recall is **perfect @5 while keyword search lands ~1.5%\nof the time** — a **~66× gap**. And it *widens* with scale: at 10K entities keyword\nrecall@5 was 0.008 while hybrid was already 1.000; keyword-only memory silently\ndegrades as an agent accumulates history, hybrid (BM25 + dense + reciprocal-rank\nfusion) does not. This is the core argument for Perseus Vault's hybrid retrieval.\n\n**Head-to-head, same box, same corpus, all fully local** (1×H100, Ollama —\nidentical fact set, queries, and substring judge for every system):\n\n| System | Recall accuracy | p50 latency | Notes |\n|---|---|---|---|\n| **Perseus Vault** (hybrid) | **1.00** | 35.6 ms | single self-contained binary, in-process |\n| Letta (archival / pgvector) | 1.00 | 135.5 ms | server + Postgres/pgvector |\n| Mem0 (vector) | 0.60 | 37.9 ms | Python + vector DB |\n| Zep (Graphiti temporal KG) | 0.20 | 49.7 ms | server + Neo4j; graph extracted by local model |\n\nEvery competitor was **stood up and run live** on the same box against the same\nlocal Ollama (`qwen2.5:14b-instruct` + `nomic-embed-text`) — no cloud, no fabricated\nnumbers. Letta ran as the `letta/letta` server (bundled Postgres/pgvector) and matched\nPerseus Vault at 1.00. Zep's self-hosted Community Edition server is deprecated and its\n`zep_python` memory API is now Zep Cloud-only, so we measured Zep's actual OSS engine —\nGraphiti temporal KG on Neo4j — with entity/edge extraction *and* embeddings on the same\nlocal Ollama. Its 0.20 reflects the honest cost of building a knowledge graph with a\n**local** model (structured extraction is lossy: 5 entities / 2 edges from 6 facts) — not\nZep Cloud, which uses frontier models. Full artifact + methodology:\n[`benchmark/lambda/results/competitors.json`](benchmark/lambda/results/competitors.json).\n\n**Cold-start:** a bare GPU box reaches its **first grounded RAG answer in 3.3s**\n(models staged on disk).\n\nReproduce: [`benchmark/lambda/scale_bench.py`](benchmark/lambda/scale_bench.py) and\n[`competitors_bench.py`](benchmark/lambda/competitors_bench.py).\n\nDeploying beside a model server on a GPU host (vLLM on MI300X/H100)? See the\n[AMD MI300X deployment reference](docs/deployment-amd-mi300x.md) — measured\nco-residency numbers plus the `/dev/shm`, PID-1, and version-pinning gotchas\nthat break these stacks in practice.\n\n## Framework Integrations\n\nReady-to-use adapters that make Perseus Vault the default memory backend for\npopular AI agent frameworks:\n\n| Framework | Integration | Type |\n|---|---|---|\n| [**LangGraph**](integrations/langgraph/) | `PerseusVaultStore` | `BaseStore` implementation |\n| [**CrewAI**](integrations/crewai/) | `PerseusVaultMemoryTool` | Agent tool |\n| [**AutoGen**](integrations/autogen/) | `PerseusVaultMemory` | `Memory` implementation |\n\nEach adapter:\n- Connects via MCP stdio subprocess (persistent session)\n- Maps the framework's memory interface to Perseus Vault tools\n- Comes with a README quickstart (5 minutes to working)\n- Has passing tests with mocked MCP transport\n\nAny MCP-compatible framework works with Perseus Vault directly. See\n[MCP client and framework integrations](docs/clients/README.md) for the full list.\n\n## Versioned Canonical MCP Tools\n\n> **The count is release/profile-specific.** The v2.23.2 `--no-default-features` snapshot in the [public API reference](https://perseus.observer/vault/mcp-reference/) publishes **175 canonical MCP tools**. The reference's `metadata.json` records the source commit, feature profile, generator versions, and raw snapshot digest.\n> New integrations should use the canonical `perseus_vault_*` namespace and verify the installed server with `perseus-vault doctor` or the published snapshot. Historical migration material is isolated in [`docs/migration/legacy-tool-prefixes.md`](docs/migration/legacy-tool-prefixes.md).\n\n### Tool advertisement profiles\n\nThe recommended configuration for an LLM agent host is the explicit lean profile:\n\n```bash\nperseus-vault serve --profile lean --db ~/.perseus-vault/data/perseus-vault.db\n```\n\n`--profile lean` reduces the advertised `tools/list` response to the core memory\nsurface: `perseus_vault_remember`, `perseus_vault_recall`,\n`perseus_vault_forget`, `perseus_vault_correct`, `perseus_vault_context`,\n`perseus_vault_workspace_status`, and `perseus_vault_health`. In lean mode,\n`perseus_vault_workspace_status` is caller-scoped to the transport-stamped\nMCP `clientInfo.name` and does not disclose other profile/workspace bindings.\nThe profile is an advertisement reduction, not an authorization boundary; hidden\ncanonical tools stay available to explicitly governed `tools/call` requests.\n\n`default` (the default) and `all` are equivalent and advertise the complete\ncanonical registry. The existing `PERSEUS_VAULT_TOOL_SCOPE` setting can further\nreduce the full view for deployments that use the older agent/ops tiers; counts\nremain release/profile-specific and must be derived from the checked-in registry.\n\n### Tool scopes (advertisement tiers, #1051)\n\nBy default `tools/list` advertises every canonical tool. Set\n`PERSEUS_VAULT_TOOL_SCOPE` to narrow the advertised surface for token- and\nattention-constrained agent clients:\n\n| Setting | Advertised surface | Count |\n|---|---|---|\n| `full` (default) | everything | 175 |\n| `ops` | agent surface + operational grooming, maintenance, governance, export | 168 |\n| `agent` | everyday memory + coordination surface (recall / remember / context / handoffs / state, plus the agent-side AAR calls) | 55 |\n\nScopes are **advertisement-only**: a hidden tool remains fully callable via\n`tools/call`, and authorization stays with workspace binding and authority\nmanifests. The tier classification is a 1:1 side table (`TOOL_SCOPES` in\n`src/mcp.rs`), CI-enforced by `scripts/registry_metadata_check.py` — every\nnew tool must be classified. `admin`-tier tools (`migrate`, `purge`,\n`erase`, `vault_import`, `authority_set` / `authority_revoke` /\n`authority_set_signed`) never appear in a scoped list.\n\nFor multi-agent or HTTP deployments, set `PERSEUS_VAULT_STRICT_SCOPE=1`.\nStrict scope mode requires every scoped read or mutation to carry a\ntransport-stamped MCP `clientInfo.name`, a non-empty `workspace_hash`, and an\nactive exact workspace binding. Unbound legacy sessions remain available only\nwhen this deployment gate is explicitly off; they are not a substitute for\nauthority manifests in a shared deployment.\n\n### Entity CRUD\n| Tool | Description |\n|---|---|\n| `perseus_vault_remember` | Store/update entity. Idempotent by (category, key); a content change snapshots the prior version into history. |\n| `perseus_vault_recall` | Search with FTS5/dense/hybrid modes, filters, stemming expansion. Query contract (#562): `query=\"\"` is match-all enumeration (the \"list all\" path); `\"*\"` and other wildcards are literal FTS5 terms, **not** globs — `\"*\"` matches nothing. |\n| `perseus_vault_scan` | Deterministic paginated enumeration of a category or the whole store (#562): immutable `id ASC` keyset pages with a `next_cursor`/`has_more` contract, so export/sync/reset callers can walk every entity exactly once. Read-only — no retrieval-count/decay side-effects, no offset cap. |\n| `perseus_vault_hygiene` | Read-only startup-memory hygiene report (#675): scores active memories by \"actionability\" (concrete anchors — issue keys, #refs, paths, URLs, decisions — vs vague/date-only/short) and lists the worst offenders with reasons, for archive/consolidate curation. |\n| `perseus_vault_recall_layer` | Recall from a specific biomimetic layer (world, episodic, semantic). |\n| `perseus_vault_recall_when` | Proactive just-in-time recall: surface entities whose `recall_when` triggers match. |\n| `perseus_vault_get_entity` | Fetch one entity by ID with full `body_json`. |\n| `perseus_vault_as_of` | Transaction-time time-travel: the version of a fact (category + key) that was *believed* at a past instant. |\n| `perseus_vault_valid_at` | Valid-time lookup: the version that was *actually true in the world* at an instant, per current knowledge (SQL:2011 APPLICATION_TIME). |\n| `perseus_vault_bitemporal` | Full 2-axis bi-temporal query: \"as of transaction time T, what did we believe was true at valid time V\" — the exact rectangle cell. |\n| `perseus_vault_history` | List superseded versions of a fact (category + key), newest first — paginated (`limit` default 20, plus `offset`); `total` reports the full trail size (companion to `perseus_vault_as_of`). |\n| `perseus_vault_forget` | Soft-delete (archived=1). |\n\n### Search & RAG\n| Tool | Description |\n|---|---|\n| `perseus_vault_ask` | RAG: recall context, query LLM, return grounded answer with sources. |\n| `perseus_vault_embed` | Generate dense vectors via the bundled model, Ollama, or OpenAI-compatible endpoint. |\n| `perseus_vault_semantic_search` | Dense-only semantic search shortcut — find entities by meaning, ranked purely by embedding similarity (no keyword fallback). |\n| `perseus_vault_context` | Pre-formatted markdown block for session injection. Recall-first by default: pass `query` (the current task/message) and only topically relevant entities are injected, clamped to a per-model budget; the legacy unconditional dump requires `mode: \"always_inject\"`. |\n| `perseus_vault_ingest` | Trigger connector syncs (GitHub, file watcher); unchanged content is skipped via containment replay (#1050). |\n| `perseus_vault_span_audit` | Extraction-loss net (#1048): retain sentences the extractor missed as residual spans, verbatim with provenance. |\n| `perseus_vault_report_refusal` | Extraction-loss net (#1048): refusal-as-signal — re-score spans vs the query, return a retry payload, flag lossy units. |\n| `perseus_vault_report_success` | Extraction-loss net (#1048): confirm a retry — attach a provisional query key so the identical repeat query serves first-pass. |\n| `perseus_vault_ingest_file` | Locally extract a document's text (plaintext/markdown always; DOCX/PDF with the `multimodal` feature) and store it as a recallable entity. |\n| `perseus_vault_extract` | Local, deterministic, rule-based knowledge extraction (facts / preferences / temporal events / episodes) from text or a stored entity. Read-only. |\n| `perseus_vault_capture` | Opt-in in-session capture (#520): distill a transcript/insight payload (text, markdown, or JSONL) into durable entities (root-cause / pitfall / decision / pattern / takeaway) the moment a problem is solved. Local rule-based distiller by default, optional `llm: true` with graceful fallback; near-dup merging stays ON plus a per-invocation cap (anti-flood). Also a CLI verb: `perseus-vault capture`. |\n| `perseus_vault_memories` | Anthropic memory-tool compatible file interface (`view`/`create`/`str_replace`/`insert`/`delete`/`rename` under `/memories`), backed by vault entities. |\n\n> 📖 **[docs/retrieval-modes.md](docs/retrieval-modes.md)** — one enumerated reference for every retrieval mode (keyword · dense · hybrid · graph · GraphRAG · proactive `recall_when` · temporal `as_of`): mechanism, when to use, invocation, and examples.\n\n### Graph\n| Tool | Description |\n|---|---|\n| `perseus_vault_link` | Create typed relationship links between entities. |\n| `perseus_vault_unlink` | Remove entity links. |\n| `perseus_vault_traverse` | Walk entity link graph up to configurable depth. |\n| `perseus_vault_communities` | GraphRAG community detection over the link graph (deterministic label propagation or greedy-modularity \"louvain\"; pure Rust, offline). |\n| `perseus_vault_community_summary` | Extractive (optionally LLM-polished) summary of one community, materialized as an entity with `evidence_for` links to members. |\n| `perseus_vault_global_recall` | GraphRAG global search: breadth over community summaries, then depth into the best communities' members — holistic answers across clusters. |\n| `perseus_vault_graph_drift` | Read-only graph/entities/indexes/receipts drift report (#869): unattested, dangling, archived/expired-target, and cross-workspace edges, stale community memberships, FTS drift, journal refs to missing entities. |\n| `perseus_vault_graph_attest` | Stamp the from-side entity id as the evidence anchor on legacy edges so they become serveable by the graph recall arms (#869); dry-run preview, journaled. |\n\n### Journal\n| Tool | Description |\n|---|---|\n| `perseus_vault_journal` | Append structured event with actor attribution. |\n| `perseus_vault_check_failure_pattern` | Deja-vu guard: check an action against previously recorded failures (journal + failure/pitfall entities) before retrying it. Read-only. |\n| `perseus_vault_timeline` | Query journal by time range with filters. |\n\n### State\n| Tool | Description |\n|---|---|\n| `perseus_vault_state_set` | Set key-value state with optional TTL. |\n| `perseus_vault_state_get` | Get state value. Returns null if expired. |\n| `perseus_vault_state_delete` | Delete state entry. |\n| `perseus_vault_state_list` | List state keys, optionally filtered by prefix. |\n\n### Lifecycle\n| Tool | Description |\n|---|---|\n| `perseus_vault_decay` | Recalculate Ebbinghaus decay scores (batched 1000-entity transactions). |\n| `perseus_vault_prune` | Bulk archive by category, decay threshold, or age. |\n| `perseus_vault_purge` | Permanently delete archived entities + VACUUM. Destructive. |\n| `perseus_vault_expire` | Time-based lifecycle sweep: entities past their body `expires_at` transition to `status='expired'` (content retained, dry-run supported). |\n| `perseus_vault_redact` | Content redaction: scrub a workspace-scoped entity's body to a hash-only marker, delete history + FTS text, keep metadata (re-ingest allowed). Requires explicit `workspace_hash`. |\n| `perseus_vault_erase` | Physical erasure of a workspace-scoped entity across ALL derived layers (FTS, history, communities, links, journal) + permanent re-ingest suppression. Requires explicit `workspace_hash`; dry-run supported. |\n| `perseus_vault_cohere` | Autonomous coherence grooming pass — promote, decay, link, archive. |\n| `perseus_vault_autocohere` | Full atomic grooming: cohere → decay → compact in one pass (supports dry-run). |\n| `perseus_vault_compact` | Archive entities below decay threshold. |\n| `perseus_vault_reindex` | Rebuild FTS5 search index from entities table. |\n| `perseus_vault_consolidate` | Merge overlapping/duplicative entities in a category into durable, evidence-tracked observations (mirror image of `perseus_vault_conflicts`). |\n| `perseus_vault_dream` | Sleep-time LLM consolidation: reflect over clusters of related episodic memories via the configured LLM and write back durable semantic insights, provenance-linked to every source. Idempotent (evidence-set hash), contradiction-aware, bounded; requires `--llm-endpoint`. |\n\n### Quality\n| Tool | Description |\n|---|---|\n| `perseus_vault_score` | Assign quality score (0.0-1.0). |\n| `perseus_vault_conflicts` | Detect conflicting entities via trigram similarity; opt-in `resolve=true` invalidates the lower-certainty side into history (reversible, dry-run by default). |\n| `perseus_vault_correct` | Structured correction capture for learning from errors. |\n| `perseus_vault_supersede` | Mark a new fact as superseding an old one (sets the old entity to `deprecated`). |\n| `perseus_vault_follow` | Record whether an entity was actually FOLLOWED or MISSED — follow-rate efficacy signal that feeds both decay scoring and outcome-weighted recall ranking (#681). |\n\n### Keystones (policy rules)\n| Tool | Description |\n|---|---|\n| `perseus_vault_keystone_set` | Author a Keystone — a mandatory policy rule that survives context compaction (#683). Scoped (tenant/fleet/agent), weight-ranked, crypto-chained on every mutation; authoring is trust-tier-gated. |\n| `perseus_vault_keystone_get` | Fetch the merged Keystones for a scope, ordered by weight (highest first) then scope specificity — the deterministic session-start counterpart to recall. A renderer injects these ahead of all other context. |\n| `perseus_vault_agent` | Register/update or look up an agent in the multi-agent registry (#684): identity + trust tier (0-3) + fleet. Trust tier gates sensitive ops (e.g. authoring keystones needs tier ≥ 2) and drives visibility enforcement on recall. |\n\n### Vault Transfer (peer federation disabled)\n| Tool | Description |\n|---|---|\n| `perseus_vault_vault_export` | Export entities to .md files with YAML frontmatter. |\n| `perseus_vault_vault_import` | Import from .md vault directory (idempotent). |\n| `perseus_vault_share` | Share one entity (by category + key) into another workspace, preserving content. |\n| `perseus_vault_workspace_list` | List all distinct entity categories. |\n\n`perseus_vault_federate` is intentionally not advertised or executable. Peer\ntransfer remains disabled until authenticated authority, rollback-capable\ncustody, conflict handling, and tombstone/erasure propagation are implemented.\nUse the explicit `vault_export` / `vault_import` tools for reviewed file-based\ntransfers.\n\n### Metrics & Ops\n| Tool | Description |\n|---|---|\n| `perseus_vault_stats` | Full DB statistics across all tables. |\n| `perseus_vault_health` | Server and DB health check. |\n| `perseus_vault_bench` | Performance benchmark tracking. |\n| `perseus_vault_maintenance` | DB maintenance: dedup, orphan detection, VACUUM, FTS5 reindex (supports dry-run). |\n| `perseus_vault_synthesize` | LLM session synthesis — extract lessons from transcripts. |\n| `perseus_vault_migrate` | Migrate v0.1.x DB to current schema. |\n\n### Tools by job (agent cheat sheet)\n\nNot a category listing — a job listing. Pick the row for what the agent is\ntrying to do:\n\n| Job | Tools |\n|---|---|\n| Remember a durable fact / decision / correction | `remember`, `capture`, `journal`, `correct` |\n| Recall before planning | `recall`, `recall_batch`, `recall_when`, `context`, `ask` |\n| Reconstruct the development narrative (intent trail, next work) | `handoff_pack` (with `include_intent_trail` / `include_next_work`), `delegation_brief`, `timeline`, `traverse` |\n| Decisions: supersession and authority | `supersede`, `history`, `authority_get`, `action_receipt_get`, `keystone_get` |\n| Ask \"what did we believe then?\" | `as_of`, `valid_at`, `bitemporal`, `history` |\n| Correct the record / surface contradictions | `correct`, `supersede`, `conflicts`, `reject_value` |\n| Policy that survives compaction | `keystone_get`, `keystone_set` |\n| Ops, trust, and scope | `health`, `stats`, `agent`, `workspace_status`, `doctor` (CLI) |\n\n## CLI\n\n```bash\n# Server\nperseus-vault serve --db /data/perseus-vault.db\nperseus-vault serve --web --port 8767 --encryption-key ~/.perseus-vault/secret.key\nperseus-vault serve --llm-endpoint http://localhost:11434/api/generate --llm-model llama3\nperseus-vault serve --transport sse --port 8787 --mcp-token my-secret-token\n\n# Maintenance (operate directly on DB, no server needed)\nperseus-vault stats          --db /data/perseus-vault.db\nperseus-vault forget         --db /data/perseus-vault.db --category decision --key stale-choice --reason \"superseded\"\nperseus-vault prune          --db /data/perseus-vault.db --category junk --min-decay 0.1 --dry-run\nperseus-vault purge          --db /data/perseus-vault.db --dry-run\nperseus-vault decay          --db /data/perseus-vault.db\nperseus-vault reindex        --db /data/perseus-vault.db\nperseus-vault vault-export   --db /data/perseus-vault.db --vault-dir ./export/\nperseus-vault vault-import   --db /data/perseus-vault.db --vault-dir ./export/\nperseus-vault obsidian-sync  ~/obsidian-vault/Perseus Vault/          # one-shot export to an Obsidian vault\nperseus-vault obsidian-sync  ~/obsidian-vault/Perseus Vault/ --watch  # continuous sync on every memory change\n\n# Key management\nperseus-vault keygen --key-file ~/.perseus-vault/secret.key\n\n# #918: read-only TUI inspector (retrieval telemetry, claim cards, entity\n# state, decay, bi-temporal history). Never writes; repairs go through the\n# governed MCP tools. Requires the default `tui` feature.\nperseus-vault inspect --db /data/perseus-vault.db --key-file ~/.perseus-vault/secret.key\n```\n\n### Live updates without restarting the session\n\n`perseus-vault serve` detects when its own binary is replaced on disk\nmid-session (the normal `cargo build` / reinstall flow) and refuses to serve\nresults from the stale process image — every tool answers a loud, explicit\nerror instead of degrading into empty results (#858, #1045). Two recovery\npaths, both on the same stdio connection (no client restart):\n\n- **Explicit:** call `perseus_vault_handoff_restart {\"confirm\": true}` — the\n  process hot-swaps to the new binary and the session continues seamlessly,\n  with the MCP session state (initialization + agent identity) preserved.\n- **Automatic (opt-in):** launch the server with\n  `PERSEUS_VAULT_AUTO_HANDOFF=1` and the swap happens transparently on the\n  next tool call, which the new binary answers directly.\n\nOn macOS/Linux the swap is a true `exec` (same PID, same pipes). Windows\nlocks a running executable, so mid-session replacement is not possible there;\nupdate across a session boundary. Full contract and the local dev workflow:\n[`docs/specs/live-update-handoff.md`](docs/specs/live-update-handoff.md).\n\n> **Manual DB edits.** The maintenance verbs above and the normal MCP write path\n> keep the FTS5 index in sync automatically. Editing the `entities` table\n> **directly** with `sqlite3` (a manual `DELETE`/`UPDATE`) bypasses that sync and\n> can leave orphaned index rows — \"ghost\" recall hits for content that is already\n> gone. After any direct SQL edit, run `perseus-vault maintain --db <path>` (or\n> `perseus-vault reindex`) to reconcile the FTS index.\n\n### Flags\n\n| Flag | Description |\n|---|---|\n| `--db` | SQLite database path (default: `~/.perseus-vault/data/perseus-vault.db`) |\n| `--profile` | MCP advertisement profile: `default`/`all` (full registry) or `lean` (core memory surface; recommended for LLM hosts) |\n| `--web` | Start web dashboard |\n| `--port` | Dashboard port (default: 8767) |\n| `--web-bind` | Dashboard bind address (default: 127.0.0.1) |\n| `--transport` | MCP transport: `stdio` (default), `sse`, or `http` |\n| `--mcp-token` | Bearer token for SSE/HTTP transport auth |\n| `--encryption-key` | AES-256-GCM key file path |\n| `--llm-endpoint` | LLM API endpoint for `perseus_vault_ask` and embeddings |\n| `--llm-model` | LLM model name (default: llama3) |\n| `--llm-api-key` | API key for LLM endpoints (OpenAI, Azure, etc.) |\n| `--embedding-endpoint` | OpenAI-compatible embedding endpoint |\n| `--connectors-config` | Path to connectors.yaml |\n\n### Database location\n\nThe **canonical** database path is:\n\n```\n~/.perseus-vault/data/perseus-vault.db\n```\n\nAlways pass `--db` (or set `$PERSEUS_VAULT_DB_PATH`) in scripts, MCP host configs, and\ncron/harvest jobs so every invocation targets the same file. When neither is\nset, Perseus Vault resolves the default in this order and uses the **first that\nalready exists** (so upgraders and legacy single-user installs are picked up\ninstead of silently starting empty):\n\n1. `~/.perseus-vault/data/perseus-vault.db` — canonical (current name)\n2. `~/.perseus-vault/data/perseus-vault.db` — pre-rename\n3. `~/.perseus-vault/data/perseus-vault.db` — pre-rename\n4. `~/perseus-vault.db` — legacy single-user install location\n\nIf none exist, it creates `~/.perseus-vault/data/perseus-vault.db`. If **more than one**\nof these exists and you did not pass `--db`/`$PERSEUS_VAULT_DB_PATH`, Perseus Vault\nprints a stderr warning naming the chosen file and the others it ignored, so an\nambiguous multi-database state is visible rather than silent. Setting `--db` or\n`$PERSEUS_VAULT_DB_PATH` explicitly always wins and suppresses the warning.\n\n## Your AI Memory in Obsidian\n\nPerseus Vault is your AI agent's long-term memory — and it doubles as **your** second\nbrain. Every entity your agent remembers exports to a plain Markdown note with\nYAML frontmatter, so your AI's memory becomes a navigable personal knowledge\nbase inside the tools you already use: **Obsidian, Logseq, or Notion.**\n\n```bash\n# Export your entire memory to an Obsidian vault as linked Markdown notes\nperseus-vault obsidian-sync ~/obsidian-vault/Perseus Vault/\n\n# Keep it live — re-export automatically on every memory change\nperseus-vault obsidian-sync ~/obsidian-vault/Perseus Vault/ --watch\n```\n\nOpen the vault in Obsidian and you get a graph of your agent's knowledge.\n\n**WikiLink backlinks.** When one entity links to another (via `perseus_vault_link` or a\n`depends_on` / `implements` / `references` relationship), the exported note gets\na `## Links` section with `[[WikiLink]]` backlinks that resolve natively in\nObsidian's graph view:\n\n```markdown\n---\nid: cli-de8dfb8364b6\ncategory: architecture\nkey: api\ntype: insight\ndecay_score: 0.5000\n---\n\n{\"content\":\"axum service\"}\n\n## Links\n\n- [[cli-99756b494c7d|database]] (depends_on)\n```\n\nLinks resolve **by entity id** (notes are written as `<id>.md`) so they never\nbreak, and Obsidian shows the human-readable `key` as the link label. Open the\ngraph view and your agent's architecture, decisions, and insights become a\nclickable knowledge map.\n\n**`--watch`** polls Perseus Vault's cheap, deterministic state digest on an interval and\nre-exports only when memory actually changes. It naturally catches every\n`perseus_vault_remember` write with no filesystem-watcher dependency and no coupling to\nthe server. Tune the interval with `PERSEUS_VAULT_SYNC_INTERVAL_SECS` (default: 2s).\n\n### Other PKM tools\n\n| Tool | How |\n|---|---|\n| **Obsidian** | `perseus-vault obsidian-sync <vault>` — WikiLinks resolve in the graph view out of the box. |\n| **Logseq** | Point `obsidian-sync` at your Logseq graph directory. Logseq reads the same `[[WikiLink]]` syntax and Markdown frontmatter. |\n| **Notion** | Run `perseus-vault vault-export`, then use Notion's *Import → Markdown & CSV* to pull the notes in. |\n\nUnlike cloud-only \"second brain\" tools, Perseus Vault runs **100% local**, is written in\n**Rust**, encrypts at rest with **AES-256-GCM**, and applies **decay scoring** so\nstale memories fade — your knowledge base stays yours and stays fresh.\n\n## Features\n\n### Semantic Search (on by default)\n- **Bundled, in-process embeddings** — a quantized all-MiniLM-L6-v2 model\n  (384-dim) is compiled into the binary, so dense/semantic search works with\n  **zero config and zero network**: no Ollama, no API key, no model download.\n  This is the default build (`bundled-embeddings` feature).\n- **Auto-embed on write (#271)** — `perseus_vault_remember` embeds each new (or\n  content-changed) entity **synchronously** as it is written, using the bundled\n  model. Single-entity embedding is deterministic and LRU-cached, so it is cheap\n  and adds no background tasks. Embedding failures are non-fatal (logged to\n  stderr); the write always succeeds.\n- **Hybrid is the default recall mode (#271)** — `perseus_vault_recall(query=...)` with\n  no `mode` flag automatically selects **hybrid** (dense + keyword fused via RRF)\n  whenever embeddings exist, and transparently falls back to **fts5** keyword\n  search when none do. No manual `perseus_vault_embed` step, no flags to remember.\n- **`perseus_vault_semantic_search(query, limit)`** — a one-tool shortcut for pure\n  dense, meaning-based search (no keyword fallback) when you just want \"find\n  things like this\".\n- **Optional alternate embedder** — to use **Ollama** or any OpenAI-compatible\n  `/v1/embeddings` endpoint instead of the bundled model, set `--llm-endpoint`\n  (and `--embedding-endpoint` / `--llm-api-key` as needed). This is entirely\n  optional; the bundled model is used by default.\n- Build a lean binary without bundled embeddings via\n  `cargo build --no-default-features` — recall then defaults to keyword search\n  unless a remote embedder is configured.\n\n### Hybrid Search internals\n- **FTS5 keyword search** with LIKE fallback and Porter stemming expansion\n- **Dense vector search** via cosine similarity on stored embeddings\n- **Reciprocal Rank Fusion (RRF)** — combine keyword + vector results\n- **Query expansion** — automatic stemming variants for broader recall\n### Memory Lifecycle\n\nPerseus Vault models memory using three biomimetic layers, inspired by human memory pathways:\n\n- **World (Core):** Slow-decaying, global facts about the environment.\n- **Episodic (Buffer):** Fast-decaying, session-specific interaction history.\n- **Semantic (Working):** Medium-decaying, general knowledge and learned concepts.\n\nYou can interact with these layers directly using the `perseus_vault_recall_layer` tool or by specifying the `layer` parameter in `perseus_vault_remember`.\n\n- **Ebbinghaus decay** — memories naturally fade unless retrieved (refresh on access)\n- **Layer promotion** — buffer → working → core based on access frequency\n- **Automatic archival** — stale entities archive; purge to permanently delete + VACUUM\n- **Always-on entities** — pin identity-critical memories for session injection (hard-capped under recall-first; prefer `recall_when` triggers)\n- **Prospective query hints (#919)** — optional 1–3 natural-language phrasings per entity (`hints` on `perseus_vault_remember`) that are indexed into FTS5 alongside the body, bridging vocabulary gaps between plain-language queries and stored wording. Default-off (`PERSEUS_VAULT_HINTS_ENABLED=1`); rejected while disabled. See [docs/specs/prospective-query-hints.md](docs/specs/prospective-query-hints.md).\n\n### Recall-First Context Injection\n\nThe vault is the query layer — it retrieves the few facts a turn needs instead of\nhanding the host a standing blob to staple into every system prompt.\n`perseus_vault_context` and `perseus-vault prepare` are **recall-first by default**:\n\n- **Relevance gating** — pass `query` (the current task/message) and only entities\n  whose `recall_when` triggers or indexed content match it are injected. No query,\n  no topical injection: the block is a compact retrieval pointer, byte-stable\n  across unrelated vault writes (prefix-cache friendly).\n- **Per-model recall budget** — output is clamped to a character budget resolved\n  from the host model: default/lean profile 1500 chars; large-window (\"opus\")\n  profile 6000 chars; `max_context_chars` overrides both.\n- **Capped always-on** — `always_on: true` still works for identity-critical\n  facts, but the recall-first set is hard-capped (top 5) and overflow emits a\n  warning steering you to `recall_when` triggers.\n- **Legacy opt-in** — the old unconditional top-N dump is still available with\n  `mode: \"always_inject\"` (`--legacy-context` for `prepare`), unclamped unless\n  you pass a budget.\n\n```bash\nperseus-vault prepare --task \"deploying the payments service\" --model claude-sonnet-4-6\nperseus-vault prepare --task \"...\" --max-context-chars 800     # explicit budget\nperseus-vault prepare --task \"...\" --legacy-context            # old dump, opt-in\n```\n\n### RAG & Embeddings\n- **`perseus_vault_ask`** — natural language Q&A over stored memories via any LLM (Ollama, OpenAI, etc.)\n- **`perseus_vault_embed`** — generate and store dense vectors via Ollama or OpenAI-compatible `/v1/embeddings`\n- Supports single-entity and batch-category embedding\n\n### Encryption\n- **AES-256-GCM** transparent encryption for live/history `body_json` and query hints\n- **Enabled by default for fresh installs** — the standard key is auto-generated at `~/.perseus-vault/secret.key` on first write\n- `--encryption-key` flag for explicit keys; `perseus-vault keygen` for custom key generation\n- Existing plaintext databases fail closed with an `init --rekey` migration path (or explicit `PERSEUS_VAULT_ALLOW_PLAINTEXT=1`)\n- Protected FTS5 search uses keyed `hmac-sha256-blind-token-v1` tokens for live and historical rows; it does not store body plaintext, but leaks deterministic token relationships\n\n### Web Dashboard\n- Built-in Axum HTTP server (`perseus-vault serve --web --port 8767`)\n- Dark-themed dashboard with search, entity table, vis.js graph, timeline\n- Default bind: `127.0.0.1` (use `--web-bind 0.0.0.0` to expose)\n- Separate SQLite connection in WAL mode for concurrent reads\n\n### External Connectors\n- **GitHub issues connector** — ingest issues/PRs by repo, rate-limit aware\n- **File watcher** — scan directories for `.md`/`.txt`/`.json` files with content-hash dedup\n- YAML-based connector config via `--connectors-config`\n\n### Multi-Transport\n- **stdio** (default) — zero-config, works with any MCP host\n- **SSE** — Server-Sent Events for HTTP-based MCP clients\n- **HTTP** — REST-style MCP endpoint\n- **Bearer token auth** — for SSE/HTTP transports\n\n## Perseus Integration\n\nPerseus Vault is the default memory backend for [Perseus](https://perseus.observer):\n\n```yaml\nperseus_vault:\n  enabled: true\n  transport: \"stdio\"\n  command: [\"perseus-vault\", \"serve\", \"--db\", \"~/.perseus-vault/data/perseus-vault.db\"]\n  timeout_s: 30.0\n  merge_strategy: \"local_first\"\n  fallback_to_local: true\n  context_categories: [\"decision\", \"architecture\", \"convention\"]\n  context_limit: 10\n```\n\n## Government & Federal Procurement\n\nPerseus Vault is built for government deployment from the ground up.\n\n| Capability | Status |\n|---|---|\n| **License** | MIT — no copyleft, no GPL/AGPL |\n| **SBOM** | [Published](./docs/SBOM.md) — NTIA minimum elements |\n| **Air-gapped** | Fully offline — no telemetry, no API calls, no network by default |\n| **Encryption at rest** | AES-256-GCM on bodies, enabled by default for fresh installs |\n| **Audit trail** | Immutable journal with chain-of-custody |\n| **Supply chain** | SLSA attestation in progress |\n\n**For federal buyers:** See [docs/federal-buyers.md](./docs/federal-buyers.md) for\nprocurement information, compliance status, and deployment models (air-gapped,\non-premises, classified environments).\n\nPerseus Computing LLC is a US-owned small business. Current procurement identifiers and owner-published readiness claims are maintained in the [public capability statement](https://perseus.observer/government/capability-statement.html). Those claims are dated and scoped; they do not constitute CMMC certification, an ATO, or a cATO authorization.\nNAICS: 541715, 541511, 541512.\n\n## Privacy Policy\n\nPerseus Vault is a **local-first MCP server** — it runs entirely on your machine.\n\n### Data Collection\n- **No data collection.** Perseus Vault does not collect, transmit, or phone home any user data, usage statistics, or telemetry.\n- All data remains in your local SQLite database file.\n\n### Data Usage & Storage\n- All memory entities, journal entries, and state are stored locally in a SQLite database at the path you specify via `--db`.\n- Optional **AES-256-GCM encryption at rest** is available — when enabled, entity bodies are encrypted before storage.\n- No data is shared with Perseus Computing LLC or any third party.\n\n### Third-Party Sharing\n- **None.** Perseus Vault is fully air-gapped by default. No API calls, no cloud services, no external network requests.\n- The optional dense vector embeddings feature uses a locally-compiled model — no external embedding API is called.\n\n### Data Retention\n- You control retention with four distinct lifecycle operations (see\n  `docs/specs/data-boundaries-retention-lifecycle.md`): soft-delete\n  (`perseus_vault_forget`, content recoverable), expiry (`perseus_vault_expire`, time-based\n  `status='expired'` with content retained), redaction (`perseus_vault_redact`,\n  content scrubbed to hash-only, metadata kept), and physical erasure\n  (`perseus_vault_erase`, removal across all derived layers with permanent re-ingest\n  suppression). `perseus_vault_purge` reclaims space from archived rows.\n- No automatic off-machine backup is performed.\n\n### Contact\n- **Email:** privacy@perseus.observer\n- **GitHub:** [Perseus-Computing-LLC/perseus-vault](https://github.com/Perseus-Computing-LLC/perseus-vault)\n\n## Release Verification\n\nRelease binaries are built from tagged commits via [GitHub Actions](.github/workflows/release.yml). Every release ships:\n\n| Artifact | Description | Verification |\n|----------|-------------|-------------|\n| `perseus-vault-<target>.tar.gz` | Full build (bundled embeddings, glibc) | SHA-256 checksum in `.sha256` sidecar |\n| `perseus-vault-lite-<target>.tar.gz` | Lean build (`--no-default-features`, musl/static) | SHA-256 checksum in `.sha256` sidecar |\n| SLSA provenance attestation | Sigstore-signed build provenance | `gh attestation verify <archive> --repo Perseus-Computing-LLC/perseus-vault` |\n\n### Verify a release binary\n\n```bash\n# 1. Verify SHA-256 checksum\nsha256sum -c perseus-vault-lite-x86_64-unknown-linux-musl.tar.gz.sha256\n\n# 2. Verify SLSA build provenance (requires gh CLI + OIDC session)\ngh attestation verify perseus-vault-lite-x86_64-unknown-linux-musl.tar.gz \\\n  --repo Perseus-Computing-LLC/perseus-vault\n\n# 3. Confirm the binary identity\n./perseus-vault --version\n# Should show both the release version AND the git commit hash, e.g.:\n#   perseus-vault 2.23.2 (v2.23.2-0-gabcdef1)\n\n# 4. Confirm the doctor reports the same identity\n./perseus-vault doctor --db /tmp/test.db | head -1\n#   perseus-vault doctor — v2.23.2 (v2.23.2-0-gabcdef1)\n```\n\n### Build reproducibly from source\n\n```bash\n# The exact same binary (bit-for-bit) requires matching:\n#   - Rust toolchain version (see rust-toolchain.toml)\n#   - Locked dependencies: `cargo build --locked`\n#   - Build flags: `--release` for release builds\n\ncargo build --locked --release\n./target/release/perseus-vault --version\n```\n\n## License\n\nMIT — see [LICENSE](./LICENSE).\n",
  "bytes": 55156,
  "sha": "3fa08b483c91c3ec8fe5e177c69fa47b8cac608b32e21608b470f5445049ce8a",
  "repo_slug": "perseus-computing-llc/perseus-vault",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_perseus_computing_llc_mimir_37e04cf7/readme"
}