Техническое задание: RAGRAF
Версия: 1.0 · Дата: 2026-10-04 · Проект: C:\AutoClaw\RAGRAF
Основание: docs/00_plan/PLAN.md, docs/01_research/SPEC_INPUT.md, docs/02_architecture/ARCHITECTURE.md
Заказчик: владелец AutoClaw. Исполнитель: AutoClaw.
Решения заказчика, зафиксированные 2026-10-04: JVM (JDK 19 + Joern) разрешена · пилот revoap.com · эмбеддинги paraphrase-multilingual-MiniLM-L12-v2 · релиз 1 — только PHP.
Сверка с кодом (16.10.2026). ТЗ описывает объём релиза 1 — 17 операций. Поставленный продукт реализует надмножество: 38 операций фасада (def op_* в src/ragraf/facade.py), 40 инструментов MCP (ragraf_* в src/ragraf/mcp_server.py) и 39 имён в CLI (OPS в src/ragraf/cli.py). Числа в требованиях ниже оставлены как исторический объём релиза 1 и намеренно не переписываются.
1. Назначение и цель
Система RAGRAF создаёт и сопровождает вспомогательную базу знаний о коде (граф + символы + вектор + лексика), чтобы LLM-агент при разработке и доработке ПО не изучал репозиторий вслепую, а получал проверяемые ответы: где лежит, кто вызывает, что сломается, как сделано в похожем месте.
Цель по трём фазам жизненного цикла:
1. перед доработкой — индексация кода;
2. во время доработки — ответы агента из базы и накопление различий между базой и кодом в отдельном журнале;
3. после доработки — переиндексация, приводящая базу в соответствие с кодом.
Ключевое требование, ради которого делается журнал: в процессе накопления различий агент не должен делать выводов по устаревшим данным, не зная об этом.
2. Объём работ
2.1 В объёме релиза 1
| № |
Работа |
| 1 |
Конвейер индексации PHP-корпуса: AST, символы, CPG, схема БД, маршруты, документация |
| 2 |
Три хранилища (граф, лексика+вектор, контроль) и схема данных с провенансом |
| 3 |
Фасад: 17 операций (§7 архитектуры), MCP-сервер и CLI |
| 4 |
Журнал расхождений: обнаружение дельт, помечивание stale, архивация при переиндексации |
| 5 |
Ревизии: иммутабельный снимок, reindex --commit, история |
| 6 |
Регламент интеграции агента (AGENTS.md проекта + skill) |
| 7 |
Стенд замеров и снятие метрик M1–M7 |
| 8 |
Документация: руководство запуска, описание ошибок, отчёт о замерах |
2.2 Вне объёма релиза 1 (явно)
- Языки кроме PHP (Python, JS/TS, C#, PowerShell, SQL-логика) — релиз 2.
- Поиск уязвимостей и taint-анализ как самостоятельная цель.
- Полноценный автономный «переписыватель кода»: RAGRAF отвечает, правки делает агент.
- Веб-интерфейс, многопользовательский режим, права доступа, облако.
- Ветвление ревизий (несколько активных индексов одновременно).
- Хранение индекса вне рабочего каталога проекта и его автоматическая доставка между машинами.
3. Терминология
| Термин |
Значение |
| Корпус |
набор файлов проекта, подлежащих индексации, по правилам config/project.yaml |
INDEX_REV |
именованная иммутабельная ревизия индекса (rev-0007) |
| Факт |
узел или ребро графа, содержащий evidence (path:line) и confidence |
stated / derived |
ребро, доказанное анализатором / выведенное эвристикой |
| Ledger |
append-only журнал различий между индексом и кодом |
stale |
факт, затронутый записью ledger и потому не гарантированно актуальный |
| Деградация |
режим ревизии без CPG (capability: degraded) |
| Замер |
процедура из ACCEPTANCE.md, дающая число |
4. Функциональные требования
Формат: требование — критерий приёмки — как проверяется. Проверка ссылается на ACCEPTANCE.md (§ протоколы) или на прямой тест.
4.1 Индексация
| ID |
Требование |
Критерий приёмки |
Проверка |
| ФТ-1 |
Индексация запускается по явной команде ragraf index --project <cfg> и создаёт новую INDEX_REV |
Команда завершается кодом 0, создаёт index/rev.json, graph.sqlite, lexvec.sqlite и запись в rev_history |
Тест M1-T1 |
| ФТ-2 |
Разбор PHP: узлы namespace/class/trait/interface/function/method/property/constant с точными path, start_line, end_line |
Для 100 намеренно выбранных символов границы строк совпадают с файлом (проверка скриптом) |
Тест M1-T2 |
| ФТ-3 |
Символьный слой: определения, ссылки, реализации |
Для 30 вручную размеченных символов множество мест использования не содержит ложных и не теряет реальных |
Тест M2-T1 |
| ФТ-4 |
Ребро вызовов: calls (точные) и calls_heuristic (динамические) раздельно |
Ни одно ребро не имеет kind без provenance; динамические вызовы не попадают в calls |
Тест M2-T2 |
| ФТ-5 |
Схема БД: таблицы, колонки, типы, ключи, FK — из information_schema и миграций |
Все таблицы схемы присутствуют; для каждой указан source |
Тест M2-T3 |
| ФТ-6 |
Связь кода с таблицами: queries, references_table из SQL-литералов |
Для 20 вручную отобранных SQL-литералов найдены таблицы; SELECT * не порождает выдуманных колонок |
Тест M2-T4 |
| ФТ-7 |
Точки входа: web_route, http_endpoint, cli_command, cron_job |
Для 15 вручную размеченных точек входа найдены обработчики |
Тест M2-T5 |
| ФТ-8 |
Документация индексируется: doc, doc_section + ребро documented_by |
Markdown-файлы корпуса присутствуют; связь поставлена там, где документ называет символ или путь |
Тест M2-T6 |
| ФТ-9 |
Текст и структура разделены: комментарии/докблоки/README/коммиты — в text_chunk, не в структурных фактах |
Ни один структурный факт не содержит текста комментария в поле props/name |
Тест M2-T7 |
| ФТ-10 |
Каждый факт несёт провенанс: evidence_path, evidence_line, confidence, sources |
Выборка 1000 случайных рёбер: у 100% заполнены evidence_path и confidence; у stated — 1.0 |
Тест M2-T8 |
| ФТ-11 |
Отчёт покрытия: разобрано/частично/не разобрано, число рёбер по видам, конфликты, дубли |
ragraf status печатает покрытие; сумма file = числу файлов корпуса (неразобранные не исчезают) |
Тест M1-T3 |
| ФТ-12 |
Режим деградации: при недоступности CPG индексация завершается, ревизия помечается degraded |
Искусственное отключение Joern → код выхода 0, joern_used = 0, slice/flow отказывают с причиной |
Тест M3-T1 |
| ФТ-13 |
Детерминированность: две сборки одного корпуса дают совпадающие идентификаторы |
corpus_hash, число узлов/рёбер и множества edge_uid совпадают |
Тест M1-T4 |
4.2 Фасад
| ID |
Требование |
Критерий приёмки |
Проверка |
| ФТ-14 |
Реализованы 17 операций §7 архитектуры с описанными входами/выходами |
Для каждой операции есть тест на валидном входе и на пустом результате |
Тест M4-T1 |
| ФТ-15 |
Агенту не доступен свободный язык запросов к графу |
Ни одна операция не принимает текст запроса; попытка передать Cypher/CPGQL отвергается с кодом ошибки |
Тест M4-T2 |
| ФТ-16 |
Каждый ответ несёт конверт: index_rev, capability, drift, provenance, limits, stale_warnings |
Ни один ответ не приходит без этих полей |
Тест M4-T3 |
| ФТ-17 |
Ответы содержат path:line для каждого факта |
Выборка 200 фактов из ответов: 100% имеют валидный path и строку в её диапазоне |
Замер M6 |
| ФТ-18 |
impact разделяет доказанные и эвристические связи |
В ответе два блока; mode: hard не содержит derived |
Тест M4-T4 |
| ФТ-19 |
slice возвращает структурный срез (узлы+рёбра+строки) без тел функций |
В ответе нет строк кода; тела доступны только через code |
Тест M4-T5 |
| ФТ-20 |
repo_map укладывается в заданный бюджет токенов |
При budget_tokens = 2000 фактический размер ≤ бюджета (счёт tiktoken) |
Замер M4 |
| ФТ-21 |
Возможность ответить «не найдено» |
При отсутствии релевантного результата операция возвращает явный флаг и предлагает live_read вместо приблизительной выдачи |
Тест M4-T6 |
| ФТ-22 |
Операции доступны как MCP-инструменты и как CLI |
Имена инструментов совпадают с именами операций; CLI отдаёт тот же JSON |
Тест M4-T7 |
| ФТ-23 |
Формулировки ответов нейтральны: без оценок, без «ранее установлено» |
В выдаче нет оценочных конструкций; прошлые выводы не подаются как факт |
Ревизия вывода на 50 ответах |
4.3 Журнал расхождений и ревизий
| ID |
Требование |
Критерий приёмки |
Проверка |
| ФТ-24 |
Индекс неизменен в пределах ревизии: во время доработки операции чтения не меняют graph.sqlite/lexvec.sqlite |
После 200 операций чтения хэши файлов хранилищ не изменились |
Тест M5-T1 |
| ФТ-25 |
Обнаружение дельт доступно 5 способами: hook:session-start, compare, git-diff, db-schema-diff, manual |
Каждый способ создаёт корректную запись drift_entry |
Тест M5-T2 |
| ФТ-26 |
Ledger append-only: нет операций удаления/обновления записей |
Попытка удаления записи невозможна через фасад; схема не содержит DELETE-путей |
Тест M5-T3 |
| ФТ-27 |
Дедупликация: повторное обнаружение той же дельты не задваивает журнал |
Двойной запуск compare без правок → число записей не изменилось |
Тест M5-T4 |
| ФТ-28 |
Помечивание stale: при непустом ledger ответы по затронутым путям несут stale_warnings |
Для 20 затронутых путей все ответы, их касающиеся, имеют предупреждение |
Замер M5 |
| ФТ-29 |
Отдельный вид записи slice_boundary при выносе кода в функцию |
Правка extract-method даёт запись slice_boundary и modify |
Тест M5-T5 |
| ФТ-30 |
Обнаружение изменения схемы БД: появившаяся/удалённая колонка → запись schema_change |
Миграция на стенде создаёт запись с именем таблицы и колонки |
Тест M5-T6 |
| ФТ-31 |
live_read показывает, чем файл отличается от индекса |
Фрагменты, изменённые после ревизии, выделены; provenance: mixed |
Тест M5-T7 |
| ФТ-32 |
reindex --commit создаёт новую ревизию, архивирует ledger, очищает stale_edge |
После команды: новая INDEX_REV, ledger пуст, файл архива создан |
Тест M5-T8 |
| ФТ-33 |
Архив переиндексации — человекочитаемый отчёт «что изменилось в знаниях» |
Отчёт содержит разделы: изменения по файлам, что устарело, границы срезов |
Тест M5-T9 |
| ФТ-34 |
История ревизий сохраняется: rev_history и drift_archive не удаляются при ротации |
После 5 переиндексаций при retain_revs: 3 — 5 записей в истории, 2 ротированные ревизии удалены из хранилищ |
Тест M5-T10 |
| ФТ-35 |
Запись дельты — только через фасад, не агентом напрямую |
Прямая запись в control.sqlite не является штатным путём; операции записи не выставляются наружу |
Ревизия интерфейса + тест |
| ФТ-36 |
drift_ack не удаляет запись, а дописывает признание |
После drift_ack запись присутствует с заполненным ack |
Тест M5-T11 |
4.4 Конфигурация и безопасность
| ID |
Требование |
Критерий приёмки |
Проверка |
| ФТ-37 |
Конфигурация корпуса: языки, включения, исключения, бюджет чанков, политика ревизий |
Конфиг читается, валидируется, влияет на отбор файлов |
Тест M1-T5 |
| ФТ-38 |
Исключения обязательны и эффективны: вендорные каталоги, .log, _bak, node_modules, артефакты агента |
Ни одного файла из exclude в file |
Тест M1-T6 |
| ФТ-39 |
Секреты не индексируются: значения из secrets_exclude отсутствуют в графе, векторе и логах |
Поиск по образцам значений (тестовые секреты) даёт 0 совпадений во всех трёх хранилищах и логах |
Тест M3-T2 |
| ФТ-40 |
Логи не содержат содержимого файлов из secrets_exclude и значений конфигов |
Ручной просмотр + автоматический поиск образцов |
Тест M3-T2 |
4.5 Функции, зависящие от CPG (доступны из-за разрешённой JVM)
| ID |
Требование |
Критерий приёмки |
Проверка |
| ФТ-41 |
slice по обратному потоку данных для PHP-функции |
Для 10 вручную размеченных случаев срез содержит реальный путь данных и не содержит посторонних узлов |
Тест M2-T9 |
| ФТ-42 |
Замер сжатия: срез против окружения символа |
Для 20 символов вычисляется отношение токенов; результат фиксируется как число, без ссылки на чужие проценты |
Замер M4 |
| ФТ-43 |
flow (поток данных между двумя узлами) — при наличии пути отдаёт доказательства по шагам |
Для 10 размеченных пар путь найден или честно сообщено об отсутствии |
Тест M2-T10 |
5. Нефункциональные требования
| ID |
Требование |
Критерий приёмки |
Проверка |
| НФТ-1 |
Работа без прав администратора; установка только в пользовательские каталоги |
Все команды проходят в неэлевированном сеансе |
Прогон установки и индексации |
| НФТ-2 |
Полная индексация пилота (~162 тыс. строк PHP) ≤ 15 мин |
Замеренное время полной сборки, зафиксировано в отчёте |
Замер M7 |
| НФТ-3 |
Переиндексация после правки — минуты, не часы |
Замер на сценарии «правка 5 файлов» |
Замер M7 |
| НФТ-4 |
Быстрые чтения: symbol/references/callers ≤ 200 мс; impact (глубина 3) ≤ 1 с; search ≤ 1 с; slice ≤ 2 с |
95-й процентиль по 100 запросам каждого вида |
Замер M7 |
| НФТ-5 |
Детерминированность идентификаторов (см. ФТ-13) |
См. ФТ-13 |
Тест M1-T4 |
| НФТ-6 |
Индекс воспроизводим и удаляем: ragraf drop + index восстанавливает состояние |
После пересборки метрики M1–M4 в пределах шума |
Замер M7 |
| НФТ-7 |
Зависимости фиксируются версиями; апгрейд — осознанный шаг |
Файл фиксации зависимостей + команда проверки версий |
Тест M1-T7 |
| НФТ-8 |
Ограничение памяти для CPG настраивается и не роняет машину |
Заданный лимит соблюдается; при нехватке — деградация, не падение |
Тест M3-T1 |
| НФТ-9 |
Код проекта — PowerShell 7.6+/Python 3.13 по правилам AGENTS.md: #Requires, utf8NoBOM, без BOM/CRLF в поставляемых файлах, без WinPS-compat |
Линтер Test-PwshApiVintage.ps1 без ошибок; проверка BOM/CRLF на всех поставляемых файлах |
Тест M6-T1 |
| НФТ-10 |
Артефакты индекса изолированы в <project>/.ragraf/ и не попадают в репозиторий проекта |
Вне каталога .ragraf новых файлов нет; есть шаблон для .gitignore |
Тест M6-T2 |
| НФТ-11 |
Восстановление после сбоя: незавершённая индексация не портит прежнюю ревизию |
Прерывание сборки на середине → прежняя ревизия остаётся рабочей |
Тест M3-T3 |
| НФТ-12 |
Диагностируемость: каждый ответ воспроизводим по index_rev + параметрам |
Повтор того же запроса на той же ревизии даёт те же факты |
Тест M6-T3 |
6. Порядок работ (милстоуны)
| М |
Содержание |
Результат |
Зависит от |
| M1 |
Каркас: структура каталогов, конфиг, схема трёх хранилищ, CLI-скелет, версионирование ревизий |
ragraf index создаёт пустую ревизию; status работает |
— |
| M2 |
Экстракторы PHP: tree-sitter → AST-узлы; SCIP/PHPStan → символы; схема БД; маршруты; документация |
Граф по пилоту без CPG; отчёт покрытия |
M1 |
| M3 |
CPG: подключение Joern + JDK 19, вызовы, CFG/DFG, срезы; режим деградации |
capability: full на пилоте; slice работает |
M2 |
| M4 |
Вектор и лексика: чанкинг по символам, эмбеддинги, FTS5, гибридный search |
search с провенансом; переиспользование эмбеддингов |
M2 |
| M5 |
Фасад: 17 операций, конверт ответа, impact, repo_map, code, live_read |
Полный набор операций + MCP-сервер |
M3, M4 |
| M6 |
Drift ledger: обнаружение дельт, stale, дедупликация, slice_boundary, reindex --commit + архив |
Журнал и переиндексация работают сквозным сценарием |
M5 |
| M7 |
Интеграция агента: AGENTS.md проекта, skill, регламент «сначала индекс» |
Прогон реальной задачи доработки с индексом |
M6 |
| M8 |
Замеры M1–M7 и отчёт: индекс против baseline |
Числа по всем метрикам, выводы, список узких мест |
M7 |
Правило каждого милстоуна: отдельный прогон на пилотной ревизии из 6–10 файлов (P7 архитектуры), затем на полном корпусе; результаты фиксируются в docs/03_implementation/.
7. Критерии приёмки релиза 1
| № |
Критерий |
Порог |
| К1 |
Все ФТ реализованы и прошли тесты |
43/43 |
| К2 |
Все НФТ выполнены или явно переоформлены с обоснованием |
12/12 либо письменное отступление |
| К3 |
Полная индексация пилота укладывается в НФТ-2 |
≤ 15 мин |
| К4 |
Каждый факт в ответе имеет провенанс |
100% (ФТ-10, ФТ-17) |
| К5 |
Сквозной сценарий работает: индексация → доработка с ledger → переиндексация → архив |
Пройден на пилоте |
| К6 |
Секреты не попали в индекс и логи |
0 совпадений по образцам |
| К7 |
Метрики M1–M7 сняты с протоколом из ACCEPTANCE.md |
Все семь |
| К8 |
Ни один вывод отчёта не опирается на устаревший факт без пометки |
Проверка выборки 50 ответов |
| К9 |
Линтер и проверка кодировок без ошибок |
0 ошибок |
Порог по метрикам (не блокирующий, но обязательный к фиксации):
| Метрика |
Целевое значение |
Обоснование цели |
| M1 — точность навигации с первого запроса |
Замерить baseline и улучшить его; абсолютная цель ставится после первого замера |
По литературе ориентира нет |
| M2 — полнота impact-анализа |
Сравниться с измеренным потолком precision 69% / recall 79% (LCIP, arXiv:1512.07435) на исторических коммитах пилота |
Единственный подтверждённый ориентир |
| M3 — экономия контекста (токены и вызовы на задачу) |
Улучшение относительно baseline; число фиксируется |
Прямого ориентира в литературе нет |
| M4 — сжатие среза |
Замерить; не сравнивать с 68–70% / 90,93% (не подтверждены) |
Свои данные |
M5 — свежесть (доля stale и инцидентов опоры на устаревшее) |
Инцидентов — 0; доля stale — информационная |
Наша метрика: в литературе нет |
| M6 — проверяемость ссылок |
≥ 99% ссылок валидны |
Измеряется автоматически |
| M7 — стоимость обновления |
Полная ≤ 15 мин, инкрементальная ≤ 3 мин |
НФТ-2/3 |
8. Риски и меры
| Риск |
Вероятность |
Влияние |
Мера |
php2cpg даёт неполный CPG на реальном коде |
Средняя |
Потеря slice/flow |
Режим degraded предусмотрен; метрика покрытия вызовов выявит потерю; при провале — slice через SCIP/собственные правила |
| Полная сборка CPG не укладывается в 15 мин |
Средняя |
Ломает НФТ-2 |
Сужение CPG: только изменённые файлы + вызывающие их (решение по замеру) |
| Joern требует больше памяти, чем доступно |
Низкая |
Сбой сборки |
Лимит -Xmx в конфиге; при нехватке — деградация, не падение (НФТ-8) |
| Работа агента оставляет индекс «протухшим» незаметно |
Средняя |
Ложные выводы |
ФТ-24, ФТ-28, ФТ-32: индекс неизменен, факты помечаются, переиндексация обязательна |
| Ложные рёбра от эвристик PHP портят ответы |
Высокая |
Снижение доверия |
Разделение stated/derived (ФТ-4, ФТ-18), калибровка достоверности на 20 примерах |
sqlite-vec меняет API (pre-v1) |
Средняя |
Ломает векторный слой |
Изоляция за модулем; переход на qdrant-client по порогу (замер) |
| Секреты попадают в индекс |
Средняя |
Утечка |
ФТ-39/ФТ-40, список исключений, тест на образцах |
| Рост ledger до нечитаемого объёма |
Средняя |
Вред от накопления (AdaRepair-Mem: «больше памяти ≠ лучше») |
Архивация при реиндексации, дедупликация (ФТ-27), приоритизация по затронутым путям |
| Ротация ревизий удаляет нужную историю |
Низкая |
Потеря данных |
История и архивы не удаляются (ФТ-34) |
9. Поставляемые артефакты
| Артефакт |
Путь |
| Документация концепции и плана |
docs/00_plan/PLAN.md |
| Отчёты исследования |
docs/01_research/*.md |
| Архитектура |
docs/02_architecture/ARCHITECTURE.md |
| ТЗ (этот документ) |
docs/02_architecture/TZ.md |
| Протоколы замеров и приёмки |
docs/02_architecture/ACCEPTANCE.md |
| Отчёты реализации по милстоунам |
docs/03_implementation/*.md |
| Код системы |
src/ |
| Тесты |
tests/ |
| Скрипты сопровождения (PowerShell 7.6+) |
scripts/ |
| Замеры и артефакты замеров |
bench/ |
10. Ограничения и оговорки
- Проценты сжатия из статьи-источника (68–70% и 90,93%) в ТЗ не используются — не подтверждены первоисточником.
- Ссылка на LeanGuard не используется — работа по этому названию не найдена.
- Все опубликованные ориентиры получены на C/C++ и на поиске уязвимостей; наши метрики снимаются на PHP и на задачах доработки, поэтому чужие числа служат только ориентиром порядка величины.
- Без CPG (режим деградации) система честно сообщает об этом и не отдаёт
slice/flow; требования к ним выполнены при capability: full.
- Пороги достоверности требуют калибровки (разброс в литературе — в 3 раза между корпусами); до калибровки используются стартовые значения из архитектуры §5.2.
- Лицензионные ограничения: CodeQL в стек не входит; Joern — Apache-2.0;
sqlite-vec, fastembed, tree-sitter, SCIP-инструменты — MIT/Apache-2.0; версии фиксируются (НФТ-7).