|
| 1 | +**Repository:** root |
| 2 | +**Status:** Completed (2026-06-02) |
| 3 | +**Created:** 2026-06-02 |
| 4 | +**Author:** lead |
| 5 | + |
| 6 | +# RAG System Documentation |
| 7 | + |
| 8 | +## Goal |
| 9 | + |
| 10 | +Produce comprehensive documentation of the semcode RAG system covering: dense |
| 11 | +vector ingestion, sparse vector (BM25) ingestion, hybrid retrieval with Reciprocal |
| 12 | +Rank Fusion (RRF), and system configuration. The user is a participant throughout |
| 13 | +the investigation — code analysis findings are shared with the user for input and |
| 14 | +correction before each draft is written, and each draft is reviewed and approved by |
| 15 | +the user before the file is saved to `docs/`. The documentation targets a mixed |
| 16 | +audience (newcomers and experienced contributors) and includes observations on |
| 17 | +design gaps and improvement opportunities per document. |
| 18 | + |
| 19 | +## Context |
| 20 | + |
| 21 | +- **User preferences:** one file per concern; mixed audience (concept intros for |
| 22 | + newcomers, design rationale for experienced contributors); include findings/observations |
| 23 | + per doc; human reviews each draft before it is saved; `docs/configuration.md` is a |
| 24 | + first-class deliverable, not just inline context. |
| 25 | +- **No existing `docs/` folder** — it will be created as part of this plan. |
| 26 | +- **Core files:** |
| 27 | + - `server/indexer/pipeline.py` — `IndexPipeline`, embedding text builders, |
| 28 | + ingestion orchestration, incremental indexing via blob SHA change detection |
| 29 | + - `server/store/qdrant.py` — `QdrantStore`, collection creation (named vectors |
| 30 | + `text-dense` + `text-sparse`), `upsert_chunks`, `search` with `FusionQuery(RRF)` |
| 31 | + - `server/tools/search.py` — MCP tools: `search_code`, `find_symbol`, |
| 32 | + `find_usages`, `get_code_context` |
| 33 | + - `server/embeddings/base.py` — `EmbeddingProvider` Protocol |
| 34 | + - `server/embeddings/factory.py` — registry pattern, singleton provider |
| 35 | + - `server/embeddings/bm25.py` — `BM25SparseProvider` using `fastembed` + |
| 36 | + `Qdrant/bm25`; uses `split_code_identifiers` pre-processing |
| 37 | + - `server/embeddings/code_tokenizer.py` — code identifier splitter for BM25 |
| 38 | + - `server/embeddings/{jina,jina_api,voyage,openai,ollama}.py` — dense providers |
| 39 | + - `server/config.py` — `Settings` (pydantic-settings), `ServiceConfig`, |
| 40 | + `EmbeddingsProviderName` |
| 41 | +- **Key design decisions visible in the code:** |
| 42 | + - Dual-text strategy: dense embeddings use a rich preamble with metadata; |
| 43 | + sparse (BM25) uses signature + docstring + source only |
| 44 | + - Incremental indexing: blob SHA comparison skips unchanged files |
| 45 | + - Deterministic point IDs: `uuid5` from `service:file_path:symbol_name:start_line` |
| 46 | + - RRF via Qdrant's native `FusionQuery(Fusion.RRF)` with 2× prefetch limit |
| 47 | + - Sparse vector stored in-memory (`on_disk=False`) |
| 48 | + - HNSW config: `m=16`, `ef_construct=128`; indexing threshold: 500 |
| 49 | +- **This is a documentation-only task** — no production code changes. |
| 50 | + |
| 51 | +## Steps |
| 52 | + |
| 53 | +- [x] Clarify requirements with user |
| 54 | +- [x] Read codebase (pipeline, store, embeddings, config, tools) |
| 55 | +- [x] Write plan |
| 56 | +- [ ] Plan review cycle |
| 57 | +- [ ] User plan approval |
| 58 | +- [ ] Workflow selection |
| 59 | +- [x] Task 1: Draft and review ingestion doc |
| 60 | +- [x] Task 2: Draft and review dense vectors doc |
| 61 | +- [x] Task 3: Draft and review sparse vectors doc |
| 62 | +- [x] Task 4: Draft and review retrieval (RRF) doc |
| 63 | +- [x] Task 5: Draft and review configuration doc |
| 64 | +- [x] Task 6: Draft and review docs/README.md index + root README.md link |
| 65 | +- [x] Commit all docs — bf0adea |
| 66 | + |
| 67 | +## Tasks |
| 68 | + |
| 69 | +### Task 1: docs/ingestion.md |
| 70 | + |
| 71 | +Investigate the `IndexPipeline` end-to-end ingestion flow — share key findings |
| 72 | +with the user before drafting, then write the document. |
| 73 | + |
| 74 | +**Investigation scope:** how a service is discovered, how files are fetched and |
| 75 | +filtered, how symbols are parsed, how both embedding types are generated, and how |
| 76 | +results are upserted into Qdrant; incremental indexing (blob SHA change detection); |
| 77 | +stale-entry cleanup. |
| 78 | + |
| 79 | +**Process:** |
| 80 | +1. Present code analysis findings and observations to the user via AskUserQuestion; |
| 81 | + proceed to drafting only after user confirms the findings are accurate. |
| 82 | +2. Write the draft; present it to the user for review via AskUserQuestion. |
| 83 | +3. Save `docs/ingestion.md` only after the user approves the draft. |
| 84 | + |
| 85 | +Acceptance criteria: |
| 86 | +- File `docs/ingestion.md` exists with sections: Overview, Pipeline Stages |
| 87 | + (Discovery → Parsing → Embedding → Upsert → Cleanup), Incremental Indexing, |
| 88 | + Data Model (what a `CodeSymbol` and its payload look like), Observations |
| 89 | +- File written to disk only after user's explicit approval of the draft |
| 90 | +- No production code is modified |
| 91 | + |
| 92 | +### Task 2: docs/dense-vectors.md |
| 93 | + |
| 94 | +Investigate how dense embeddings are produced — share key findings with the user |
| 95 | +before drafting, then write the document. |
| 96 | + |
| 97 | +**Investigation scope:** `EmbeddingProvider` Protocol, the factory/registry |
| 98 | +pattern, five concrete providers (jina local, jina API, voyage, openai, ollama), |
| 99 | +the rich preamble text strategy in `_build_embedding_text`, the 6000-char |
| 100 | +truncation limit, provider selection at startup. |
| 101 | + |
| 102 | +**Process:** |
| 103 | +1. Present code analysis findings and observations to the user via AskUserQuestion; |
| 104 | + proceed to drafting only after user confirms the findings are accurate. |
| 105 | +2. Write the draft; present it to the user for review via AskUserQuestion. |
| 106 | +3. Save `docs/dense-vectors.md` only after the user approves the draft. |
| 107 | + |
| 108 | +Acceptance criteria: |
| 109 | +- File `docs/dense-vectors.md` exists with sections: Overview, Provider Protocol, |
| 110 | + Embedding Text Strategy (preamble construction), Supported Providers (comparison |
| 111 | + table), Provider Selection, Observations |
| 112 | +- File written to disk only after user's explicit approval of the draft |
| 113 | +- No production code is modified |
| 114 | + |
| 115 | +### Task 3: docs/sparse-vectors.md |
| 116 | + |
| 117 | +Investigate how sparse BM25 embeddings are produced — share key findings with the |
| 118 | +user before drafting, then write the document. |
| 119 | + |
| 120 | +**Investigation scope:** `BM25SparseProvider`, `Qdrant/bm25` fastembed model, |
| 121 | +`split_code_identifiers` pre-processing (and why it matters for code), distinction |
| 122 | +between `passage_embed` and `query_embed`, sparse vector structure |
| 123 | +(`indices` + `values`). |
| 124 | + |
| 125 | +**Process:** |
| 126 | +1. Present code analysis findings and observations to the user via AskUserQuestion; |
| 127 | + proceed to drafting only after user confirms the findings are accurate. |
| 128 | +2. Write the draft; present it to the user for review via AskUserQuestion. |
| 129 | +3. Save `docs/sparse-vectors.md` only after the user approves the draft. |
| 130 | + |
| 131 | +Acceptance criteria: |
| 132 | +- File `docs/sparse-vectors.md` exists with sections: Overview, BM25 for Code |
| 133 | + (why BM25 complements dense), Code Tokenizer Pre-processing, Passage vs Query |
| 134 | + Embedding, Sparse Vector Structure, Observations |
| 135 | +- File written to disk only after user's explicit approval of the draft |
| 136 | +- No production code is modified |
| 137 | + |
| 138 | +### Task 4: docs/retrieval-rrf.md |
| 139 | + |
| 140 | +Investigate the hybrid retrieval path — share key findings with the user before |
| 141 | +drafting, then write the document. |
| 142 | + |
| 143 | +**Investigation scope:** `QdrantStore.search` dual-prefetch (dense + sparse, each |
| 144 | +at 2× limit), Qdrant's native RRF fusion, `find_by_name` fallback (exact scroll vs. |
| 145 | +substring scan), four MCP tool entry points (`search_code`, `find_symbol`, |
| 146 | +`find_usages`, `get_code_context`), result formatting for MCP clients. |
| 147 | + |
| 148 | +**Process:** |
| 149 | +1. Present code analysis findings and observations to the user via AskUserQuestion; |
| 150 | + proceed to drafting only after user confirms the findings are accurate. |
| 151 | +2. Write the draft; present it to the user for review via AskUserQuestion. |
| 152 | +3. Save `docs/retrieval-rrf.md` only after the user approves the draft. |
| 153 | + |
| 154 | +Acceptance criteria: |
| 155 | +- File `docs/retrieval-rrf.md` exists with sections: Overview, Hybrid Search |
| 156 | + Architecture, RRF Fusion, MCP Tool Interface, Result Formatting, Observations |
| 157 | +- File written to disk only after user's explicit approval of the draft |
| 158 | +- No production code is modified |
| 159 | + |
| 160 | +### Task 5: docs/configuration.md |
| 161 | + |
| 162 | +Investigate all configuration knobs — share key findings with the user before |
| 163 | +drafting, then write the document. |
| 164 | + |
| 165 | +**Investigation scope:** every env var in `Settings` (name, default, which |
| 166 | +provider it applies to), `config.yaml` service fields (`name`, `github_repo`, |
| 167 | +`github_ref`, `root`, `exclude`), collection settings, transport settings, startup |
| 168 | +dimension-mismatch validation. |
| 169 | + |
| 170 | +**Process:** |
| 171 | +1. Present code analysis findings and observations to the user via AskUserQuestion; |
| 172 | + proceed to drafting only after user confirms the findings are accurate. |
| 173 | +2. Write the draft; present it to the user for review via AskUserQuestion. |
| 174 | +3. Save `docs/configuration.md` only after the user approves the draft. |
| 175 | + |
| 176 | +Acceptance criteria: |
| 177 | +- File `docs/configuration.md` exists with sections: Overview, Environment |
| 178 | + Variables (table: var, default, description), config.yaml Structure, Startup |
| 179 | + Validation, Observations |
| 180 | +- File written to disk only after user's explicit approval of the draft |
| 181 | +- No production code is modified |
| 182 | + |
| 183 | +### Task 6: docs/README.md + root README.md link |
| 184 | + |
| 185 | +Write a one-page index that describes the system at a glance (what semcode RAG |
| 186 | +is, what it indexes, how it serves queries), lists the five topic docs with |
| 187 | +one-line descriptions (ingestion.md, dense-vectors.md, sparse-vectors.md, |
| 188 | +retrieval-rrf.md, configuration.md), and provides a quick-start pointer to |
| 189 | +`docs/configuration.md`. Then add a link from the root `README.md` into the |
| 190 | +new `docs/` tree so readers arriving at the project's entry point can discover |
| 191 | +the detailed documentation. |
| 192 | + |
| 193 | +**Process:** |
| 194 | +1. Present draft of `docs/README.md` to the user for review via AskUserQuestion. |
| 195 | +2. Save `docs/README.md` only after the user approves the draft. |
| 196 | +3. Add a "Documentation" section to the root `README.md` linking to |
| 197 | + `docs/README.md` with a one-line description; present the addition to the user |
| 198 | + before saving. |
| 199 | + |
| 200 | +Acceptance criteria: |
| 201 | +- File `docs/README.md` exists with sections: What is semcode RAG, Documentation |
| 202 | + Index (links to the five topic docs: ingestion, dense-vectors, sparse-vectors, |
| 203 | + retrieval-rrf, configuration), Quick Start |
| 204 | +- Root `README.md` contains a link to `docs/README.md` |
| 205 | +- Both files written to disk only after user's explicit approval |
| 206 | +- No production code is modified |
| 207 | + |
| 208 | +## Decisions |
| 209 | + |
| 210 | +- **One file per concern:** user preference — separate files for ingestion, dense |
| 211 | + vectors, sparse vectors, retrieval, and configuration; plus README index. |
| 212 | +- **Two-checkpoint workflow per document:** (1) findings are shared with the user |
| 213 | + via AskUserQuestion before drafting begins — the user can correct or redirect |
| 214 | + the analysis; (2) the draft is presented to the user before the file is written |
| 215 | + to disk. This fulfills the "human in every part of the investigation" requirement |
| 216 | + at both the analysis and the writing stage. |
| 217 | +- **Observations included:** each doc has a findings/observations section surfacing |
| 218 | + design gaps and improvement ideas — user preference. |
| 219 | +- **Mixed audience:** docs include brief concept intros (what RAG is, what BM25 is) |
| 220 | + alongside design-specific detail. |
| 221 | +- **docs/ coexists with root README.md:** the existing root `README.md` already |
| 222 | + covers the RAG system at a high level (indexing, embedding providers, env vars). |
| 223 | + The new `docs/` files provide deeper, structured documentation of each concern. |
| 224 | + Rather than rewrite or condense the root README, this plan adds only a |
| 225 | + "Documentation" link section pointing to `docs/README.md`. The two sources are |
| 226 | + complementary: the root README serves as a project overview and quick-start; |
| 227 | + `docs/` serves as the authoritative deep-dive reference. |
| 228 | +- **No production code changes:** this plan produces only markdown files in `docs/` |
| 229 | + and a minor link addition to the root `README.md`. |
| 230 | + |
| 231 | +## Non-Goals |
| 232 | + |
| 233 | +- Documenting the parser subsystem (`server/parser/`) — out of scope; not part of |
| 234 | + the RAG ingestion or retrieval path. |
| 235 | +- Documenting git history indexing (`server/indexer/git_history.py`, |
| 236 | + `server/store/commit_store.py`) — separate concern from the RAG system. |
| 237 | +- Making code changes to fix observed gaps — observations are documented only; |
| 238 | + improvements are a separate plan. |
0 commit comments