{"id":"8f565340-e735-4652-928a-58a313f5aa5c","slug":"slm-vault","kind":"mcp","name":"slm-vault","summary":"Privacy-first AI personal data manager. A local trusted agent that external AIs command via MCP — they never see your documents. Encrypted storage, local RAG, activity logging, and per-agent permissio","owner":"zd87pl","repoUrl":"https://github.com/zd87pl/slm-vault","license":"Apache-2.0","licenseTier":"permissive","trust":"community","stars":2,"match":null,"fewStars":true,"format":"mcp","createdAt":"2025-10-11T19:08:37.000Z","addedAt":"2026-10-21T05:41:57.034Z","logoUrl":"https://avatars.githubusercontent.com/u/174021523?u=c50be5d526a519bfd5518b76d01c7b256ad1f447&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["search","data-analytics","memory-knowledge"],"tags":["agentic-ai","ai","apple-silicon","encryption","llm","local-first","mlx","personal-data"],"runtime":"python","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-26T13:02:34.080Z","sample":false,"url":"https://conduits.dev/tools/slm-vault","language":"Python","transports":["stdio"],"install":{"pypi":"enclave-vault"},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# Enclave\n\n**Privacy-First AI Personal Data Manager**\n\n> Your local agent that external AIs query via MCP — they get answers generated on your machine instead of your files.\n\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)\n[![MCP](https://img.shields.io/badge/MCP-compatible-green.svg)](https://modelcontextprotocol.io/)\n\n> **Early beta.** Local chat in the desktop app works only on Apple Silicon\n> Macs today, and only document text and secret values are encrypted at rest.\n> Read [Known Limitations](#known-limitations) before trusting it with\n> sensitive files.\n\n## Quick Start (Apple Silicon Mac)\n\nLocal chat needs a Mac with Apple Silicon (M1 or later); 16 GB+ RAM is\nrecommended. Other machines: see [Platform support](#platform-support).\n\n```bash\ngit clone https://github.com/zd87pl/slm-vault\ncd slm-vault\n./setup.sh\n```\n\n`setup.sh` creates a `.venv`, detects Apple Silicon, installs the right extras\n(MLX local inference, desktop GUI, fast vector search), and finishes with an\nenvironment check. Then:\n\n```bash\nsource .venv/bin/activate\n\nenclave-gui             # 1. Launch the desktop app\nenclave mcp install     # 2. Connect Claude Desktop (merges into your existing config)\nenclave doctor          # 3. Anytime something looks off\n```\n\nRestart Claude Desktop after step 2 and ask Claude about your documents.\nEnclave retrieves the relevant passages and writes the answer locally; Claude\nreceives that answer, not your files.\n\n> **First run notes**: the install itself is several GB (it includes PyTorch).\n> The first chat downloads a ~1 GB local model (Qwen 2.5 1.5B, 4-bit) from\n> Hugging Face; the first document you index downloads a ~130 MB embedding\n> model. Both are cached afterwards. When an AI app calls Enclave, a consent\n> dialog appears: \"Allow Once\" is the cautious choice (you are asked again\n> next time), while \"Always Allow\" lets that app call every tool its policy\n> allows, with no expiry. On a default install Enclave cannot tell AI apps\n> apart, so \"Always Allow\" applies to all of them (see [Consent](#consent)),\n> but no app can use the `vault_*` secrets tools until you opt it in. Calls\n> are logged locally either way.\n\n### Having trouble?\n\n`enclave doctor` checks Python, RAM, disk, every dependency, your vault, and\nthe Claude Desktop integration — and prints the exact command to fix anything\nthat's missing.\n\n## The Problem\n\nEvery AI wants your data to be useful. But once you share documents with\nClaude, Cursor, or Copilot, you lose control. They see your raw data. You\ncan't audit access. You can't revoke it.\n\n## The Solution\n\nEnclave is a **local trusted agent** that sits between you and external AIs.\n\n```\nExternal Agent (Claude Desktop / Cursor / Copilot)\n        ↓ MCP command: \"Summarize Q3 report\"\n        ↓\n┌───────────────────────────────────────┐\n│  LOCAL TRUSTED AGENT (Enclave)        │\n│  • Full access to your indexed docs   │\n│  • Reads & processes locally          │\n│  • Generates synthesized response     │\n│  • Logs every access                  │\n└───────────────────────────────────────┘\n        ↓ Response: \"Q3 revenue was $4.2M...\"\n        ↓\nExternal Agent (gets the answer, not the file)\n```\n\nExternal AIs send requests. Enclave retrieves the relevant passages and\ngenerates an answer locally, and the agent receives that answer instead of\nyour files. This limits bulk copying, but answers can quote or closely\nparaphrase your documents, so an agent you allow can still learn whatever it\nasks about. **Consent prompts and the activity log are the controls** — see\n[Privacy Model](#privacy-model).\n\n## Features\n\n- **Local RAG**: Add documents and ask questions over them with semantic search\n- **MCP Integration**: Works with Claude Desktop, Cursor, and any MCP client\n- **Encrypted document text**: ChaCha20-Poly1305 for document and chunk text\n  in the index (names, embeddings and chat history are not encrypted yet —\n  see [What is and isn't encrypted](#what-is-and-isnt-encrypted))\n- **Activity Logging**: MCP tool calls are recorded locally with the calling app\n- **Consent and Allow-Lists**: A consent prompt per calling app, plus a\n  per-app tool allow-list in `~/.enclave/policies.toml` (app detection is\n  limited — see [Consent](#consent))\n- **Local Inference**: MLX-powered LLM on Apple Silicon (Qwen 2.5 1.5B by default)\n- **Desktop GUI**: Flet app; local chat currently needs an Apple Silicon Mac\n- **Adapter Training** (experimental, Apple Silicon only): Fine-tune local\n  models on your documents\n\n### Performance Optimizations\n\n- **HNSW Index**: Approximate vector search via `hnswlib` (installed by\n  `setup.sh`; without it Enclave falls back to brute-force search)\n- **E5-small Embeddings**: `intfloat/e5-small-v2`, 384 dimensions\n- **Persistent Cache**: Embeddings are cached on disk, so unchanged text is not re-embedded\n- **Recursive Chunking**: Chunks split on paragraph and sentence boundaries\n\n## Installation Options\n\nThe recommended path is `./setup.sh` (above). If you prefer manual control:\n\n```bash\npython3.11 -m venv .venv\nsource .venv/bin/activate\npip install -U pip\n\n# Apple Silicon Mac — everything (MLX + GUI + fast search):\npip install -e \".[mac]\"\n\n# Any other machine — GUI + fast search; no MLX, so desktop chat does not\n# work and CLI/MCP answers come from a small fallback model (see Platform support):\npip install -e \".[gui,mac-performance]\"\n\n# Minimal — CLI + MCP server only (still pulls PyTorch, several GB):\npip install -e .\n```\n\nEntry points installed with the package:\n\n| Command | What it does |\n|---------|--------------|\n| `enclave` | CLI (vault, models, prosumer vaults, doctor, MCP setup) |\n| `enclave-gui` | Desktop app |\n| `enclave-mcp` | MCP server (stdio) — what Claude Desktop launches |\n\n### Connect Claude Desktop\n\nThe easy way — detects Claude Desktop, merges into your existing config\n(other MCP servers are preserved; back the file up first if it may not be\nvalid JSON), and points at the right Python:\n\n```bash\nenclave mcp install          # or: enclave mcp install --target cursor\nenclave mcp status           # verify detection + configuration\n```\n\nManual way — `enclave mcp config` prints the JSON block to paste into\n`~/Library/Application Support/Claude/claude_desktop_config.json`.\n\nRestart Claude Desktop afterwards.\n\n### Index Documents (Python API)\n\nThe desktop app and MCP server manage their own encrypted index under\n`~/.vault`. For scripting against a separate index:\n\n```python\nfrom advanced_vault.training import RAGIndex\nimport os\n\n# Generate or load a 32-byte encryption key. Persist the key if you persist\n# the index — a new random key cannot decrypt an existing database.\nmaster_key = os.urandom(32)\n\n# Create encrypted index (explicit path keeps this demo self-contained)\nwith RAGIndex(master_key=master_key, db_path=\"./demo_rag.db\") as index:\n    # Add documents\n    index.add_document(\n        name=\"Q3 Report\",\n        content=\"Revenue increased 15% to $4.2M in Q3...\"\n    )\n\n    # Search\n    results = index.search(\"What was Q3 revenue?\")\n    for r in results:\n        print(f\"{r.document_name}: {r.chunk.content[:100]}...\")\n```\n\n## MCP Tools\n\nThe main tools Enclave exposes to AI agents:\n\n| Tool | Description |\n|------|-------------|\n| `agent_query` | Ask questions about indexed documents |\n| `agent_summarize` | Summarize a topic or document |\n| `agent_draft` | Draft content informed by your documents |\n| `agent_status` | Check indexed documents and agent status |\n| `vault_store` | Store secrets (API keys, passwords) |\n| `vault_recall` | Retrieve a stored secret by its exact entry name |\n\nThe server also advertises experimental tools: `sheriff_*` file-access\nleases (which can return file contents; the default policy blocks them), a\nmock wallet, and cloud `langchain_*` tools that do nothing unless configured.\n\nWhich tools each app may call is set in `~/.enclave/policies.toml`. On a\ndefault install Enclave cannot tell AI apps apart (see [Consent](#consent)),\nso every app gets the file's `default` entry, which allows the `agent_*`\ntools and `query_knowledge` but not the `vault_*` secrets tools. To give\nthem to one app, see\n[Letting one app use the secrets tools](#letting-one-app-use-the-secrets-tools).\nEarlier versions put `vault_*` in `default`. If you never edited the file,\nEnclave replaces it with the new default the next time it starts, keeping\nthe old one as `policies.toml.bak-<date>`; if you did, `enclave doctor`\ntells you which line to change.\n\n**What agents receive**: the `agent_*` tools return text generated locally\nfrom retrieved passages, plus the names of the source documents — not the\nfiles. That text can quote your documents, so treat anything an allowed agent\nasks about as shared with it. `vault_recall` returns the stored secret itself.\n\n## Personal Data Vaults\n\nEnclave can sort your documents into **vault categories**, each with an\noptional, experimental adapter preset:\n\n| Vault | Documents | AI Adapter |\n|-------|-----------|------------|\n| 🏥 **Health** | Medical records, prescriptions, lab results | Health Advisor |\n| 💰 **Finance** | Bank statements, tax returns, investments | Tax Assistant |\n| ⚖️ **Legal** | Contracts, wills, immigration papers | Legal Companion |\n| 🧠 **Personal** | Journals, emails, notes, memories | Life Archivist |\n\n### Auto-Classification\n\nEnclave suggests a category from keywords in each file's name and content\n(a heuristic, so check the result):\n\n```bash\n# Classify a single file\nenclave prosumer classify blood_test.pdf\n\n# Classify an entire folder\nenclave prosumer classify-folder ~/Documents --recursive\n```\n\n### Adapter Training (experimental)\n\nTrain a domain-specific adapter on your documents (Apple Silicon only):\n\n```bash\n# List training presets\nenclave prosumer presets list\n\n# Train via GUI: Drop docs → Click \"Train AI\"\n```\n\nEach preset's system prompt asks the model to stay within limits (these are\ninstructions to the model, not guarantees):\n- **Health Advisor**: Never prescribes, always recommends seeing a doctor\n- **Tax Assistant**: Shows calculations, suggests consulting a CPA\n- **Legal Companion**: Summarizes only, never gives legal advice\n\n### Encrypted Adapter Backup & Sharing (experimental)\n\nA trained adapter is not a copy of your documents, but it can memorize parts\nof them. Treat an exported adapter as being as sensitive as the documents it\nwas trained on:\n\n```bash\n# Export encrypted adapter\nenclave prosumer backup export ~/.vault/adapters/health.wdva \\\n  --name \"My Health Advisor\" --category health\n\n# Import on another device\nenclave prosumer backup import ./health.enclave\n\n# Verify integrity\nenclave prosumer backup verify ./health.enclave\n\n# List all backups\nenclave prosumer backup list\n```\n\n**What's included**: The adapter file exactly as it is on disk (WDVA\nadapters are already encrypted; the backup adds no encryption of its own) +\nmetadata.\n**What's NOT included**: The document files themselves, or any key needed to\ndecrypt the adapter — move that separately if you import on another device.\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                     External AI Agents                       │\n│            (Claude Desktop, Cursor, Copilot)                │\n└───────────────────────────┬─────────────────────────────────┘\n                            │ MCP Protocol\n                            ▼\n┌─────────────────────────────────────────────────────────────┐\n│                      Enclave MCP Server                      │\n│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │\n│  │   Consent   │  │   Activity  │  │  Agent Commands     │  │\n│  │   Manager   │  │   Logger    │  │  (query/summarize)  │  │\n│  └─────────────┘  └─────────────┘  └─────────────────────┘  │\n└───────────────────────────┬─────────────────────────────────┘\n                            │\n        ┌───────────────────┼───────────────────┐\n        ▼                   ▼                   ▼\n┌───────────────┐  ┌───────────────┐  ┌───────────────────┐\n│   RAG Index   │  │  Local LLM    │  │ Encrypted Vault   │\n│  (HNSW+E5)    │  │   (MLX)       │  │ (ChaCha20)        │\n└───────────────┘  └───────────────┘  └───────────────────┘\n```\n\n## Privacy Model\n\n1. **Documents stay local**: They are indexed and stored on your device. What\n   leaves is what Enclave returns to an agent (answers, or a secret via\n   `vault_recall`) — and if that agent is a cloud assistant such as Claude, it\n   becomes part of that conversation.\n2. **Answers, not files**: Agents get locally generated answers and source\n   document names. Answers can quote passages, so this limits bulk copying but\n   cannot stop an allowed agent from learning what it asks about.\n3. **Consent and allow-lists**: See [Consent](#consent).\n4. **Audit trail**: MCP tool calls are logged locally with the calling app,\n   the tool, and whether it was allowed (`~/.vault/activity.jsonl`, plus a\n   policy audit log for calls the allow-list blocks). A call that crashes with\n   an unexpected error after consent is not logged.\n5. **Encryption at rest (partial)**: See below.\n\n### What is and isn't encrypted\n\nEncrypted with ChaCha20-Poly1305 (random 96-bit nonce per record):\n\n- Document text and chunk text in the RAG index (`rag.db`)\n- Secrets and notes stored with `vault_store`, `enclave add-secret` or\n  `enclave add-note` (their service names, tags and descriptions are not\n  encrypted)\n\nNot encrypted yet:\n\n- File names, full source paths and folder metadata\n- Content hashes — an unsalted SHA-256 of each document, which lets anyone\n  holding the database check whether it contains a file they already have\n- Embeddings/vectors (in `rag.db` and the HNSW index files) and the shared\n  embedding cache `~/.enclave/embedding_cache.db`, which keeps entries after a\n  document is deleted; embeddings can leak some of the text they came from\n- Chat history (`~/.vault/chat_history_<profile>.json`, `~/.vault/question_history.json`)\n- Query, activity and audit logs\n\n**The key**: each encrypted database uses a random 32-byte key kept in a\n`master.key` file right next to it. There is no passphrase and no OS keychain\nyet, so anything that can read that folder — malware running as you, a backup\nor sync of the whole folder — can read the vault. The encryption only helps\nwhen a database file is copied without its key file. Turn on FileVault (or\nyour OS's full-disk encryption).\n\n### Consent\n\n- When an app calls a tool (other than the `sheriff_*` tools, which use\n  their own lease flow), Enclave asks in a system dialog. On macOS the choices\n  are Allow Once, Always Allow or Deny; the Linux (zenity) dialog also offers\n  Deny Always. Until you make a lasting choice you are asked on every call. If\n  no dialog can be shown or you don't answer in time, the call is denied.\n- **\"Always Allow\" covers every tool that app's policy allows, with no\n  expiry.**\n- **App identity is a best guess**, from the `MCP_CLIENT` or `PARENT_PROCESS`\n  environment variables (neither is set by `enclave mcp install`) or, if the\n  optional `psutil` package is installed, the parent process name. `psutil` is\n  not an Enclave dependency, so on a default install Claude Desktop, Cursor\n  and every other client are all the same app, `unknown`: they get the\n  `default` policy (document tools only, no `vault_*` secrets tools) and they\n  share one consent decision — \"Always Allow\" for one of them approves them\n  all.\n- To change a decision, **fully quit the AI app first** — the MCP server\n  reads `permissions.json` and `policies.toml` only when it starts, and a\n  running server can write its old permissions back — then edit and restart\n  the app. Remove the app's entry from `~/.vault/permissions.json` to undo\n  \"Always Allow\"; replace it with `{\"denied\": true}` to block the app\n  permanently (macOS has no Deny Always button); edit\n  `~/.enclave/policies.toml` to limit which tools an app can call at all.\n- The desktop app also shows per-app permission toggles, a Revoke button,\n  finer-grained scopes and time-limited access; these are **not enforced yet**.\n  Its global kill switch (Settings → Security) is saved to `policies.toml`,\n  so it reaches an MCP server that is already running only after the AI app\n  restarts.\n- **On Windows, consent prompts are not implemented, so every call that needs\n  consent is denied.**\n\n#### Letting one app use the secrets tools\n\nNo AI app can call the `vault_*` tools until you opt it in:\n\n1. Name the app: in its MCP config (`claude_desktop_config.json` for Claude\n   Desktop, `~/.cursor/mcp.json` for Cursor), add\n   `\"MCP_CLIENT\": \"claude-desktop\"` (or `\"cursor\"`) to the `\"env\"` of the\n   `enclave` server entry.\n2. In `~/.enclave/policies.toml`, add the tools to that app's `[[agents]]`\n   entry (`agent_id = \"claude-desktop\"` or `\"cursor\"`): for example\n   `\"vault_recall\", \"vault_list_entries\"` in its `allowed_tools`, or\n   `\"vault_*\"` to also allow storing and deleting.\n3. Fully quit and reopen the app.\n\nNaming the app applies everything in its `[[agents]]` entry, not just the tools\nyou add: the shipped `claude-desktop` and `cursor` entries also allow the\n(mock) wallet tools, including `request_purchase` with auto-approval under\n$25. Remove `\"wallet\"` from that entry's `allowed_modules` if you don't want\nthat.\n\n`MCP_CLIENT` is a label, not proof: any program that starts Enclave's server\nwith the same label gets that entry (as does, with `psutil` installed, any\napp whose process name contains \"claude\" or \"cursor\"). Only software already\nrunning as you can do that, and it could read the vault files directly\nanyway. Re-running `enclave mcp install` rewrites the server entry without\nthe label, which takes the secrets tools away again. Never add `vault_*` to\n`default` — that gives them to every app Enclave cannot identify, and\n`enclave doctor` warns about it.\n\n### Network access\n\n- **Hugging Face Hub**: model downloads on first use; loading a cached model\n  may also check the Hub for updates. No document content is sent.\n- **npm**: if a PDF has little extractable text and Node's `npx` is on your\n  PATH, the parser runs `npx -y @llamaindex/liteparse`, which downloads and\n  runs that package. Set `ENCLAVE_LITEPARSE_ALLOW_NPX=false` to prevent this.\n- **PyPI**: some desktop-app features (SmolDocling PDF extraction, Q&A\n  generation) pip-install missing packages the first time you use them.\n- **Ollama** (optional OCR for scanned PDFs, and Q&A generation where MLX is\n  unavailable): the desktop app never installs or starts Ollama, and never\n  runs an installer script. If Ollama is missing or stopped, it tells you to\n  install it from https://ollama.com or start it yourself. It downloads an\n  Ollama model (for example `llama3.2-vision:11b`, about 8 GB) only after you\n  confirm a prompt that names the model and its size (Settings → Run Local\n  Setup). Otherwise it only checks whether Ollama is running on `localhost`\n  (or at `OLLAMA_BASE_URL`, if you set it).\n- **Cloud backend**: none by default. Unless you set `ENCLAVE_BACKEND_URL`\n  (in the environment or in `~/.enclave/config.env`), the desktop app sends\n  no backend requests, and on older screens (for example Settings → Advanced\n  → System Setup, Training Queue or Activity Log) the app bar's status icon\n  has the tooltip \"Cloud backend: not configured (local-only)\". An empty\n  value counts as unset. If you set it, those screens request its `/health`\n  endpoint to show whether it is reachable (no vault content is sent), and\n  the desktop cloud features use it once you sign in.\n- **Cloud features** (desktop cloud sync and sign-in, the MCP `langchain_*`\n  tools) are **off by default**; the MCP tools stay inert unless both\n  `ENCLAVE_API_KEY` and `ENCLAVE_API_BASE_URL` are set.\n\n## Known Limitations\n\n- **Local chat needs Apple Silicon.** On Intel Macs, Linux and Windows the\n  desktop app's chat never sends (it keeps offering a model download), and the\n  CLI and MCP server fall back to TinyLlama 1.1B on PyTorch, whose answers are\n  poor.\n- **Windows**: no setup script, and no consent prompt, so MCP calls are denied.\n- **Partial encryption, key stored next to the data** — see\n  [What is and isn't encrypted](#what-is-and-isnt-encrypted).\n- **Coarse consent**: no expiry; on a default install every AI app is\n  `unknown` and they all share one consent decision; opting one app in to the\n  secrets tools relies on a label its config declares; revoking access (or\n  using the kill switch) takes effect only after the AI app restarts. See\n  [Consent](#consent).\n- **Documents can steer answers**: retrieved text goes into the local model's\n  prompt as-is, so a malicious document can plant instructions in the answer\n  an agent receives.\n- **Heavy install**: the core install pulls PyTorch — about 5–6 GB on Linux,\n  several GB on macOS.\n- **No releases yet**: no signed app, installer or PyPI package; install from source.\n- **Adapter training and packaging are experimental**, and training needs\n  Apple Silicon. Password-protected adapter packages derive their key with a\n  single unsalted SHA-256, so use a long random password.\n\n## Project Structure\n\n```\nslm-vault/\n├── advanced_vault/          # Core application (see advanced_vault/README.md)\n│   ├── gui/                 # Desktop GUI (Flet)\n│   ├── cli/                 # `enclave` CLI (incl. doctor + MCP setup)\n│   ├── training/            # RAG index, embeddings, caching (+ experimental adapter training)\n│   ├── prosumer/            # Personal data vaults (Health, Finance, Legal, Personal)\n│   └── mcp_server/          # MCP server implementation\n├── setup.sh                 # One-command setup (macOS/Linux)\n├── docs/                    # Documentation (index: docs/README.md)\n├── examples/                # Secrets-store demo scripts\n├── scripts/                 # Build, packaging and verification scripts\n└── tests/                   # Test suite\n```\n\n> **Legacy code lives on the\n> [`legacy-archive-2026-09-29`](https://github.com/zd87pl/slm-vault/tree/legacy-archive-2026-09-29)\n> branch**, not on `main`: the RunPod cloud-training stack (`src/`, the\n> Dockerfiles and RunPod scripts), the sync backend (`advanced_vault/backend/`),\n> the browser extension, the LangChain package and the OpenClaw plugin, with\n> their docs. That code is unmaintained.\n\n**Not part of the local-only story**: the desktop app's cloud sync, RunPod and\nbackend-status features (which stay off until you configure a backend URL or\nRunPod credentials) and the MCP server's `langchain_*` tools are experimental\nor legacy. They are not covered by the privacy model above and may be removed\n(see also [Network access](#network-access)).\n\n## Requirements\n\n- Python 3.11+\n- For local chat: a Mac with Apple Silicon (M1 or later)\n- 8 GB+ RAM (16 GB+ recommended for local LLM)\n- Disk: the core install pulls PyTorch (through `sentence-transformers`) —\n  about 5–6 GB on Linux, where pip also fetches the CUDA libraries, and\n  several GB on macOS — plus about 1.1 GB of models on first use (the non-Mac\n  fallback model alone is about 2.2 GB)\n\n### Platform support\n\n| | Apple Silicon Mac | Intel Mac, Linux | Windows |\n|---|---|---|---|\n| Desktop app chat | Yes (MLX) | No — keeps offering a model download | No |\n| CLI and MCP server | Yes | Run, but answers come from TinyLlama 1.1B (PyTorch) and are poor | Same as Linux, and MCP calls are denied (no consent prompt) |\n| `setup.sh` | Yes | Yes | No (bash only; install with pip) |\n\n## Advanced Local Training (experimental)\n\nApple Silicon only. Enclave supports advanced training algorithms via\n`mlx-lm-lora` (`pip install -e \".[advanced-training]\"`). There is no\nevaluation yet showing that adapters answer better than retrieval alone.\n\n| Algorithm | Use Case | Env Var |\n|-----------|----------|---------|\n| **SFT** (default) | Standard fine-tuning on Q&A pairs | `ENCLAVE_LOCAL_TRAIN_MODE=sft` |\n| **DPO** | Preference optimization (good vs bad answers) | `ENCLAVE_LOCAL_TRAIN_MODE=dpo` |\n| **ORPO** | Odds-ratio preference optimization | `ENCLAVE_LOCAL_TRAIN_MODE=orpo` |\n| **GRPO** | Group-relative policy optimization with custom rewards | `ENCLAVE_LOCAL_TRAIN_MODE=grpo` |\n| **SFT+QAT** | Quantization-aware training for smaller adapters | `ENCLAVE_LOCAL_TRAIN_MODE=sft` + `ENCLAVE_LOCAL_QAT=true` |\n\n### Environment Variables\n\n```bash\n# Training algorithm\nexport ENCLAVE_LOCAL_TRAIN_MODE=dpo      # sft | dpo | orpo | grpo\n\n# QAT (Quantization Aware Training)\nexport ENCLAVE_LOCAL_QAT=true            # true/false\n\n# LoRA hyperparameters\nexport ENCLAVE_LOCAL_LORA_RANK=8\nexport ENCLAVE_LOCAL_LORA_ALPHA=16\nexport ENCLAVE_LOCAL_LR=1e-5\nexport ENCLAVE_LOCAL_BATCH_SIZE=4\n\n# DPO/ORPO specific\nexport ENCLAVE_LOCAL_DPO_BETA=0.1\n\n# GRPO specific\nexport ENCLAVE_LOCAL_GRPO_GROUP_SIZE=4\nexport ENCLAVE_LOCAL_GRPO_REWARD_COMBO=rag_default  # rag_default | citation_heavy | concise | structured\n\n# Force local vs cloud training\nexport ENCLAVE_LOCAL_TRAINING=true       # true | false | auto\n```\n\n### Package & Share Adapters\n\nThe password is turned into a key with a single unsalted SHA-256, which is\nweak against guessing — use a long random password.\n\n```bash\n# Package a trained adapter (prompts for an encryption password)\nenclave model package ~/.enclave/adapters/my_adapter ./my_adapter.enclave \\\n  --train-mode dpo --qat\n\n# Unpack (prompts for the password)\nenclave model unpack ./my_adapter.enclave ~/.enclave/adapters/restored\n\n# Verify integrity (prompts for the password)\nenclave model verify ./my_adapter.enclave\n```\n\n## Development\n\n```bash\ngit clone https://github.com/zd87pl/slm-vault\ncd slm-vault\n\n# Install with dev dependencies\npip install -e \".[dev]\"\n\n# Run tests (tests needing missing optional deps skip automatically)\npytest\n\n# Lint (the correctness rules CI enforces)\nruff check advanced_vault/ --select F821,F811,F823,E9,F63,F7\n\n# Type checking\nmypy advanced_vault/\n```\n\n## Documentation\n\n- [Security policy and threat model](SECURITY.md)\n- [MCP server](advanced_vault/mcp_server/README.md) — manual client setup and the `vault_*` secrets tools (its roadmap section is out of date)\n- [Private Language Models](docs/PRIVATE_LANGUAGE_MODELS.md) — CLI profiles: ingest, chat, adapters\n\nThe [documentation index](docs/README.md) lists the rest; the older notes\nthere may not match the code.\n\n## Status\n\n- [x] RAG indexing (HNSW acceleration when `hnswlib` is installed)\n- [x] E5-small embeddings with persistent cache\n- [x] MCP server with agent commands\n- [x] ChaCha20-Poly1305 encryption of document text and secret values\n- [x] Activity logging and per-app consent (coarse; see [Consent](#consent))\n- [x] Desktop GUI (Flet) — local chat on Apple Silicon only\n- [x] Local LLM inference (MLX, Apple Silicon)\n- [x] Advanced local training (DPO, ORPO, GRPO, QAT via mlx-lm-lora) — experimental\n- [x] Encrypted adapter packaging & distribution — experimental\n- [x] One-command setup (`setup.sh`, macOS/Linux), `enclave doctor`, `enclave mcp install`\n- [ ] Encrypted file names, embeddings, chat history and logs\n- [ ] Vault key protected by a passphrase or the OS keychain\n- [ ] Usable local chat on Intel Macs, Linux and Windows\n- [ ] Fine-grained, expiring consent\n- [ ] Multi-device sync (encrypted)\n- [ ] Adapter marketplace\n\n## Contributing\n\nWe welcome contributions! Please:\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Run tests and linting\n5. Submit a pull request\n\nPlease report security issues privately — see [SECURITY.md](SECURITY.md).\n\n## License\n\nApache License 2.0 - see [LICENSE](LICENSE)\n\n---\n\n**Enclave**: Privacy-first AI. Your data, your control.\n"}