Files
claudetools/.claude/CONTEXT_RECALL_ARCHITECTURE.md
Mike Swanson 390b10b32c Complete Phase 6: MSP Work Tracking with Context Recall System
Implements production-ready MSP platform with cross-machine persistent memory for Claude.

API Implementation:
- 130 REST API endpoints across 21 entities
- JWT authentication on all endpoints
- AES-256-GCM encryption for credentials
- Automatic audit logging
- Complete OpenAPI documentation

Database:
- 43 tables in MariaDB (172.16.3.20:3306)
- 42 SQLAlchemy models with modern 2.0 syntax
- Full Alembic migration system
- 99.1% CRUD test pass rate

Context Recall System (Phase 6):
- Cross-machine persistent memory via database
- Automatic context injection via Claude Code hooks
- Automatic context saving after task completion
- 90-95% token reduction with compression utilities
- Relevance scoring with time decay
- Tag-based semantic search
- One-command setup script

Security Features:
- JWT tokens with Argon2 password hashing
- AES-256-GCM encryption for all sensitive data
- Comprehensive audit trail for credentials
- HMAC tamper detection
- Secure configuration management

Test Results:
- Phase 3: 38/38 CRUD tests passing (100%)
- Phase 4: 34/35 core API tests passing (97.1%)
- Phase 5: 62/62 extended API tests passing (100%)
- Phase 6: 10/10 compression tests passing (100%)
- Overall: 144/145 tests passing (99.3%)

Documentation:
- Comprehensive architecture guides
- Setup automation scripts
- API documentation at /api/docs
- Complete test reports
- Troubleshooting guides

Project Status: 95% Complete (Production-Ready)
Phase 7 (optional work context APIs) remains for future enhancement.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-17 06:00:26 -07:00

26 KiB

Context Recall System - Architecture

Visual architecture and data flow for the Claude Code Context Recall System.

System Overview

┌─────────────────────────────────────────────────────────────────┐
│                      Claude Code Session                         │
│                                                                   │
│  ┌──────────────┐                            ┌──────────────┐   │
│  │ User writes  │                            │ Task         │   │
│  │ message      │                            │ completes    │   │
│  └──────┬───────┘                            └──────┬───────┘   │
│         │                                            │           │
│         ▼                                            ▼           │
│  ┌─────────────────────┐              ┌─────────────────────┐  │
│  │ user-prompt-submit  │              │  task-complete      │  │
│  │ hook triggers       │              │  hook triggers      │  │
│  └─────────┬───────────┘              └─────────┬───────────┘  │
└────────────┼──────────────────────────────────────┼─────────────┘
             │                                      │
             │ ┌──────────────────────────────────┐ │
             │ │  .claude/context-recall-         │ │
             └─┤  config.env                      ├─┘
               │  (JWT_TOKEN, PROJECT_ID, etc.)   │
               └──────────────────────────────────┘
             │                                      │
             ▼                                      ▼
┌────────────────────────────┐    ┌────────────────────────────┐
│ GET /api/conversation-     │    │ POST /api/conversation-    │
│ contexts/recall            │    │ contexts                   │
│                            │    │                            │
│ Query Parameters:          │    │ POST /api/project-states   │
│ - project_id               │    │                            │
│ - min_relevance_score      │    │ Payload:                   │
│ - limit                    │    │ - context summary          │
└────────────┬───────────────┘    │ - metadata                 │
             │                    │ - relevance score          │
             │                    └────────────┬───────────────┘
             │                                 │
             ▼                                 ▼
┌─────────────────────────────────────────────────────────────────┐
│                    FastAPI Application                           │
│                                                                   │
│  ┌──────────────────────────┐    ┌───────────────────────────┐ │
│  │ Context Recall Logic     │    │ Context Save Logic        │ │
│  │ - Filter by relevance    │    │ - Create context record   │ │
│  │ - Sort by score          │    │ - Update project state    │ │
│  │ - Format for display     │    │ - Extract metadata        │ │
│  └──────────┬───────────────┘    └───────────┬───────────────┘ │
│             │                                 │                  │
│             ▼                                 ▼                  │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │              Database Access Layer                        │  │
│  │              (SQLAlchemy ORM)                             │  │
│  └──────────────────────────┬───────────────────────────────┘  │
└─────────────────────────────┼──────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    PostgreSQL Database                           │
│                                                                   │
│  ┌────────────────────────┐       ┌─────────────────────────┐  │
│  │ conversation_contexts  │       │   project_states        │  │
│  │                        │       │                         │  │
│  │ - id (UUID)            │       │ - id (UUID)             │  │
│  │ - project_id (FK)      │       │ - project_id (FK)       │  │
│  │ - context_type         │       │ - state_type            │  │
│  │ - title                │       │ - state_data (JSONB)    │  │
│  │ - dense_summary        │       │ - created_at            │  │
│  │ - relevance_score      │       └─────────────────────────┘  │
│  │ - metadata (JSONB)     │                                     │
│  │ - created_at           │       ┌─────────────────────────┐  │
│  │ - updated_at           │       │      projects           │  │
│  └────────────────────────┘       │                         │  │
│                                    │ - id (UUID)             │  │
│                                    │ - name                  │  │
│                                    │ - description           │  │
│                                    │ - project_type          │  │
│                                    └─────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

