diff --git a/.docs/design-claude-analyzer-terraphim-integration.md b/.docs/design-claude-analyzer-terraphim-integration.md new file mode 100644 index 000000000..d61ab4008 --- /dev/null +++ b/.docs/design-claude-analyzer-terraphim-integration.md @@ -0,0 +1,81 @@ +# Design: Enhance claude-log-analyzer with terraphim_automata + +## Problem Statement + +The claude-log-analyzer crate has terraphim_automata integration behind a feature flag, but underutilizes its capabilities: +- Only uses `find_matches()` for basic pattern matching +- Hardcodes concept definitions instead of dynamic extraction +- Clones thesaurus on every call (inefficient) +- Doesn't use fuzzy matching, autocomplete, or graph connectivity features + +## Goals + +1. Better text processing using terraphim_automata capabilities +2. Dynamic concept/pattern learning from observed tool usage +3. Efficient thesaurus management with caching +4. Leverage graph connectivity for relationship inference + +## Implementation Plan + +### Step 1: Improve TerraphimMatcher Pattern Matching + +**File**: `src/patterns/matcher.rs` + +Current: +```rust +terraphim_find_matches(text, thesaurus.clone(), true) +``` + +Changes: +- Cache compiled automata instead of rebuilding +- Use fuzzy matching for typo tolerance +- Add context extraction for better pattern understanding + +### Step 2: Dynamic Concept Building in KnowledgeGraphBuilder + +**File**: `src/kg/builder.rs` + +Current: Hardcoded concept lists (BUN, NPM, INSTALL, etc.) + +Changes: +- Learn concepts dynamically from observed patterns +- Use terraphim_automata's thesaurus capabilities +- Build hierarchical concept relationships + +### Step 3: Enhanced Search with Graph Connectivity + +**File**: `src/kg/search.rs` + +Current: Manual proximity-based result merging + +Changes: +- Use `is_all_terms_connected_by_path()` for semantic relationships +- Improve relevance scoring with concept graph distances +- Cache search results for repeated queries + +### Step 4: Integrate Learned Patterns with Terraphim + +**File**: `src/patterns/knowledge_graph.rs` + +Current: Separate learning system from terraphim + +Changes: +- Store learned patterns in terraphim thesaurus +- Use graph structure for relationship inference +- Export/import learned knowledge + +## File Changes + +| File | Action | Purpose | +|------|--------|---------| +| `src/patterns/matcher.rs:159-290` | Modify | Cache automata, add fuzzy matching | +| `src/kg/builder.rs` | Modify | Dynamic concept learning | +| `src/kg/search.rs` | Modify | Graph connectivity for search | +| `src/patterns/knowledge_graph.rs` | Modify | Integrate with terraphim learning | + +## Acceptance Criteria + +1. Pattern matching uses cached automata (no clone per call) +2. Concepts learned dynamically from tool observation +3. Fuzzy matching available for typo-tolerant search +4. Tests pass with `--features terraphim` diff --git a/.github/workflows/vm-execution-tests.yml b/.github/workflows/vm-execution-tests.yml index 865ce7ba8..2c88ddfb7 100644 --- a/.github/workflows/vm-execution-tests.yml +++ b/.github/workflows/vm-execution-tests.yml @@ -4,6 +4,7 @@ name: VM Execution Tests # Firecracker is Linux-only - these tests will not work on macOS/Windows # The scratchpad/firecracker-rust directory is gitignored (experimental code) # Tests will skip gracefully if the directory is not present +# Triggered manually for adaptive concurrency testing on: push: @@ -94,18 +95,47 @@ jobs: runs-on: [self-hosted, linux, x64] timeout-minutes: 15 - services: - redis: - image: redis:7-alpine - ports: - - 6379:6379 - options: >- - --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 + # NOTE: No services block - we check for existing Redis on self-hosted runner + # and only start a container if none is available steps: + - name: Check for existing Redis + id: redis_check + run: | + if redis-cli -h 127.0.0.1 -p 6379 ping 2>/dev/null | grep -q PONG; then + echo "Redis is available on localhost:6379" + echo "redis_available=true" >> $GITHUB_OUTPUT + echo "redis_host=127.0.0.1" >> $GITHUB_OUTPUT + echo "redis_port=6379" >> $GITHUB_OUTPUT + echo "redis_started=false" >> $GITHUB_OUTPUT + else + echo "No Redis found, will start container on port 6380" + echo "redis_available=false" >> $GITHUB_OUTPUT + echo "redis_host=127.0.0.1" >> $GITHUB_OUTPUT + echo "redis_port=6380" >> $GITHUB_OUTPUT + echo "redis_started=true" >> $GITHUB_OUTPUT + fi + + - name: Start Redis container (if needed) + if: steps.redis_check.outputs.redis_available == 'false' + run: | + docker run -d --name ci-redis-${{ github.run_id }} \ + -p 6380:6379 \ + --health-cmd "redis-cli ping" \ + --health-interval 10s \ + --health-timeout 5s \ + --health-retries 5 \ + redis:7-alpine + # Wait for Redis to be healthy + for i in {1..30}; do + if redis-cli -h 127.0.0.1 -p 6380 ping 2>/dev/null | grep -q PONG; then + echo "Redis container is ready" + break + fi + echo "Waiting for Redis container... ($i/30)" + sleep 2 + done + - name: Checkout code uses: actions/checkout@v6 @@ -172,6 +202,10 @@ jobs: - name: Run integration tests if: steps.check_fcctl.outputs.exists == 'true' + env: + REDIS_HOST: ${{ steps.redis_check.outputs.redis_host }} + REDIS_PORT: ${{ steps.redis_check.outputs.redis_port }} + REDIS_URL: redis://${{ steps.redis_check.outputs.redis_host }}:${{ steps.redis_check.outputs.redis_port }} run: | cd scratchpad/firecracker-rust/fcctl-web cargo test llm_api_tests \ @@ -180,6 +214,10 @@ jobs: - name: Run HTTP API security tests if: steps.check_fcctl.outputs.exists == 'true' + env: + REDIS_HOST: ${{ steps.redis_check.outputs.redis_host }} + REDIS_PORT: ${{ steps.redis_check.outputs.redis_port }} + REDIS_URL: redis://${{ steps.redis_check.outputs.redis_host }}:${{ steps.redis_check.outputs.redis_port }} run: | cd scratchpad/firecracker-rust/fcctl-web cargo test security_tests \ @@ -197,6 +235,12 @@ jobs: kill $FCCTL_WEB_PID || true fi + - name: Stop Redis container (if started) + if: always() && steps.redis_check.outputs.redis_started == 'true' + run: | + docker stop ci-redis-${{ github.run_id }} || true + docker rm ci-redis-${{ github.run_id }} || true + websocket-tests: name: WebSocket Tests runs-on: [self-hosted, linux, x64] diff --git a/scripts/test-vm-execution.sh b/scripts/test-vm-execution.sh index 066d2d7bb..8e1a51f8b 100755 --- a/scripts/test-vm-execution.sh +++ b/scripts/test-vm-execution.sh @@ -202,16 +202,6 @@ check_dependencies() { exit 1 fi -<<<<<<< HEAD - # Check for fcctl-web binary if we need to start server - if [ "$START_SERVER" = true ]; then - if [ ! -f "scratchpad/firecracker-rust/fcctl-web/target/debug/fcctl-web" ] && - [ ! -f "scratchpad/firecracker-rust/fcctl-web/target/release/fcctl-web" ]; then - log_info "Building fcctl-web server..." - cd scratchpad/firecracker-rust/fcctl-web - cargo build --release - cd - > /dev/null -======= # Check if fcctl-web directory exists if [ ! -d "scratchpad/firecracker-rust/fcctl-web" ]; then log_warning "fcctl-web directory not found (scratchpad/firecracker-rust/fcctl-web)" @@ -228,7 +218,6 @@ check_dependencies() { cargo build --release cd - > /dev/null fi ->>>>>>> origin/main fi fi @@ -241,14 +230,11 @@ start_server() { return fi -<<<<<<< HEAD -======= if [ "${NO_FCCTL_WEB:-false}" = true ]; then log_warning "Skipping fcctl-web server start - directory not present (expected for CI)" return fi ->>>>>>> origin/main log_info "Starting fcctl-web server..." cd scratchpad/firecracker-rust/fcctl-web @@ -284,14 +270,11 @@ start_server() { check_server() { log_info "Checking fcctl-web server availability..." -<<<<<<< HEAD -======= if [ "${NO_FCCTL_WEB:-false}" = true ]; then log_warning "Skipping server check - fcctl-web not present (expected for CI)" return fi ->>>>>>> origin/main if curl -s "$FCCTL_WEB_URL/health" > /dev/null 2>&1; then log_success "fcctl-web server is available at $FCCTL_WEB_URL" else @@ -325,14 +308,11 @@ run_unit_tests() { run_integration_tests() { log_info "Running integration tests..." -<<<<<<< HEAD -======= if [ "${NO_FCCTL_WEB:-false}" = true ]; then log_warning "Skipping integration tests - fcctl-web not present (expected for CI)" return 0 fi ->>>>>>> origin/main cd scratchpad/firecracker-rust/fcctl-web local test_args=() @@ -356,14 +336,11 @@ run_integration_tests() { run_websocket_tests() { log_info "Running WebSocket tests..." -<<<<<<< HEAD -======= if [ "${NO_FCCTL_WEB:-false}" = true ]; then log_warning "Skipping WebSocket tests - fcctl-web not present (expected for CI)" return 0 fi ->>>>>>> origin/main cd scratchpad/firecracker-rust/fcctl-web local test_args=("--ignored") @@ -387,14 +364,11 @@ run_websocket_tests() { run_e2e_tests() { log_info "Running end-to-end tests..." -<<<<<<< HEAD -======= if [ "${NO_FCCTL_WEB:-false}" = true ]; then log_warning "Skipping end-to-end tests - fcctl-web not present (expected for CI)" return 0 fi ->>>>>>> origin/main local test_args=("--ignored") if [ "$VERBOSE" = true ]; then test_args+=("--" "--nocapture") @@ -432,10 +406,6 @@ run_security_tests() { else log_warning "Skipping integration security tests - fcctl-web not present (expected for CI)" fi -<<<<<<< HEAD - cd - > /dev/null -======= ->>>>>>> origin/main if [ $result -eq 0 ]; then log_success "Security tests passed" @@ -467,10 +437,6 @@ run_performance_tests() { else log_warning "Skipping integration performance tests - fcctl-web not present (expected for CI)" fi -<<<<<<< HEAD - cd - > /dev/null -======= ->>>>>>> origin/main # Agent performance tests if ! cargo test agent_performance_tests --ignored --release 2>&1 | tee -a "$LOG_FILE"; then