Claude Code Memory System

← Back to Index

Repo: https://github.com/jhathcock-sys/ai-assistant-config | Writeup: https://jhathcock-sys.github.io/me/projects/claude-memory/


Overview

Structured context system for AI-assisted infrastructure development. Version 3.0 (Feb 2026) adds semantic search via ChromaDB vector database with MCP integration. Version 2.0 uses XML format and symlink-based architecture. Version 1.0 was the initial file-based system.


Memory System 3.0: Semantic Memory (Feb 9, 2026)

Major Evolution: Shifted from file-based context to semantic vector search. Adds ChromaDB vector database for on-demand retrieval with MCP (Model Context Protocol) integration.

The Problem with File-Based Memory

  • Context window limits - Can’t load all documentation at once
  • Keyword matching is brittle - No semantic understanding
  • Manual maintenance doesn’t scale - Every service needs XML updates

ChromaDB Architecture

Three Collections:

CollectionPurposeExample
infrastructureNetwork topology, IPs, services, stacks”Wazuh SIEM at 192.168.1.XXX”
documentationHow-to guides, runbooks, troubleshooting”Restart monitoring: docker compose up -d”
decisionsArchitecture rationale, lessons learned”Chose Wazuh over ELK for lower resources”

Storage: /home/cib/.chroma-db

MCP Integration

Claude can query ChromaDB transparently using MCP tools:

  • chroma_query_documents - Semantic search across collections
  • chroma_add_documents - Store new knowledge
  • chroma_get_documents - Retrieve specific documents
  • chroma_list_collections - List available collections

Configuration: ~/.config/claude/config.json

{
  "mcpServers": {
    "homelab-memory": {
      "command": "uvx",
      "args": ["chroma-mcp", "--chroma-db-path", "/home/cib/.chroma-db"]
    }
  }
}

How It Works

Example query: “What IP is Wazuh on?”

  1. Claude calls chroma_query_documents on infrastructure collection
  2. ChromaDB converts query to vector, finds semantic matches
  3. Returns: “Wazuh SIEM at 192.168.1.XXX, dashboard on port 443”
  4. Claude responds naturally with the answer

Key benefit: No need to specify file names or use exact keywords. Semantic search bridges the gap.

Complementary Design

System 3.0 complements rather than replaces Systems 1.0 and 2.0:

  • CLAUDE.md/MEMORY.md - Stable context loaded at conversation start (persona, directives, topology)
  • ChromaDB - Growing documentation queried on-demand (runbooks, decisions, detailed configs)

Both systems work together. XML files provide structure, vector database provides searchable depth.

Benefits Over Previous Systems

FeatureSystem 1.0System 2.0System 3.0
StorageSingle CLAUDE.mdSynced files via symlinksVector database
RetrievalLoaded at startLoaded at startQueried on demand
SearchManual/keywordManual/keywordSemantic similarity
ScalingLimited by context windowLimited by context windowGrows independently
MaintenanceManual XML editingManual with syncProgrammatic updates

Memory System 2.0 Architecture (Feb 5, 2026)

Major Refactoring: Eliminated duplicate directories, manual sync commands, and content overlap. New symlink-based workflow makes the backup repository the single source of truth.

Three-Layer Hierarchy

LayerFileSizeContents
Global~/.claude/CLAUDE.mdai-assistant-config/global/CLAUDE.md~3KBUser profile, persona, core directives, interaction rules
Session~/.claude/projects/-home-cib--claude/memory/MEMORY.mdai-assistant-config/session/MEMORY.md~8KBWorkflow reminders, infrastructure notes, project quick-ref, active services
Projecthomelab-ops/CLAUDE.md~15KBInfrastructure topology, Docker stacks, monitoring, security
Projecthomelab-docs/CLAUDE.md~5KBObsidian vault structure, navigation, documentation
Projecthomelab-wiki/CLAUDE.md~6KBQuartz v4 wiki, sanitization pipeline, deployment
Projectpodcast-studio/CLAUDE.md~8KBLiveKit video recording, architecture, deployment
Projectmy-portfolio/CLAUDE.md~3KBHugo site structure, content tips, commands
Local<project>/CLAUDE.internal.mdvariesPrivate notes, credentials (gitignored)