Data Flow: Context Recall

1. User writes message in Claude Code
   │
   ▼
2. user-prompt-submit hook executes
   │
   ├─ Load config from .claude/context-recall-config.env
   ├─ Detect PROJECT_ID (git config or remote URL hash)
   ├─ Check if CONTEXT_RECALL_ENABLED=true
   │
   ▼
3. HTTP GET /api/conversation-contexts/recall
   │
   ├─ Headers: Authorization: Bearer {JWT_TOKEN}
   ├─ Query: ?project_id={ID}&limit=10&min_relevance_score=5.0
   │
   ▼
4. API processes request
   │
   ├─ Authenticate JWT token
   ├─ Query database:
   │    SELECT * FROM conversation_contexts
   │    WHERE project_id = {ID}
   │      AND relevance_score >= 5.0
   │    ORDER BY relevance_score DESC, created_at DESC
   │    LIMIT 10
   │
   ▼
5. API returns JSON array of contexts
   [
     {
       "id": "uuid",
       "title": "Session: 2025-01-15",
       "dense_summary": "...",
       "relevance_score": 8.5,
       "context_type": "session_summary",
       "metadata": {...}
     },
     ...
   ]
   │
   ▼
6. Hook formats contexts as Markdown
   │
   ├─ Parse JSON response
   ├─ Format each context with title, score, type
   ├─ Include summary and metadata
   │
   ▼
7. Hook outputs formatted markdown
   ## 📚 Previous Context

   ### 1. Session: 2025-01-15 (Score: 8.5/10)
   *Type: session_summary*

   [Summary content...]
   │
   ▼
8. Claude Code injects context before user message
   │
   ▼
9. Claude processes message WITH context

Data Flow: Context Saving

1. User completes task in Claude Code
   │
   ▼
2. task-complete hook executes
   │
   ├─ Load config from .claude/context-recall-config.env
   ├─ Detect PROJECT_ID
   ├─ Gather task information:
   │   ├─ Git branch (git rev-parse --abbrev-ref HEAD)
   │   ├─ Git commit (git rev-parse --short HEAD)
   │   ├─ Changed files (git diff --name-only)
   │   └─ Timestamp
   │
   ▼
3. Build context payload
   {
     "project_id": "{PROJECT_ID}",
     "context_type": "session_summary",
     "title": "Session: 2025-01-15T14:30:00Z",
     "dense_summary": "Task completed on branch...",
     "relevance_score": 7.0,
     "metadata": {
       "git_branch": "main",
       "git_commit": "a1b2c3d",
       "files_modified": "file1.py,file2.py",
       "timestamp": "2025-01-15T14:30:00Z"
     }
   }
   │
   ▼
4. HTTP POST /api/conversation-contexts
   │
   ├─ Headers:
   │   ├─ Authorization: Bearer {JWT_TOKEN}
   │   └─ Content-Type: application/json
   ├─ Body: [context payload]
   │
   ▼
5. API processes request
   │
   ├─ Authenticate JWT token
   ├─ Validate payload
   ├─ Insert into database:
   │    INSERT INTO conversation_contexts
   │    (id, project_id, context_type, title,
   │     dense_summary, relevance_score, metadata)
   │    VALUES (...)
   │
   ▼
6. Build project state payload
   {
     "project_id": "{PROJECT_ID}",
     "state_type": "task_completion",
     "state_data": {
       "last_task_completion": "2025-01-15T14:30:00Z",
       "last_git_commit": "a1b2c3d",
       "last_git_branch": "main",
       "recent_files": "file1.py,file2.py"
     }
   }
   │
   ▼
7. HTTP POST /api/project-states
   │
   ├─ Headers: Authorization: Bearer {JWT_TOKEN}
   ├─ Body: [state payload]
   │
   ▼
