Dual ~/.claude.json divergence — session reads /home/claude/.claude.json not /root

Claude Code has TWO parallel user-config files that can drift silently:

  • /home/claude/.claude.json — read when the session runs as claude user (default)
  • /root/.claude.json — read when sudo claude or any root-invoked claude CLI runs

Silent drift symptom: MEMORY.md asserts “Permanent 10 MCPs”, but live claude mcp list (as claude-user) showed only 8. Root cause: 2 MCPs (researchclaw, xint) were registered only in /root/.claude.json, never cascaded to /home/claude/.claude.json. Session couldn’t see them.

Detection command:

diff <(jq -S .mcpServers /home/claude/.claude.json) <(jq -S .mcpServers /root/.claude.json)

Empty diff = synced; any output = drift.

Reconciliation:

import json
home_cfg = json.load(open('/home/claude/.claude.json'))
root_cfg = json.load(open('/root/.claude.json'))
all_names = set(home_cfg.get('mcpServers',{})) | set(root_cfg.get('mcpServers',{}))
# For each name, ensure it's in both with identical config

Rule: when claude mcp add --scope user is used, it writes ONLY to the running-user’s home. Always cascade to both files manually, or use a prepare-mcp hook. MEMORY.md now documents this as a CRITICAL system invariant. Session-start pristine sweep added a dual-config diff check (evolution-backlog item).

Universal lesson: when the same data has TWO physical homes (root-user vs claude-user, host vs container, primary vs replica), documentation cannot prevent drift — only automated diff/sync can.