# AGENT_INSTALL — mempalace-code Install Runbook for Coding Agents

> **Audience:** Coding agents (Claude Code, Codex, Cursor, autopilot orchestrators) installing
> mempalace-code on behalf of a human. This is a decision-tree script, not prose. Execute steps
> sequentially; each step has a shell check, a **Pass →** branch, and a **Fail →** branch.
>
> **Hard constraints:**
> - NEVER use `sudo`. All install paths are user-level.
> - NEVER make path or scope decisions without asking the human first.
> - When a step says **ASK HUMAN**, pause and wait for a reply before continuing.
> - All commands target Unix/macOS. Windows is out of scope for v1.0.

---

## Section 0 — Capability Map for Install Evaluation

Use this section when the human asks whether mempalace-code is worth installing. It is a
feature checklist, not an install step.

| Surface | Current capability |
|---------|--------------------|
| Code/docs mining | `mempalace-code mine <dir>` indexes supported source, docs, prose, config, and data files into LanceDB |
| Conversation/log ingest | `mempalace-code mine <dir> --mode convos` ingests Claude Code JSONL, Codex CLI JSONL, Gemini CLI JSONL, Claude.ai JSON, ChatGPT JSON, Slack JSON, and plain text transcripts |
| Multi-project sync | `mempalace-code mine-all <parent>` assigns one wing per initialized project; `--new-only` skips already-known wings |
| Auto-watch | `mempalace-code watch <parent>` re-mines initialized projects on commit by default; `--on-save` is available but noisier |
| MCP tools | 28 tools (default `full` profile): semantic search, code search, file context, manual drawers, KG, architecture retrieval, graph tunnels, diary, re-mine; named profiles (`minimal`, `kg`, `code`, `notes`) reduce the exposed subset at startup |
| KG / architecture | Temporal facts plus .NET/Python architecture extraction; .NET project/type graph tools require pre-mined symbols |
| Local-model fallback | `mempalace-code wake-up` emits memory layers for agents without MCP support |
| Safety/ops | Local embeddings, no API key, backup/restore/export/import, health/repair/cleanup, scan excludes, disk-budget guards |

Language support summary:
- `code_search(language=...)` accepts 45 searchable labels from the shared miner catalog.
- Tree-sitter AST when `[treesitter]` is installed: Python, TypeScript, JavaScript, TSX, JSX, Go, Rust.
- Regex structural: Java, Kotlin, C#, F#, VB.NET, XAML, Swift, PHP, Scala, Dart, Lua, Ruby, Terraform/HCL.
- YAML-aware/static: Kubernetes manifests, Helm charts/templates, Ansible playbooks/roles/inventory.
- Prose/metadata: Markdown and plain text keep heading paths and section flags.
- Adaptive/searchable: C/C++, shell, SQL, HTML/CSS, JSON/YAML/TOML, CSV, Dockerfile, Make, templates, config.
- Extensions outside the miner catalog are skipped by normal scans unless an exact file path is force-included.

Evaluation output contract:
1. Estimate token/context waste from repeated explanation and repeated file reads.
2. Rank high-ROI indexed surfaces in the target repo.
3. List supported and unsupported stack pieces from the table above.
4. If the repo already has curated memory docs, recommend a complement strategy:
   KG for volatile current facts, drawers/indexes for verbatim source material,
   curated docs for compressed narrative and reasoning.
5. Recommend adoption order: KG first, docs/drawers second, one scoped code project last.
6. Recommend MCP scope: `project` for trial/tool-surface control, `global` for mature cross-project use, or skip.
7. Name the cost: 28 MCP tools (default `full` profile) plus the injected usage rules add a prompt/tool-surface floor. Mention that `--profile=minimal` reduces this to 4 tools.
8. Give decision: install now, try scoped, wait for a named feature, or skip; include exact first commands. If recommending a trial, suggest `--profile=minimal` or `--profile=code` to limit tool surface.

---

## Section 1 — Preflight

Run all preflight checks before asking the human anything. Record results; they feed later branching.

---

### Step 1.1: Python version

**Check:**
```bash
python3 --version
```

Parse `major.minor` from stdout (e.g. `Python 3.11.4` → `3.11`).

**Pass →** Python is 3.11 or later. Record Python binary as `PYTHON=python3`. Continue to Step 1.2.

**Fail →** Python is absent or version < 3.11. **ASK HUMAN:** "Python 3.11 or later is required but was not found (or is too old). Please install Python 3.11+ and re-run this script. Reply `ready` when done."
Wait for `ready`. Re-run Step 1.1. If still failing after one retry, halt and report: "Cannot proceed — Python 3.11+ is required."

---

### Step 1.2: Existing mempalace-code install

**Check:**
```bash
command -v mempalace-code
```

Exit code 0 = binary found; non-zero = not installed.