8. API updates project state
   │
   ├─ Upsert project state record
   ├─ Merge state_data with existing
   │
   ▼
9. Context saved ✓
   │
   ▼
10. Available for future recall

Authentication Flow

┌──────────────┐
│ Initial      │
│ Setup        │
└──────┬───────┘
       │
       ▼
┌─────────────────────────────────────┐
│ bash scripts/setup-context-recall.sh│
└──────┬──────────────────────────────┘
       │
       ├─ Prompt for username/password
       │
       ▼
┌──────────────────────────────────────┐
│ POST /api/auth/login                 │
│                                      │
│ Request:                             │
│ {                                    │
│   "username": "admin",               │
│   "password": "secret"               │
│ }                                    │
└──────┬───────────────────────────────┘
       │
       ▼
┌──────────────────────────────────────┐
│ Response:                            │
│ {                                    │
│   "access_token": "eyJ...",          │
│   "token_type": "bearer",            │
│   "expires_in": 86400                │
│ }                                    │
└──────┬───────────────────────────────┘
       │
       ▼
┌──────────────────────────────────────┐
│ Save to .claude/context-recall-      │
│ config.env:                          │
│                                      │
│ JWT_TOKEN=eyJ...                     │
└──────┬───────────────────────────────┘
       │
       ▼
┌──────────────────────────────────────┐
│ All API requests include:            │
│ Authorization: Bearer eyJ...         │
└──────────────────────────────────────┘

Project Detection Flow

Hook needs PROJECT_ID
   │
   ├─ Check: $CLAUDE_PROJECT_ID set?
   │   └─ Yes → Use it
   │   └─ No → Continue detection
   │
   ├─ Check: git config --local claude.projectid
   │   └─ Found → Use it
   │   └─ Not found → Continue detection
   │
   ├─ Get: git config --get remote.origin.url
   │   └─ Found → Hash URL → Use as PROJECT_ID
   │   └─ Not found → No PROJECT_ID available
   │
   └─ If no PROJECT_ID:
       └─ Silent exit (no context available)

Database Schema

-- Projects table
CREATE TABLE projects (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    description TEXT,
    project_type VARCHAR(50),
    metadata JSONB,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

-- Conversation contexts table
CREATE TABLE conversation_contexts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    project_id UUID REFERENCES projects(id),
    context_type VARCHAR(50),
    title VARCHAR(500),
    dense_summary TEXT NOT NULL,
    relevance_score DECIMAL(3,1) CHECK (relevance_score >= 0 AND relevance_score <= 10),
    metadata JSONB,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),

    INDEX idx_project_relevance (project_id, relevance_score DESC),
    INDEX idx_project_type (project_id, context_type),
    INDEX idx_created (created_at DESC)
);

-- Project states table
CREATE TABLE project_states (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    project_id UUID REFERENCES projects(id),
    state_type VARCHAR(50),
    state_data JSONB NOT NULL,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW(),

    INDEX idx_project_state (project_id, state_type)
);

Component Interaction

┌─────────────────────────────────────────────────────────────┐
│ File System                                                  │
│                                                              │
│ .claude/                                                     │
│ ├── hooks/                                                   │
│ │   ├── user-prompt-submit    ◄─── Executed by Claude Code  │
│ │   └── task-complete         ◄─── Executed by Claude Code  │
│ │                                                            │
│ └── context-recall-config.env ◄─── Read by hooks            │
│                                                              │
└────────────────┬────────────────────────────────────────────┘
                 │
                 │ (Hooks read config and call API)
                 │
                 ▼
