# Offline Mode Test Procedure **Version:** 2.0 **Date:** 2026-01-17 **System Status:** ✅ All Components Installed and Ready --- ## Pre-Test Verification (COMPLETED) ### ✅ Infrastructure Check ```bash # Verified directories exist ls -la .claude/context-cache/ # ✅ Exists ls -la .claude/context-queue/ # ✅ Exists (pending, uploaded, failed) # Verified v2 hooks installed head -3 .claude/hooks/user-prompt-submit # ✅ v2 with offline support head -3 .claude/hooks/task-complete # ✅ v2 with offline support head -3 .claude/hooks/sync-contexts # ✅ Sync script ready # Verified configuration grep CLAUDE_API_URL .claude/context-recall-config.env # ✅ Output: CLAUDE_API_URL=http://172.16.3.30:8001 # Verified gitignore grep context-cache .gitignore # ✅ Present grep context-queue .gitignore # ✅ Present ``` ### ✅ Current System Status - **API:** http://172.16.3.30:8001 (ONLINE) - **Database:** 172.16.3.30:3306 (ONLINE) - **Health Check:** {"status":"healthy","database":"connected"} - **Hooks:** V2 (offline-capable) - **Storage:** Ready --- ## Test Procedure ### Phase 1: Baseline Test (Online Mode) **Purpose:** Verify normal operation before testing offline ```bash # 1. Open Claude Code in D:\ClaudeTools cd D:\ClaudeTools # 2. Send a test message to Claude # Expected output should include: # # ## 📚 Previous Context # 3. Check that context was cached PROJECT_ID=$(git config --local claude.projectid 2>/dev/null || git config --get remote.origin.url | md5sum | cut -d' ' -f1) ls -la .claude/context-cache/$PROJECT_ID/ # Expected: latest.json and last_updated files # 4. Verify cache contents cat .claude/context-cache/$PROJECT_ID/latest.json | python -m json.tool # Expected: Array of context objects with titles, summaries, scores ``` **Success Criteria:** - ✅ Context retrieved from API - ✅ Cache file created with timestamp - ✅ Context injected into conversation --- ### Phase 2: Offline Mode Test (Cache Fallback) **Purpose:** Verify system uses cached context when API unavailable ```bash # 1. SSH to RMM server ssh guru@172.16.3.30 # 2. Stop the API service sudo systemctl stop claudetools-api # 3. Verify API is stopped sudo systemctl status claudetools-api --no-pager # Expected: Active: inactive (dead) # 4. Exit SSH exit # 5. Back on Windows - test context recall # Open Claude Code and send a message # Expected output: # # ## 📚 Previous Context # ⚠️ **Offline Mode** - Using cached context (API unavailable) ``` **Success Criteria:** - ✅ Hook detects API unavailable - ✅ Falls back to cached context - ✅ Clear "Offline Mode" warning displayed - ✅ Conversation continues with cached context --- ### Phase 3: Context Queuing Test (Save Fallback) **Purpose:** Verify contexts queue locally when API unavailable ```bash # 1. API should still be stopped from Phase 2 # 2. Complete a task in Claude Code # (This triggers task-complete hook) # Expected stderr output: # ⚠ Context queued locally (API unavailable) - will sync when online # 3. Check queue directory ls -la .claude/context-queue/pending/ # Expected: One or more .json files with timestamp names # Example: claudetools_20260117_143022_context.json # 4. View queued context cat .claude/context-queue/pending/*.json | python -m json.tool # Expected: JSON with project_id, context_type, title, dense_summary, etc. ``` **Success Criteria:** - ✅ Context save attempt fails gracefully - ✅ Context queued in pending/ directory - ✅ User warned about offline queuing - ✅ No data loss --- ### Phase 4: Automatic Sync Test **Purpose:** Verify queued contexts sync when API restored ```bash # 1. SSH to RMM server ssh guru@172.16.3.30 # 2. Start the API service sudo systemctl start claudetools-api # 3. Verify API is running sudo systemctl status claudetools-api --no-pager # Expected: Active: active (running) # 4. Test API health curl http://localhost:8001/health # Expected: {"status":"healthy","database":"connected"} # 5. Exit SSH exit # 6. Back on Windows - trigger sync # Method A: Send any message in Claude Code (automatic background sync) # Method B: Manual sync command bash .claude/hooks/sync-contexts # Expected output from manual sync: # =================================== # Syncing Queued Contexts # =================================== # Found X pending context(s) # # Processing: [filename].json # ✓ Uploaded successfully # # =================================== # Sync Complete # =================================== # Successful: X # Failed: 0 # 7. Verify queue cleared ls -la .claude/context-queue/pending/ # Expected: Empty (or nearly empty) ls -la .claude/context-queue/uploaded/ # Expected: Previously pending files moved here # 8. Verify contexts in database curl -s "http://172.16.3.30:8001/api/conversation-contexts?limit=5" \ -H "Authorization: Bearer $JWT_TOKEN" | python -m json.tool # Expected: Recently synced contexts appear in results ``` **Success Criteria:** - ✅ Background sync triggered automatically - ✅ Queued contexts uploaded successfully - ✅ Files moved from pending/ to uploaded/ - ✅ Contexts visible in database --- ### Phase 5: Cache Refresh Test **Purpose:** Verify cache updates when API available ```bash # 1. API should be running from Phase 4 # 2. Delete local cache to force fresh fetch PROJECT_ID=$(git config --local claude.projectid 2>/dev/null || git config --get remote.origin.url | md5sum | cut -d' ' -f1) rm -rf .claude/context-cache/$PROJECT_ID # 3. Open Claude Code and send a message # Expected: # - Hook fetches fresh context from API # - Cache recreated with new timestamp # - Online mode message (no offline warning) # 4. Verify fresh cache ls -la .claude/context-cache/$PROJECT_ID/ # Expected: latest.json with recent timestamp cat .claude/context-cache/$PROJECT_ID/last_updated # Expected: Current timestamp (2026-01-17T...) ``` **Success Criteria:** - ✅ Cache recreated from API - ✅ Fresh timestamp recorded - ✅ Online mode confirmed --- ## Test Results Template ```markdown ## Offline Mode Test Results **Date:** [DATE] **Tester:** [NAME] **System:** [OS/Machine] ### Phase 1: Baseline (Online Mode) - [ ] Context retrieved from API - [ ] Cache created successfully - [ ] Context injected correctly **Notes:** ### Phase 2: Offline Mode (Cache Fallback) - [ ] API stopped successfully - [ ] Offline warning displayed - [ ] Cached context used - [ ] No errors encountered **Notes:** ### Phase 3: Context Queuing - [ ] Context queued locally - [ ] Queue file created - [ ] Warning message shown **Notes:** ### Phase 4: Automatic Sync - [ ] API restarted successfully - [ ] Sync triggered automatically - [ ] All contexts uploaded - [ ] Queue cleared **Notes:** ### Phase 5: Cache Refresh - [ ] Old cache deleted - [ ] Fresh cache created - [ ] Online mode confirmed **Notes:** ### Overall Result - [ ] PASS - All phases successful - [ ] FAIL - Issues encountered (see notes) ### Issues Found [List any issues, errors, or unexpected behavior] ### Recommendations [Any suggestions for improvements] ``` --- ## Troubleshooting ### Issue: API Won't Stop ```bash # Force stop sudo systemctl kill claudetools-api # Verify stopped sudo systemctl status claudetools-api ``` ### Issue: Cache Not Being Used ```bash # Check if cache exists PROJECT_ID=$(git config --local claude.projectid) ls -la .claude/context-cache/$PROJECT_ID/ # Check hook version head -3 .claude/hooks/user-prompt-submit # Should show: "v2 - with offline support" # Check hook is executable ls -l .claude/hooks/user-prompt-submit # Should show: -rwxr-xr-x ``` ### Issue: Contexts Not Queuing ```bash # Check queue directory permissions ls -ld .claude/context-queue/pending/ # Check hook version head -3 .claude/hooks/task-complete # Should show: "v2 - with offline support" # Check environment source .claude/context-recall-config.env echo $CLAUDE_API_URL # Should show: http://172.16.3.30:8001 ``` ### Issue: Sync Not Working ```bash # Check JWT token source .claude/context-recall-config.env echo $JWT_TOKEN # Should show a long token string # Manual sync with debug bash -x .claude/hooks/sync-contexts # Check API is accessible curl http://172.16.3.30:8001/health ``` ### Issue: Contexts Moved to Failed/ ```bash # View failed contexts ls -la .claude/context-queue/failed/ # Check specific failed context cat .claude/context-queue/failed/[filename].json | python -m json.tool # Check API response curl -X POST http://172.16.3.30:8001/api/conversation-contexts \ -H "Authorization: Bearer $JWT_TOKEN" \ -H "Content-Type: application/json" \ -d @.claude/context-queue/failed/[filename].json # Move back to pending for retry mv .claude/context-queue/failed/*.json .claude/context-queue/pending/ bash .claude/hooks/sync-contexts ``` --- ## Expected Behavior Summary | Scenario | Hook Action | User Experience | |----------|-------------|-----------------| | **API Online** | Fetch from API → Cache locally → Inject | Normal operation, no warnings | | **API Offline (Recall)** | Read from cache → Inject with warning | "⚠️ Offline Mode - Using cached context" | | **API Offline (Save)** | Queue locally → Trigger background sync | "⚠ Context queued locally - will sync when online" | | **API Restored** | Background sync uploads queue → Clear | Silent sync, contexts uploaded | | **Fresh Start** | No cache available → Skip injection | Silent (no context to inject) | --- ## Performance Expectations | Operation | Expected Time | Notes | |-----------|--------------|-------| | API Fetch | < 3 seconds | Timeout configured at 3s | | Cache Read | < 100ms | Local file read | | Queue Write | < 100ms | Local file write | | Background Sync | 0.5s per context | Non-blocking | --- ## Security Notes **What's Cached:** - Context summaries (dense_summary) - Titles, tags, scores - Project IDs (non-sensitive) **What's NOT Cached:** - JWT tokens (in config file, gitignored) - Credentials or passwords - Full conversation transcripts **Best Practices:** - Keep `.claude/context-cache/` in .gitignore - Keep `.claude/context-queue/` in .gitignore - Review queued contexts before manual sync if handling sensitive projects - Clear cache when switching machines: `rm -rf .claude/context-cache/` --- ## Quick Reference Commands ```bash # Stop API (simulate offline) ssh guru@172.16.3.30 "sudo systemctl stop claudetools-api" # Start API (restore online) ssh guru@172.16.3.30 "sudo systemctl start claudetools-api" # Check API status curl -s http://172.16.3.30:8001/health # View cache PROJECT_ID=$(git config --local claude.projectid) cat .claude/context-cache/$PROJECT_ID/latest.json | python -m json.tool # View queue ls -la .claude/context-queue/pending/ # Manual sync bash .claude/hooks/sync-contexts # Clear cache (force refresh) rm -rf .claude/context-cache/$PROJECT_ID # Clear queue (CAUTION: data loss!) rm -rf .claude/context-queue/pending/*.json ``` --- **Last Updated:** 2026-01-17 **Status:** Ready for Testing **Documentation:** See .claude/OFFLINE_MODE.md for architecture details