**Pass →** Binary found. Record version — try the pipx venv Python first (works for any install method), fall back to system python3:
```bash
MPALACE_VER=$(
  "$(pipx environment --value PIPX_LOCAL_VENVS 2>/dev/null)/mempalace-code/bin/python" \
    -c "import mempalace_code; print(mempalace_code.__version__)" 2>/dev/null \
  || python3 -c "import mempalace_code; print(mempalace_code.__version__)" 2>/dev/null
)
echo "$MPALACE_VER"
```
If this prints a version string, record `MEMPALACE_VERSION=$MPALACE_VER` and set `ALREADY_INSTALLED=true`. Skip Section 3 (Install). Continue to Step 1.3.

**Note:** For pipx installs, system `python3` cannot import mempalace_code — only the pipx venv Python can. The two-command fallback above handles both cases.
The `mempalace` command name may belong to upstream/vanilla MemPalace; do not use it
to detect this fork unless it was explicitly created by `mempalace-code install-alias`.

**Fail →** Binary not found. Set `ALREADY_INSTALLED=false`. Continue to Step 1.3.

---

### Step 1.3: Existing palace directory

**Check:**
```bash
test -d ~/.mempalace/palace && echo "exists" || echo "absent"
```

**Pass →** Output is `exists`. Set `PALACE_EXISTS=true`. Continue to Step 1.4.

**Fail →** Output is `absent`. Set `PALACE_EXISTS=false`. Continue to Step 1.4.

---

### Step 1.4: pipx availability

**Check:**
```bash
command -v pipx
```

**Pass →** Set `HAS_PIPX=true`. Continue to Step 1.5.

**Fail →** Set `HAS_PIPX=false`. Continue to Step 1.5.

---

### Step 1.5: uv availability

**Check:**
```bash
command -v uv
```

**Pass →** Set `HAS_UV=true`. Continue to Section 2.

**Fail →** Set `HAS_UV=false`. Continue to Section 2.

---

## Section 2 — Human-in-the-loop Questions

Ask all five questions before acting. Record answers; they parameterize Sections 3–5.

---

### Q1 — Install method

**Condition:** `ALREADY_INSTALLED=false`

**ASK HUMAN:** "I can install mempalace-code at the user level (recommended: `uv tool install` or `pipx`, isolated from other packages) or as a project dependency in the current virtual environment (`pip`). Reply `user` for isolated install or `project` for the current venv."

**Parse response:**
- `user` → Set `INSTALL_METHOD=user`. Prefer `uv tool install` if `HAS_UV=true`, else fall back to `pipx`.
- `project` → Set `INSTALL_METHOD=project`.
- Anything else → Repeat the question once. If still unclear, default to `user` and inform the human.

**Skip if:** `ALREADY_INSTALLED=true` — no install needed.

---

### Q2 — Palace storage path

**ASK HUMAN:** "Where should the memory palace be stored? The default location is `~/.mempalace/palace`. Reply `default` to use it, or provide a custom absolute path (e.g. `/data/mempalace/palace`). Advanced: you can also set the `MEMPALACE_PALACE_PATH` environment variable instead."

**Parse response:**
- `default` → Set `PALACE_PATH=~/.mempalace/palace`.
- An absolute path (starts with `/` or `~/`) → Set `PALACE_PATH=<that path>`.
- A `MEMPALACE_PALACE_PATH=...` export → Record the env var; set `PALACE_PATH` from it.
- Anything else → Repeat once; default to `~/.mempalace/palace` if still unclear.

**Note:** `PALACE_PATH` is the vector DB storage location. It is separate from the project directory passed to `mempalace-code init`.

---

### Q3 — Model download consent

**ASK HUMAN:** "mempalace-code uses a local embedding model (~80 MB) downloaded once from HuggingFace. This requires internet access during setup; after that everything runs offline. Reply `yes` to download now, `no` to skip (you can run `mempalace-code fetch-model` later), or `offline` if this machine has no internet access."

**Parse response:**
- `yes` → Set `DOWNLOAD_MODEL=yes`.
- `no` → Set `DOWNLOAD_MODEL=no`.
- `offline` → Set `DOWNLOAD_MODEL=no`. Note: airgapped setup — see `docs/OFFLINE_USAGE.md`.
- Anything else → Repeat once; default to `no` to be safe.

---

### Q4 — MCP scope

**ASK HUMAN:** "Should the mempalace-code MCP server be registered globally (available in all projects) or only for the current project? Reply `global` to register in `~/.mcp.json` (Claude Code) / `~/.codex/config.toml` (Codex), or `project` to register in `.mcp.json` in the current directory."

**Parse response:**
- `global` → Set `MCP_SCOPE=global`.
- `project` → Set `MCP_SCOPE=project`.
- Anything else → Repeat once; default to `global`.

---

### Q5 — MCP tool profile

**ASK HUMAN:** "Which tool profile should the mempalace-code MCP server use? Reply with one of:
- `full` — all 28 tools (default; no surface reduction)
- `minimal` — 4 tools: search + store only
- `kg` — 8 tools: minimal + temporal knowledge graph
- `code` — 10 tools: code archaeology (no drawer-write/diary)
- `notes` — 12 tools: knowledge management + diary (no code-search)

If unsure, reply `full` to start with everything and narrow later."

