Зачем гибридный индекс и почему он устроен именно так
Это текст для человека, который открывает репозиторий MCP: зачем слой между агентом и кодовой базой и почему выбраны конкретные компромиссы. Формальное архитектурное решение с нумерацией ADR относится к CascadeIDE — см. ADR 0105 (Accepted · Implemented). Интеграция продукта в IDE — ADR 0106.
Какую проблему решаем
Агенту и человеку в IDE нужно быстро сузить область поиска: куда смотреть, какие файлы открыть, какие символы потом проверять Roslyn’ом. «Перечитать полрепозитория» или десятки вызовов навигации — слишком дорого по шагам и по контексту модели.
При этом для C# у нас уже есть единственный надёжный источник для опасных операций (переименование, usages, семантический impact) — это Roslyn. Индекс не должен создавать иллюзию «ещё один компилятор».
Почему два слоя: Roslyn и «слой B»
- Roslyn даёт истину по символам там, где есть семантическая модель.
- Часть артефактов Roslyn не индексирует как символы (или не индексирует вообще): Razor/Blazor разметка, AXAML, markdown, конфиги, пайплайны, CSS/HTML. Там нужен хотя бы полнотекст и эвристики, чтобы не грепать всё дерево вслепую.
*.csв FTS опционально и осознанно «как текст»: это помощь для ориентации и поиска по строкам/идентификаторам, не замена поиску символов. Иначе агент перепутает «попало в топ» с «семантически это то же».
Отсюда же требование явной метки типа попадания (hit_kind и связанные поля в ответах): человек или оркестратор должен понимать, перед ним текстовое совпадение или путь к следующему вызову Roslyn.
Почему SQLite FTS5 (+ опционально вектора в том же мире)
- Нужен один локальный артефакт на workspace/решение без обязательного Docker и без обязательного отдельного сервера в baseline установки.
- FTS5 — зрелый keyword-слой с предсказуемой стоимостью и маленьким operational footprint для Windows/Linux/macOS.
- Векторный канал (semantic) — включение по желанию: отдельные провайдеры эмбеддингов, отдельные настройки; keyword остаётся основой «всегда работает».
Тяжёлые альтернативы класса «всегда включённый граф + Qdrant + контейнеры» откладываем: они хороши для исследований, но плохо совпадают с целью «поднять и искать локально».
Почему отдельный процесс MCP, а не только библиотека внутри IDE
- Те же tool id и JSON-контракты можно вызывать из Cursor/другого хоста MCP без запуска Avalonia и без общей памяти с IDE.
- Индекс, watcher и SQLite обновления изолированы: сбои и перезапуск не привязаны жёстко к UI-процессу CascadeIDE.
IDE может позже использовать то же ядро in-process или тот же бинарник как дочерний процесс — контракт остаётся общим.
Почему эвристики Razor / AXAML в виде «заголовков» к чанку (__hci_*)
Полный парсер Razor/XAML давал бы точность ценой сложности и зависимостей. На первом слое нужно ускорить поиск ключевых слов: директивы (@page, @inject, …), обработчики, ресурсы, пары файл–code-behind. Эти строки добавляются в начало текстового содержимого артефакта при индексации так, чтобы FTS нашёл их по запросу, не притворяясь синтаксическим деревом.
Это сознательно подсказка для ориентации, а не замена редактору форм или анализатору AXAML/CDS в IDE.
Что сознательно не делаем в этом MCP
- Не заменяем Roslyn для рефакторингов по C#.
- Не строим канонический semantic graph приложения как у карты намерений в CascadeIDE (0106): индекс — вход для orientation, не источник графа управления UI.
- Не тащим в baseline обязательный Docker/облако — только опции.
Куда смотреть дальше
| Документ | Содержание |
|---|---|
| ADR 0105 в CascadeIDE | Решение, слои, глоссарий, план внедрения, эскизы чанкинга и фьюжна |
| MCP-TOOLS | Описание инструментов MCP (генерируется из кода) |
| README | Установка, settings.toml, быстрый старт |