Why this works:

  • Global = Rarely changes (who I am, how I think)
  • Session = Updates frequently (operational knowledge, recent changes)
  • Project = Repository-specific context (loaded when in that directory)
  • Local = Never committed (credentials, session history)
# Active locations are symlinked to backup repo
~/.claude/CLAUDE.md → ~/ai-assistant-config/global/CLAUDE.md
~/.claude/projects/-home-cib--claude/memory/MEMORY.md → ~/ai-assistant-config/session/MEMORY.md
 
# Edits anywhere propagate immediately (same file)
# No manual copy commands needed

Repository Structure (2.0)

ai-assistant-config/ (Single source of truth)
├── global/
│   └── CLAUDE.md              # User profile, persona, directives (~3KB)
│                              # Symlinked from ~/.claude/CLAUDE.md
├── session/
│   └── MEMORY.md              # Operational knowledge, active services (~8KB)
│                              # Symlinked from ~/.claude/projects/-home-cib--claude/memory/
├── projects/                  # Project-specific context (ONE location per project)
│   ├── homelab-ops/CLAUDE.md  # Infrastructure, topology, monitoring (~15KB)
│   ├── homelab-docs/CLAUDE.md # Obsidian vault structure (~5KB)
│   ├── homelab-wiki/CLAUDE.md # Quartz wiki, sanitization (~6KB)
│   ├── podcast-studio/CLAUDE.md # LiveKit architecture (~8KB)
│   └── my-portfolio/CLAUDE.md # Hugo site structure (~3KB)
├── agents/                    # Custom agent definitions
│   ├── deploy-helper.md       # Validate Docker Compose files
│   ├── infra-validator.md     # Pre-deployment validation
│   ├── security-reviewer.md   # Security audit for stacks
│   └── doc-sync.md            # Vault synchronization
├── claude-code/               # Claude Code settings
│   ├── settings.json          # Status line enabled
│   ├── statusline.sh          # Custom status bar script
│   └── skills/                # Custom skills (future)
├── scripts/
│   ├── install-symlinks.sh    # One-time setup (creates symlinks)
│   └── sync.sh                # Commit and push changes
├── prompts/                   # Reusable prompt templates (future)
├── .gitignore                 # Protect credentials (*.local.md)
└── README.md                  # Documentation

Content by Layer

global/CLAUDE.md (~65 lines, ~3KB):

  • meta_data (name, location, experience, strengths)
  • persona (role, mission, core directives)
  • interaction_rules
  • learning_path (certifications, focus areas)
  • goals (prioritized projects)

session/MEMORY.md (~130 lines, ~8KB):

  • Project quick-reference table (paths, repos, URLs)
  • Workstation configuration (shell, aliases, tools)
  • Workflow reminders (Quartz wiki, documentation sync)
  • Infrastructure notes (server resources, GitOps workflow)
  • Common mistakes avoided (SSH auth, Docker networks)
  • Active services (URLs, monitoring stack)
  • Recent changes log