**Parse response:**
- `full` → Set `MCP_PROFILE=full`.
- `minimal` → Set `MCP_PROFILE=minimal`.
- `kg` → Set `MCP_PROFILE=kg`.
- `code` → Set `MCP_PROFILE=code`.
- `notes` → Set `MCP_PROFILE=notes`.
- Anything else → Repeat once; default to `full`.

---

### Q6 — Project or corpus to mine

**ASK HUMAN:** "Should I index something into the palace now? Reply `project:/abs/path` for code/docs, `convos:/abs/path` for conversation/log exports, a bare absolute path for code/docs, or `skip` to do it later. For large monorepos, a high-ROI docs/spec subdirectory is valid for the first trial."

**Parse response:**
- `project:/abs/path` → Set `MINE_PATH=<path>` and `MINE_MODE=projects`.
- `convos:/abs/path` → Set `MINE_PATH=<path>` and `MINE_MODE=convos`.
- A bare absolute path → Set `MINE_PATH=<that path>` and `MINE_MODE=projects`.
- `skip` → Set `MINE_PATH=skip` and `MINE_MODE=projects`.
- Anything else → Repeat once; default to `skip`.

---

## Section 3 — Install

**Skip this section if `ALREADY_INSTALLED=true`.**

For side-by-side use with upstream/vanilla MemPalace, prefer an isolated user-level
install (`uv tool install` or `pipx`). Packaged installs use the console command
`mempalace-code` and the Python import package `mempalace_code`, so they can
share a Python environment with upstream/vanilla `mempalace`.

---

### Step 3.0: Bootstrap script (preferred)

The bootstrap script handles venv creation, pip upgrade, install, and PATH symlink in one step.
It is the recommended path for servers, CI, and any machine where system pip may be outdated.

```bash
# From PyPI (default, once published)
curl -fsSL https://raw.githubusercontent.com/rergards/mempalace-code/main/scripts/bootstrap.sh | bash

# From git (before PyPI publish)
curl -fsSL https://raw.githubusercontent.com/rergards/mempalace-code/main/scripts/bootstrap.sh | MEMPALACE_SOURCE=git bash
```

**Pass →** Script exits 0 and prints `Done. mempalace-code <version> is ready.` Skip to Section 4.

**Fail →** Script exits non-zero. Read the error output. Common causes: no Python 3.11+, no `venv` module (`apt install python3-venv`). Fix and re-run, or fall through to manual Steps 3.1–3.3.

---

### Step 3.1: Install via pipx (INSTALL_METHOD=user, HAS_PIPX=true)

**Check:**
```bash
command -v pipx
```

**Pass →** Run:
```bash
pipx install mempalace-code
```
Exit code 0 = success. Continue to Step 3.4.

**Fail →** pipx not found but `INSTALL_METHOD=user`. Attempt to install pipx:
```bash
python3 -m pip install --user pipx
python3 -m pipx ensurepath
```
If that succeeds, re-run `pipx install mempalace-code`. If pipx install fails, fall through to Step 3.2.

---

### Step 3.2: Install via uv (INSTALL_METHOD=user and HAS_UV=true, or pipx unavailable)

**Check:**
```bash
command -v uv
```

**Pass →** Run:
```bash
uv tool install mempalace-code
```
Exit code 0 = success. Continue to Step 3.4.

**Fail →** uv not found. Fall through to Step 3.3.

---

### Step 3.3: Install via pip in venv (fallback)

No pipx, no uv. Create a venv and install.

**Important:** Ubuntu 22.04 and similar distros ship pip 22.x, which cannot build hatchling metadata. Upgrade pip inside the venv first.

```bash
python3 -m venv ~/.mempalace/venv
~/.mempalace/venv/bin/pip install --upgrade pip
~/.mempalace/venv/bin/pip install mempalace-code
```

Exit code 0 = success. Set `PYTHON=~/.mempalace/venv/bin/python`. Continue to Step 3.4.

**Fail →** pip install failed. **ASK HUMAN:** "Installation failed. Common causes: network error, Python too old, or permissions issue. Error output: `<paste stderr>`. Please check your network and Python version, then reply `retry` or `abort`."
- `retry` → Re-run Step 3.3 once.
- `abort` → Halt. Report error to human.

---

### Step 3.4: Post-install verification

```bash
python3 -c "import mempalace_code; print(mempalace_code.__version__)"
```

**Pass →** Prints a version string (e.g. `3.0.0`). Record `MEMPALACE_VERSION`. Continue to Section 4.

**Fail →** Import error. Likely cause: shell PATH not updated after pipx install. Try:
```bash
hash -r && python3 -c "import mempalace_code; print(mempalace_code.__version__)"
```
If still failing, **ASK HUMAN:** "mempalace-code was installed but cannot be imported. This usually means the pipx venv Python is not on PATH, or install was into a different environment. Reply `retry` after sourcing your shell profile (`. ~/.bashrc` or `. ~/.zshrc`) or `abort`."

---

### Step 3.5: Optional `mempalace` alias

The default executable is `mempalace-code` so this fork can coexist with
upstream/vanilla `mempalace` on the same machine. Only create the shorter alias if
the command name is unused:

```bash
command -v mempalace || mempalace-code install-alias
```

