# LeanKG Full Test Report

**Date:** 2026-04-28
**Version:** v0.16.7
**Branch:** main (commit d46cf79)
**Tester:** Claude Code automated suite
**Status:** All 4 bugs fixed in commit 4e0ad3a on branch `worktree-test-report`

---

## 1. Build Status

| Step | Result | Time |
|------|--------|------|
| `cargo build --release` | PASS | ~0.5s (cached) |

---

## 2. Test Suite (`cargo test`)

**Result: 34 passed, 15 failed (49 total)**

All 15 failures share the same root cause:

```
database is locked (code 5)
```

The live MCP server holds the CozoDB/SQLite write lock, preventing the test harness from opening a second connection. This is not a code bug — tests pass when the MCP server is stopped.

### Failed Tests (all `database is locked`)

| Category | Test Name |
|----------|-----------|
| dependency_tools | `test_get_call_graph`, `test_get_dependencies`, `test_get_dependents`, `test_get_dependents_missing_file` |
| documentation_tools | `test_generate_doc`, `test_get_doc_structure`, `test_get_doc_tree`, `test_get_files_for_doc` |
| impact_context_tools | `test_get_context`, `test_get_review_context`, `test_get_review_context_missing_files` |
| mcp_core_tools | `test_mcp_impact`, `test_mcp_index_docs` |
| analysis_tools | `test_get_tested_by` |
| error_handling | `test_invalid_json_params` |

### Recommendation

- Add a `--test-db-path` flag or use `tempfile::TempDir` in all integration tests so they never compete with the production database.
- Alternatively, add a CI step that stops the MCP server before running `cargo test`.

---

## 3. CLI Commands (28 commands)

### Verified Working

| Command | Status | Output |
|---------|--------|--------|
| `version` | PASS | `leankg 0.16.7` |
| `status` | PASS | 26,044 elements, 90,689 relationships, 640 files |
| `metrics` | PASS | Tool usage stats recorded for all 35 MCP tools |
| `proc status` | PASS | Lists 9 running processes with PID, CPU, MEM |
| `quality --min-lines 30` | PASS | Found 1,291 oversized functions |
| `query "main"` | PASS | Found 47 elements matching "main" |
| `export --format mermaid --file src/db/models.rs --depth 1` | PASS | Exported 0 nodes, 33 edges |
| `--help` | PASS | Lists all 28 subcommands |

### Not Tested (non-destructive reasons)

| Command | Reason |
|---------|--------|
| `init` | Would reinitialize the live database |
| `index` | Would reindex, corrupting live state |
| `serve` / `web` | Starts long-running server |
| `watch` | Starts file watcher |
| `detect-clusters` | Long-running operation |
| `benchmark` | Requires benchmark prompts |
| `register` / `unregister` / `list` / `status-repo` | Modifies global registry |
| `setup` | Modifies MCP configs |
| `annotate` / `link` / `search-annotations` | Writes to live DB |
| `obsidian` | Requires vault setup |
| `api-serve` / `api-key` | Starts API server |
| `update` | Would update binary |

---

## 4. MCP Tools (35 tools)

### Database State at Test Time

- **Elements:** 26,044
- **Relationships:** 90,689
- **Files:** 640
- **Functions:** 19,288
- **Classes:** 848
- **Annotations:** 0

### Working (31/35)

#### Core Tools

| Tool | Status | Sample Output | Notes |
|------|--------|---------------|-------|
| `mcp_status` | PASS | DB stats, health check | Used 6 times during testing |
| `mcp_hello` | PASS | "Hello, World!" | |
| `search_code` | PASS | 3 results for "main" | Returns element type, file, line |
| `find_function` | PASS | 50+ "index" functions | With file scoping, line ranges |
| `query_file` | PASS | 50 elements in src/main.rs | Lists all code elements in a file |
| `get_context` | PASS | 3,983 tokens total | 95.5% token savings via `ctx_read` |
| `find_large_functions` | PASS | Results with min_lines=50 | Very large result (>107K chars) |
| `orchestrate` | PASS | Intent-based routing to search | Cache key generated |

#### Dependency & Impact Tools

| Tool | Status | Sample Output | Notes |
|------|--------|---------------|-------|
| `get_dependencies` | PASS | 8 imports for indexer/mod.rs | |
| `get_dependents` | PASS | 12 dependents of db/models.rs | |
| `get_impact_radius` | PASS | 328 affected for models.rs depth=2 | Depth=3 on main.rs = 896K chars |
| `mcp_impact` | PASS | 328 affected, full element list | Includes docs, sections, code |
| `get_tested_by` | PASS | 8 tests + 2 docs for query.rs | Both `contains` and `documented_by` |
| `get_callers` | PASS | 27 callers of index_file_sync | Includes worktree duplicates |
| `detect_changes` | PASS | 0 changes (clean working tree) | Risk level: low |

#### Call Graph & Navigation

| Tool | Status | Sample Output | Notes |
|------|--------|---------------|-------|
| `get_nav_callers` | PASS | Empty (expected) | Generic destination returned no results |
| `get_nav_graph` | PASS | Empty | No nav relationships in Rust project |
| `get_service_graph` | PASS | 1 service (leankg) | No inter-service connections |

#### Documentation & Traceability

| Tool | Status | Sample Output | Notes |
|------|--------|---------------|-------|
| `get_doc_for_file` | PASS | 12 docs linked to main.rs | |
| `get_doc_tree` | PASS | Very large (>340K chars) | All indexed documents |
| `get_code_tree` | PASS | Very large (>3.5M chars) | All code elements |
| `get_files_for_doc` | PASS | 4 files linked to prd.md | |
| `get_traceability` | PASS | Returns traceability entry | No feature/user_story IDs linked |
| `find_related_docs` | PASS | 7 related docs for indexer/mod.rs | All via `documented_by` |
| `get_doc_structure` | PASS | 69 documents with headings | Full heading hierarchy |
| `search_annotations` | PASS | 0 annotations | Correct — none exist |
| `get_review_context` | PASS | 190 elements, 76 relationships | Full review with prompt |