projects/*/CLAUDE.md (varies):

  • Repository structure and file organization
  • Deployment conventions and commands
  • Access points (SSH, web interfaces)
  • Technology stack and dependencies
  • Project-specific workflows

XML Structure

<root>
    <meta_data>           <!-- Name, location, experience, strengths -->
    <persona>             <!-- Role definition and core directives -->
    <interaction_rules>   <!-- How to work with the user -->
    <learning_path>       <!-- Current focus areas, certifications -->
    <goals>               <!-- Prioritized project goals -->
    <infrastructure>      <!-- Topology, access points, services -->
    <projects>            <!-- Repos, paths, stack mappings -->
    <monitoring_config>   <!-- Dashboards, alerts, Wazuh agents -->
    <documentation_links> <!-- Obsidian log, session notes -->
</root>

Core Directives

DirectivePurpose
IdempotencyPrefer solutions that can run multiple times without breaking
Security FirstLeast-privilege, no chmod 777, always suggest UFW rules
Network AwarenessCheck Network-Topology before suggesting static IPs
DocumentationInclude educational comments in all scripts
Docker Compose OnlyNever provide docker run, always provide compose files

Benefits

  • Consistent context across all sessions
  • Enterprise-grade suggestions via persona definition
  • Security by default reinforces Security+ studies
  • No IP conflicts via network topology awareness
  • GitOps-compatible output via Docker Compose directive

Setup (One-Time)

Install symlinks to enable zero-copy workflow:

cd ~/ai-assistant-config
./scripts/install-symlinks.sh
 
# This script:
# 1. Backs up existing files to *.bak
# 2. Creates symlinks from active locations to backup repo
# 3. Makes backup repo the single source of truth

Verify installation:

ls -la ~/.claude/CLAUDE.md
# Should show: ~/.claude/CLAUDE.md -> /home/cib/ai-assistant-config/global/CLAUDE.md
 
ls -la ~/.claude/projects/-home-cib--claude/memory/MEMORY.md
# Should show: ...memory/MEMORY.md -> /home/cib/ai-assistant-config/session/MEMORY.md

Daily Workflow

Edit memory files (same as before):

# Edit directly in repo (or through symlinks - same file!)
vim ~/ai-assistant-config/global/CLAUDE.md
vim ~/ai-assistant-config/session/MEMORY.md
vim ~/ai-assistant-config/projects/homelab-ops/CLAUDE.md

Sync to GitHub (one command):

cd ~/ai-assistant-config
./scripts/sync.sh "Optional commit message"
 
# ✅ Committed and pushed in one command
# No manual copy commands needed!

Manual sync (if preferred):

cd ~/ai-assistant-config
git add -A
git commit -m "Memory update"
git push

Benefits of 2.0 Refactoring

MetricBefore (1.0)After (2.0)
Sync workflow3 manual commands./scripts/sync.sh
Duplicate files3+ copies per project1 canonical location
Edit-to-commit time~2 minutes~10 seconds
Credential exposure riskMedium (no gitignore)Low (.gitignore + patterns)
File size (global)~6KB~3KB
File size (session)~4KB~8KB
ClarityConfusing duplicatesClear 3-layer hierarchy

Security Improvements

.gitignore added:

# Sensitive files - credentials and tokens
*.local.md
**/CLAUDE.internal.md
secrets/
credentials/

Credential pattern:

<web_interface name="Grafana" url="http://192.168.1.XXX:3030" />
<note>Credentials stored in CLAUDE.internal.md (gitignored)</note>

Instead of hardcoding passwords in committed files.


Refactoring History

Version 1.0 (Feb 2-4, 2026)

  • Initial XML-based memory system
  • Manual copy commands for backup
  • Global memory at ~/.claude/CLAUDE.md (~6KB)
  • Project files scattered at root level
  • No gitignore for credentials

Version 2.0 (Feb 5, 2026)

  • Symlink-based architecture - zero-copy workflow
  • Three-layer hierarchy - global (3KB), session (8KB), projects
  • Helper scripts - install-symlinks.sh, sync.sh
  • Consolidated structure - all projects in projects/ directory
  • Security improvements - .gitignore for *.local.md files
  • Content reorganization - moved workstation/project details to session layer
  • Eliminated duplicates - single source of truth in backup repo

Problems solved:

  • Duplicate directories (homelab-ops/ at root AND in projects/)
  • Manual 3-command sync workflow (error-prone, easy to forget)
  • Content overlap (workstation details in multiple files)
  • No protection against accidentally committing credentials

Key lessons:

  • Symlinks eliminate an entire class of sync problems
  • Separation of concerns applies to context too (global/session/project)
  • Automation compounds (30-second script saves hours over time)
  • Git is the perfect memory backend (history, rollback, backup)

Version 3.0 (Feb 9, 2026)

  • ChromaDB vector database - semantic memory storage
  • MCP integration - transparent tool access for Claude
  • Three collections - infrastructure, documentation, decisions
  • On-demand retrieval - query what’s needed, when it’s needed
  • Semantic search - finds relevant info without exact keywords
  • Complementary design - works alongside file-based systems

Problems solved:

  • Context window limitations (can’t load all docs at once)
  • Brittle keyword matching (semantic understanding instead)
  • Scaling issues (database grows independently of context window)
  • Manual file references (automatic retrieval via MCP)

Key lessons:

  • Vector databases work great for personal knowledge management
  • MCP makes external tools feel native to Claude
  • Semantic search reduces need for rigid structure
  • Different knowledge types benefit from different storage (XML + vector DB)

Portfolio Writeup

Part 1 & 2: Systems 1.0 and 2.0 (XML-based, symlink architecture)

Part 3: System 3.0 (ChromaDB semantic memory)