If `command -v mempalace` prints a path, leave it untouched. It may belong to
upstream/vanilla MemPalace or another local install.

---

## Section 4 — Init + Model Download

---

### Step 4a: Configure palace storage path

The palace storage path resolves in this priority order:
1. `MEMPALACE_PALACE_PATH` environment variable (highest)
2. `palace_path` key in `~/.mempalace/config.json`
3. Default: `~/.mempalace/palace`

**Check (custom path case):**
If `PALACE_PATH != ~/.mempalace/palace`, set the env var so all subsequent commands use it:
```bash
export MEMPALACE_PALACE_PATH="<PALACE_PATH>"
```
To make it permanent, also write to `~/.mempalace/config.json`:
```bash
mkdir -p ~/.mempalace
python3 -c "
import json, pathlib
cfg = pathlib.Path.home() / '.mempalace' / 'config.json'
data = json.loads(cfg.read_text()) if cfg.exists() else {}
data['palace_path'] = '<PALACE_PATH>'
cfg.write_text(json.dumps(data, indent=2))
print('palace_path written')
"
```

**Pass →** Output is `palace_path written`. Continue to Step 4b.

**Fail →** Write failed. **ASK HUMAN:** "Could not write `~/.mempalace/config.json`. The `MEMPALACE_PALACE_PATH` env var is still set for this session. Reply `continue` to proceed with session-only config, or `abort` to stop."

**Default path case:** No action needed — `mempalace-code init` will create `~/.mempalace/palace` automatically.

---

### Step 4b: Initialize a project directory

**Condition:** `MINE_PATH != skip`

Run:
```bash
mempalace-code init "<MINE_PATH>"
```

`mempalace-code init` is non-interactive by default — it detects rooms from the folder structure
and writes `mempalace.yaml` without prompting. The `--yes` flag is accepted for backward
compatibility with existing scripts but is no longer required.
Heuristic people/project entity detection is opt-in; add `--detect-entities` only when the
human explicitly wants entity detection during initialization.

`--detect-entities` is intended for prose-heavy folders (meeting notes, client notes,
personal notes, conversation exports), not ordinary code repos. It samples up to 10
readable files, prefers prose extensions (`.md`, `.txt`, `.rst`, `.csv`), reads the first
5 KB of each sampled file, and looks for heuristic people/project signals. If candidates
are confirmed, init writes `<MINE_PATH>/entities.json` with:

```json
{"people": ["Alice"], "projects": ["Apollo"]}
```

For unattended setup, use `--detect-entities` only after the human accepts the
tradeoff: detected people/projects are auto-accepted and uncertain candidates are skipped.
Do not add the flag just because a directory is a source repo; code symbols are handled by
`mempalace-code mine`, and broad entity scans over code create false positives.

**Pass →** Exit code 0. Config and room setup complete. Continue to Step 4c.

**Fail →** Non-zero exit. Common causes: directory does not exist, permissions error. **ASK HUMAN:** "Could not initialize `<MINE_PATH>`. Error: `<paste stderr>`. Please confirm the path exists and is readable, then reply `retry` with a corrected path, or `skip`."
- `retry <path>` → Re-run with the corrected path.
- `skip` → Set `MINE_PATH=skip`. Continue to Step 4c.

---

### Step 4c: Download embedding model

**Condition:** `DOWNLOAD_MODEL=yes`

Run:
```bash
mempalace-code fetch-model
```

`fetch-model` is idempotent — if the model is already cached it loads instantly from disk (no network call). Expected output ends with `Done — embedding model is ready for offline use.`

Exit code 0 = success. Set `MODEL_READY=true`. Continue to Step 4d.

**Fail →** Retry once. If still failing, **ASK HUMAN:** "Model download failed (network error or HuggingFace unavailable). The palace will work without the model, but search quality will degrade until it is available. Reply `retry` to try again, or `continue` to proceed without the model (run `mempalace-code fetch-model` later)."

**Condition:** `DOWNLOAD_MODEL=no` → Set `MODEL_READY=false`. Note to human: run `mempalace-code fetch-model` before first search.

---

### Step 4d: Mine the project (if applicable)

**Condition:** `MINE_PATH != skip`

```bash
mempalace-code mine "<MINE_PATH>" --mode "<MINE_MODE>"
```

**Pass →** Exit code 0. Output ends with a filed-drawer count. Continue to Section 5.

**Fail →** Mine failed. **ASK HUMAN:** "Mining `<MINE_PATH>` failed. Error: `<paste stderr>`. Reply `retry` or `skip`."

---

## Section 5 — MCP Wiring

Wire the mempalace-code MCP server so your AI assistant can call it during conversations.
Use `mempalace-code` as the MCP server registration name. The exposed MCP tool
identifiers stay `mempalace_*` for compatibility with existing agents and usage rules.

**Important:** The MCP server is `python -m mempalace_code.mcp_server`, not a CLI subcommand. The Python interpreter used must be the one that has `mempalace_code` importable:
- **pipx install:** `$(pipx environment --value PIPX_LOCAL_VENVS)/mempalace-code/bin/python`
- **uv / pip-in-venv:** the venv Python (e.g. `~/.mempalace/venv/bin/python` or `.venv/bin/python`)
- **pip --user install:** `python3` if the package is on PATH

