# KG Not Rebuilding on Force Reindex - Fix (v2.3.42)

## Issue
The Knowledge Graph (KG) was NOT being rebuilt when running `mcp-vector-search index -f` (force reindex). The KG should clear and rebuild from scratch on force reindex, but instead it retained old data.

## Investigation

### Symptoms
1. Running `index -f --limit 20` indexed only 20 files (466 chunks)
2. KG stats showed 15,652 entities (old data from full index)
3. KG stats showed "Last Build: 10h ago" (not updated)
4. **Expected**: KG should rebuild with ONLY entities from 20 files
5. **Actual**: KG retained all 15,652 entities from previous full index

### Root Cause
During atomic rebuild (`force_reindex=True`), the system builds into temporary databases with `.new` suffix:
- `lance.new` - chunks backend
- `code_search.lance.new` - vectors backend
- `knowledge_graph.new` - KG backend (expected)

**Bug**: In `src/mcp_vector_search/cli/commands/index.py` lines 1008-1022, the KG path was hardcoded to `knowledge_graph` instead of checking if we're in atomic rebuild mode and using `knowledge_graph.new`.

This caused:
1. KG was cleared at the OLD path (`knowledge_graph`)
2. KG was built at the OLD path (not `.new`)
3. During atomic finalize (lines 766-771 in indexer.py), the system expected `knowledge_graph.new` to exist for swapping
4. Since `knowledge_graph.new` didn't exist, the OLD KG was never replaced

### Code Flow
```python
# Before fix (WRONG):
kg_path = indexer.project_root / ".mcp-vector-search" / "knowledge_graph"
# Always uses old path, regardless of force_reindex

# After fix (CORRECT):
if force_reindex:
    kg_path = indexer.project_root / ".mcp-vector-search" / "knowledge_graph.new"
else:
    kg_path = indexer.project_root / ".mcp-vector-search" / "knowledge_graph"
# Uses .new path during atomic rebuild
```

## Fix Applied

**File**: `src/mcp_vector_search/cli/commands/index.py`
**Lines**: 1008-1032

### Changes
1. Added conditional KG path selection based on `force_reindex` flag
2. During atomic rebuild (`force_reindex=True`): use `knowledge_graph.new`
3. During incremental update: use `knowledge_graph` (old behavior)
4. Clear the KG at the CORRECT path (`.new` for atomic, regular for incremental)
5. Updated log message to show which path is being cleared

### Code Diff
```python
# Determine KG path based on rebuild mode
# During atomic rebuild (force_reindex), use .new suffix
# to match atomic finalize expectations
if force_reindex:
    kg_path = (
        indexer.project_root
        / ".mcp-vector-search"
        / "knowledge_graph.new"
    )
else:
    kg_path = (
        indexer.project_root
        / ".mcp-vector-search"
        / "knowledge_graph"
    )

# Clear existing KG path
# For atomic rebuild, this clears the .new path (not old one)
# For incremental, this clears the regular path for rebuild
if kg_path.exists():
    import shutil

    logger.info(
        f"Clearing knowledge graph at {kg_path.name} for rebuild..."
    )
    shutil.rmtree(kg_path, ignore_errors=True)
```

## Verification

### Test 1: KG directory creation
```bash
# Before fix:
mcp-vector-search index -f --limit 20 --compute-relationships
ls .mcp-vector-search/ | grep knowledge
# Output: knowledge_graph (OLD path, not rebuilt)

# After fix:
mcp-vector-search index -f --limit 20 --compute-relationships
ls .mcp-vector-search/ | grep knowledge
# Output:
#   knowledge_graph (OLD, preserved during build)
#   knowledge_graph.new (NEW, being built)
# After finalize: knowledge_graph.new → knowledge_graph (atomic swap)
```

### Test 2: Entity counts
```bash
# With --limit 20, KG should have ~50-100 entities (only from 20 files)
# NOT 15,652 entities (from full codebase)
```

## Important Notes

### Default Behavior
By default, `mcp-vector-search index` uses `--skip-relationships` (KG build is skipped). To test KG rebuild, you MUST use:
```bash
mcp-vector-search index -f --compute-relationships
```

### Kuzu Segfault Issue (Separate Bug)
During testing, Kuzu database segfaults during KG build with concurrent operations:
```
Fatal Python error: Segmentation fault
File "kuzu/connection.py", line 134 in execute
File "knowledge_graph.py", line 2164 in _add_relationships_batch_by_type
```

This is a separate Kuzu bug, NOT related to the KG path fix. The fix correctly creates `knowledge_graph.new`, but Kuzu crashes during relationship insertion.

**Workaround**:
1. KG build may need to be single-threaded or use smaller batches
2. This is a Kuzu concurrency issue, not a path issue
3. The fix DOES work (confirmed by `knowledge_graph.new` creation)

## Atomic Finalize Flow
After successful indexing, `_finalize_atomic_rebuild()` (indexer.py lines 729-807):
1. Renames `knowledge_graph` → `knowledge_graph.old` (backup)
2. Renames `knowledge_graph.new` → `knowledge_graph` (activate new)
3. Deletes `knowledge_graph.old` (cleanup)

This ensures atomic swap with rollback capability on failure.

## Related Code
- **Atomic rebuild setup**: `src/mcp_vector_search/core/indexer.py` lines 659-727
- **Atomic finalize**: `src/mcp_vector_search/core/indexer.py` lines 729-807
- **KG build in index.py**: `src/mcp_vector_search/cli/commands/index.py` lines 989-1061

## Version
- **Fixed in**: v2.3.42
- **Previous issue in**: v2.3.36-v2.3.41 (partial fix attempted, but path was still wrong)

## Testing Checklist
- [x] Verify `knowledge_graph.new` is created during `index -f`
- [x] Verify KG clearing message shows correct path name
- [ ] Verify atomic finalize swaps `.new` to final (blocked by Kuzu segfault)
- [ ] Verify entity count matches only indexed files (blocked by Kuzu segfault)
- [ ] Verify `kg stats` shows new data after rebuild completes (blocked by Kuzu segfault)

## Next Steps
1. **Fix Kuzu segfault** (separate issue):
   - Investigate concurrent KG relationship insertion
   - Consider single-threaded mode or smaller batches
   - Check Kuzu version compatibility

2. **Complete testing** after Kuzu fix:
   - Full rebuild with `--compute-relationships`
   - Verify entity counts match indexed files
   - Verify atomic swap completes successfully
