# Регламент интеграции RAGRAF с агентами

Документ описывает, как агент должен работать с базой знаний: что вызывать, в каком порядке, чего нельзя делать. Тексты ниже готовы к переносу в `AGENTS.md` проекта и в skill.

---

## 1. Подключение

### 1.1 MCP-сервер (основной канал)

Конфигурация MCP-клиента:

```json
{
  "mcpServers": {
    "ragraf": {
      "command": "python",
      "args": [
        "C:/AutoClaw/RAGRAF/tools/ragraf-mcp.py",
        "--project",
        "C:/AutoClaw/RAGRAF/config/revoap.yaml"
      ]
    }
  }
}
```

Сервер объявляет **40 инструментов** с префиксом `ragraf_` (проверено по коду `src/ragraf/mcp_server.py`): `index_status`, `context`, `drift_report`, `search`, `search_multi`, `duplicates`, `entrypoints`, `dead_code`, `symbol`, `references`, `callers`, `callees`, `impact`, `slice`, `code`, `repo_map`, `schema`, `table_usage`, `routes`, `live_read`, `drift_ack`, `policy_trace`, `class_usage`, `write_check`, `usage`, `freshness`, `catalog`, `use_project`, `ensure`, `diff`, `note`, `notes`, `task`, `task_stats` (§3.4: отчёт по задаче — обращения, факты, решения гейта) — и шесть инструментов живых баз данных: `db_schema`, `db_table`, `db_relations`, `db_sample`, `db_drift`, `db_cross`.

Гейт использования индекса (§3.2) отдельным инструментом не выставляется намеренно: он вызывается хуком клиента (`PreToolUse`), а ручная проверка идёт через CLI — `query gate --payload -`. Подключение: `harness/README.md`.

`context` отвечает на вопрос «о каком проекте мне сейчас отвечают»: имя разработки, корень, ревизия, свежесть и на каком основании корпус определён (аргумент запуска, рабочий каталог процесса, реестр или `use_project`). Он работает и без выбранного корпуса — в отличие от остальных операций.

Инструмента свободных запросов к графу **нет и не будет** (ФТ-15): попытка передать `MATCH ... RETURN` отвергается с кодом `-32602`.

### 1.2 CLI (отладка и ручные операции)

```powershell
python tools/ragraf.py --project config/revoap.yaml status
python tools/ragraf.py --project config/revoap.yaml query impact --target "Core\Config::get" --depth 3
```

### 1.3 Предварительная индексация

```powershell
python tools/ragraf.py --project config/revoap.yaml index
```

Первая индексация скачивает модель эмбеддингов (0,22 ГБ, один раз в `<домашний каталог>/.ragraf/models`). Дальше — только из кэша.

---

## 2. Регламент работы агента

### 2.1 Перед началом работы над задачей

```
1. ragraf_index_status   → узнать ревизию, полноту разбора, доступные возможности
2. ragraf_drift_report   → если журнал непуст, учесть расхождения ДО любых выводов
```

**Почему именно так.** Между индексом и кодом могут быть расхождения: индекс в пределах ревизии неизменен, а код правился. Если агент начнёт работу, не посмотрев журнал, он может опереться на факт, который уже неверен, — и не заметит этого.

### 2.2 Ответ на вопрос о коде

| Вопрос агента | Операция |
|---|---|
| «где это лежит?» | `ragraf_symbol`, при неуверенности — `ragraf_search` |
| «как устроен модуль?» | `ragraf_repo_map` (в бюджете токенов; поле `chars_used` — фактический объём, а не оценка по синтетической строке) |
| «кто это вызывает?» | `ragraf_callers` |
| «что оно вызывает?» | `ragraf_callees` |
| «что сломается, если изменить?» | `ragraf_impact` (перед правкой — обязательно) |
| «где ещё используется?» | `ragraf_references` |
| «какие данные текут сюда?» | `ragraf_slice` (только при `capability=full`) |
| «что в таблице и кто её читает?» | `ragraf_schema`, `ragraf_table_usage` |
| «какие есть маршруты?» | `ragraf_routes` |
| «покажи код» | `ragraf_code` (только по явному запросу) |
| «что это за фрагмент?» | `ragraf_search` с `with_text: true` — адрес и текст одним вызовом |
| «покажи это место подробнее» | `ragraf_code` с `entry_ids` из хита (`node_id`/`chunk_id`) |

### 2.2.1 Текст берётся из индекса, а не с диска

Замер 12 октября 2026: `search` возвращал только адрес хита, поэтому текст
приходилось забирать ВТОРЫМ вызовом, а `code` всегда читал файл с диска —
даже когда индекс отвечал ровно то же самое. Изменения:

* **`search --with-text`** добавляет к каждому хиту поле `snippet` — начало
  сырого текста чанка из индекса. Признак `text_from_index: true` подтверждает,
  что текст взят из базы; если для части хитов текста нет, это видно в `limits`
  с числом таких хитов, а не молчаливой пустой строкой.
* **`code` по умолчанию отдаёт текст из индекса**, а не с диска. Источник
  назван в каждом спане полем `text_source` (`index` либо `disk`), а провенанс
  ответа соответствует фактическому источнику. Прежнее поведение доступно
  как `--source disk`; профиль корпуса остаётся тот же: индекс не становится
  источником «истины», он лишь избавляет от лишнего чтения.