Resolve the Python path before Step 5.1:
```bash
MPALACE_PYTHON=$(python3 -c "import sys; print(sys.executable)")
# Verify mempalace-code is importable from this Python:
"$MPALACE_PYTHON" -c "import mempalace_code; print('ok')"
```

**Pass →** Output is `ok`. Use `$MPALACE_PYTHON` in all MCP wiring below.

**Compatibility note:** source checkouts also provide `python -m mempalace.mcp_server`
when the checkout is on `PYTHONPATH`, so older repo-local Codex/Autopilot MCP
configs keep working. New installs and docs should use
`python -m mempalace_code.mcp_server`.

**Fail →** Find the pipx venv Python:
```bash
MPALACE_PYTHON=$(pipx environment --value PIPX_LOCAL_VENVS)/mempalace-code/bin/python
"$MPALACE_PYTHON" -c "import mempalace_code; print('ok')"
```

---

### Step 5.1: Claude Code MCP Wiring

**Check — already wired?**
```bash
claude mcp list 2>/dev/null | grep -i mempalace-code
```

**Pass →** mempalace-code is already in the MCP list. Set `CLAUDE_WIRED=true`. Skip to Step 5.2.

**Fail →** Not wired. Proceed based on `MCP_SCOPE`.

#### 5.1-A: Global scope (MCP_SCOPE=global)

Preferred (CLI):
```bash
claude mcp add --scope user mempalace-code -- "$MPALACE_PYTHON" -m mempalace_code.mcp_server --profile=$MCP_PROFILE
```

Exit code 0 = success. This writes to `~/.mcp.json` under the `mcpServers` key.

**Fail (CLI not available) →** Manual fallback — edit `~/.mcp.json` (create if absent), substituting `<MCP_PROFILE>` with the value from Q5:
```json
{
  "mcpServers": {
    "mempalace-code": {
      "type": "stdio",
      "command": "<MPALACE_PYTHON>",
      "args": ["-m", "mempalace_code.mcp_server", "--profile=<MCP_PROFILE>"]
    }
  }
}
```
If `~/.mcp.json` already exists with other entries, merge only the `"mempalace-code"` key into `"mcpServers"` without overwriting other keys.

#### 5.1-B: Project scope (MCP_SCOPE=project)

Preferred (CLI):
```bash
claude mcp add --scope project mempalace-code -- "$MPALACE_PYTHON" -m mempalace_code.mcp_server --profile=$MCP_PROFILE
```

**Fail (CLI not available) →** Manual fallback — create or update `.mcp.json` in the current working directory, substituting `<MCP_PROFILE>` with the value from Q5:
```json
{
  "mcpServers": {
    "mempalace-code": {
      "command": "<MPALACE_PYTHON>",
      "args": ["-m", "mempalace_code.mcp_server", "--profile=<MCP_PROFILE>"]
    }
  }
}
```

**Post-wire check:**
```bash
claude mcp list 2>/dev/null | grep -i mempalace-code
```

**Pass →** Set `CLAUDE_WIRED=true`. Continue to Step 5.2.

**Fail →** **ASK HUMAN:** "Claude Code MCP wiring appears to have failed — `claude mcp list` does not show mempalace-code. Manual fix: add the entry to `~/.claude.json` (global) or `.mcp.json` (project) as shown above, then reply `done` to continue."

---

### Step 5.2: Codex MCP Wiring

**Check — codex CLI available?**
```bash
command -v codex
```

**Pass →** Codex CLI found. Check if `codex mcp` subcommand exists:
```bash
codex mcp --help 2>/dev/null && echo "has_mcp" || echo "no_mcp"
```

If `has_mcp`:
```bash
codex mcp add mempalace-code -- "$MPALACE_PYTHON" -m mempalace_code.mcp_server --profile=$MCP_PROFILE
```

Exit code 0 = success. Set `CODEX_WIRED=true`.

If `no_mcp` or CLI add fails → Fall through to manual TOML edit below.

**Fail (no codex CLI) →** Skip Codex wiring or use manual TOML if the human uses Codex.

#### Manual TOML fallback (any Codex install)

Edit `~/.codex/config.toml`. Resolve `MPALACE_PYTHON` first (see Step 5 preamble), then append, substituting `<MCP_PROFILE>` with the value from Q5:

```toml
[mcp_servers.mempalace-code]
command = "<MPALACE_PYTHON>"
args = ["-m", "mempalace_code.mcp_server", "--profile=<MCP_PROFILE>"]
```

If `~/.codex/config.toml` does not exist, create the directory first:
```bash
mkdir -p ~/.codex
```

**Pass →** File written. Set `CODEX_WIRED=true`.

**Fail →** **ASK HUMAN:** "Could not write `~/.codex/config.toml`. Error: `<paste>`. Please create the file manually using the TOML snippet above, then reply `done`."

---

### Step 5.3: Auto-save for conversation context

