ADR 0082 — Chat RAG: собственная вкладка гибридного поиска, без переименования "Chat"
Статус
Принят.
Контекст
ADR 0080 (PROGRAMA 28,
Волна 4, направление G2) оставил готовыми конвейер индексации и три HTTP-маршрута
Chat RAG — POST .../rag/search, POST .../rag/reindex,
GET .../rag/coverage, — но явно объявил, что ЭКРАН —
работа Волны 5. Тем временем ADR 0078
(RN-202) решил, что вкладка sessions останется с меткой "Chat",
никогда "Chat RAG", как просит более свежий handoff, — потому что в тот
момент "Chat RAG" описывал возможность, которой у продукта не было
(без конвейера, без UI цитирования). Это направление (Волна 5, G3) — момент,
когда эта возможность начинает действительно существовать, и вопрос, на который ему
нужно ответить: теперь, когда RAG существует, куда идёт метка "Chat RAG"?
Два варианта: переименовать sessions в "Chat RAG" (что handoff
буквально предлагает) или дать "Chat RAG" СОБСТВЕННУЮ вкладку. Два
экрана отвечают на структурно разные вопросы — sessions — это
разговор с АКТИВИРОВАННЫМ агентом, который тратит ключ owner на каждый ход
(RN-058) и может писать в backlog, в код, в любой инструмент,
который есть у агента; RAG — это поиск по уже построенному ИНДЕКСУ, без
какого-либо агента посередине и только для чтения по природе (три маршрута ADR
0080 — viewer/viewer/maintainer, ни один не вызывает разговорный
LLM). Слияние двух в одной вкладке вынудило бы UI выражать "это
цитата индексированного чанка" и "это реплика агента" в
одной ленте, когда пользователь никогда не просил обе вещи одновременно.
Решение
"Chat RAG" становится собственной вкладкой, key: 'rag', не трогая метку
sessions. RN-202 остаётся действительной как была — sessions никогда
не был "Chat RAG" и по-прежнему не является, — но её причина меняется с "возможности
не существует" на "возможность существует в ДРУГОМ месте". Вкладка
входит в apps/web/src/routes/project-tabs.ts (ordem: 28, сразу после
code и перед backlog) — то же соседство "посмотреть, что уже
произведено/проиндексировано", что занимает вкладка Código, и перед Backlog, где
рождается новое производство.
Экран потребляет три контракта ADR 0080, не угадывая форму
(apps/web/src/lib/api-client.ts/api-types.ts получают searchRag/
getRagCoverage/reindexRag и типы, отражённые 1:1 из DTO —
RagSearchHit, RagChunkOrigin как объединение, различаемое по kind,
RagCoverage). У UI три части:
RagCoveragePanel— РЕАЛЬНОЕ количество проиндексированныхdocs/adr/сессий против реального итога, иchunksTotal/chunksWithoutVector. Никакого "переиндексировано Xмин назад": ответ backend не несёт этих данных с ADR 0080, и не этот экран будет их выдумывать (RN-252).- Поиск с фильтром области (pills
docs/adr/session, отсутствие = все) и предупреждение, когдаvectorAvailable: false— "busca só por palavra-chave — embedding indisponível", с причиной, когда backend её даёт (RN-252, та же честная деградация RN-233, доходящая до UI). RagCitationCard— цитата с комбинированным score и двумя раздельными сигналами (null, когда сигнал не нашёл чанк, никогда 0%, сохраняя различие ADR 0080). Источникfileпоказывает путь/headingPathкак текст; источникsessionпереходит к точному СОБЫТИЮ черезuseNavigate+search: { highlightEvent }— ТОТ ЖЕ маршрут и тот же параметр, что уже используют чипы свидетельств Psicólogo (HypothesisCard.tsx, Фаза 4b), — переиспользование, а не второй путь навигации (RN-253).
Кнопка "Reindexar agora" появляется только для owner/maintainer,
повторяя на клиенте мерило, которое маршрут уже применяет (RN-238), — тот же
шаблон useCurrentWorkspaceWithRole, что ProjectSettingsTab/
ProjectApprovalsTab уже используют для других gates maintainer (RN-254).
Тот, у кого нет роли, просто не видит кнопку, вместо того чтобы видеть её
отключённой: переиндексация запускает N вызовов к репозиторию проекта и
к provider embedding — то же мерило "меняет то, что тратит продукт, не
спрашивая", что у предела параллелизма области (RN-083).
Последствия
Обещание, которое RN-202 отложила, приходит, но не так, как нарисовал handoff. Handoff переименовывает существующую вкладку; продукт открывает новую. Это наиболее защитимое решение, учитывая, что у двух экранов никогда не было одного и того же вопроса, — а цена ошибки (лишняя вкладка в реестре) меньше, чем цена смешения разговора-с-агентом и поиска-по-индексу на одной поверхности.
Нет глубокой ссылки по пути на вкладку Código. Цитата с
источником file показывает sourcePath/headingPath простым текстом, без
перехода, — у вкладки Código (FASE 26/26b) сегодня нет механизма открытия
конкретного файла через маршрут/search, а построение этого механизма вне
области этого направления. Это объявлено, а не наполовину реализовано: текст
показывает реальный путь, просто он не кликабелен.
Gate maintainer на клиенте — лишь UX. Гарантирует, что
reindex не выполнится без роли, по-прежнему api (RequireRole,
RN-238) — экран лишь избегает клика, который api отклонила бы в любом
случае. Это следует тому же шаблону, что все остальные UI-gates
продукта (auto mode, предел параллелизма, модель области): ни один из них
не заменяет проверку сервера.