┌─────────────────────────────────────────────────────────────┐
│ FastAPI Application (http://localhost:8000)                  │
│                                                              │
│ Endpoints:                                                   │
│ ├── POST /api/auth/login                                     │
│ ├── GET  /api/conversation-contexts/recall                   │
│ ├── POST /api/conversation-contexts                          │
│ ├── POST /api/project-states                                 │
│ └── GET  /api/projects/{id}                                  │
│                                                              │
└────────────────┬────────────────────────────────────────────┘
                 │
                 │ (API queries/updates database)
                 │
                 ▼
┌─────────────────────────────────────────────────────────────┐
│ PostgreSQL Database                                          │
│                                                              │
│ Tables:                                                      │
│ ├── projects                                                 │
│ ├── conversation_contexts                                    │
│ └── project_states                                           │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Error Handling

Hook Execution
   │
   ├─ Config file missing?
   │   └─ Silent exit (context recall unavailable)
   │
   ├─ PROJECT_ID not detected?
   │   └─ Silent exit (no project context)
   │
   ├─ JWT_TOKEN missing?
   │   └─ Silent exit (authentication unavailable)
   │
   ├─ API unreachable? (timeout 3-5s)
   │   └─ Silent exit (API offline)
   │
   ├─ API returns error (401, 404, 500)?
   │   └─ Silent exit (log if debug enabled)
   │
   └─ Success
       └─ Process and inject context

Philosophy: Hooks NEVER break Claude Code. All failures are silent.

Performance Characteristics

Timeline for user-prompt-submit:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

0ms        Hook starts
           ├─ Load config (10ms)
           ├─ Detect project (5ms)
           │
15ms       HTTP request starts
           ├─ Connection (20ms)
           ├─ Query execution (50-100ms)
           ├─ Response formatting (10ms)
           │
145ms      Response received
           ├─ Parse JSON (10ms)
           ├─ Format markdown (30ms)
           │
185ms      Context injected
           │
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Total: ~200ms average overhead per message
Timeout: 3000ms (fails gracefully)

Configuration Impact

┌──────────────────────────────────────┐
│ MIN_RELEVANCE_SCORE                  │
├──────────────────────────────────────┤
│  Low (3.0)                           │
│  ├─ More contexts recalled           │
│  ├─ Broader historical view          │
│  └─ Slower queries                   │
│                                      │
│  Medium (5.0) ← Recommended          │
│  ├─ Balanced relevance/quantity      │
│  └─ Fast queries                     │
│                                      │
│  High (7.5)                          │
│  ├─ Only critical contexts           │
│  ├─ Very focused                     │
│  └─ Fastest queries                  │
└──────────────────────────────────────┘

┌──────────────────────────────────────┐
│ MAX_CONTEXTS                         │
├──────────────────────────────────────┤
│  Few (5)                             │
│  ├─ Focused context                  │
│  ├─ Shorter prompts                  │
│  └─ Faster processing                │
│                                      │
│  Medium (10) ← Recommended           │
│  ├─ Good coverage                    │
│  └─ Reasonable prompt size           │
│                                      │
│  Many (20)                           │
│  ├─ Comprehensive context            │
│  ├─ Longer prompts                   │
│  └─ Slower Claude processing         │
└──────────────────────────────────────┘

Security Model

┌─────────────────────────────────────────────────────────────┐
│ Security Boundaries                                          │
│                                                              │
│ 1. Authentication                                            │
│    ├─ JWT tokens (24h expiry)                               │
│    ├─ Bcrypt password hashing                               │
│    └─ Bearer token in Authorization header                  │
│                                                              │
│ 2. Authorization                                             │
│    ├─ Project-level access control                          │
│    ├─ User can only access own projects                     │
│    └─ Token includes user_id claim                          │
│                                                              │
│ 3. Data Protection                                           │
│    ├─ Config file gitignored                                │
│    ├─ JWT tokens never in version control                   │
│    └─ HTTPS recommended for production                      │
│                                                              │
│ 4. Input Validation                                          │
│    ├─ API validates all payloads                            │
│    ├─ SQL injection protected (ORM)                         │
│    └─ JSON schema validation                                │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Deployment Architecture

Development:
┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│ Claude Code  │────▶│ API          │────▶│ PostgreSQL   │
│ (Desktop)    │     │ (localhost)  │     │ (localhost)  │
└──────────────┘     └──────────────┘     └──────────────┘

Production:
┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│ Claude Code  │────▶│ API          │────▶│ PostgreSQL   │
│ (Desktop)    │     │ (Docker)     │     │ (RDS/Cloud)  │
└──────────────┘     └──────────────┘     └──────────────┘
      │                     │
      │                     │ (HTTPS)
      │                     ▼
      │              ┌──────────────┐
      │              │ Redis Cache  │
      │              │ (Optional)   │
      └──────────────┴──────────────┘

Scalability Considerations

Database Optimization:
├─ Indexes on (project_id, relevance_score)
├─ Indexes on (project_id, context_type)
├─ Indexes on created_at for time-based queries
└─ JSONB indexes on metadata for complex queries

Caching Strategy:
├─ Redis for frequently-accessed contexts
├─ Cache key: project_id + min_score + limit
├─ TTL: 5 minutes
└─ Invalidate on new context creation

Query Optimization:
├─ Limit results (MAX_CONTEXTS)
├─ Filter early (MIN_RELEVANCE_SCORE)
├─ Sort in database (not application)
└─ Paginate for large result sets

This architecture provides a robust, scalable, and secure system for context recall in Claude Code sessions.