Code mining is handled by the watcher (`mempalace-code watch`) and works with any client. Conversation context (decisions, discussions, debugging notes) is saved via **MCP tools + usage rules** — this works identically across all agents.

The recommended approach for **all agents** (Claude Code, Codex, Cursor, etc.):
1. Wire the MCP server (Steps 5.1/5.2) so the agent can call `mempalace_add_drawer` and `mempalace_diary_write`.
2. Add usage rules to the agent's instructions (Section 7) so it knows when to save.

That's it. No hooks needed.

> **Legacy: Claude Code auto-save hooks.** Claude Code also supports optional bash hooks that fire on Stop/PreCompact events and remind the AI to save at fixed intervals. These are redundant if you have MCP + usage rules set up, but are documented in [`hooks/README.md`](../hooks/README.md) for users who want belt-and-suspenders.

---

## Section 6 — Verification

Run all checks. Each one is a pass/fail with an explicit failure action.

---

### Step 6.1: Palace status

```bash
mempalace-code status
```

**Pass →** Exit code 0. Output shows palace path, total drawers, and wing list. Confirm `palace_path` in the output matches `PALACE_PATH`.

**Fail →** Exit code non-zero or output is empty/error. Likely causes: wrong `PALACE_PATH`, palace not initialized. **ASK HUMAN:** "Palace status check failed. Error: `<paste stderr>`. Common fix: check `MEMPALACE_PALACE_PATH` env var or run `mempalace-code init <project_dir>`. Reply `retry` after fixing, or `skip`."

---

### Step 6.2: Search smoke test

```bash
mempalace-code search "test" --results 1
```

**Pass →** Exit code 0. Output contains a formatted result block with `wing`, `room`, and `similarity` fields, or an `empty palace` message (acceptable for a fresh palace). Either is a pass.

**Fail →** Exit code non-zero. Common causes: palace not initialized, embedding model not downloaded.
- If model not downloaded: run `mempalace-code fetch-model` (see Step 4c), then retry.
- Otherwise: **ASK HUMAN:** "Search smoke test failed. Error: `<paste stderr>`. Reply `retry` or `skip`."

---

### Step 6.3: MCP tool availability

For Claude Code:
```bash
claude mcp list 2>/dev/null | grep mempalace-code
```

**Pass →** mempalace-code appears in the list. Wiring is confirmed.

**Fail →** Not in list. Re-run Step 5.1 wiring. If still failing after one retry, **ASK HUMAN:** "MCP wiring could not be confirmed. Please check `~/.claude.json` or `.mcp.json` manually and reply `done` when corrected."

---

## Section 7 — Usage Rules (CLAUDE.md injection)

After a successful install and verification, offer to inject mempalace usage rules into the human's CLAUDE.md. These rules teach the AI assistant *how* to use mempalace effectively — without them, the tools are available but the assistant won't know when or how to call them.

> **Source of truth:** the usage-rules block lives in [`docs/LLM_USAGE_RULES.md`](LLM_USAGE_RULES.md) (below the `# mempalace-code — Usage Rules` heading). If you keep the inline block below in sync with that file, either works. Humans doing this manually should copy from `LLM_USAGE_RULES.md`.

---

### Step 7.1: Offer injection

**ASK HUMAN:** "mempalace-code is installed and working. Should I add usage rules to your CLAUDE.md so your AI assistant knows how to use mempalace effectively? This teaches it when to search, when to store, and how to organize memories. Reply `yes` (recommended) or `skip`."

- `yes` → Continue to Step 7.2.
- `skip` → Skip Section 7 entirely.

---

### Step 7.2: Determine target file

Based on `MCP_SCOPE`:

- `global` → Target: `~/.claude/CLAUDE.md` (or create if absent)
- `project` → Target: `CLAUDE.md` in the current working directory

If the target file already contains `mempalace` (case-insensitive), **ASK HUMAN:** "Your CLAUDE.md already mentions mempalace-code. Should I append the usage rules anyway? Reply `yes` or `skip`."

---

### Step 7.3: Append usage rules

Append the block below to the target file. Do not modify any existing content. The block is the canonical usage rules from [`docs/LLM_USAGE_RULES.md`](LLM_USAGE_RULES.md) — keep the two in sync (single source of truth is `LLM_USAGE_RULES.md`; this copy is embedded so the agent runbook stays self-contained).

````markdown

# mempalace-code — Usage Rules

mempalace-code is a local semantic memory system exposed over MCP. Content is stored verbatim in a vector database; no cloud, no API keys, no summarisation.

## Mental model

- **Wing** — a project or knowledge domain. One per repo, plus cross-project wings like `people`, `decisions`.
- **Room** — a topic within a wing (`backend`, `debugging`, `meetings`). Organisational; searches ignore rooms unless you scope explicitly.
- **Drawer** — verbatim content stored in a room. Persistent, shared across agents, retrieved by meaning.
- **Knowledge Graph (KG)** — entity-relationship triples with validity windows. For facts that evolve (versions, roles, statuses, deadlines).
- **Diary** — agent-scoped first-person session log. Read on next session to restore continuity; not team-authoritative.

## Routing: which tool, when?