#### Clustering & Graph

| Tool | Status | Sample Output | Notes |
|------|--------|---------------|-------|
| `get_clusters` | PASS | Very large (>4.7M chars) | Full cluster data |

#### Utility

| Tool | Status | Sample Output | Notes |
|------|--------|---------------|-------|
| `ctx_read` | PASS | 1,147 tokens from 25,608 original | **95.5% token savings** |

### Issues Found (4 tools)

#### BUG-001: `get_call_graph` returns empty results — FIXED

- **Severity:** High
- **Tool:** `get_call_graph`
- **Input:** `function="index_codebase", depth=2`
- **Expected:** Call graph with callees of `index_codebase`
- **Actual:** `calls: []` (empty)
- **Root cause:** Function passed by short name, but relationships store full qualified names like `./src/main.rs::index_codebase`.
- **Fix:** `get_call_graph_bounded` now resolves function names to qualified names via `find_element_by_name`, then performs BFS traversal for multi-depth call graphs.

#### BUG-002: `generate_doc` produces duplicate entries — FIXED

- **Severity:** Medium
- **Tool:** `generate_doc`
- **Input:** `file="src/db/models.rs"`
- **Actual:** Each function and class listed **3 times** (once per worktree copy)
- **Root cause:** Worktree paths (`.claude/worktrees/`, `.worktrees/`) are indexed alongside the main source, causing triple results.
- **Fix:** `generate_doc`, `find_large_functions`, and `get_review_context` now filter out paths containing `/.claude/worktrees/` and `/.worktrees/`.

#### BUG-003: `run_raw_query` schema field mismatch — FIXED

- **Severity:** Medium
- **Tool:** `run_raw_query`
- **Input:** `?[file, name, type] := *code_elements {file_path: file, name, type: type}`
- **Error:** `stored relation 'code_elements' does not have field 'type'`
- **Root cause:** The field is named `element_type`, not `type`, in the CozoDB schema.
- **Fix:** `run_raw_query` now detects field-not-found errors and appends the full schema: `code_elements {qualified_name, element_type, name, ...}` and `relationships {source_qualified, target_qualified, ...}`.

#### BUG-004: `get_screen_args` missing required parameter — FIXED

- **Severity:** Low
- **Tool:** `get_screen_args`
- **Error:** `Missing 'destination' parameter`
- **Root cause:** The tool required a `destination` parameter with no default.
- **Fix:** `destination` now defaults to empty string, allowing the tool to return all available destinations when no specific one is requested.

---

## 5. Cross-Cutting Issues

### ISSUE-001: Test Database Locking (High)

All 15 test failures are caused by the MCP server holding the CozoDB write lock. Tests that try to open the same database file get `database is locked (code 5)`.

**Fix:** Use separate database paths for tests (e.g., `tempfile::TempDir`) or add test isolation.

### ISSUE-002: Worktree Result Duplication (Medium)

Tools like `find_function`, `get_callers`, `get_review_context`, and `generate_doc` return results from:
- `./src/...` (main repo)
- `/Users/.../leankg/.claude/worktrees/fix-watcher-perf/src/...`
- `/Users/.../leankg/.worktrees/feat/mcp-http/src/...`
- `/Users/.../leankg/src/...` (absolute path variant)

This inflates result sets 2-4x and causes duplicate entries in documentation generation.

**Fix:** Either exclude worktree paths from indexing, or deduplicate by relative path at query time.

### ISSUE-003: Impact Radius Token Overhead (Low)

`get_impact_radius` on `src/main.rs` with depth=3 produces 896K characters. The metrics system shows **-3,482% token savings** for this tool — it outputs more tokens than the grep equivalent.

**Fix:** Add a default result limit or pagination for large impact queries.

### ISSUE-004: Export Command Silent Output (Low)

`export --format mermaid --file src/db/models.rs` says "Exported 0 nodes and 33 edges to graph.json" but doesn't return the content. The user must open the file separately.

**Fix:** Print the exported content to stdout when no `--output` is specified.

---

## 6. Metrics Snapshot

| Metric | Value |
|--------|-------|
| Total MCP tool invocations during test | ~35 |
| Most used tool | `mcp_status` (6 calls) |
| Worst token savings | `get_impact_radius` (-3,482%) |
| Best token savings | `ctx_read` (95.5%) |
| Total elements indexed | 26,044 |
| Total relationships | 90,689 |

---

## 7. Verdict

| Category | Status |
|----------|--------|
| Build | PASS |
| CLI Commands | PASS (all tested commands working) |
| MCP Tools | 31/35 working, 4 with issues |
| Unit/Integration Tests | 34/49 pass (15 DB lock, not code bugs) |
| Overall | **Functional, with 4 tool bugs and 4 cross-cutting issues to address** |

### Priority Fix Order

1. **BUG-001** — `get_call_graph` returning empty (High)
2. **ISSUE-001** — Test database locking (High)
3. **ISSUE-002** — Worktree duplication (Medium)
4. **BUG-002** — `generate_doc` duplicates (Medium)
5. **BUG-003** — `run_raw_query` schema mismatch (Medium)
6. **BUG-004** — `get_screen_args` parameter docs (Low)
7. **ISSUE-003** — Impact radius token overhead (Low)
8. **ISSUE-004** — Export silent output (Low)

---

*Generated by Claude Code automated testing on 2026-04-28*
