Skip to content

Рецепты восстановления

Справочник к навыку ragraf-core. Каждый рецепт — для состояния, которое уже случалось в этом проекте или описано кодом. Порядок: диагностика, затем действие, затем проверка результата.

1. Индекс устарел или «дрожит»

Симптом. Операция отвечает, но факты не совпадают с кодом; freshness сообщает о расхождении; check повторяет реиндексацию при каждом вызове.

Диагностика.

python tools/ragraf.py -p config/ragraf.yaml check
python tools/ragraf.py -p config/ragraf.yaml status

check сравнивает сумму корпуса с записанной в ревизии. Если суммы совпадают, а stale не снимается, дело не в файлах, а в записи ревизии.

Действие.

python tools/ragraf.py -p config/ragraf.yaml reindex

Причина зацикливания, если оно повторяется. Контрольная сумма обязана считаться по тем же файлам, что попадают в индекс, и после схлопывания дублей (src/ragraf/corpus.py:59-70, :242-253). Если схлопывание вынести в индексатор или в сторож, сумма разойдётся с содержимым индекса и переиндексация не остановится. Проверка на этот случай — tools/Invoke-ProjectDoctrine.ps1, правило о схлопывании.

2. Реестр показывает пустую ревизию и нули

Симптом. python tools/ragraf.py catalog для корпуса показывает rev- «нет», nodes 0, edges 0, хотя status того же корпуса сообщает ревизию и узлы.

Причина (измерено). Заведение корпуса через ensure регистрирует разработку до индексации и результат прогона в реестр не записывает (src/ragraf/ensure.py:308-312). Запись остаётся с триггером register и нулями.

Действие — немедленный обход.

python tools/ragraf.py -p config/ragraf.yaml index

Этот путь пишет результат в реестр (src/ragraf/cli.py:247). Второй путь — любое обращение, приводящее к работе сторожа: сторож записывает результат сам (src/ragraf/watch.py:554). Подтверждение после действия — catalog: у записи появляется ревизия, число узлов и рёбер и триггер вида guard:fast.

Правильное исправление. Добавить запись результата в ensure после успешной индексации, вызывая catalog.record_run (src/ragraf/catalog.py:235) с числами из прочитанной ревизии — так же, как это делает сторож. После правки: python tests/test_ensure.py, затем повторный прогон чекера: правило о покрытии реестра обязано позеленеть.

3. capability=degraded

Симптом. index_status сообщает capability=degraded, операция среза отказывает.

Что это значит. Слой свойств кода не построен или его экспорт не удался; остальные слои (лексика, вектор, граф разбора) работают. Молчаливой деградации не бывает: src/ragraf/cpg.py:9-11.

Диагностика.

python tools/ragraf.py -p config/ragraf.yaml status

В стадии cpg будет записана причина. Известный случай на собственном корпусе: экспорт вернул код 1, ошибка вида «next on empty iterator», при этом файл графа свойств был построен. Причина не локализована — это дефект слоя, а не настройки.

Действие.

  1. Убедиться, что Java и Joern доступны и расположены там, где их ищет код (src/ragraf/cpg.py:82-93, :391).
  2. Перезапустить индексацию: слой строится заново.
  3. Если отказ повторяется — работать без операций среза и записать находку отдельно; не выдавать degraded за поломку всего индекса.

Важно. Сервер Joern останавливается автоматически при закрытии индексатора (src/ragraf/indexer.py:1166-1183). Незакрытый сервер — висящий процесс на гигабайты, который держит порт; проверять список процессов после ручных экспериментов.

4. Правка исключений выбросила рабочий код

Симптом. Файлы, которые были видны в поиске, исчезли; ошибок при этом нет.

Причина. Сопоставление шаблонов регистрозависимо и понимает только шаблоны с хвостом «любой каталог» для отсечения каталогов: **/cache/** ловит src/cache/, но не src/Cache/ (src/ragraf/util.py:72-158).

Действие.

python tools/measure_safe_excludes.py     # сколько файлов выпадет по каждому корпусу
python tools/check_ragraf_config.py       # точность исключений собственного корпуса
python tools/check_service_excludes.py    # служебные каталоги не попадают в скан

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

5. Схлопывание дублей и его цена

Симптом. Число файлов в индексе меньше числа файлов на диске.

Что это. Копии с одинаковым содержимым схлопываются, остаётся одна главная; файлы на диске не удаляются. По умолчанию схлопывание выключено (src/ragraf/config.py:541), и в конфиге собственного корпуса раздела с этими настройками нет — значит на этом корпусе оно не применяется. Когда оно включено, состояние индекса несёт счётчики отброшенного: сколько копий, сколько групп, байт и строк (src/ragraf/indexer.py:779-786).

Чего нельзя делать. Менять правило выбора главной копии на «первую попавшуюся»: ничья обязана разрешаться путём, иначе сумма корпуса дрожит и сторож зацикливается (src/ragraf/dedupe.py:165-223).

Проверка.

python tools/measure_dedupe_rules.py
python tests/test_dedupe.py

Помнить. Включение схлопывания меняет контрольную сумму корпуса: сторож один раз переиндексирует корпус. Это осознанное следствие, а не дефект.

6. Вычислитель ушёл на процессор

Симптом. index_status сообщает процессорный вычислитель; время индексации выше ожидаемого.

Причины (по порядку проверки).

  1. Видеокарта выключена в настройках.
  2. Объём работы ниже порога окупаемости: подготовка карты занимает около четверти минуты разово, поэтому на малом числе текстов она проигрывает (src/ragraf/config.py:276-301).
  3. Не установлен пакет, требующийся карте: sentence-transformers и torch не объявлены в описании пакета (src/ragraf/compute.py:141-146).
  4. Свободной памяти карты меньше порога — переход на процессор с причиной.

Действие. Смотреть поле reason в состоянии вычислений: там записана причина, а не догадка. Понижать порог «чтобы карта работала» не нужно — это замедлит работу.

7. Панель администратора

python tools/ragraf-admin.py --no-browser

Только локальный доступ, порт 8777, токен печатается при старте и выдаётся странице отдельным запросом. Читающие запросы токена не требуют; любая правка настроек — требует, пишется с резервной копией и проверкой ключей и границ (src/ragraf/settings.py:327-386). Живые проверки панели: python tests/check_admin_agents.py и python tests/check_admin_dedupe.py (панель должна быть запущена).

8. Что делать при любом из состояний

  1. Записать измеренное: команду, вывод, ревизию, сумму.
  2. Отличить уже существующее состояние от последствия своей правки: baseline чекера записан в AGENTS.md, раздел 10 — 2 ошибок, 0 предупреждений.
  3. Не выдавать зелёный результат, не осмотрев объект: у каждой проверки в чекере есть счётчик осмотренных объектов, и ноль при успехе считается ложным PASS.