| Task                                                | Primary tool                         |
|-----------------------------------------------------|--------------------------------------|
| "Have we discussed X before?" / past decisions      | `mempalace_search`                   |
| "What is the current value of X?" (temporal fact)   | `mempalace_kg_query`                 |
| "How did X change over time?"                       | `mempalace_kg_timeline`              |
| Find a function/class/symbol/file                   | `mempalace_code_search`              |
| All indexed chunks for a specific file              | `mempalace_file_context`             |
| Refresh/re-mine an indexed source/docs directory    | `mempalace_mine`                     |
| Explain how a subsystem works                       | `mempalace_explain_subsystem`        |
| Classify dependencies as core / platform / glue     | `mempalace_extract_reusable`         |
| Inheritance chain (ancestors + descendants)         | `mempalace_show_type_dependencies`   |
| Project-level dependency graph (.NET)               | `mempalace_show_project_graph`       |
| Walk related rooms from a starting room             | `mempalace_traverse`                 |
| Find rooms that bridge two wings                    | `mempalace_find_tunnels`             |
| Save a decision, root cause, or discussion          | `mempalace_add_drawer`               |
| Save/update a temporal fact                         | `mempalace_kg_invalidate` + `mempalace_kg_add` |
| End-of-session continuity note (self-scoped)        | `mempalace_diary_write`              |
| Resume prior session continuity                     | `mempalace_diary_read`               |
| Verify palace is alive before relying on it         | `mempalace_status`                   |

Default to `mempalace_search` only when no more specific tool applies.

## Search rules

Call `mempalace_search` **before substantial repo exploration** (reading many files, broad grepping, planning) when prior context could plausibly exist — new feature requests, bug investigations, questions about past decisions, people, timelines, or project history.

- Try 2–3 reformulations on low-confidence or empty results before giving up.
- Scope with `wing=<project_slug>` for project-local topics; omit for cross-cutting ones.
- On persistent miss, proceed with host tools and consider writing a drawer after the task so the next agent finds it.
- For entity-specific facts, also call `mempalace_kg_query`.

Skip search for pure mechanical operations (run tests, format files, rename within one file).

## Index freshness rules

MCP search only sees indexed content. If a source/docs directory is missing or stale and the tool exists, use `mempalace_mine(directory=...)` to refresh it before relying on search. For conversation/log exports, use the CLI path (`mempalace-code mine <dir> --mode convos`) or ask the human to run it; `mempalace_mine` is project-source re-mining only.

For large monorepos, prefer the highest-ROI initialized subdirectory first when the human wants a trial. Do not assume unsupported extensions are indexed: normal scans skip file types outside the miner catalog unless an exact file path is force-included.

## Existing memory systems

If the repo already has curated memory docs (`MEMORY.md`, project notes, hand-written summaries), do not mirror them wholesale into drawers. Use stores by job:
- KG = volatile current facts that need exact lookup or history.
- Drawers = verbatim source material, decisions, root causes, and discussion excerpts.
- Diary = this agent's own continuity notes.
- Curated docs = compressed narrative, rationale, and human-maintained summaries.

Do not turn a carefully compressed memory file into drawer content unless the human explicitly asks. Prefer adding precise KG triples for facts that drift and drawers for original verbatim evidence.

## Knowledge Graph rules

Use the KG for facts that **change over time** or need **exact-match lookup** — version numbers, stack choices, ownership, statuses, deadlines.

Update protocol: `mempalace_kg_query` → `mempalace_kg_invalidate` (old triple, today's date) → `mempalace_kg_add` (new triple, validity window). Never leave two live triples for the same `(subject, predicate)`.

Bad for KG: code patterns, debugging notes, prose — those belong in a drawer.

## Drawer rules

Write a drawer after:
- A significant decision or architectural discussion — include reasoning and rejected alternatives.
- Debugging a hard problem — capture the root cause, not the symptom.
- Durable context about people, timelines, or project goals.
- Significant session wrap-up others might need.

**Before filing substantial new prose, call `mempalace_check_duplicate`** and merge rather than overwrite if a near-duplicate exists.

Content rules: store verbatim; one topic per drawer; keep it ≤ ~60 lines; reference file paths and issue/PR IDs rather than pasting large blobs.

## Wing & room conventions

| Wing              | Use for                                              |
|-------------------|------------------------------------------------------|
| `<project_slug>`  | Project-specific knowledge. One wing per repo.       |
| `people`          | Facts about collaborators and stakeholders.          |
| `decisions`       | Cross-project architectural or process decisions.    |

Call `mempalace_list_wings` / `mempalace_list_rooms` before inventing new names. Reuse existing rooms (`backend`, `frontend`, `architecture`, `debugging`, `meetings`, `infrastructure`, `general`) unless a genuinely new topic warrants a new one.

## Diary rules

`mempalace_diary_write` creates an agent-scoped first-person session record.

- Pass `agent_name` = the value of `MEMPALACE_AGENT_NAME` from the environment. Do not guess, do not hardcode another agent's identity.
- Write once at end of a meaningful session — not per message.
- Content: what was attempted, what shipped, what remains, where you left off.
- Read with `mempalace_diary_read` at session start when continuity matters.

Diary ≠ drawer. Diary is for the same agent's next run; drawer is for the team.

## Never

- Never fabricate a tool call or invent tool names. If the tool is not in your MCP tool list, it is not available — fall back to host tools.
- Never store secrets, tokens, credentials, private keys, or PII (home addresses, phone numbers, government IDs) in drawers or the KG. Collaborator context (name, role, team, preferences, working relationships) in the `people` wing is fine — that is the wing's purpose.
- Never summarise or compress drawer content; store verbatim.
- Never create a new wing when an existing one fits.
- Never leave two live KG triples for the same `(subject, predicate)`.
- Never call `mempalace_delete_drawer` or `mempalace_delete_wing` except to correct content that is *wrong*. Evolved facts get a new drawer / a KG invalidate-and-add, not a delete.
- Never treat diary entries as team-authoritative memory. They are agent-scoped context, not a source of truth.
- Never infer absence from a search miss. "Not found" means "not indexed or not phrased to match," not "does not exist."

## Corrections (no update tool)

To correct *wrong* content: `mempalace_search` the drawer → `mempalace_delete_drawer` with its ID → `mempalace_add_drawer` with the fix. For *evolved* facts, add a new drawer instead and let history stand; track current state in the KG.
````

**Pass →** Content appended. Inform human: "Added mempalace usage rules to `<target file>`. Your AI assistant will now use mempalace proactively."

**Fail →** File write failed. Print the snippet above and **ASK HUMAN:** "Could not write to `<target file>`. Please paste the block above into your CLAUDE.md manually."

---

## End State

A successful install produces:

| Item | Expected state |
|------|---------------|
| `python3 -c "import mempalace_code; print(mempalace_code.__version__)"` | Prints version string |
| `command -v mempalace-code` | Returns path to binary |
| `mempalace-code status` | Exit 0, shows palace path |
| `mempalace-code search "test" --results 1` | Exit 0, formatted output |
| `claude mcp list \| grep mempalace-code` | Shows entry (if Claude Code target) |
| `~/.codex/config.toml` contains `mcp_servers.mempalace-code` | Present (if Codex target) |

### Version Check (opt-in)

The installer does **not** enable periodic version checks. Users may opt in interactively
(the CLI will prompt once on the first interactive command) or explicitly:

```bash
mempalace-code version-check --enable   # opt in
mempalace-code version-check --disable  # opt out (suppress future prompts)
mempalace-code version-check            # show current status (local-only)
mempalace-code version-check --check-now  # fetch from PyPI right now
```

For automated installs, CI pipelines, and non-interactive agents:
- The first-run prompt is suppressed automatically when stdin/stdout/stderr are not TTYs.
- To permanently disable prompts and checks: `mempalace-code version-check --disable` or set
  `MEMPALACE_VERSION_CHECK=0` in the environment.
- No version-check network call is ever made unless the user has opted in or passed `--check-now`.

---

## Reference

| Topic | Source |
|-------|--------|
| Palace path config | `MempalaceConfig.palace_path` in `mempalace_code/config.py` — env → config.json → default |
| All CLI flags | `mempalace-code --help` / `mempalace-code <cmd> --help` |
| MCP tool list and profiles | `README.md` → MCP Server section and MCP Tool Profiles table |
| Auto-save hooks | `hooks/README.md` |
| Airgapped / offline setup | `docs/OFFLINE_USAGE.md` |
| Manual MCP setup examples | `examples/mcp_setup.md` |

---

## Troubleshooting

### Search returns empty or counts don't match

```bash
mempalace-code health
```

If `ok: false` or errors reported:

```bash
mempalace-code repair --dry-run    # see what would be recovered
mempalace-code repair --rollback   # roll back to last working version
```

### MCP tools return empty wings/rooms

Same as above — likely fragment corruption. Run `mempalace-code health`.

### "Table unreadable" or LanceDB errors

Storage corruption. Use `mempalace-code repair --rollback`. Data added after corruption point is lost. This is why auto-backup exists (`~/.mempalace/backups/pre_optimize_*.tar.gz`). Pre-optimize archives are bounded by default (newest 5 kept); scheduled archives are bounded by default (newest 14 kept); set `MEMPALACE_BACKUP_RETAIN_COUNT=0` to keep all kinds unbounded. Successful optimize runs also perform best-effort verified stale-version cleanup; use `mempalace-code cleanup` manually for older accumulations or emergency disk recovery after stopping writers.

### Re-mine doesn't fix the issue

Manual drawers are not regenerated by mining. Check if you have a backup:

```bash
mempalace-code backup list
mempalace-code restore <backup.tar.gz>
```

---

## Validation Log

*End-to-end validation status: pending — to be recorded after first clean-machine agent run.*

Record format (fill in after validation):
```
Agent:      <Claude Code | Codex | other>
Date:       <ISO date>
Machine:    <clean VM / CI container / other>
Deviations: <list any step where agent deviated from script, or "none">
Questions outside script: <list any, or "none">
Result:     <pass | fail>
```