* **`code --entry-ids`** принимает `node_id` и/или `chunk_id` из хитов `search`
  — до этого их нельзя было передать никуда. Неопознанные идентификаторы
  возвращаются списком `unresolved`, а не отбрасываются.

Цена и честность: таблица `chunk_text` хранит сырой текст чанков; при ротации
ревизий он удаляется вместе с ними. Текст в индексе может отстать от файла —
тогда срабатывает `changed_since_index`, и решение о доверии остаётся за
вызывающим.

### 2.3 Жёсткие правила

1. **Читать файлы целиком — последнее средство.** Сначала операция индекса; `rg` и чтение файлов — когда индекс ответил «не найдено» или когда факт помечен `stale`.
2. **Факт с `stale_warnings` нельзя использовать как основание для вывода.** Сначала `ragraf_live_read` по этому пути.
3. **Тела функций не приходят в `impact`, `slice`, `repo_map`.** Это сделано осознанно: структурный контекст точнее и в разы меньше. Код запрашивается отдельно — и, если он нужен, дешевле одним вызовом: `search` с `with_text: true` либо `code` с `entry_ids` по адресу хита.
4. **Разделять доказанное и эвристическое.** В ответах `impact` и `callers` блоки `stated` и `derived` разделены. Вывод, опирающийся на `derived`, должен быть помечен как требующий проверки.
5. **Учитывать `capability`.** При `degraded` недоступны срезы и потоки данных: операция откажет с причиной. Это ограничение, а не пустой результат.
6. **Читать `limits`.** Каждый ответ перечисляет свои ограничения (например, «динамика не покрыта»). Игнорировать их — значит делать выводы на неполной картине.
7. **Во время доработки индекс не обновляется.** Правки регистрируются в журнал, не в индекс.

### 2.4 Во время доработки

После правок:

```powershell
python tools/ragraf.py --project config/revoap.yaml drift --scan
```

Это сравнит индекс с рабочим деревом и допишет различия в журнал. **Индекс при этом не меняется** — это принципиально.

Если правка была выносом кода в новую функцию или метод, будет создана запись вида `slice_boundary`. Это важно: такие изменения меняют границы срезов, и выводы вокруг затронутой функции нужно пересмотреть после переиндексации.

### 2.5 После завершения доработки

```powershell
python tools/ragraf.py --project config/revoap.yaml reindex
```

Что произойдёт: построится новый снимок индекса, журнал расхождений будет архивирован в `drift/archive/<из>_to_<в>.md` с тремя обязательными разделами — «что изменилось в корпусе», «что в знаниях перепроверено», «изменённые границы срезов». Предыдущие записи и история ревизий **не удаляются**.

---

## 3. Текст для `AGENTS.md` проекта (готов к вставке)

```markdown
## База знаний о коде (RAGRAF)

Перед работой с кодом используй RAGRAF, а не чтение файлов вслепую.

Порядок:
1. `ragraf_index_status` — состояние индекса.
2. `ragraf_drift_report` — если журнал непуст, сначала учти расхождения.
3. Вопросы о коде — через операции: `ragraf_symbol`, `ragraf_callers`, `ragraf_impact`,
   `ragraf_search`, `ragraf_repo_map`.
4. `rg` и чтение файлов целиком — только если индекс ответил «не найдено» либо факт
   помечен `stale` (тогда сначала `ragraf_live_read`).
5. Перед правкой, затрагивающей публичный метод или таблицу, обязательно
   `ragraf_impact` — чтобы не сломать потребителей.
6. После правок: `ragraf drift --scan` (индекс НЕ обновляется).
7. По завершении доработки: `ragraf reindex`.

Запрещено:
- писать запросы к графу (Cypher/CPGQL) — доступен только фиксированный набор операций;
- опираться на факт с пометкой `stale` без предварительного `ragraf_live_read`;
- трактовать `derived`-связи как доказанные;
- игнорировать `limits` и `capability` в ответах.
```

---

## 4. Описание skill

**Имя:** RAGRAF — база знаний о коде
**Когда применять:** любая задача, требующая понимания существующего кода: найти, где реализовано; выяснить, кто вызывает; оценить последствия правки; добавить функциональность в незнакомый модуль.

**Что делает:** обращается к проиндексированной базе и возвращает проверяемые факты о коде с указанием файла и строки — вместо последовательного чтения файлов.

**Ключевое правило:** база отвечает **до** чтения файлов; файлы читаются только тогда, когда база честно сообщила «не найдено» или что факт устарел.

---

## 5. Что нужно для реального включения

| Шаг | Состояние |
|---|---|
| MCP-сервер написан и проверен тестом | ✅ `tests/test_mcp.py` — все проверки пройдены |
| Конфигурация корпуса | ✅ `config/revoap.yaml` |
| Индекс построен | ✅ ревизия `rev-0012`, 392 файла |
| `AGENTS.md` в проекте-пилоте | ⏳ **не изменялся**: файл в чужом проекте, вставка текста из §3 требует согласия владельца |
| Регистрация MCP-сервера в клиенте | ⏳ требует правки конфигурации клиента пользователем |
| Замеры пользы (M1, M3, M6) | ⏳ нужен набор задач и baseline без индекса |
