mirror of
https://github.com/samvallad33/vestige.git
synced 2026-06-20 21:18:08 +02:00
Merge branch 'main' into design-adr-0002-phase-2-execution
This commit is contained in:
commit
fc0681ed0f
479 changed files with 38415 additions and 8692 deletions
81
docs/AGENT-MEMORY-PROTOCOL.md
Normal file
81
docs/AGENT-MEMORY-PROTOCOL.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# Agent Memory Protocol
|
||||
|
||||
> Minimal instructions for any MCP-compatible agent using Vestige.
|
||||
|
||||
Vestige is an MCP server, not a Claude-specific workflow. Register `vestige-mcp`
|
||||
with your client, then give the agent a short instruction that makes memory part
|
||||
of its normal reasoning loop.
|
||||
|
||||
## Register Vestige
|
||||
|
||||
Use your client's MCP server configuration format. The command is the same:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "vestige-mcp"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
claude mcp add vestige vestige-mcp -s user
|
||||
codex mcp add vestige -- vestige-mcp
|
||||
```
|
||||
|
||||
## Agent Instruction
|
||||
|
||||
Add this to the agent's global or project instruction file:
|
||||
|
||||
```text
|
||||
Use Vestige as durable local memory.
|
||||
|
||||
At the start of a new session, call `session_context` with the current user,
|
||||
project, and task context. If `session_context` is unavailable or too broad, call
|
||||
`search` with a concrete query matching the current task.
|
||||
|
||||
When accuracy or prior decisions matter, call `deep_reference`. When memories may
|
||||
conflict, call `contradictions` before answering. Compose retrieved evidence into
|
||||
the answer; do not merely paste memory summaries.
|
||||
|
||||
Save durable preferences, project decisions, recurring corrections, stable facts,
|
||||
and reusable code patterns with `smart_ingest`. Do not store secrets, credentials,
|
||||
one-off logs, speculation, or transient command output.
|
||||
|
||||
When the user says a memory was useful, call `memory` with `action="promote"`.
|
||||
When the user says a memory was wrong or unhelpful, call `memory` with
|
||||
`action="demote"`. When the user explicitly asks to erase a memory permanently,
|
||||
call `memory` with `action="purge"` and `confirm=true`.
|
||||
```
|
||||
|
||||
## Practical Tool Choices
|
||||
|
||||
| Situation | Tool |
|
||||
|-----------|------|
|
||||
| Start of session | `session_context` |
|
||||
| Find exact identifiers, paths, env vars, names | `search` |
|
||||
| Answer from prior decisions or evolving facts | `deep_reference` |
|
||||
| Inspect disagreements before answering | `contradictions` |
|
||||
| Save a preference, decision, correction, or code pattern | `smart_ingest` |
|
||||
| Retrieve, promote, demote, edit, or purge one memory | `memory` |
|
||||
| Create a future reminder | `intention` |
|
||||
| Check health or maintenance state | `system_status` |
|
||||
|
||||
## What Not To Store
|
||||
|
||||
- API keys, tokens, passwords, private keys, or session cookies.
|
||||
- Raw logs or command output unless the durable lesson is extracted first.
|
||||
- Guesswork the agent has not verified.
|
||||
- Temporary plans that will be obsolete after the current session.
|
||||
- User data the user asked not to retain.
|
||||
|
||||
## Portability Notes
|
||||
|
||||
The same protocol applies to Claude Code, Codex, Cursor, VS Code, Xcode,
|
||||
JetBrains, Windsurf, and any other client that can run a stdio MCP server. Claude
|
||||
Code's Cognitive Sandwich hooks are optional companion files; they are not
|
||||
required for normal Vestige memory.
|
||||
233
docs/COGNITIVE_SANDWICH.md
Normal file
233
docs/COGNITIVE_SANDWICH.md
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
# Cognitive Sandwich
|
||||
|
||||
**Vestige's defense-in-depth safety architecture for Claude Code.**
|
||||
|
||||
The default Cognitive Sandwich installer only stages files and removes old v2.1.0 hook wiring. It activates no Claude Code hooks and makes no automatic model calls. Both the preflight layer and the Stop-hook layer are explicit opt-ins:
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────┐
|
||||
│ 🥪 TOP BREAD — UserPromptSubmit hooks │
|
||||
│ • Vestige memory graph injection │
|
||||
│ • CWD / git / CI state injection │
|
||||
│ • Synthesis-protocol gate (decision-adjacent) │
|
||||
│ • Lateral-thinker subconscious swarm │
|
||||
│ • Pulse daemon (background dream insights) │
|
||||
├────────────────────────────────────────────────┤
|
||||
│ 🥩 MEAT — Claude Code reasons │
|
||||
├────────────────────────────────────────────────┤
|
||||
│ 🥪 OPTIONAL BOTTOM BREAD — Stop hooks │
|
||||
│ • Veto-detector / synthesis validator │
|
||||
│ • Sanhedrin Executioner verifier │
|
||||
└────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Sanhedrin, preflight, and all Vestige Claude Code hooks are optional. The default installer wires none of them; it does not call Claude, start MLX, require a 19 GB model download, or require 20+ GB of RAM. Users who want preflight context can opt in with `--enable-preflight`. Users who want the post-response verifier can opt in with `--enable-sanhedrin` and point it at any OpenAI-compatible `/v1/chat/completions` endpoint. On Apple Silicon, an additional `--with-launchd` flag can auto-start the local MLX Qwen backend.
|
||||
|
||||
---
|
||||
|
||||
## How a single response flows through the Sandwich
|
||||
|
||||
1. **You type a prompt in Claude Code.**
|
||||
2. **If explicitly enabled, UserPromptSubmit hooks fire in parallel** (none can block — all fail-open):
|
||||
- `load-all-memory.sh` (opt-in) — dumps every memory MD into context
|
||||
- `synthesis-preflight.sh` — POSTs your prompt to `vestige-mcp` `/api/deep_reference`, injects the trust-scored reasoning chain
|
||||
- `cwd-state-injector.sh` — captures git status, branch, open PRs/issues, modified files
|
||||
- `vestige-pulse-daemon.sh` — injects fresh Vestige dream insights from the past 20 min into the next prompt context
|
||||
- `preflight-swarm.sh` — spawns the `lateral-thinker` subagent in fresh context to surface cross-disciplinary structural parallels
|
||||
3. **Claude reads the assembled context and generates a draft.**
|
||||
4. **By default, no Vestige Stop hooks are installed.** If explicitly enabled, Stop hooks fire serially (any can VETO with `exit 2`, forcing a rewrite):
|
||||
- `veto-detector.sh` — fast regex against `veto`-tagged Vestige memories (~50ms)
|
||||
- `sanhedrin.sh` → `sanhedrin-local.py` — optional Sanhedrin verifier
|
||||
- `synthesis-stop-validator.sh` — regex against forbidden patterns (hedging, summary-instead-of-composition)
|
||||
5. **If all enabled Stop hooks return `exit 0`, the response is delivered.**
|
||||
|
||||
---
|
||||
|
||||
## The Sanhedrin Executioner protocol
|
||||
|
||||
Sanhedrin has two execution modes:
|
||||
|
||||
- **Legacy mode** (`VESTIGE_SANHEDRIN_CLAIM_MODE=0`) keeps the original broad draft-level semantic check for technical-looking responses.
|
||||
- **Claim mode** (`VESTIGE_SANHEDRIN_CLAIM_MODE=1`) extracts check-worthy claims, retrieves Vestige evidence per claim, and aggregates structured verdicts before the Stop hook allows delivery.
|
||||
|
||||
The claim-mode Executioner extracts atomic claims from Claude's draft across these classes:
|
||||
|
||||
`TECHNICAL` · `BIOGRAPHICAL` · `FINANCIAL` · `ACHIEVEMENT` · `TIMELINE` · `QUANTITATIVE` · `ATTRIBUTION` · `CAUSAL` · `COMPARATIVE` · `EXISTENTIAL` · plus v2.1.0 additions: `VAGUE-QUANTIFIER` · `UNVERIFIED-POSITIVE`
|
||||
|
||||
For each check-worthy claim, claim mode calls Vestige's `/api/deep_reference` and judges the claim against high-trust durable evidence plus any optional staged evidence overlay. Decision rules:
|
||||
|
||||
| Class | Rule |
|
||||
|---|---|
|
||||
| TECHNICAL / EXISTENTIAL / CAUSAL / COMPARATIVE | VETO only on same-subject durable contradiction; missing memory is `NEI` |
|
||||
| BIOGRAPHICAL / FINANCIAL / ACHIEVEMENT / TIMELINE / QUANTITATIVE / ATTRIBUTION / VAGUE-QUANTIFIER about the user | zero high-trust durable evidence is `REFUTED_BY_ABSENCE` and blocks |
|
||||
| **VAGUE-QUANTIFIER** | VETO on vague achievement or financial claims without durable enumeration |
|
||||
| **UNVERIFIED-POSITIVE** | VETO on specific named institutions/dates/employers not in evidence |
|
||||
|
||||
Structured verdicts:
|
||||
|
||||
| Verdict | Meaning |
|
||||
|---|---|
|
||||
| `SUPPORTED` | High-trust evidence supports or does not contradict the claim |
|
||||
| `REFUTED` | High-trust durable evidence directly contradicts the same-subject claim |
|
||||
| `REFUTED_BY_ABSENCE` | User-critical claim has no high-trust durable Vestige evidence |
|
||||
| `NEI` | Not enough information; allow unless another claim blocks |
|
||||
|
||||
The bridge still prints legacy one-line `yes` / `no - ...` by default for Stop-hook compatibility. With `VESTIGE_SANHEDRIN_OUTPUT=json`, it emits structured JSON containing `decision`, `reason`, and per-claim verdicts. `sanhedrin.sh` can parse either format.
|
||||
|
||||
### Staged evidence overlay
|
||||
|
||||
`VESTIGE_SANHEDRIN_STAGE_FILE` may point to a JSON array of current-turn evidence candidates. Sanhedrin can read this staged evidence as context, but staged evidence is deliberately non-durable:
|
||||
|
||||
- it never calls `smart_ingest`
|
||||
- it cannot promote, demote, merge, suppress, or supersede durable memories
|
||||
- it does not satisfy the durable-evidence requirement for `REFUTED_BY_ABSENCE`
|
||||
- durable memory writes remain a separate commit-after-pass step
|
||||
|
||||
False-positive guards (added v2.1.0 after dogfood):
|
||||
- Subject-equality gate (memory about Vestige codebase ≠ contradiction with external tools)
|
||||
- Version-discriminator rule (M3 Max ≠ M5 Max; Qwen3.5 ≠ Qwen3.6)
|
||||
- Agreement-is-not-contradiction (memory that AGREES with draft → PASS)
|
||||
- Architecture-vs-component (overall architecture memory doesn't contradict component-level draft)
|
||||
- Inference-verb ban (no `implies` / `suggests` / `must mean` in veto reasons)
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### From an installed Vestige CLI
|
||||
|
||||
```bash
|
||||
vestige sandwich install
|
||||
```
|
||||
|
||||
`vestige update` updates binaries only by default. To refresh these optional
|
||||
Claude Code companion files during an update, run
|
||||
`vestige update --sandwich-companion`. The companion installer does not activate
|
||||
any Claude Code hook unless you pass an explicit opt-in flag. It removes old
|
||||
v2.1.0 Vestige hook wiring from `~/.claude/settings.json` while preserving
|
||||
unrelated user hooks.
|
||||
|
||||
### From a checkout
|
||||
|
||||
```bash
|
||||
git clone https://github.com/samvallad33/vestige
|
||||
cd vestige
|
||||
./scripts/install-sandwich.sh # add --force to overwrite existing hooks
|
||||
./scripts/check-sandwich-prereqs.sh # verify no Vestige hooks are wired by default
|
||||
```
|
||||
|
||||
### Optional Preflight
|
||||
|
||||
Preflight is a separate opt-in layer. It includes `preflight-swarm.sh`, which uses `claude -p --model claude-haiku-4-5-20251001`; it is not wired by default.
|
||||
|
||||
```bash
|
||||
vestige sandwich install --enable-preflight
|
||||
scripts/check-sandwich-prereqs.sh --preflight
|
||||
```
|
||||
|
||||
### Optional Sanhedrin
|
||||
|
||||
Sanhedrin is a separate opt-in layer.
|
||||
|
||||
```bash
|
||||
# Wire the Sanhedrin Stop hook, using the default OpenAI-compatible endpoint.
|
||||
vestige sandwich install --enable-sanhedrin
|
||||
|
||||
# Apple Silicon only, and only if the machine has enough memory:
|
||||
vestige sandwich install --enable-sanhedrin --with-launchd
|
||||
|
||||
# x86 / Linux / Intel Mac: use any OpenAI-compatible endpoint.
|
||||
vestige sandwich install \
|
||||
--enable-sanhedrin \
|
||||
--sanhedrin-endpoint=http://127.0.0.1:11434/v1/chat/completions \
|
||||
--sanhedrin-model=qwen2.5:14b
|
||||
```
|
||||
|
||||
### Prerequisites
|
||||
|
||||
| Tool | Install |
|
||||
|---|---|
|
||||
| Python 3.10+ | typically preinstalled |
|
||||
| `jq` | `brew install jq` |
|
||||
| `vestige-mcp` | `npm install -g vestige-mcp-server` |
|
||||
| Claude Code | https://claude.ai/code |
|
||||
|
||||
Optional Apple Silicon local Sanhedrin backend:
|
||||
|
||||
| Tool | Install |
|
||||
|---|---|
|
||||
| macOS Apple Silicon (M1+) | required for MLX launchd only |
|
||||
| `uv` | `brew install uv` |
|
||||
| `mlx-lm` | `uv tool install mlx-lm` |
|
||||
| `huggingface_hub[cli]` | `uv tool install 'huggingface_hub[cli]'` |
|
||||
| Qwen3.6-35B-A3B-4bit | `hf download mlx-community/Qwen3.6-35B-A3B-4bit` (~19 GB) |
|
||||
|
||||
### What the installer does
|
||||
|
||||
1. Verifies prereqs (warnings for missing tools, fatal only on jq/python3).
|
||||
2. Copies hooks to `~/.claude/hooks/`, agents to `~/.claude/agents/`.
|
||||
3. Backs up existing `~/.claude/settings.json` to `.bak.pre-sandwich`, then removes old Vestige hook wiring from previous v2.1.0 installs.
|
||||
4. With `--enable-preflight`, merges the UserPromptSubmit hooks block.
|
||||
5. With `--enable-sanhedrin`, writes `~/.claude/hooks/vestige-sanhedrin.env` and merges a Sanhedrin-enabled Stop hooks block.
|
||||
6. With `--enable-sanhedrin --with-launchd` on Apple Silicon, renders and loads `launchd/com.vestige.mlx-server.plist.template`.
|
||||
|
||||
### Uninstall
|
||||
|
||||
```bash
|
||||
launchctl unload ~/Library/LaunchAgents/com.vestige.mlx-server.plist
|
||||
rm ~/Library/LaunchAgents/com.vestige.mlx-server.plist
|
||||
cp ~/.claude/settings.json.bak.pre-sandwich ~/.claude/settings.json
|
||||
# Hook files in ~/.claude/hooks/ can be deleted manually.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance notes
|
||||
|
||||
Optional local MLX backend on M3 Max 16-core (400 GB/s memory bandwidth):
|
||||
- Legacy Sanhedrin verdict: 5–15 seconds end-to-end (single deep_reference + single Qwen call)
|
||||
- Claim mode: one `/api/deep_reference` call per extracted check-worthy claim, capped by `VESTIGE_SANHEDRIN_MAX_CLAIMS`
|
||||
- mlx_lm.server token generation: ~82 tok/s
|
||||
- mlx_lm.server peak resident memory: ~19.7 GB
|
||||
- Cold model load: ~5 seconds
|
||||
|
||||
On M3 Max 14-core or M2/M1 Max: closer to 3–7s prompt processing, ~50–60 tok/s generation.
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
| Env var | Default | Effect |
|
||||
|---|---|---|
|
||||
| `VESTIGE_SANHEDRIN_ENABLED` | `0` | Set to `1` to enable the optional Sanhedrin Stop hook |
|
||||
| `VESTIGE_SWARM_ENABLED` | `1` | Set to `0` to disable preflight lateral-thinker swarm |
|
||||
| `VESTIGE_DASHBOARD_PORT` | `3927` | Vestige MCP HTTP API port used by hooks |
|
||||
| `VESTIGE_SANHEDRIN_ENDPOINT` | `http://127.0.0.1:8080/v1/chat/completions` | OpenAI-compatible chat completions endpoint for Sanhedrin |
|
||||
| `VESTIGE_SANHEDRIN_MODEL` | `mlx-community/Qwen3.6-35B-A3B-4bit` | Model name sent to the Sanhedrin endpoint |
|
||||
| `VESTIGE_SANHEDRIN_CLAIM_MODE` | `1` when installed with `--enable-sanhedrin` | Enables per-claim retrieval and fail-closed user-critical lanes |
|
||||
| `VESTIGE_SANHEDRIN_OUTPUT` | `json` when installed with `--enable-sanhedrin` | Emits structured JSON from the bridge; shell hook also accepts legacy text |
|
||||
| `VESTIGE_SANHEDRIN_STAGE_FILE` | unset | Optional JSON-array staged evidence overlay, read-only and non-durable |
|
||||
| `VESTIGE_SANHEDRIN_MAX_CLAIMS` | `8` | Max check-worthy claims adjudicated per draft |
|
||||
| `VESTIGE_SANHEDRIN_PYTHON` | `python3` from `PATH` | Optional Python interpreter override for the Stop hook bridge |
|
||||
| `MLX_ENDPOINT` / `VESTIGE_SANDWICH_MODEL` | legacy aliases | Backward-compatible names still read by the bridge |
|
||||
| `VESTIGE_MEMORY_DIR` | (auto) | Override per-user Claude memory dir |
|
||||
|
||||
---
|
||||
|
||||
## Architecture provenance
|
||||
|
||||
The Cognitive Sandwich originated April 2026 as a defense against a dogfood failure mode: Claude retrieved relevant memories but summarized them instead of composing them into a recommendation. The pre-cognitive layer enforces composition; the post-cognitive layer catches contradictions before they ship.
|
||||
|
||||
Full architecture memory: search Vestige for `god-tier-plan` or `cognitive-sandwich` tags after install.
|
||||
|
||||
---
|
||||
|
||||
## Linux / Intel Mac / x86
|
||||
|
||||
The base hook harness runs on x86. The launchd MLX helper is macOS-arm64-only.
|
||||
|
||||
On Linux, Windows under WSL, or Intel Mac:
|
||||
- Run `scripts/install-sandwich.sh` normally to stage files and remove old Vestige hook wiring. No hooks are activated.
|
||||
- If you want Sanhedrin, run an OpenAI-compatible endpoint such as vLLM, Ollama, llama.cpp server, or a remote MLX/vLLM box.
|
||||
- Install with `--enable-sanhedrin --sanhedrin-endpoint=<url> --sanhedrin-model=<model>`.
|
||||
- If the endpoint is unreachable, Sanhedrin fails open and does not block Claude Code.
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
## First-Run Network Requirement
|
||||
|
||||
Vestige downloads the **Nomic Embed Text v1.5** model (~130MB) from Hugging Face on first use.
|
||||
Vestige downloads the **Nomic Embed Text v1.5** model (~130MB) from Hugging Face on first use. Qwen3 embeddings are opt-in and download their own Hugging Face model when selected.
|
||||
|
||||
**All subsequent runs are fully offline.**
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ The embedding model is cached in platform-specific directories:
|
|||
|
||||
| Platform | Cache Location |
|
||||
|----------|----------------|
|
||||
| macOS | `~/Library/Caches/com.vestige.core/fastembed` |
|
||||
| macOS | `~/Library/Caches/vestige/fastembed` |
|
||||
| Linux | `~/.cache/vestige/fastembed` |
|
||||
| Windows | `%LOCALAPPDATA%\vestige\cache\fastembed` |
|
||||
|
||||
|
|
@ -25,16 +25,28 @@ Override with environment variable:
|
|||
export FASTEMBED_CACHE_PATH="/custom/path"
|
||||
```
|
||||
|
||||
Qwen3 currently uses Hugging Face Hub's Candle loader directly, so use the standard Hugging Face cache environment such as `HF_HOME` if you need to relocate that larger model cache.
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `VESTIGE_DATA_DIR` | Platform default | Custom database location |
|
||||
| `VESTIGE_LOG_LEVEL` | `info` | Logging verbosity |
|
||||
| `RUST_LOG` | - | Detailed tracing output |
|
||||
| `FASTEMBED_CACHE_PATH` | `./.fastembed_cache` | Embedding model cache location |
|
||||
| `VESTIGE_DATA_DIR` | OS per-user data directory | Storage directory fallback; overridden by `--data-dir`; database lives at `<dir>/vestige.db` |
|
||||
| `VESTIGE_EMBEDDING_MODEL` | `nomic-v1.5` | Embedding backend selector. Use `qwen3-0.6b` with a build that enables `qwen3-embeddings` |
|
||||
| `RUST_LOG` | `info` (via tracing-subscriber) | Log verbosity + per-module filtering |
|
||||
| `FASTEMBED_CACHE_PATH` | Platform cache directory; `./.fastembed_cache` fallback | Embedding model cache location |
|
||||
| `VESTIGE_DASHBOARD_PORT` | `3927` | Dashboard HTTP + WebSocket port |
|
||||
| `VESTIGE_HTTP_ENABLED` | `false` | Set `true` or `1` to enable optional MCP-over-HTTP |
|
||||
| `VESTIGE_HTTP_PORT` | `3928` | Optional MCP-over-HTTP port; `--http-port` also enables HTTP |
|
||||
| `VESTIGE_HTTP_BIND` | `127.0.0.1` | HTTP bind address |
|
||||
| `VESTIGE_HTTP_ALLOWED_ORIGINS` | localhost origins for the HTTP port | Comma-separated browser origins allowed to call MCP-over-HTTP |
|
||||
| `VESTIGE_AUTH_TOKEN` | auto-generated | Dashboard + MCP HTTP bearer auth |
|
||||
| `VESTIGE_DASHBOARD_ENABLED` | `false` | Set `true` or `1` to enable the web dashboard |
|
||||
| `VESTIGE_CONSOLIDATION_INTERVAL_HOURS` | `6` | FSRS-6 decay cycle cadence |
|
||||
|
||||
> **Storage location precedence:** `--data-dir <path>` wins over `VESTIGE_DATA_DIR`; if neither is set, Vestige uses your OS's per-user data directory: `~/Library/Application Support/com.vestige.core/` on macOS, `~/.local/share/vestige/core/` on Linux, `%APPDATA%\vestige\core\` on Windows. Custom paths are directories, are created if missing, expand a leading `~`, and store the database at `<dir>/vestige.db`.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -42,6 +54,8 @@ export FASTEMBED_CACHE_PATH="/custom/path"
|
|||
|
||||
```bash
|
||||
vestige-mcp --data-dir /custom/path # Custom storage location
|
||||
VESTIGE_DATA_DIR=~/.vestige vestige-mcp # Env fallback storage location
|
||||
VESTIGE_DATA_DIR=./.vestige vestige stats # Point the CLI at the same custom DB
|
||||
vestige-mcp --help # Show all options
|
||||
```
|
||||
|
||||
|
|
@ -58,6 +72,10 @@ vestige stats --states # Cognitive state distribution
|
|||
vestige health # System health check
|
||||
vestige consolidate # Run memory maintenance
|
||||
vestige restore <file> # Restore from backup
|
||||
vestige portable-export <file> # Exact Vestige-to-Vestige archive
|
||||
vestige portable-import <file> # Import exact archive into an empty database
|
||||
vestige portable-import <file> --merge # Merge exact archive into this database
|
||||
vestige sync <file> # Pull/merge/push through a file backend
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -140,6 +158,14 @@ For per-project or custom storage:
|
|||
}
|
||||
```
|
||||
|
||||
For a shell-level default:
|
||||
|
||||
```bash
|
||||
export VESTIGE_DATA_DIR="/path/to/custom/dir"
|
||||
```
|
||||
|
||||
`--data-dir` takes precedence over `VESTIGE_DATA_DIR`, so you can keep a global env default and still isolate one client or project with an explicit CLI argument.
|
||||
|
||||
See [Storage Modes](STORAGE.md) for more options.
|
||||
|
||||
---
|
||||
|
|
@ -148,16 +174,27 @@ See [Storage Modes](STORAGE.md) for more options.
|
|||
|
||||
**Latest version:**
|
||||
```bash
|
||||
cd vestige
|
||||
git pull
|
||||
cargo build --release
|
||||
sudo cp target/release/vestige-mcp /usr/local/bin/
|
||||
vestige update
|
||||
```
|
||||
|
||||
This updates `vestige`, `vestige-mcp`, and `vestige-restore`. It does not mutate
|
||||
Claude Code Cognitive Sandwich companion files unless you explicitly request it.
|
||||
|
||||
**Also refresh optional Claude Code companion files:**
|
||||
```bash
|
||||
vestige update --sandwich-companion
|
||||
```
|
||||
|
||||
**Pin to specific version:**
|
||||
```bash
|
||||
git checkout v1.1.2
|
||||
cargo build --release
|
||||
vestige update --version v2.1.21
|
||||
```
|
||||
|
||||
**Manage the optional Cognitive Sandwich layer without updating binaries:**
|
||||
```bash
|
||||
vestige sandwich install
|
||||
vestige sandwich install --enable-preflight
|
||||
vestige sandwich install --enable-sanhedrin --sanhedrin-endpoint=http://127.0.0.1:11434/v1/chat/completions
|
||||
```
|
||||
|
||||
**Check your version:**
|
||||
|
|
|
|||
54
docs/FAQ.md
54
docs/FAQ.md
|
|
@ -22,13 +22,13 @@
|
|||
## Getting Started
|
||||
|
||||
<details>
|
||||
<summary><b>"Can Vestige support a two-Claude household?"</b></summary>
|
||||
<summary><b>"Can Vestige support multiple agents or MCP clients?"</b></summary>
|
||||
|
||||
**Yes!** See [Storage Modes](STORAGE.md#option-3-multi-claude-household). You can either:
|
||||
- **Share memories**: Both Claudes point to the same `--data-dir`
|
||||
- **Separate identities**: Each Claude gets its own data directory
|
||||
**Yes.** See [Storage Modes](STORAGE.md#option-3-multi-agent-household). You can either:
|
||||
- **Share memories**: Multiple agents point to the same `--data-dir`
|
||||
- **Separate identities**: Each agent gets its own data directory
|
||||
|
||||
For two Claudes with distinct personas (e.g., "Domovoi" and "Storm") sharing the same human, use separate directories but consider a shared "household" memory for common knowledge.
|
||||
For two agents with distinct roles sharing the same human, use separate directories but consider a shared "household" memory for common knowledge.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
|
@ -38,28 +38,28 @@ For two Claudes with distinct personas (e.g., "Domovoi" and "Storm") sharing the
|
|||
|
||||
**For non-technical users:**
|
||||
1. Have a technical friend do the 5-minute install
|
||||
2. Add the CLAUDE.md instructions
|
||||
3. Just talk to Claude normally—it handles the memory calls
|
||||
2. Add the [agent memory protocol](AGENT-MEMORY-PROTOCOL.md) to your MCP client's instruction file
|
||||
3. Just talk normally; the agent handles the memory calls
|
||||
|
||||
**The magic**: Once set up, you never think about it. Claude just... remembers.
|
||||
**The magic**: Once set up, you never think about it. Your agent just remembers.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>"What input do you feed it? How does it create memories?"</b></summary>
|
||||
|
||||
Claude creates memories via MCP tool calls. Three ways:
|
||||
Your agent creates memories via MCP tool calls. Three ways:
|
||||
|
||||
1. **Explicit**: You say "Remember that I prefer dark mode" → Claude calls `smart_ingest`
|
||||
2. **Automatic**: Claude notices something important → calls `smart_ingest` proactively
|
||||
3. **Codebase**: Claude detects patterns/decisions → calls `remember_pattern` or `remember_decision`
|
||||
1. **Explicit**: You say "Remember that I prefer dark mode" -> the agent calls `smart_ingest`
|
||||
2. **Automatic**: The agent notices something important -> calls `smart_ingest` proactively
|
||||
3. **Codebase**: The agent detects patterns/decisions -> calls `codebase(action="remember_pattern")` or `codebase(action="remember_decision")`
|
||||
|
||||
The CLAUDE.md instructions tell Claude when to create memories proactively.
|
||||
The agent memory protocol tells the client when to create memories proactively.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>"Can it be filled with a conversation stream in realtime?"</b></summary>
|
||||
|
||||
Not currently. Vestige is **tool-based**, not stream-based. Claude decides what's worth remembering, not everything gets saved.
|
||||
Not currently. Vestige is **tool-based**, not stream-based. The agent decides what's worth remembering, not everything gets saved.
|
||||
|
||||
This is intentional—saving everything would:
|
||||
- Bloat the knowledge base
|
||||
|
|
@ -160,6 +160,8 @@ Accessibility is calculated as: `0.5 × retention + 0.3 × retrieval_strength +
|
|||
|
||||
Memories are never deleted automatically. They fade from relevance but can be revived if accessed again (like human memory—"oh, I forgot about that!").
|
||||
|
||||
If you explicitly want content gone, use `memory(action="purge", confirm=true)`. Purge permanently removes the memory content and embeddings, scrubs internal references, and keeps only a non-content tombstone so sync/audit can prove the deletion happened.
|
||||
|
||||
**To configure decay**: The FSRS-6 algorithm auto-tunes based on your usage patterns. Memories you access stay strong; memories you ignore fade. No manual tuning needed.
|
||||
</details>
|
||||
|
||||
|
|
@ -209,11 +211,9 @@ In Vestige's current implementation:
|
|||
|
||||
In Vestige's implementation:
|
||||
```
|
||||
importance(
|
||||
memory_id="the-important-one",
|
||||
event_type="user_flag", # or "emotional", "novelty", "repeated_access", "cross_reference"
|
||||
hours_back=9, # Look back 9 hours (configurable)
|
||||
hours_forward=2 # Capture next 2 hours too
|
||||
importance_score(
|
||||
content="the-important content",
|
||||
context_topics=["release", "memory"]
|
||||
)
|
||||
```
|
||||
|
||||
|
|
@ -328,9 +328,9 @@ The unified `search` always uses hybrid, which gives you the best of both worlds
|
|||
|
||||
Three approaches:
|
||||
|
||||
1. **Mark as important**: `importance(memory_id="xxx", event_type="user_flag")`
|
||||
1. **Mark as important**: `importance_score(content="...", event_type="user_flag")`
|
||||
2. **Access regularly**: The Testing Effect strengthens memories each time you retrieve them
|
||||
3. **Promote explicitly**: `promote_memory(id="xxx")` after it proves valuable
|
||||
3. **Promote explicitly**: `memory(action="promote", id="xxx")` after it proves valuable
|
||||
|
||||
For truly critical information, consider also:
|
||||
- Using specific tags like `["critical", "never-forget"]`
|
||||
|
|
@ -547,13 +547,13 @@ Common issues:
|
|||
|
||||
| Feature | Notes App | Vestige |
|
||||
|---------|-----------|---------|
|
||||
| Retrieval | You search manually | Claude searches contextually |
|
||||
| Retrieval | You search manually | The agent searches contextually |
|
||||
| Decay | Everything stays forever | Unused knowledge fades naturally |
|
||||
| Duplicates | You manage manually | Prediction Error Gating auto-merges |
|
||||
| Context | Static text | Active part of AI reasoning |
|
||||
| Strengthening | Manual review | Automatic via Testing Effect |
|
||||
|
||||
The key difference: **Vestige is part of Claude's cognitive loop.** Notes are external reference—Vestige is internal memory.
|
||||
The key difference: **Vestige is part of the agent's cognitive loop.** Notes are external reference; Vestige is active working memory.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
|
@ -617,7 +617,7 @@ Why Nomic:
|
|||
- No API costs or rate limits
|
||||
- Fast enough for real-time search
|
||||
|
||||
The model is cached at `~/.cache/huggingface/` after first run.
|
||||
The model is cached in the platform user cache directory first, with `./.fastembed_cache` as a fallback. Set `FASTEMBED_CACHE_PATH` to choose a specific cache path.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
|
@ -815,11 +815,11 @@ See [CLAUDE-SETUP.md](CLAUDE-SETUP.md) for the full template. The key elements:
|
|||
**During Work**:
|
||||
- Notice a pattern? `codebase(action="remember_pattern")`
|
||||
- Made a decision? `codebase(action="remember_decision")` with rationale
|
||||
- Something important? `importance()` to strengthen recent memories
|
||||
- Something important? `importance_score(content="...")` to score it before saving or promoting
|
||||
|
||||
**Memory Hygiene**:
|
||||
- When a memory helps: `promote_memory`
|
||||
- When a memory misleads: `demote_memory`
|
||||
- When a memory helps: `memory(action="promote", id="...")`
|
||||
- When a memory misleads: `memory(action="demote", id="...")`
|
||||
</details>
|
||||
|
||||
---
|
||||
|
|
|
|||
72
docs/INSTALL-INTEL-MAC.md
Normal file
72
docs/INSTALL-INTEL-MAC.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Intel Mac Installation
|
||||
|
||||
The Intel Mac (`x86_64-apple-darwin`) binary links dynamically against a system
|
||||
ONNX Runtime instead of a prebuilt ort-sys library. Microsoft is discontinuing
|
||||
x86_64 macOS prebuilts after ONNX Runtime v1.23.0, so we use the
|
||||
`ort-dynamic` feature to runtime-link against the version you install locally.
|
||||
This keeps Vestige working on Intel Mac without waiting for a dead upstream.
|
||||
|
||||
## Prerequisite
|
||||
|
||||
Install ONNX Runtime via Homebrew:
|
||||
|
||||
```bash
|
||||
brew install onnxruntime
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
# 1. Install the binary
|
||||
npm install -g vestige-mcp-server@latest
|
||||
|
||||
# 2. Point the binary at Homebrew's libonnxruntime
|
||||
echo 'export ORT_DYLIB_PATH="'"$(brew --prefix onnxruntime)"'/lib/libonnxruntime.dylib"' >> ~/.zshrc
|
||||
source ~/.zshrc
|
||||
|
||||
# 3. Verify
|
||||
vestige-mcp --version
|
||||
|
||||
# 4. Connect to Claude Code
|
||||
claude mcp add vestige vestige-mcp -s user
|
||||
```
|
||||
|
||||
`ORT_DYLIB_PATH` is how the `ort` crate's `load-dynamic` feature finds the
|
||||
shared library at runtime. Without it the binary starts but fails on the first
|
||||
embedding call with a "could not find libonnxruntime" error.
|
||||
|
||||
## Building from source
|
||||
|
||||
```bash
|
||||
brew install onnxruntime
|
||||
git clone https://github.com/samvallad33/vestige && cd vestige
|
||||
cargo build --release -p vestige-mcp \
|
||||
--no-default-features \
|
||||
--features ort-dynamic,vector-search
|
||||
export ORT_DYLIB_PATH="$(brew --prefix onnxruntime)/lib/libonnxruntime.dylib"
|
||||
./target/release/vestige-mcp --version
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**`dyld: Library not loaded: libonnxruntime.dylib`** — `ORT_DYLIB_PATH` is not
|
||||
set for the shell that spawned `vestige-mcp`. Claude Code / Codex inherits the
|
||||
env vars from whatever launched it; export `ORT_DYLIB_PATH` in `~/.zshrc` or
|
||||
`~/.bashrc` and restart the client.
|
||||
|
||||
**`error: ort-sys does not provide prebuilt binaries for the target
|
||||
x86_64-apple-darwin`** — you hit this only if you ran `cargo build` without the
|
||||
`--no-default-features --features ort-dynamic,vector-search` flags. The default
|
||||
feature set still tries to download a non-existent prebuilt. Add the flags and
|
||||
rebuild.
|
||||
|
||||
**Homebrew installed `onnxruntime` but `brew --prefix onnxruntime` prints
|
||||
nothing** — upgrade brew (`brew update`) and retry. Older brew formulae used
|
||||
`onnx-runtime` (hyphenated). If your brew still has the hyphenated formula,
|
||||
substitute accordingly in the commands above.
|
||||
|
||||
## Long-term
|
||||
|
||||
Intel Mac will move to a fully pure-Rust backend (`ort-candle`) in Vestige
|
||||
v2.1, removing the Homebrew prerequisite entirely. Track progress at
|
||||
[issue #41](https://github.com/samvallad33/vestige/issues/41).
|
||||
|
|
@ -126,11 +126,9 @@ In Vestige's implementation:
|
|||
|
||||
In Vestige:
|
||||
```
|
||||
importance(
|
||||
memory_id="the-important-one",
|
||||
event_type="user_flag",
|
||||
hours_back=9,
|
||||
hours_forward=2
|
||||
importance_score(
|
||||
content="the-important content",
|
||||
context_topics=["release", "memory"]
|
||||
)
|
||||
```
|
||||
|
||||
|
|
@ -183,7 +181,7 @@ This gives you exact keyword matching AND semantic understanding in one search.
|
|||
- Runs 100% local (after first download)
|
||||
- Competitive with OpenAI's ada-002
|
||||
|
||||
The model is cached at `~/.cache/huggingface/` after first run.
|
||||
The model is cached in the platform user cache directory after first run, with `./.fastembed_cache` as a fallback. Set `FASTEMBED_CACHE_PATH` to choose a specific cache path.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
157
docs/STORAGE.md
157
docs/STORAGE.md
|
|
@ -1,6 +1,6 @@
|
|||
# Storage Configuration
|
||||
|
||||
> Global, per-project, and multi-Claude setups
|
||||
> Global, per-project, and multi-agent setups
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -14,6 +14,52 @@ All memories are stored in a **single local SQLite file**:
|
|||
| Linux | `~/.local/share/vestige/core/vestige.db` |
|
||||
| Windows | `%APPDATA%\vestige\core\vestige.db` |
|
||||
|
||||
Override precedence:
|
||||
|
||||
1. `vestige-mcp --data-dir <path>`
|
||||
2. `VESTIGE_DATA_DIR=<path>`
|
||||
3. OS default shown above
|
||||
|
||||
`--data-dir` and `VESTIGE_DATA_DIR` both point to a **directory**, not the database file itself. Vestige creates the directory if it does not exist, expands a leading `~`, and stores the database at `<data-dir>/vestige.db`.
|
||||
|
||||
---
|
||||
|
||||
## Moving Memories Between Devices
|
||||
|
||||
For device-to-device migration, use a portable archive instead of the normal JSON export:
|
||||
|
||||
```bash
|
||||
# On the source machine
|
||||
vestige portable-export ~/Desktop/vestige-portable.json
|
||||
|
||||
# On the destination machine, before adding memories
|
||||
vestige portable-import ~/Desktop/vestige-portable.json
|
||||
```
|
||||
|
||||
Portable archives preserve raw Vestige storage rows: memory IDs, FSRS state, graph connections, suppression state, timestamps, audit history, and embedding blobs.
|
||||
|
||||
For one-time migration, keep the conservative empty-database import:
|
||||
|
||||
```bash
|
||||
vestige portable-import ~/Desktop/vestige-portable.json
|
||||
```
|
||||
|
||||
For cross-device sync, use merge mode or the file-backed sync command:
|
||||
|
||||
```bash
|
||||
# Merge a portable archive into an existing database.
|
||||
vestige portable-import ~/Dropbox/vestige/portable.json --merge
|
||||
|
||||
# Pull, merge, and push through a shared archive file.
|
||||
vestige sync ~/Dropbox/vestige/portable.json
|
||||
```
|
||||
|
||||
`vestige sync` uses the same pluggable portable-sync backend interface as the core library. v2.1.1 ships a file backend, which works with Dropbox, iCloud Drive, Syncthing, Git, network shares, or any folder-sync system. The merge algorithm applies delete tombstones, keeps newer local memories on timestamp conflicts, preserves stable IDs, rebuilds FTS after import, and writes the pushed archive atomically when the filesystem supports rename. v2.1.2 also carries non-content purge tombstones so a hard purge can sync without retaining the deleted memory text.
|
||||
|
||||
When using the MCP `export` tool with `format: "portable"`, Vestige writes the archive under the active data directory's `exports/` folder. The MCP `restore` tool only reads from that `exports/` or `backups/` folder by default; pass `allowAnyPath: true` only for a trusted local file you selected manually.
|
||||
|
||||
The regular `vestige export` / `vestige restore` path remains useful for human-readable backups, partial exports, and older files, but it re-ingests memory content and does not preserve every storage-level relationship.
|
||||
|
||||
---
|
||||
|
||||
## Storage Modes
|
||||
|
|
@ -30,6 +76,12 @@ One shared memory for all projects. Good for:
|
|||
claude mcp add vestige vestige-mcp -s user
|
||||
```
|
||||
|
||||
To set a global override for all MCP launches that inherit your shell environment:
|
||||
|
||||
```bash
|
||||
export VESTIGE_DATA_DIR="~/.vestige"
|
||||
```
|
||||
|
||||
### Option 2: Per-Project Memory
|
||||
|
||||
Separate memory per codebase. Good for:
|
||||
|
|
@ -37,9 +89,9 @@ Separate memory per codebase. Good for:
|
|||
- Different coding styles per project
|
||||
- Team environments
|
||||
|
||||
**Claude Code Setup:**
|
||||
**MCP Client Setup:**
|
||||
|
||||
Add to your project's `.claude/settings.local.json`:
|
||||
Add an MCP server entry to your client or project config:
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
|
|
@ -53,6 +105,15 @@ Add to your project's `.claude/settings.local.json`:
|
|||
|
||||
This creates `.vestige/vestige.db` in your project root. Add `.vestige/` to `.gitignore`.
|
||||
|
||||
If both `VESTIGE_DATA_DIR` and `--data-dir` are set, the CLI flag wins. Use the env var for a machine-wide default and the CLI flag for per-client or per-project overrides.
|
||||
|
||||
The `vestige` CLI also honors `VESTIGE_DATA_DIR`, so use the same directory when inspecting or exporting a custom MCP instance:
|
||||
|
||||
```bash
|
||||
VESTIGE_DATA_DIR=./.vestige vestige stats
|
||||
VESTIGE_DATA_DIR=./.vestige vestige portable-export ./vestige-portable.json
|
||||
```
|
||||
|
||||
**Multiple Named Instances:**
|
||||
|
||||
For power users who want both global AND project memory:
|
||||
|
|
@ -70,11 +131,11 @@ For power users who want both global AND project memory:
|
|||
}
|
||||
```
|
||||
|
||||
### Option 3: Multi-Claude Household
|
||||
### Option 3: Multi-Agent Household
|
||||
|
||||
For setups with multiple Claude instances (e.g., Claude Desktop + Claude Code, or two personas):
|
||||
For setups with multiple MCP clients or agent personas:
|
||||
|
||||
**Shared Memory (Both Claudes share memories):**
|
||||
**Shared Memory (all clients share memories):**
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
|
|
@ -86,27 +147,27 @@ For setups with multiple Claude instances (e.g., Claude Desktop + Claude Code, o
|
|||
}
|
||||
```
|
||||
|
||||
**Separate Identities (Each Claude has own memory):**
|
||||
**Separate Identities (each agent has its own memory):**
|
||||
|
||||
Claude Desktop config - for "Domovoi":
|
||||
Client config for "Research":
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "vestige-mcp",
|
||||
"args": ["--data-dir", "~/vestige-domovoi"]
|
||||
"args": ["--data-dir", "~/vestige-research"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Claude Code config - for "Storm":
|
||||
Client config for "Builder":
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"vestige": {
|
||||
"command": "vestige-mcp",
|
||||
"args": ["--data-dir", "~/vestige-storm"]
|
||||
"args": ["--data-dir", "~/vestige-builder"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -116,7 +177,7 @@ Claude Code config - for "Storm":
|
|||
|
||||
## Data Safety
|
||||
|
||||
**Important:** Vestige stores data locally with no cloud sync, redundancy, or automatic backup.
|
||||
**Important:** Vestige stores data locally. v2.1.1 adds user-controlled file-backed sync through `vestige sync`, but Vestige does not run a hosted cloud service, background replication daemon, or automatic backup for you.
|
||||
|
||||
| Use Case | Risk Level | Recommendation |
|
||||
|----------|------------|----------------|
|
||||
|
|
@ -169,3 +230,75 @@ SELECT COUNT(*) FROM knowledge_nodes WHERE retention_strength < 0.1;
|
|||
```
|
||||
|
||||
**Caution**: Don't modify the database while Vestige is running.
|
||||
|
||||
---
|
||||
|
||||
## Multi-Process Safety
|
||||
|
||||
Vestige's SQLite configuration is tuned for **safe concurrent reads alongside a single writer**. Multiple `vestige-mcp` processes pointed at the same database file is a supported *read-heavy* pattern; concurrent heavy writes from multiple processes is **experimental** and documented here honestly.
|
||||
|
||||
### What's shipped
|
||||
|
||||
Every `Storage::new()` call executes these pragmas on both the reader and writer connection (`crates/vestige-core/src/storage/sqlite.rs`):
|
||||
|
||||
```sql
|
||||
PRAGMA journal_mode = WAL; -- readers don't block writers, writers don't block readers
|
||||
PRAGMA synchronous = NORMAL; -- durable across app crashes, not across OS crashes
|
||||
PRAGMA cache_size = -64000; -- 64 MiB page cache per connection
|
||||
PRAGMA temp_store = MEMORY;
|
||||
PRAGMA foreign_keys = ON;
|
||||
PRAGMA busy_timeout = 5000; -- wait 5s on SQLITE_BUSY before surfacing the error
|
||||
PRAGMA mmap_size = 268435456; -- 256 MiB memory-mapped I/O window
|
||||
PRAGMA journal_size_limit = 67108864;
|
||||
PRAGMA optimize = 0x10002;
|
||||
```
|
||||
|
||||
Internally the `Storage` type holds **separate reader and writer connections**, each guarded by its own `Mutex<Connection>`. Within a single process this means:
|
||||
|
||||
- Any number of concurrent readers share the read connection lock.
|
||||
- Writers serialize on the writer connection lock.
|
||||
- WAL lets readers continue while a writer commits — they don't block each other at the SQLite level.
|
||||
|
||||
### What works today
|
||||
|
||||
| Pattern | Status | Notes |
|
||||
|---------|--------|-------|
|
||||
| One `vestige-mcp` + one MCP client | **Supported** | The default case. Zero contention. |
|
||||
| Multiple MCP clients, separate `--data-dir` | **Supported** | Each process owns its own DB file. No shared state. |
|
||||
| Multiple MCP clients, **shared** `--data-dir`, **one** `vestige-mcp` | **Supported** | Clients talk to a single MCP process that owns the DB. Recommended for multi-agent setups. |
|
||||
| CLI (`vestige` binary) reading while `vestige-mcp` runs | **Supported** | WAL makes this safe — queries see a consistent snapshot. |
|
||||
| Time Machine / `rsync` backup during writes | **Supported** | WAL journal gets copied with the main file; recovery handles it. |
|
||||
|
||||
### What's experimental
|
||||
|
||||
| Pattern | Status | Notes |
|
||||
|---------|--------|-------|
|
||||
| **Two `vestige-mcp` processes** writing the same DB concurrently | **Experimental** | SQLite serializes writers via a lock; if contention exceeds the 5s `busy_timeout`, writes surface `SQLITE_BUSY`. No exponential backoff or inter-process coordination layer beyond the pragma. |
|
||||
| External writers (another SQLite client holding a write transaction open) | **Experimental** | Same concern as above — the 5s window is the only safety net. |
|
||||
| Corrupted WAL recovery after hard-kill | **Supported by SQLite** | WAL is designed for crash recovery, but we do not explicitly test the `PRAGMA wal_checkpoint(RESTART)` path under load. |
|
||||
|
||||
If you hit `database is locked` errors:
|
||||
|
||||
```bash
|
||||
# Identify the holder
|
||||
lsof ~/Library/Application\ Support/com.vestige.core/vestige.db
|
||||
|
||||
# Clean shutdown of all vestige processes
|
||||
pkill -INT vestige-mcp
|
||||
```
|
||||
|
||||
### Why the "Stigmergic Swarm" story is honest
|
||||
|
||||
Multi-agent coordination through a shared memory graph — where agents alter the graph and other agents later *sense* those changes rather than passing explicit messages — is a first-class pattern on the **shared `--data-dir` + one `vestige-mcp`** setup above. In that configuration, every write flows through a single MCP process: WAL gives readers (agents querying state) a consistent view while the writer commits atomically, and the broadcast channel in `dashboard/events.rs` surfaces each cognitive event (dream, consolidation, promotion, suppression, Rac1 cascade) to every connected client in real time. No inter-process write coordination is required because there is one writer.
|
||||
|
||||
Running two or more `vestige-mcp` processes against the same file is where "experimental" kicks in. For the swarm narrative, point every agent at one MCP instance — that's the shipping pattern.
|
||||
|
||||
### Roadmap
|
||||
|
||||
Things we haven't shipped yet, tracked for a future release:
|
||||
|
||||
1. **File-based advisory lock** (`fs2` / `fcntl`) to detect and refuse startup when another `vestige-mcp` already owns the DB, instead of failing later with a lock error.
|
||||
2. **Retry with jitter on `SQLITE_BUSY`** in addition to the pragma's blocking wait.
|
||||
3. **Load test**: two `vestige-mcp` instances hammering the same file with mixed read/write traffic, verifying zero corruption and bounded write latency.
|
||||
|
||||
Until those land, treat "two writer processes on one file" as experimental. For everything else on this page, WAL + the 5s busy timeout is the shipping story.
|
||||
|
|
|
|||
102
docs/VESTIGE_STATE_AND_PLAN.md
Normal file
102
docs/VESTIGE_STATE_AND_PLAN.md
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
# Vestige State And Plan
|
||||
|
||||
This document is a public, sanitized replacement for an older internal planning
|
||||
snapshot. It intentionally omits private local paths, personal operating
|
||||
context, unpublished roadmap notes, and private repository locations.
|
||||
|
||||
For current user-facing release information, use:
|
||||
|
||||
- `README.md`
|
||||
- `CHANGELOG.md`
|
||||
- `docs/STORAGE.md`
|
||||
- `docs/COGNITIVE_SANDWICH.md`
|
||||
- `docs/AGENT-MEMORY-PROTOCOL.md`
|
||||
- `docs/CLAUDE-SETUP.md`
|
||||
|
||||
## Current Release Shape
|
||||
|
||||
Vestige v2.1.21 is the "Agent-Neutral Hardening" release. Its public scope is:
|
||||
|
||||
- stdio MCP as the default agent transport, with HTTP MCP opt-in only
|
||||
- binary-only `vestige update` by default
|
||||
- delete and purge confirmation parity for destructive memory removal
|
||||
- portable sync fixes for purge tombstones, UPSERT merge, and vector index
|
||||
reloads
|
||||
- safer release packaging with dashboard freshness checks and checksums
|
||||
- agent-neutral memory instructions for any MCP-compatible client
|
||||
|
||||
The release keeps the local-first baseline intact. Heavy model hooks, local
|
||||
verifier models, and preflight automation remain optional.
|
||||
|
||||
## Release Gates
|
||||
|
||||
Before tagging a release, run:
|
||||
|
||||
```sh
|
||||
cargo test --workspace --no-fail-fast
|
||||
cargo clippy --workspace -- -D warnings
|
||||
pnpm --filter @vestige/dashboard check
|
||||
pnpm --filter @vestige/dashboard build
|
||||
git diff --check
|
||||
```
|
||||
|
||||
For dashboard route changes, rebuild and stage `apps/dashboard/build/` so the
|
||||
embedded static assets match `apps/dashboard/src/`.
|
||||
|
||||
## Product Principles
|
||||
|
||||
- Exact things should stay exact. Literal identifiers should not lose to
|
||||
semantic expansion.
|
||||
- Forgetting should be honest. A hard purge should remove content, embeddings,
|
||||
graph edges, and derived references while retaining only non-content proof
|
||||
that deletion happened.
|
||||
- Contradictions should be visible. Trust-weighted disagreement should be
|
||||
inspectable directly instead of hidden inside a broader reasoning tool.
|
||||
- Installation should remain boring. Users should not need a large local model
|
||||
or background hook system just to use memory.
|
||||
- Pro features should add managed convenience without weakening local-first
|
||||
ownership.
|
||||
|
||||
## Public Architecture Summary
|
||||
|
||||
Vestige is organized as:
|
||||
|
||||
- `crates/vestige-core`: storage, search, embeddings, memory lifecycle, FSRS,
|
||||
graph, dream, and cognitive modules
|
||||
- `crates/vestige-mcp`: MCP server, CLI, dashboard backend, tools, update flow
|
||||
- `apps/dashboard`: SvelteKit dashboard source
|
||||
- `packages/vestige-mcp-npm`: npm wrapper for the MCP binary
|
||||
- `packages/vestige-init`: installer helper
|
||||
- `docs`: user and integration documentation
|
||||
|
||||
## v2.1.21 Implementation Notes
|
||||
|
||||
HTTP MCP is disabled unless the user passes `--http`, passes `--http-port`, or
|
||||
sets `VESTIGE_HTTP_ENABLED=1`. The stdio MCP server remains the portable default
|
||||
for Claude Code, Codex, Cursor, VS Code, Xcode, JetBrains, Windsurf, and other
|
||||
clients.
|
||||
|
||||
Purge is implemented transactionally in storage and surfaced through the MCP
|
||||
`memory` tool. `memory(action="purge", confirm=true)` is the explicit hard
|
||||
delete path. `delete` remains a backwards-compatible alias but also requires
|
||||
`confirm=true`.
|
||||
|
||||
Portable merge imports preserve both sync tombstones and non-content deletion
|
||||
tombstones. Keyed table writes use UPSERT rather than `INSERT OR REPLACE` so
|
||||
related rows are not accidentally cascaded away.
|
||||
|
||||
Claude Code Cognitive Sandwich files are optional companion files, not the
|
||||
default Vestige setup path. Use `vestige update --sandwich-companion` or
|
||||
`vestige sandwich install` only when that hook layer is wanted.
|
||||
|
||||
## 15. Autopilot Rationale
|
||||
|
||||
The backend event bus exists so dashboard and MCP activity can be observed by
|
||||
the cognitive engine without making user-facing agent hooks mandatory. Any
|
||||
autonomous behavior should be conservative, rate-limited, and local-first.
|
||||
|
||||
Autopilot-style routing should never require a remote model, a heavy local
|
||||
model, or a Claude hook to make normal memory useful. It should only connect
|
||||
already-emitted Vestige events to existing cognitive modules when that improves
|
||||
maintenance, retrieval quality, or dashboard fidelity without surprising the
|
||||
user.
|
||||
|
|
@ -20,8 +20,7 @@ It speaks MCP (Model Context Protocol), the same protocol Xcode 26.3 uses for to
|
|||
|
||||
**Step 1:** Install Vestige
|
||||
```bash
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-aarch64-apple-darwin.tar.gz | tar -xz
|
||||
sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/
|
||||
npm install -g vestige-mcp-server
|
||||
```
|
||||
|
||||
**Step 2:** Drop one file in your project root
|
||||
|
|
@ -110,8 +109,7 @@ The full setup takes 30 seconds:
|
|||
|
||||
```bash
|
||||
# Install Vestige
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-aarch64-apple-darwin.tar.gz | tar -xz
|
||||
sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/
|
||||
npm install -g vestige-mcp-server
|
||||
|
||||
# Add to your project (run from project root)
|
||||
cat > .mcp.json << 'EOF'
|
||||
|
|
|
|||
72
docs/integrations/codex-intelligent-memory.md
Normal file
72
docs/integrations/codex-intelligent-memory.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Codex Intelligent Memory Protocol
|
||||
|
||||
Codex can connect to Vestige through MCP, but MCP registration alone only makes
|
||||
the tools available. It does not make Codex automatically reason with memory.
|
||||
|
||||
Use this protocol when configuring a Codex workspace that should behave like it
|
||||
has long-term cognitive memory.
|
||||
|
||||
## 1. Register Vestige MCP
|
||||
|
||||
```toml
|
||||
[mcp_servers.vestige]
|
||||
command = "/absolute/path/to/vestige-mcp"
|
||||
```
|
||||
|
||||
Restart Codex after changing MCP configuration.
|
||||
|
||||
## 2. Add An `AGENTS.md` Trigger
|
||||
|
||||
Codex reads `AGENTS.md` files as workspace instructions. Put a file at the repo
|
||||
root, or a higher workspace root, with a rule like:
|
||||
|
||||
```markdown
|
||||
Before answering substantive prompts, consult Vestige using the current prompt
|
||||
plus project and user context. Use `session_context` for broad context, `search`
|
||||
for quick memory checks, and `deep_reference` for decisions, contradictions, or
|
||||
accuracy-sensitive questions. Compose memories into actions; do not summarize
|
||||
retrievals.
|
||||
```
|
||||
|
||||
This is the Codex equivalent of the lightweight top-bread memory trigger.
|
||||
|
||||
## 3. Use A Query Router
|
||||
|
||||
Use the smallest call that can change the answer:
|
||||
|
||||
- `session_context`: start of a topic or project switch.
|
||||
- `search`: identity, preference, exact memory, or quick project context.
|
||||
- `deep_reference` / `cross_reference`: decision history, contradictions,
|
||||
timelines, or root-cause analysis.
|
||||
- `memory(get_batch)`: expand specific load-bearing memories.
|
||||
- `smart_ingest`: save durable corrections, decisions, or new preferences.
|
||||
|
||||
## 4. Compose, Do Not Summarize
|
||||
|
||||
Retrieved memory is evidence, not the final answer.
|
||||
|
||||
Use this mental transform:
|
||||
|
||||
```text
|
||||
memory fact -> implication -> action
|
||||
```
|
||||
|
||||
If memory does not change the action, do not mention it. If it does, make the
|
||||
changed recommendation clear.
|
||||
|
||||
## 5. Know The Limit
|
||||
|
||||
Claude Code's Cognitive Sandwich can use `UserPromptSubmit` and `Stop` hooks to
|
||||
wrap every response. Codex may expose different hook events depending on version.
|
||||
Do not assume Claude's hook chain is active in Codex just because Vestige MCP is
|
||||
registered.
|
||||
|
||||
For Codex, the reliable portable layer is:
|
||||
|
||||
1. MCP server configured.
|
||||
2. `AGENTS.md` instruction trigger.
|
||||
3. Local Codex rule docs.
|
||||
4. Explicit agent discipline: call Vestige before substantive answers.
|
||||
|
||||
If a future Codex version supports a stable pre-prompt hook, wire that hook to
|
||||
inject a short Vestige reminder or context packet before the model answers.
|
||||
|
|
@ -89,6 +89,27 @@ args = ["--data-dir", "/Users/you/projects/my-app/.vestige"]
|
|||
|
||||
---
|
||||
|
||||
## Intelligent Memory Protocol
|
||||
|
||||
MCP registration makes Vestige tools available to Codex. It does not, by itself,
|
||||
force Codex to call those tools before answering.
|
||||
|
||||
For workspaces where Codex should behave like it has persistent cognitive
|
||||
memory, add an `AGENTS.md` file at the workspace or repo root:
|
||||
|
||||
```markdown
|
||||
Before answering substantive prompts, consult Vestige using the current prompt
|
||||
plus project and user context. Use `session_context` for broad context, `search`
|
||||
for quick memory checks, and `deep_reference` for decisions, contradictions, or
|
||||
accuracy-sensitive questions. Compose memories into actions; do not summarize
|
||||
retrievals.
|
||||
```
|
||||
|
||||
Then use the full protocol in
|
||||
[`codex-intelligent-memory.md`](./codex-intelligent-memory.md).
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<details>
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ It remembers.
|
|||
|
||||
## Important: Tool Limit
|
||||
|
||||
Windsurf has a **hard cap of 100 tools** across all MCP servers. Vestige uses 24 tools, leaving plenty of room for other servers.
|
||||
Windsurf has a **hard cap of 100 tools** across all MCP servers. Vestige uses 25 tools, leaving plenty of room for other servers.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,7 @@ Xcode 26.3 supports [agentic coding](https://developer.apple.com/documentation/x
|
|||
### 1. Install Vestige
|
||||
|
||||
```bash
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-aarch64-apple-darwin.tar.gz | tar -xz
|
||||
sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/
|
||||
npm install -g vestige-mcp-server@latest
|
||||
```
|
||||
|
||||
### 2. Add to your Xcode project
|
||||
|
|
@ -27,7 +26,7 @@ cat > /path/to/your/project/.mcp.json << 'EOF'
|
|||
"mcpServers": {
|
||||
"vestige": {
|
||||
"type": "stdio",
|
||||
"command": "/usr/local/bin/vestige-mcp",
|
||||
"command": "vestige-mcp",
|
||||
"args": [],
|
||||
"env": {
|
||||
"PATH": "/usr/local/bin:/usr/bin:/bin"
|
||||
|
|
@ -51,7 +50,7 @@ Quit Xcode completely (Cmd+Q) and reopen your project.
|
|||
|
||||
### 4. Verify
|
||||
|
||||
Type `/context` in the Agent panel. You should see `vestige` listed with 24 tools.
|
||||
Type `/context` in the Agent panel. You should see `vestige` listed with 25 tools.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -166,7 +165,7 @@ See [CLAUDE.md templates](../CLAUDE-SETUP.md) for a full setup.
|
|||
The first time Vestige runs, it downloads the embedding model (~130MB). In Xcode's sandboxed environment, the cache location is:
|
||||
|
||||
```
|
||||
~/Library/Caches/com.vestige.core/fastembed
|
||||
~/Library/Caches/vestige/fastembed
|
||||
```
|
||||
|
||||
If the download fails behind a corporate proxy, pre-download by running `vestige-mcp` once from your terminal.
|
||||
|
|
@ -231,7 +230,7 @@ Xcode 26.3 has a feature gate (`claudeai-mcp`) that may block custom MCP servers
|
|||
The first run downloads ~130MB. If Xcode's sandbox blocks the download:
|
||||
|
||||
1. Run `vestige-mcp` once from your terminal to cache the model
|
||||
2. The cache at `~/Library/Caches/com.vestige.core/fastembed` will be available to the sandboxed instance
|
||||
2. The cache at `~/Library/Caches/vestige/fastembed` will be available to the sandboxed instance
|
||||
|
||||
Behind a proxy:
|
||||
```bash
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ SQLite is the most deployed database in the world for a reason. WAL mode gives u
|
|||
|
||||
### fastembed (Nomic Embed v1.5)
|
||||
|
||||
All embeddings run locally. The Nomic Embed v1.5 model produces 768-dimensional vectors, runs via ONNX Runtime, and is competitive with OpenAI's ada-002. The model is cached at `~/.cache/huggingface/` after first download (~130MB). No API keys. No network calls during operation. Your memories never leave your machine.
|
||||
All embeddings run locally. The Nomic Embed v1.5 model produces 768-dimensional vectors, runs via ONNX Runtime, and is competitive with OpenAI's ada-002. The model is cached in the platform user cache directory after first download (~130MB), with `./.fastembed_cache` as a fallback. No API keys. No network calls during operation. Your memories never leave your machine.
|
||||
|
||||
### Performance
|
||||
|
||||
|
|
|
|||
|
|
@ -194,10 +194,10 @@ wc -l $(find /path/to/vestige/crates -name "*.rs") | tail -1
|
|||
# → 77,840 total
|
||||
```
|
||||
|
||||
> Seventy-eight thousand lines of Rust. Seven hundred thirty-four tests. Twenty-two megabyte binary. Ships with the dashboard embedded. Install is one curl command:
|
||||
> Seventy-eight thousand lines of Rust. Seven hundred thirty-four tests. Twenty-two megabyte binary. Ships with the dashboard embedded. Install is one npm command:
|
||||
|
||||
```bash
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-aarch64-apple-darwin.tar.gz | tar -xz
|
||||
npm install -g vestige-mcp-server
|
||||
claude mcp add vestige vestige-mcp -s user
|
||||
```
|
||||
|
||||
|
|
@ -241,8 +241,7 @@ claude mcp add vestige vestige-mcp -s user
|
|||
|
||||
```bash
|
||||
# Install (macOS Apple Silicon)
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-aarch64-apple-darwin.tar.gz | tar -xz
|
||||
sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/
|
||||
npm install -g vestige-mcp-server
|
||||
```
|
||||
|
||||
> Three binaries. The MCP server, the CLI admin tool, and a restore utility. Twenty-two megabytes total. No Docker. No Python. No node_modules. No cloud API key.
|
||||
|
|
@ -389,7 +388,7 @@ vestige-mcp --version
|
|||
# <300ns cosine similarity (benchmarked with Criterion)
|
||||
# Zero cloud dependencies
|
||||
# Zero API keys required
|
||||
# One curl command to install
|
||||
# One command to install
|
||||
```
|
||||
|
||||
> This is what I've been building for the past three months. I'm one person, I'm twenty-one years old, and I believe this is how AI memory should work — grounded in real science, running locally, open source.
|
||||
|
|
@ -420,7 +419,7 @@ vestige-mcp --version
|
|||
> Yes. It speaks MCP — the Model Context Protocol. One config change and it works with Claude Desktop, Cursor, VS Code Copilot, JetBrains, Windsurf, Xcode 26.3. Anything that speaks MCP.
|
||||
|
||||
**Q: What about multi-user or team memory?**
|
||||
> That's the v3.0 roadmap — "Hivemind." Ed25519 identity, CRDT-based sync, transactive directory (Wegner's "who knows what" routing), federated retrieval with differential privacy. The open source version is single-user, local-first. Team and cloud features will be proprietary.
|
||||
> The current Pro plan is more pragmatic: prove portable sync/storage first, then ship Solo and Team workflows around managed sync, backups, onboarding, and support. The open-source core stays local-first; paid team features should stay in the separate Pro/commercial boundary.
|
||||
|
||||
**Q: How does Prediction Error Gating prevent duplicate memories?**
|
||||
> When you ingest a new memory, it computes embedding similarity against all existing memories. If similarity is above 0.92, it reinforces the existing memory (bumps FSRS stability). Between 0.75 and 0.92, it updates/merges. Below 0.75, it creates a new memory. The thresholds come from computational neuroscience research on prediction error signals — the brain stores what's surprising, reinforces what's familiar, and updates what's partially known. Same principle.
|
||||
|
|
@ -479,7 +478,7 @@ vestige-mcp --version
|
|||
- **Start from the dashboard.** The 3D graph is the hook. It's visual, it's unusual, it makes people lean in.
|
||||
- **Don't rush the dream sequence.** The purple wash and sequential node pulses are the most visually impressive moment. Let it breathe for 3-4 seconds.
|
||||
- **Say the scientists' names.** "Ebbinghaus," "Bjork," "Frey and Morris" — this signals that you've done the reading. The MCP Dev Summit audience respects depth.
|
||||
- **Make eye contact during the punchline.** "One curl command. Your AI now has a brain." Look at the audience, not the screen.
|
||||
- **Make eye contact during the punchline.** "One command. Your AI now has a brain." Look at the audience, not the screen.
|
||||
- **Own your age.** Twenty-one, solo developer, zero funding. This is an asset, not a liability. You built something that the well-funded competitors haven't.
|
||||
- **The dashboard is your co-presenter.** Every time Claude does something, the dashboard should be showing the corresponding event. Practice the terminal-to-browser switch until it's seamless.
|
||||
- **Don't apologize.** Not for bugs, not for the AGPL, not for being solo. Confident but not arrogant. The work speaks.
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ I've been building Vestige — an MCP memory server that gives Claude persistent
|
|||
|
||||
But last week it almost cost me hours of debugging.
|
||||
|
||||
Claude confidently told me my AIMO3 competition notebook should use `--enable-prefix-caching` with vLLM. I trusted it. The notebook crashed. Scored 0/50. Burned a daily submission.
|
||||
Claude confidently told me a benchmark notebook should use `--enable-prefix-caching` with vLLM. I trusted it. The notebook crashed. Burned a daily submission.
|
||||
|
||||
The problem? I had TWO memories:
|
||||
- **January**: "prefix caching crashes with our vLLM build"
|
||||
- **March**: "prefix caching works with the new animsamuelk wheels"
|
||||
- **March**: "prefix caching works with the newer vLLM build"
|
||||
|
||||
Claude found both. Picked the wrong one. Gave me a confident wrong answer based on the January memory. The March memory was correct — but Claude had no way to know they conflicted.
|
||||
|
||||
|
|
@ -38,11 +38,11 @@ And gets back:
|
|||
{
|
||||
"newer": {
|
||||
"date": "2026-03-18",
|
||||
"preview": "Switched to animsamuelk wheels which support --enable-prefix-caching..."
|
||||
"preview": "Switched to a newer vLLM build that supports --enable-prefix-caching..."
|
||||
},
|
||||
"older": {
|
||||
"date": "2026-01-15",
|
||||
"preview": "prefix caching crashed with our samvalladares vLLM build..."
|
||||
"preview": "prefix caching crashed with our older local vLLM build..."
|
||||
},
|
||||
"recommendation": "Trust the newer memory. Consider demoting the older one."
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ Memory systems need to be SMARTER, not just bigger. That's what Vestige does —
|
|||
### Install (30 seconds):
|
||||
```bash
|
||||
# macOS Apple Silicon
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-aarch64-apple-darwin.tar.gz | tar -xz
|
||||
npm install -g vestige-mcp-server
|
||||
sudo mv vestige-mcp /usr/local/bin/
|
||||
claude mcp add vestige vestige-mcp -s user
|
||||
```
|
||||
|
|
@ -162,7 +162,7 @@ The AI sees the conflict. Picks the right one. Every time.
|
|||
**100% local. Your data never leaves your machine.**
|
||||
|
||||
```bash
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-aarch64-apple-darwin.tar.gz | tar -xz
|
||||
npm install -g vestige-mcp-server
|
||||
sudo mv vestige-mcp /usr/local/bin/
|
||||
claude mcp add vestige vestige-mcp -s user
|
||||
```
|
||||
|
|
|
|||
|
|
@ -401,8 +401,7 @@ locally on your machine.
|
|||
**Setup (2 minutes):**
|
||||
|
||||
```bash
|
||||
curl -L https://github.com/samvallad33/vestige/releases/latest/download/vestige-mcp-aarch64-apple-darwin.tar.gz | tar -xz
|
||||
sudo mv vestige-mcp vestige vestige-restore /usr/local/bin/
|
||||
npm install -g vestige-mcp-server
|
||||
claude mcp add vestige vestige-mcp -s user
|
||||
```
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue