RAG for code search and understanding, chatbot for code queries, and MCP for Claude Code RAG skills.
1
stars
71
commits
Rust
primary language
Aug 12, 2026
updated
Test it by asking questions about my portfolio at paulxie.com/demos/code-rag/
A RAG chatbot that answers questions about code repositories. Ingests all sibling project directories, parses Rust, Python, TypeScript, and Go codebases with tree-sitter, extracts docstrings and a persistent AST call graph, generates embeddings, and responds via Google Gemini. Intent classification routes queries to optimized retrieval strategies — including graph augmentation for relationship queries and per-comparator decomposition for comparison queries. Retrieval traces surface all sources with relevance scores — the system shows its work.
The retrieval brain ships as code-rag-mcp, a single-binary MCP server you can drop into any of your own repos to give Claude Code intent-routed retrieval, call-graph traversal, architecture overviews, and topology insight — emergent-module maps with folder-drift comparison, "read these first" rankings, dependency-cycle detection, and call-path tracing with Mermaid output (nine tools). No API keys, no cloud.
Install is three steps, no terminal commands once the exe is on disk:
code-rag-mcp.config.yaml template.target_path to your repo (or a parent folder with workspace: true for many sub-projects)..claude/skills/code-rag.md, .mcp.json, and a .gitignore entry into your target dir, then exits.Open Claude Code in the target dir. The bundled skill instructs the agent to run code_rag_reindex mode=full for the initial ingest automatically.
Full walkthrough: crates/code-rag-mcp/README.md. Release process: docs/release.md.
Place this repo alongside the projects you want to index:
any-parent-folder/
├── code-rag/ ← this repo
├── project-a/
├── project-b/
└── ...
Ingestion walks all sibling directories — each becomes a separate project. The parent folder name doesn't matter.
docker-compose -f docker-compose-ingest.yaml updocker-compose upTo clean, run sh clean_docker.sh.
| Version | Date | Focus |
|---|---|---|
| V0.1 | 2025-12-23 | MVP - Core engine |
| V0.2 | 2026-01-01 | Docker deployment |
| V0.3 | 2026-01-31 | Workspace restructuring |
| V1.1 | 2026-02-04 | Schema foundation (UUID, content_hash, delete API) |
| V1.2 | 2026-02-06 | LanguageHandler trait refactor |
| V1.3 | 2026-02-06 | Incremental ingestion (SHA256, three-layer architecture) |
| V1.4 | 2026-02-07 | TypeScript support (TSX grammar, JSDoc) |
| V1.5 | 2026-02-07 | Docstring extraction (Rust, Python, TypeScript) |
| V2.1 | 2026-02-07 | Inline call context (AST-based call extraction) |
| V2.2 | 2026-02-08 | Intent classification + query routing (cosine similarity) |
| V2.3 | 2026-02-08 | Retrieval traces (scored sources, cross-type ranking) |
| Leptos Migration | 2026-03-25 | WASM frontend (replace htmx/Askama with Leptos) |
| GitHub Pages Demo | 2026-03-25 | Shared engine crate + standalone WASM deployment |
| V3.1 | 2026-04-02 | Retrieval test dataset (43 queries, 4 intent categories) |
| V3.2 | 2026-04-02 | Recall measurement harness (recall@K, MRR, intent accuracy) |
| V3.3 | 2026-04-03 | Baseline quality metrics (dual-run, per-intent breakdown) |
| B1 | 2026-04-04 | Cross-encoder reranking (ms-marco-MiniLM-L-6-v2) |
| B2 | 2026-04-04 | Hybrid BM25+semantic search infrastructure (disabled pending B3) |
| B3 | 2026-04-05 | Declaration signatures + searchable_text + per-intent gating (recall@5 0.70→0.75) |
| B4 | 2026-04-05 | Intent classifier 58%→74% (prototypes + k-NN + keyword pre-filter) |
| B5 | 2026-04-06 | Dual-vector schema + per-intent ArmPolicy (bm25/rerank gating) |
| C1 | 2026-04-09 | Graph RAG — call graph edges + 3-tier resolution + traversal (relationship 0.50→0.57) |
| C2 | 2026-04-09 | Graph result protection — SOTA routing + soft reserve (relationship 0.57→0.60) |
| C3 | 2026-04-09 | Comparison query decomposition — per-comparator RRF + project filter (comparison 0.62→0.65, aggregate 0.71→0.72) |
| A1 | 2026-04-17 | Text module consolidation — single code-rag-engine::text for tokenize/IDF/BM25/searchable_text (WASM/native single source) |
| A2 | 2026-04-17 | Folder-level embeddings — FolderChunk (5-line template, 118 chunks) shipped dark for A3 activation |
| A3 | 2026-04-17 | Collapsed-tree routing — folder arm activated for Overview/Implementation/Comparison (comparison 0.31→0.67 +36pp) |
| A4 | 2026-04-18 | File-level embeddings — FileChunk (4-line template, 247 chunks) + stratified relationship retrieval (recall@pool metric introduced) |
| MCP | 2026-04-24 | Claude Code MCP server (code-rag-mcp) — five tools (search, graph, overview, neighbors, reindex) on rmcp 1.5; bundled Skill; single-binary install (download → edit code-rag-mcp.config.yaml → run exe); subsumes code-rag-ingest via internal ingest subcommand; manually-triggered cross-platform release pipeline; agent-driven first ingest |
| Caravan | 2026-05-21 | Caravan adoption (B0p → M5). Four #[wagon] seams (Embedder / Reranker / VectorReader / LlmClient); RigGeminiImpl extracted to code-rag-llm; chat-side core (AppState, retrieve) extracted to code-rag-core (MCP no longer transitively depends on chat binary); four mix-and-match caravan.yaml targets (dev-monolith / dev-split-light / dev-split-mixed / dev-split-heavy) exercise per-seam independent dispatch. caravan-rpc 0.1.0 published to crates.io |
| R0 | 2026-06-08 | Crate split — parser/ingester renamed code-rag-ingest; code-raptor reclaimed as the topology engine (Track R home) |
| R1 | 2026-06-08 | RelationGraph + typed relation edges (graph_edges: imports/re_exports/contains/implements/extends/embeds/references/rationale_for) with per-language anchored resolution. Hardened 2026-08: project-scoped identifier index (graph never links projects) + documented per-language import matching |
| R2 | 2026-06-10 | Emergent communities — deterministic Louvain (no RNG) + hub exclusion + cohesion scoring, persisted to additive community_assignments table; folder→file contains excluded from partition input by design |
| R3 | 2026-06-10 | ClusterChunk summaries (template tier, cluster_chunks table, retrieval arm) — arm gated OFF by measurement (displaced code/folder chunks on Overview; machinery stays wired for a slot-protection/LLM-tier revisit) |
| R4 | 2026-08-06 | Structural analytics + per-project architecture report — degree centrality (wasm-safe), Brandes edge-betweenness bridges, surprise ranking, import-cycle detection (Tarjan SCC + bounded canonical DFS), byte-deterministic markdown artifact |
| R5 | 2026-08-10 | Track R capstone — emergent-vs-folder drift comparison (report section), interactive topology view in the demo (d3-force, click-a-node → chat query), GraphML + viz JSON exports, four MCP topology tools (communities / central_nodes / cycles / path with Mermaid call-flow) via revived find_path |
code-rag adopts Caravan, an application-definition compiler. The four inter-component boundaries (Embedder, Reranker, VectorReader, LlmClient) are wrapped as caravan-rpc seams; a single yaml projects code-rag onto multiple deployment topologies with zero source-code edits between them.
# caravan.yaml (excerpt)
targets:
dev-monolith: # all 4 seams inproc — baseline single binary
runtime: docker-compose
entries: { code-rag-chat: container }
dev-split-mixed: # 2 seams flipped to separate compose services
runtime: docker-compose
entries: { code-rag-chat: container }
seams:
Embedder: container
Reranker: container
# VectorReader + LlmClient default to inproc
caravan compile --target=dev-split-mixed
docker compose \
-f docker-compose.yaml \
-f infra/dev-split-mixed/generated/docker-compose.override.generated.yaml \
up
Caravan emits a compose override that layers atop the hand-authored docker-compose.yaml — adding peer services for split seams + injecting the per-deploy-unit CARAVAN_RPC_PEERS table the SDK reads at runtime. Same chat image, same binary, same source tree; only the env var changes.
SDK adoption surface is closed at four touchpoints in user code:
#[wagon] on each seam trait (declares the wire surface, crates/code-rag-store/src/seams.rs)caravan_rpc::provide::<dyn I>(Arc::new(impl_)) at startup (crates/code-rag-core/src/state.rs)caravan_rpc::client::<dyn I>().method(...) at call sitescaravan_rpc::run_or_serve(user_main) once in src/main.rs so the same binary can detour into peer-server mode based on CARAVAN_RPC_ROLENo-config inertness: when CARAVAN_RPC_PEERS is unset, client::<dyn T>() returns the registered Arc<dyn T> directly with zero overhead. All existing deployment surfaces — compose chat, compose ingest, local cargo run, WASM gh-pages, single-binary MCP release — keep working unchanged.
See caravan.yaml for the full seam declarations and four mix-and-match targets (dev-monolith / dev-split-light / dev-split-mixed / dev-split-heavy).
"Vertical slices, retrieval quality, code understanding"
| Principle | Meaning |
|---|---|
| Vertical | Build working end-to-end first, then deepen |
| Retrieval | Quality of retrieved context determines answer quality |
| Understanding | Goal is semantic code understanding, not just text search |
| Crate | Single Responsibility |
|---|---|
code-rag-ingest | Ingestion CLI — parsing, chunk extraction, data export |
code-raptor | Topology engine (Track R) — derives architectural structure from persisted relation edges |
code-rag-engine | Shared algorithms — intent, context, scoring (pure, no I/O) |
code-rag-store | Storage seams + LanceDB-backed impls; fastembed Embedder + Reranker |
code-rag-llm | LLM-provider seam impls (rig-core-backed Gemini today; extracted at M5 so synthetic Caravan peer services can build against the impl) |
code-rag-core | Chat-side core shared between the chat binary and the MCP server — AppState, retrieve(), EngineError, SourceInfo. Extracted at M5 to break code-rag-mcp's transitive dep on code-rag-chat |
code-rag-types | Shared types — no logic |
code-rag-chat | HTTP routing + Askama templates + binary main (2 binaries: chat server + harness). Core logic moved to code-rag-core |
code-rag-mcp | MCP stdio server (single-binary release) — depends on code-rag-core directly, no chat-binary transitive |
code-rag-ui | Leptos WASM SPA — chat interface (backend or standalone mode) |
/// (Rust), """ (Python), /** */ (TypeScript JSDoc), // (Go)FolderChunk (1 per directory, 5-line template — folder/files+languages/key types/key functions/subfolders) and FileChunk (1 per source file, 4-line template — file/exports/imports/purpose). Built deterministically at ingest from existing CodeChunk metadata + C1 imports map — no LLM. Both render through pure code-rag-engine::{folder,file} functions, so server-embedded bytes and browser BM25 bytes are byte-identicalcall_edges table, 3-tier resolver (same-file → import-based → unique-global), AST scoped-identifier (module::function()) extractiongraph_edges table persists imports / re_exports / contains / implements / extends / embeds / references / rationale_for edges with per-language anchored resolution, project-scoped so the graph never links sibling projects (retrieval stays corpus-wide)community_assignments. Folder→file edges are deliberately excluded from the partition input so the emergent-vs-folder comparison is earned, not self-fulfillingvector_store.rs monolith splitting into 15 communities)graph_viz_<project>.json (browser artifact, capped 5000 nodes / 15 000 edges) + full-graph GraphML for Gephi/yEd — both byte-deterministic across runstests/, filename test_*.py / *.test.ts, AST-walked #[cfg(test)] enclosing-mod detection (~24% chunk reduction)searchable_text + vector) → cross-encoder reranking (ms-marco-MiniLM-L-6-v2), fused via N-ary RRF in shared code-rag-engine::fusionArmPolicy: per-intent {body_vec, sig_vec, bm25, rerank, folder_vec, file_vec} gating (single source of truth, server + browser). Overview = hybrid+rerank; Implementation = rerank-only; Relationship = hybrid+rerank; Comparison = vector-only. Folder arm gated off for Relationship after empirical regression (folder chunks of X displaced consumers of X — stratified retrieval, file arm stays on)code-rag-engine::graph (graph_augment, merge_graph_chunks, reserve_graph_slots, detect_direction). Two protection paths: SOTA routing for explicit-direction queries ("what calls X / called by") partitions graph chunks out of the reranker entirely; soft reserve for ambiguous-direction over-retains the code arm by +5 and rescues demoted graph chunks. Mirrored line-for-line in WASM standalonecode-rag-engine::comparison): regex extracts ≥2 comparators → per-comparator body-vec sub-searches (comparator name prepended to original query) → vote-based dominant-project filter → RRF fusion → max-of-natural rescoring so RRF outputs compete with non-code arms. Mirrored in WASM standalonecode-rag-engine::text is the sole home for tokenize, IdfTable, BM25 kernel, build_searchable_text, split_camel_case, and intent prototype texts. Compiles to native + wasm32 — no duplication across server, store, raptor, or UIsignature_vector column populated at ingest (shipped OFF after 8-config space sweep; column retained for future experiments)recall@pool (introduced in A4 — recall over every chunk reaching build_context, no top-k truncation), MRR, intent accuracy, latency — dual-run modecode-rag-engine crate: pure algorithms compile to native + wasm32standalone feature runs the full RAG pipeline in-browser (LLM generation optional), plus an interactive topology tab — d3-force canvas of each project's emergent communities (community-colored, degree-sized, relation-dashed edges; theme-aware palette), click a node to run a code-rag query about itFileChunk, FolderChunk). Repo-level summary considered and retired by measurement (existing READMEs + project-root FolderChunks already covered the 3 hero queries at recall@10=1.0)comp-retriever-generator, b4-comp-retriever-api) remain — BGE-small produces noisy vectors for bare hyphenated identifiers (retriever, generator), and the C3 regex extracts comparators only from explicit "compare X and Y / X vs Y" phrasings. Gated on a future embedder upgrade (BGE-base / jina-code) or MMR fallbackSee project-vision.md and development_plan.md for roadmap.
RustLayered Architecture (API/Store/Ingestion) · Trait-Based Abstraction (LanguageHandler) · Registry Pattern (OnceLock) · Three-Layer Pipeline (Parse→Reconcile→Orchestrate) · Router Pattern · Handler Pattern · Shared State (Arc) · Repository Pattern · DTO Pattern · Modular Design · Pipeline Pattern (Ingest→Embed→Store) · Visitor Pattern (WalkDir) · Error Propagation (thiserror) · Ephemeral Side-Channel Pattern · Declarative Routing Table · Scored Search API · ScoredChunk<T> (Generic Wrapper) · Retrieval Traces · Multi-Binary Crate (lib.rs extraction) · FlatChunk CentralizationRAG (Retrieval-Augmented Generation) · Graph RAG · Call Graph Augmentation · Graph-Augmented Retrieval · SOTA Routing (Reranker Bypass) · Soft Reserve · Comparison Query Decomposition · Per-Comparator RRF Fusion · Sub-Query Expansion · Vote-Based Project Filter · Max-of-Natural Rescoring · LLM Integration · Google Gemini API · rig-core · Semantic Search · Chatbot · Intent Classification (Cosine Similarity) · Prototype Query Embeddings · k-NN Prototype Voting · Keyword Pre-Filter (adversarial-guarded) · Intent-Aware Retrieval · Per-Intent Gating (ArmPolicy) · Two-Stage Retrieval · Cross-Encoder Reranking · Hybrid Search (BM25 + Dense) · RRF Fusion · Dual-Vector Schema · Declaration Signatures · searchable_text (IR field boosting) · camelCase Splitting (index-time) · Cross-Type Source Ranking · Distance-to-Relevance Scoring · Retrieval TransparencyRecall@K · MRR (Mean Reciprocal Rank) · Intent Accuracy · Latency Percentiles (p50/p95) · Dual-Run Evaluation (Classifier vs Ground-Truth) · Per-Intent Breakdown · Declarative Test Dataset · Substring File Matching · Dataset Freeze Policy · Baseline Regression Tracking · Space Search (per-intent ArmPolicy sweep) · Adversarial Test Cases · Held-out Classifier EvalLanceDB · LanceDB FTS · Scalar-Only LanceDB Table (call_edges) · BM25 · FastEmbed · BGE Embeddings · ms-marco-MiniLM-L-6-v2 (ONNX)Tree-sitter · AST Parsing · Code Chunking · Docstring Extraction · JSDoc Parsing · Multi-Language (Rust, Python, TypeScript, Go) · Incremental Ingestion (SHA256) · Call Graph Extraction (AST-based) · Function Call Detection (Direct + Method) · Call Edge Resolution (3-tier) · Import-Based Symbol Resolution · Scoped Identifier Extraction · Test Code Exclusion (cfg(test) AST walk)Community Detection (Louvain) · Modularity Maximization · Cohesion Scoring · Edge Betweenness (Brandes) · Tarjan SCC · Dependency Cycle Detection · Emergent Architecture · Architecture Drift (Emergent vs Folder) · Typed Relation Edges · Degree Centrality · GraphML Export · Mermaid Call-Flow · Force-Directed Layout (d3-force) · Deterministic Graph AlgorithmsAxum · Leptos (WASM CSR) · Tower HTTP · CORSTokio Runtime · Async ProgrammingDocker · Docker Compose · GitHub Pages (WASM) · Google OAuth2 (GIS)tracing · Error Handling (anyhow/thiserror) · Serde · clap (CLI) · chrono71 commits
Rust
97.3%
CSS
1.1%
JavaScript
1.0%
RAG for code search and understanding, chatbot for code queries, and MCP for Claude Code RAG skills.
1
stars
71
commits
Rust
primary language
Aug 12, 2026
updated
Test it by asking questions about my portfolio at paulxie.com/demos/code-rag/
A RAG chatbot that answers questions about code repositories. Ingests all sibling project directories, parses Rust, Python, TypeScript, and Go codebases with tree-sitter, extracts docstrings and a persistent AST call graph, generates embeddings, and responds via Google Gemini. Intent classification routes queries to optimized retrieval strategies — including graph augmentation for relationship queries and per-comparator decomposition for comparison queries. Retrieval traces surface all sources with relevance scores — the system shows its work.
The retrieval brain ships as code-rag-mcp, a single-binary MCP server you can drop into any of your own repos to give Claude Code intent-routed retrieval, call-graph traversal, architecture overviews, and topology insight — emergent-module maps with folder-drift comparison, "read these first" rankings, dependency-cycle detection, and call-path tracing with Mermaid output (nine tools). No API keys, no cloud.
Install is three steps, no terminal commands once the exe is on disk:
code-rag-mcp.config.yaml template.target_path to your repo (or a parent folder with workspace: true for many sub-projects)..claude/skills/code-rag.md, .mcp.json, and a .gitignore entry into your target dir, then exits.Open Claude Code in the target dir. The bundled skill instructs the agent to run code_rag_reindex mode=full for the initial ingest automatically.
Full walkthrough: crates/code-rag-mcp/README.md. Release process: docs/release.md.
Place this repo alongside the projects you want to index:
any-parent-folder/
├── code-rag/ ← this repo
├── project-a/
├── project-b/
└── ...
Ingestion walks all sibling directories — each becomes a separate project. The parent folder name doesn't matter.
docker-compose -f docker-compose-ingest.yaml updocker-compose upTo clean, run sh clean_docker.sh.
| Version | Date | Focus |
|---|---|---|
| V0.1 | 2025-12-23 | MVP - Core engine |
| V0.2 | 2026-01-01 | Docker deployment |
| V0.3 | 2026-01-31 | Workspace restructuring |
| V1.1 | 2026-02-04 | Schema foundation (UUID, content_hash, delete API) |
| V1.2 | 2026-02-06 | LanguageHandler trait refactor |
| V1.3 | 2026-02-06 | Incremental ingestion (SHA256, three-layer architecture) |
| V1.4 | 2026-02-07 | TypeScript support (TSX grammar, JSDoc) |
| V1.5 | 2026-02-07 | Docstring extraction (Rust, Python, TypeScript) |
| V2.1 | 2026-02-07 | Inline call context (AST-based call extraction) |
| V2.2 | 2026-02-08 | Intent classification + query routing (cosine similarity) |
| V2.3 | 2026-02-08 | Retrieval traces (scored sources, cross-type ranking) |
| Leptos Migration | 2026-03-25 | WASM frontend (replace htmx/Askama with Leptos) |
| GitHub Pages Demo | 2026-03-25 | Shared engine crate + standalone WASM deployment |
| V3.1 | 2026-04-02 | Retrieval test dataset (43 queries, 4 intent categories) |
| V3.2 | 2026-04-02 | Recall measurement harness (recall@K, MRR, intent accuracy) |
| V3.3 | 2026-04-03 | Baseline quality metrics (dual-run, per-intent breakdown) |
| B1 | 2026-04-04 | Cross-encoder reranking (ms-marco-MiniLM-L-6-v2) |
| B2 | 2026-04-04 | Hybrid BM25+semantic search infrastructure (disabled pending B3) |
| B3 | 2026-04-05 | Declaration signatures + searchable_text + per-intent gating (recall@5 0.70→0.75) |
| B4 | 2026-04-05 | Intent classifier 58%→74% (prototypes + k-NN + keyword pre-filter) |
| B5 | 2026-04-06 | Dual-vector schema + per-intent ArmPolicy (bm25/rerank gating) |
| C1 | 2026-04-09 | Graph RAG — call graph edges + 3-tier resolution + traversal (relationship 0.50→0.57) |
| C2 | 2026-04-09 | Graph result protection — SOTA routing + soft reserve (relationship 0.57→0.60) |
| C3 | 2026-04-09 | Comparison query decomposition — per-comparator RRF + project filter (comparison 0.62→0.65, aggregate 0.71→0.72) |
| A1 | 2026-04-17 | Text module consolidation — single code-rag-engine::text for tokenize/IDF/BM25/searchable_text (WASM/native single source) |
| A2 | 2026-04-17 | Folder-level embeddings — FolderChunk (5-line template, 118 chunks) shipped dark for A3 activation |
| A3 | 2026-04-17 | Collapsed-tree routing — folder arm activated for Overview/Implementation/Comparison (comparison 0.31→0.67 +36pp) |
| A4 | 2026-04-18 | File-level embeddings — FileChunk (4-line template, 247 chunks) + stratified relationship retrieval (recall@pool metric introduced) |
| MCP | 2026-04-24 | Claude Code MCP server (code-rag-mcp) — five tools (search, graph, overview, neighbors, reindex) on rmcp 1.5; bundled Skill; single-binary install (download → edit code-rag-mcp.config.yaml → run exe); subsumes code-rag-ingest via internal ingest subcommand; manually-triggered cross-platform release pipeline; agent-driven first ingest |
| Caravan | 2026-05-21 | Caravan adoption (B0p → M5). Four #[wagon] seams (Embedder / Reranker / VectorReader / LlmClient); RigGeminiImpl extracted to code-rag-llm; chat-side core (AppState, retrieve) extracted to code-rag-core (MCP no longer transitively depends on chat binary); four mix-and-match caravan.yaml targets (dev-monolith / dev-split-light / dev-split-mixed / dev-split-heavy) exercise per-seam independent dispatch. caravan-rpc 0.1.0 published to crates.io |
| R0 | 2026-06-08 | Crate split — parser/ingester renamed code-rag-ingest; code-raptor reclaimed as the topology engine (Track R home) |
| R1 | 2026-06-08 | RelationGraph + typed relation edges (graph_edges: imports/re_exports/contains/implements/extends/embeds/references/rationale_for) with per-language anchored resolution. Hardened 2026-08: project-scoped identifier index (graph never links projects) + documented per-language import matching |
| R2 | 2026-06-10 | Emergent communities — deterministic Louvain (no RNG) + hub exclusion + cohesion scoring, persisted to additive community_assignments table; folder→file contains excluded from partition input by design |
| R3 | 2026-06-10 | ClusterChunk summaries (template tier, cluster_chunks table, retrieval arm) — arm gated OFF by measurement (displaced code/folder chunks on Overview; machinery stays wired for a slot-protection/LLM-tier revisit) |
| R4 | 2026-08-06 | Structural analytics + per-project architecture report — degree centrality (wasm-safe), Brandes edge-betweenness bridges, surprise ranking, import-cycle detection (Tarjan SCC + bounded canonical DFS), byte-deterministic markdown artifact |
| R5 | 2026-08-10 | Track R capstone — emergent-vs-folder drift comparison (report section), interactive topology view in the demo (d3-force, click-a-node → chat query), GraphML + viz JSON exports, four MCP topology tools (communities / central_nodes / cycles / path with Mermaid call-flow) via revived find_path |
code-rag adopts Caravan, an application-definition compiler. The four inter-component boundaries (Embedder, Reranker, VectorReader, LlmClient) are wrapped as caravan-rpc seams; a single yaml projects code-rag onto multiple deployment topologies with zero source-code edits between them.
# caravan.yaml (excerpt)
targets:
dev-monolith: # all 4 seams inproc — baseline single binary
runtime: docker-compose
entries: { code-rag-chat: container }
dev-split-mixed: # 2 seams flipped to separate compose services
runtime: docker-compose
entries: { code-rag-chat: container }
seams:
Embedder: container
Reranker: container
# VectorReader + LlmClient default to inproc
caravan compile --target=dev-split-mixed
docker compose \
-f docker-compose.yaml \
-f infra/dev-split-mixed/generated/docker-compose.override.generated.yaml \
up
Caravan emits a compose override that layers atop the hand-authored docker-compose.yaml — adding peer services for split seams + injecting the per-deploy-unit CARAVAN_RPC_PEERS table the SDK reads at runtime. Same chat image, same binary, same source tree; only the env var changes.
SDK adoption surface is closed at four touchpoints in user code:
#[wagon] on each seam trait (declares the wire surface, crates/code-rag-store/src/seams.rs)caravan_rpc::provide::<dyn I>(Arc::new(impl_)) at startup (crates/code-rag-core/src/state.rs)caravan_rpc::client::<dyn I>().method(...) at call sitescaravan_rpc::run_or_serve(user_main) once in src/main.rs so the same binary can detour into peer-server mode based on CARAVAN_RPC_ROLENo-config inertness: when CARAVAN_RPC_PEERS is unset, client::<dyn T>() returns the registered Arc<dyn T> directly with zero overhead. All existing deployment surfaces — compose chat, compose ingest, local cargo run, WASM gh-pages, single-binary MCP release — keep working unchanged.
See caravan.yaml for the full seam declarations and four mix-and-match targets (dev-monolith / dev-split-light / dev-split-mixed / dev-split-heavy).
"Vertical slices, retrieval quality, code understanding"
| Principle | Meaning |
|---|---|
| Vertical | Build working end-to-end first, then deepen |
| Retrieval | Quality of retrieved context determines answer quality |
| Understanding | Goal is semantic code understanding, not just text search |
| Crate | Single Responsibility |
|---|---|
code-rag-ingest | Ingestion CLI — parsing, chunk extraction, data export |
code-raptor | Topology engine (Track R) — derives architectural structure from persisted relation edges |
code-rag-engine | Shared algorithms — intent, context, scoring (pure, no I/O) |
code-rag-store | Storage seams + LanceDB-backed impls; fastembed Embedder + Reranker |
code-rag-llm | LLM-provider seam impls (rig-core-backed Gemini today; extracted at M5 so synthetic Caravan peer services can build against the impl) |
code-rag-core | Chat-side core shared between the chat binary and the MCP server — AppState, retrieve(), EngineError, SourceInfo. Extracted at M5 to break code-rag-mcp's transitive dep on code-rag-chat |
code-rag-types | Shared types — no logic |
code-rag-chat | HTTP routing + Askama templates + binary main (2 binaries: chat server + harness). Core logic moved to code-rag-core |
code-rag-mcp | MCP stdio server (single-binary release) — depends on code-rag-core directly, no chat-binary transitive |
code-rag-ui | Leptos WASM SPA — chat interface (backend or standalone mode) |
/// (Rust), """ (Python), /** */ (TypeScript JSDoc), // (Go)FolderChunk (1 per directory, 5-line template — folder/files+languages/key types/key functions/subfolders) and FileChunk (1 per source file, 4-line template — file/exports/imports/purpose). Built deterministically at ingest from existing CodeChunk metadata + C1 imports map — no LLM. Both render through pure code-rag-engine::{folder,file} functions, so server-embedded bytes and browser BM25 bytes are byte-identicalcall_edges table, 3-tier resolver (same-file → import-based → unique-global), AST scoped-identifier (module::function()) extractiongraph_edges table persists imports / re_exports / contains / implements / extends / embeds / references / rationale_for edges with per-language anchored resolution, project-scoped so the graph never links sibling projects (retrieval stays corpus-wide)community_assignments. Folder→file edges are deliberately excluded from the partition input so the emergent-vs-folder comparison is earned, not self-fulfillingvector_store.rs monolith splitting into 15 communities)graph_viz_<project>.json (browser artifact, capped 5000 nodes / 15 000 edges) + full-graph GraphML for Gephi/yEd — both byte-deterministic across runstests/, filename test_*.py / *.test.ts, AST-walked #[cfg(test)] enclosing-mod detection (~24% chunk reduction)searchable_text + vector) → cross-encoder reranking (ms-marco-MiniLM-L-6-v2), fused via N-ary RRF in shared code-rag-engine::fusionArmPolicy: per-intent {body_vec, sig_vec, bm25, rerank, folder_vec, file_vec} gating (single source of truth, server + browser). Overview = hybrid+rerank; Implementation = rerank-only; Relationship = hybrid+rerank; Comparison = vector-only. Folder arm gated off for Relationship after empirical regression (folder chunks of X displaced consumers of X — stratified retrieval, file arm stays on)code-rag-engine::graph (graph_augment, merge_graph_chunks, reserve_graph_slots, detect_direction). Two protection paths: SOTA routing for explicit-direction queries ("what calls X / called by") partitions graph chunks out of the reranker entirely; soft reserve for ambiguous-direction over-retains the code arm by +5 and rescues demoted graph chunks. Mirrored line-for-line in WASM standalonecode-rag-engine::comparison): regex extracts ≥2 comparators → per-comparator body-vec sub-searches (comparator name prepended to original query) → vote-based dominant-project filter → RRF fusion → max-of-natural rescoring so RRF outputs compete with non-code arms. Mirrored in WASM standalonecode-rag-engine::text is the sole home for tokenize, IdfTable, BM25 kernel, build_searchable_text, split_camel_case, and intent prototype texts. Compiles to native + wasm32 — no duplication across server, store, raptor, or UIsignature_vector column populated at ingest (shipped OFF after 8-config space sweep; column retained for future experiments)recall@pool (introduced in A4 — recall over every chunk reaching build_context, no top-k truncation), MRR, intent accuracy, latency — dual-run modecode-rag-engine crate: pure algorithms compile to native + wasm32standalone feature runs the full RAG pipeline in-browser (LLM generation optional), plus an interactive topology tab — d3-force canvas of each project's emergent communities (community-colored, degree-sized, relation-dashed edges; theme-aware palette), click a node to run a code-rag query about itFileChunk, FolderChunk). Repo-level summary considered and retired by measurement (existing READMEs + project-root FolderChunks already covered the 3 hero queries at recall@10=1.0)comp-retriever-generator, b4-comp-retriever-api) remain — BGE-small produces noisy vectors for bare hyphenated identifiers (retriever, generator), and the C3 regex extracts comparators only from explicit "compare X and Y / X vs Y" phrasings. Gated on a future embedder upgrade (BGE-base / jina-code) or MMR fallbackSee project-vision.md and development_plan.md for roadmap.
RustLayered Architecture (API/Store/Ingestion) · Trait-Based Abstraction (LanguageHandler) · Registry Pattern (OnceLock) · Three-Layer Pipeline (Parse→Reconcile→Orchestrate) · Router Pattern · Handler Pattern · Shared State (Arc) · Repository Pattern · DTO Pattern · Modular Design · Pipeline Pattern (Ingest→Embed→Store) · Visitor Pattern (WalkDir) · Error Propagation (thiserror) · Ephemeral Side-Channel Pattern · Declarative Routing Table · Scored Search API · ScoredChunk<T> (Generic Wrapper) · Retrieval Traces · Multi-Binary Crate (lib.rs extraction) · FlatChunk CentralizationRAG (Retrieval-Augmented Generation) · Graph RAG · Call Graph Augmentation · Graph-Augmented Retrieval · SOTA Routing (Reranker Bypass) · Soft Reserve · Comparison Query Decomposition · Per-Comparator RRF Fusion · Sub-Query Expansion · Vote-Based Project Filter · Max-of-Natural Rescoring · LLM Integration · Google Gemini API · rig-core · Semantic Search · Chatbot · Intent Classification (Cosine Similarity) · Prototype Query Embeddings · k-NN Prototype Voting · Keyword Pre-Filter (adversarial-guarded) · Intent-Aware Retrieval · Per-Intent Gating (ArmPolicy) · Two-Stage Retrieval · Cross-Encoder Reranking · Hybrid Search (BM25 + Dense) · RRF Fusion · Dual-Vector Schema · Declaration Signatures · searchable_text (IR field boosting) · camelCase Splitting (index-time) · Cross-Type Source Ranking · Distance-to-Relevance Scoring · Retrieval TransparencyRecall@K · MRR (Mean Reciprocal Rank) · Intent Accuracy · Latency Percentiles (p50/p95) · Dual-Run Evaluation (Classifier vs Ground-Truth) · Per-Intent Breakdown · Declarative Test Dataset · Substring File Matching · Dataset Freeze Policy · Baseline Regression Tracking · Space Search (per-intent ArmPolicy sweep) · Adversarial Test Cases · Held-out Classifier EvalLanceDB · LanceDB FTS · Scalar-Only LanceDB Table (call_edges) · BM25 · FastEmbed · BGE Embeddings · ms-marco-MiniLM-L-6-v2 (ONNX)Tree-sitter · AST Parsing · Code Chunking · Docstring Extraction · JSDoc Parsing · Multi-Language (Rust, Python, TypeScript, Go) · Incremental Ingestion (SHA256) · Call Graph Extraction (AST-based) · Function Call Detection (Direct + Method) · Call Edge Resolution (3-tier) · Import-Based Symbol Resolution · Scoped Identifier Extraction · Test Code Exclusion (cfg(test) AST walk)Community Detection (Louvain) · Modularity Maximization · Cohesion Scoring · Edge Betweenness (Brandes) · Tarjan SCC · Dependency Cycle Detection · Emergent Architecture · Architecture Drift (Emergent vs Folder) · Typed Relation Edges · Degree Centrality · GraphML Export · Mermaid Call-Flow · Force-Directed Layout (d3-force) · Deterministic Graph AlgorithmsAxum · Leptos (WASM CSR) · Tower HTTP · CORSTokio Runtime · Async ProgrammingDocker · Docker Compose · GitHub Pages (WASM) · Google OAuth2 (GIS)tracing · Error Handling (anyhow/thiserror) · Serde · clap (CLI) · chrono71 commits
Rust
97.3%
CSS
1.1%
JavaScript
1.0%