diff --git a/src/app/core/agent/processes/v2/doc_rules/README.md b/src/app/core/agent/processes/v2/doc_rules/README.md
index 7d5472f..db15670 100644
--- a/src/app/core/agent/processes/v2/doc_rules/README.md
+++ b/src/app/core/agent/processes/v2/doc_rules/README.md
@@ -42,7 +42,8 @@
### Sections
- `sections/summary.md`
- `sections/details.md`
-- `sections/api-scenario.md`
+- `sections/tech-use-case.md`
+- `sections/fr.md`
- `sections/api-contract.md`
- `sections/requirements-format.md`
diff --git a/src/app/core/agent/processes/v2/doc_rules/artifact-types/api_method.md b/src/app/core/agent/processes/v2/doc_rules/artifact-types/api_method.md
index bfc6428..3f62fb5 100644
--- a/src/app/core/agent/processes/v2/doc_rules/artifact-types/api_method.md
+++ b/src/app/core/agent/processes/v2/doc_rules/artifact-types/api_method.md
@@ -25,6 +25,7 @@
## Особые правила
+- Во frontmatter обязательно указывать `endpoint` (например: `POST /api/v1/clients/contacts-dgr`).
- Сценарий оформляется как технический use case.
- Функциональные требования маркируются `FR-*`.
- Нефункциональные требования маркируются `NFR-*`.
diff --git a/src/app/core/agent/processes/v2/doc_rules/global/frontmatter.md b/src/app/core/agent/processes/v2/doc_rules/global/frontmatter.md
index 2b4dee5..47b7d1a 100644
--- a/src/app/core/agent/processes/v2/doc_rules/global/frontmatter.md
+++ b/src/app/core/agent/processes/v2/doc_rules/global/frontmatter.md
@@ -47,6 +47,7 @@ system_analytics_refs: []
- `module` — модуль или подсистема.
- `layer` — слой системы.
- `updated_at` хранится в формате `YYYY-MM-DD`.
+- Для документов с `doc_type: api_method` поле `endpoint` является обязательным.
## Связи и навигация
diff --git a/src/app/core/agent/processes/v2/doc_rules/sections/api-scenario.md b/src/app/core/agent/processes/v2/doc_rules/sections/api-scenario.md
deleted file mode 100644
index c9066af..0000000
--- a/src/app/core/agent/processes/v2/doc_rules/sections/api-scenario.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# API Scenario Rules
-
-## Назначение
-
-Этот файл описывает, как оформлять подраздел `### Сценарий` в API-документах.
-
-## Обязательные части
-
-- название
-- предусловия
-- триггер
-- основной сценарий
-- альтернативный сценарий
-- обработка ошибок
-- постусловие
-
-## Правила
-
-- Сценарий должен быть лаконичным.
-- Сценарий должен отражать суть шага.
-- Сложные технические детали надо выносить в `FR-*`.
diff --git a/src/app/core/agent/processes/v2/doc_rules/sections/fr.md b/src/app/core/agent/processes/v2/doc_rules/sections/fr.md
new file mode 100644
index 0000000..f212330
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules/sections/fr.md
@@ -0,0 +1,37 @@
+# Functional requrements rules
+
+## Назначение
+
+Этот файл описывает, как оформлять функциональные требования в подраздел `### Функциональные требования` в документах.
+
+## Правила
+- Функциональное требование (FR) расширяет и дополняет шаги, описанные в сценарии.
+- Функциональное требование (FR) не должно копировать шаг сценария не неся дополнительной информации.
+- Название функционального требования формируется следующим образом - "FR.<номер>. <Название>", где
+ - <номер> идет инкрементально внутри конкретного документа, начинается с 1.
+ - <Название> - кратко описывает что делает требование, суть действий (от 3 до 7 слов)
+
+
+
+## Пример целевого описания сценария
+
+### Примеры названия FR
+ - Получение данных клиента из АС ЕПК
+ - Проверка уровня доступа
+ - Сценарий построения списка связанных предложений
+
+
+ ### Примеры описания FR
+FR.1. Получение данных клиента из АС ЕПК
+1. Сформировать запрос к эндпоинту POST /api/v1/path/to/resourse в АС ЕПК
+ - Заголовки
+ - <тут идет описание заголовков и того как они формируются>
+ - Параметры запроса
+ - <тут идет описание параметров и того как они формируются>
+ - Тело запроса
+ - <тут идет описание структуры объекта JSON или payload в другмо формате так как это задано требованиями>
+
+2. Обработать ответ от АС ЕПК
+ Успешный ответ - <взять из описания вызываеого api критерии успешного ответа >
+ Ничего не найдено - <взять из описания вызываеого api критерии успешного овтета, опционально (если применимо)>
+ Ошибка - <взять из описания вызываеого api критерии успешного ответа >
\ No newline at end of file
diff --git a/src/app/core/agent/processes/v2/doc_rules/sections/tech-use-case.md b/src/app/core/agent/processes/v2/doc_rules/sections/tech-use-case.md
new file mode 100644
index 0000000..572d52f
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules/sections/tech-use-case.md
@@ -0,0 +1,66 @@
+# Scenario Rules
+
+## Назначение
+
+Этот файл описывает, как оформлять технический USE CASE в подраздел `### Сценарий` в документах.
+
+## Обязательные части
+
+- название
+- предусловия
+- триггер
+- основной сценарий
+- альтернативный сценарий
+- обработка ошибок
+- постусловие
+
+## Правила
+- Основной и альтернативные сценарии состоят из шагов.
+
+- Каждый шаг описывается одним предложением не более 15-20 слов, и состоит из двух частей. Первая часть описывает что мы делаем по смыслу, чтобы это было понятно человеку без низкоуровневых технических деталей. Например: авторизует запрос, получает данные клиента, запрашивает справочники. Вторая часть описывает как это реализовано технически - вызывает эндпоинт /path/to/resource в системе <название системы>.
+
+- В описании шага не должно быть длинных технических деталей. Если техничсекую реализацию нельхзя описатьодним предложенеим (в лимите длины описания шага), то необхлодимо это вынести в отдельное функциональное требование FR.<номер>. <Название> и описать в нем технические детали. А в шаге сослаться на это требование через "Описание приведено в FR.<номер>. <Название>"
+
+- Для шагов авторизации обязателен доп шаг с описанием обработки ошибки.
+- Для шагов с интеграцией обязателен доп шаг с описанием обработки ошибки.
+- Для шагов с проверкой условий обязательны доп шаги с описанием переходов по сценарию.
+
+- Название "FR.<номер>. <Название>" формируется следующим образом:
+ - <номер> идет инкрементально внутри конкретного документа, начинается с 1.
+ - <Название> - кратко описывает что делает требование, суть действий.
+
+- Для каждого шага при необходимости нужно прописать логику действий в случае ошибки или если логика шага определяет несколько сценариев разивития при выполнении заданных условий.
+
+- Для шагов, которые описывают интеграцию с другой системой необходимо указать название точки интеграции (название эндпоинта, название топика и так далее) и сделать ссылку на FR.<номер>. <Название> с описанием шагов интеграции - как сформировать запрос/сообщение, как обработать ответ, политику ретраев.
+
+ - Сценарий собирается из тезисов, приведенных системной аналимтике в свободной формулировке
+
+ - Функциональные требования "FR.<номер>. <Название>" не должны дублировать шагов сценария в use case. Они содержат детали, которые вынесены из юзкейса чтобы не делать его тяжелым. Если шаг юзкейса описывается одним предложением в лимите длины, то FR делать не нужно.
+
+ - FR обязательно описывается для шага с интеграцией
+ - FR Не описывается для шага авторизации.
+
+
+
+
+
+
+## Пример целевого описания сценария
+
+### Примеры шагов сценария
+
+Пример 1
+- Авторизует запрос пользователя по наличию у него экшена ролевой модели CI02792632.ContactsDGR.Detail
+ - В случае ошибки - завершить сценарий с кодом UNAUTHORIZED
+
+Пример 2
+- Запрашивает данные клиента - вызывает /api/v1/clients/{client-id}/info
+ - В случае ошибки - завершить сценарий с кодом CLIENT_INFO_REQUEST_FAIL
+
+Пример 3
+- Возвращает ответ в формате <название DTO>
+
+### Примеры названия FR
+ - Получение данных клиента из АС ЕПК
+ - Проверка уровня доступа
+ - Сценарий построения списка связанных предложений
\ No newline at end of file
diff --git a/src/app/core/agent/processes/v2/doc_rules/templates/api_method.template.md b/src/app/core/agent/processes/v2/doc_rules/templates/api_method.template.md
index ba2ac07..3f5a79e 100644
--- a/src/app/core/agent/processes/v2/doc_rules/templates/api_method.template.md
+++ b/src/app/core/agent/processes/v2/doc_rules/templates/api_method.template.md
@@ -8,6 +8,7 @@ module: example_module
layer: application
domain: example_domain
sub_domain: example_subdomain
+endpoint: POST /api/v1/example
related_docs: []
status: draft
updated_at: 2026-03-20
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/README.md b/src/app/core/agent/processes/v2/doc_rules_v2/README.md
new file mode 100644
index 0000000..1a3ed4b
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/README.md
@@ -0,0 +1,27 @@
+# Documentation Rules V2
+
+Этот каталог — новая структура правил для DOC_UPDATE/FROM_FEATURE.
+
+## Цель
+
+Разделить инструкции на 2 независимых блока:
+
+1. `types/` — инструкции по структуре конкретных типов документов (`ui_page`, `api_method`, и т.д.).
+2. `common-elements/` — инструкции по структуре общих элементов страницы (`tech-use-case`, `fr`, и др.).
+
+## Структура каталога
+
+- `documentation-rules.md` — верхнеуровневые правила.
+- `global/` — общие правила оформления и frontmatter.
+- `types/` — правила по типам документов (вместо `artifact-types/`).
+- `common-elements/` — правила по общим секциям (вместо `sections/`).
+- `templates/` — шаблоны документов.
+
+## Переключение профиля
+
+Загрузчик поддерживает переключение через env:
+
+- `DOC_RULES_PROFILE=v2` (по умолчанию) — использовать `doc_rules_v2`.
+- `DOC_RULES_PROFILE=legacy` — использовать старый каталог `doc_rules`.
+
+Если `v2` не содержит валидных пар `type + template`, загрузчик автоматически fallback на `doc_rules`.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/api-contract.md b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/api-contract.md
new file mode 100644
index 0000000..fc313ea
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/api-contract.md
@@ -0,0 +1,24 @@
+# API Contract Rules
+
+## Назначение
+
+Этот файл описывает, как оформлять подраздел `## Контракт` в API-документах.
+
+## Что должно быть описано
+
+- входные параметры
+- выходные параметры
+- JSON-структуры запросов и ответов
+- обязательность полей
+- типы полей
+- ограничения
+- описание назначения полей
+- примеры данных
+- auth
+- idempotency
+- timeout
+- ошибки и их HTTP-коды
+
+## Правило качества
+
+Контракт должен быть достаточно формальным, чтобы по нему можно было собрать OpenAPI-спецификацию.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/details.md b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/details.md
new file mode 100644
index 0000000..33ed824
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/details.md
@@ -0,0 +1,13 @@
+# Details Section Rules
+
+## Назначение
+
+Этот файл задает общие правила для секции `## Details`.
+
+## Правила
+
+- `Details` оформляется как `## Details`.
+- Внутри `Details` используются заголовки уровня `###` и ниже.
+- Структура Details зависит от типа документа.
+- В Details не нужно повторно дублировать навигацию и связи, если они уже есть во frontmatter.
+- Интеграции, ошибки и кодовые привязки должны быть выделены в отдельные подразделы, если они существенны для понимания документа.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/fr.md b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/fr.md
new file mode 100644
index 0000000..f212330
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/fr.md
@@ -0,0 +1,37 @@
+# Functional requrements rules
+
+## Назначение
+
+Этот файл описывает, как оформлять функциональные требования в подраздел `### Функциональные требования` в документах.
+
+## Правила
+- Функциональное требование (FR) расширяет и дополняет шаги, описанные в сценарии.
+- Функциональное требование (FR) не должно копировать шаг сценария не неся дополнительной информации.
+- Название функционального требования формируется следующим образом - "FR.<номер>. <Название>", где
+ - <номер> идет инкрементально внутри конкретного документа, начинается с 1.
+ - <Название> - кратко описывает что делает требование, суть действий (от 3 до 7 слов)
+
+
+
+## Пример целевого описания сценария
+
+### Примеры названия FR
+ - Получение данных клиента из АС ЕПК
+ - Проверка уровня доступа
+ - Сценарий построения списка связанных предложений
+
+
+ ### Примеры описания FR
+FR.1. Получение данных клиента из АС ЕПК
+1. Сформировать запрос к эндпоинту POST /api/v1/path/to/resourse в АС ЕПК
+ - Заголовки
+ - <тут идет описание заголовков и того как они формируются>
+ - Параметры запроса
+ - <тут идет описание параметров и того как они формируются>
+ - Тело запроса
+ - <тут идет описание структуры объекта JSON или payload в другмо формате так как это задано требованиями>
+
+2. Обработать ответ от АС ЕПК
+ Успешный ответ - <взять из описания вызываеого api критерии успешного ответа >
+ Ничего не найдено - <взять из описания вызываеого api критерии успешного овтета, опционально (если применимо)>
+ Ошибка - <взять из описания вызываеого api критерии успешного ответа >
\ No newline at end of file
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/requirements-format.md b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/requirements-format.md
new file mode 100644
index 0000000..14eb0c3
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/requirements-format.md
@@ -0,0 +1,16 @@
+# Requirements Format Rules
+
+## Назначение
+
+Этот файл задает формат для функциональных и нефункциональных требований.
+
+## Функциональные требования
+
+- Использовать коды `FR-1`, `FR-2`, `FR-3` и так далее.
+- Каждое требование должно описывать отдельный обязательный аспект поведения.
+- Идентификаторы локальны в пределах одного документа.
+
+## Нефункциональные требования
+
+- Использовать коды `NFR-1`, `NFR-2`, `NFR-3` и так далее.
+- Требования должны описывать характеристики качества, ограничения и эксплуатационные свойства.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/summary.md b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/summary.md
new file mode 100644
index 0000000..7f7fa7b
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/summary.md
@@ -0,0 +1,13 @@
+# Summary Section Rules
+
+## Назначение
+
+Этот файл задает правила для секции `## Summary`.
+
+## Правила
+
+- Summary должен быть коротким explain-слоем быстрого контекста.
+- Summary должен объяснять суть документа без лишних деталей.
+- Summary должен быть пригоден для explain и быстрого чтения.
+- Предпочтительный формат: список ключевых фактов `Purpose`, `Actor`, `Trigger`, `Errors`, `Related ...` и т.д.
+- Для крупных документов допустим более длинный summary, если он остается структурированным.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/tech-use-case.md b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/tech-use-case.md
new file mode 100644
index 0000000..572d52f
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/common-elements/tech-use-case.md
@@ -0,0 +1,66 @@
+# Scenario Rules
+
+## Назначение
+
+Этот файл описывает, как оформлять технический USE CASE в подраздел `### Сценарий` в документах.
+
+## Обязательные части
+
+- название
+- предусловия
+- триггер
+- основной сценарий
+- альтернативный сценарий
+- обработка ошибок
+- постусловие
+
+## Правила
+- Основной и альтернативные сценарии состоят из шагов.
+
+- Каждый шаг описывается одним предложением не более 15-20 слов, и состоит из двух частей. Первая часть описывает что мы делаем по смыслу, чтобы это было понятно человеку без низкоуровневых технических деталей. Например: авторизует запрос, получает данные клиента, запрашивает справочники. Вторая часть описывает как это реализовано технически - вызывает эндпоинт /path/to/resource в системе <название системы>.
+
+- В описании шага не должно быть длинных технических деталей. Если техничсекую реализацию нельхзя описатьодним предложенеим (в лимите длины описания шага), то необхлодимо это вынести в отдельное функциональное требование FR.<номер>. <Название> и описать в нем технические детали. А в шаге сослаться на это требование через "Описание приведено в FR.<номер>. <Название>"
+
+- Для шагов авторизации обязателен доп шаг с описанием обработки ошибки.
+- Для шагов с интеграцией обязателен доп шаг с описанием обработки ошибки.
+- Для шагов с проверкой условий обязательны доп шаги с описанием переходов по сценарию.
+
+- Название "FR.<номер>. <Название>" формируется следующим образом:
+ - <номер> идет инкрементально внутри конкретного документа, начинается с 1.
+ - <Название> - кратко описывает что делает требование, суть действий.
+
+- Для каждого шага при необходимости нужно прописать логику действий в случае ошибки или если логика шага определяет несколько сценариев разивития при выполнении заданных условий.
+
+- Для шагов, которые описывают интеграцию с другой системой необходимо указать название точки интеграции (название эндпоинта, название топика и так далее) и сделать ссылку на FR.<номер>. <Название> с описанием шагов интеграции - как сформировать запрос/сообщение, как обработать ответ, политику ретраев.
+
+ - Сценарий собирается из тезисов, приведенных системной аналимтике в свободной формулировке
+
+ - Функциональные требования "FR.<номер>. <Название>" не должны дублировать шагов сценария в use case. Они содержат детали, которые вынесены из юзкейса чтобы не делать его тяжелым. Если шаг юзкейса описывается одним предложением в лимите длины, то FR делать не нужно.
+
+ - FR обязательно описывается для шага с интеграцией
+ - FR Не описывается для шага авторизации.
+
+
+
+
+
+
+## Пример целевого описания сценария
+
+### Примеры шагов сценария
+
+Пример 1
+- Авторизует запрос пользователя по наличию у него экшена ролевой модели CI02792632.ContactsDGR.Detail
+ - В случае ошибки - завершить сценарий с кодом UNAUTHORIZED
+
+Пример 2
+- Запрашивает данные клиента - вызывает /api/v1/clients/{client-id}/info
+ - В случае ошибки - завершить сценарий с кодом CLIENT_INFO_REQUEST_FAIL
+
+Пример 3
+- Возвращает ответ в формате <название DTO>
+
+### Примеры названия FR
+ - Получение данных клиента из АС ЕПК
+ - Проверка уровня доступа
+ - Сценарий построения списка связанных предложений
\ No newline at end of file
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/documentation-rules.md b/src/app/core/agent/processes/v2/doc_rules_v2/documentation-rules.md
new file mode 100644
index 0000000..1be0884
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/documentation-rules.md
@@ -0,0 +1,71 @@
+# Documentation Rules
+
+Этот каталог оформляет MVP документации проекта в атомарном формате.
+
+## Базовая структура
+
+- Каждый документ содержит YAML frontmatter.
+- В документе должен быть один `H1`, совпадающий с `title`.
+- Основные разделы оформляются как `## Summary` и `## Details`.
+- Внутри `Details` используются заголовки уровня `###` и ниже.
+- Связи, сущности и навигация описываются во frontmatter через `related_docs`, `links`, `entities`, `parent`, `children`.
+
+## Summary
+
+- Краткий explain-слой быстрого контекста.
+- Должен позволять быстро понять назначение документа без чтения `Details`.
+- Предпочтительный формат: компактный список ключевых фактов без длинных абзацев.
+
+## Details
+
+- Раскрывает полное описание объекта.
+- Структура `Details` зависит от типа документа.
+- Сценарии, ограничения, интеграции, ошибки и кодовые привязки должны быть разнесены по отдельным подразделам.
+
+## API documents
+
+Для `api_method` внутри `## Details` обязательны разделы:
+- `### Описание`
+- `### Сценарий`
+- `### Функциональные требования`
+- `### Нефункциональные требования`
+- `### Контракт`
+
+Если у метода есть интеграции и ошибки, также обязательны:
+- `### Интеграции`
+- `### Ошибки`
+- `### Связанный код`
+- `### История изменений`
+
+### Сценарий
+
+Сценарий оформляется как технический use case и содержит:
+- название
+- предусловия
+- триггер
+- основной сценарий
+- альтернативный сценарий
+- обработку ошибок
+- постусловие
+
+### Требования
+
+- Функциональные требования маркируются как `FR-1`, `FR-2`, ...
+- Нефункциональные требования маркируются как `NFR-1`, `NFR-2`, ...
+- Идентификаторы требований локальны в рамках одного документа.
+
+### Контракт
+
+Контракт должен быть пригоден для последующей сборки OpenAPI-спецификации и включать:
+- входные параметры
+- выходные параметры
+- структуру JSON-сообщений
+- обязательность полей
+- типы и ограничения
+- описание полей
+- правила заполнения
+- примеры данных
+- auth
+- idempotency
+- timeout
+- ошибки и их HTTP-коды
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/global/documentation-system.md b/src/app/core/agent/processes/v2/doc_rules_v2/global/documentation-system.md
new file mode 100644
index 0000000..656b569
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/global/documentation-system.md
@@ -0,0 +1,38 @@
+# Documentation System
+
+## Назначение
+
+Этот файл задает общую модель документации проекта.
+
+## Базовая модель
+
+Каждый документ должен состоять из двух слоев:
+- YAML frontmatter
+- контент
+
+Контент всегда состоит из двух обязательных разделов:
+- `## Summary`
+- `## Details`
+
+Над ними должен быть один заголовок `#
`, совпадающий со значением `title` во frontmatter.
+
+## Принципы
+
+- Документы должны быть атомарными.
+- Один документ описывает одну тему.
+- Вместо дублирования между документами используются явные ссылки.
+- Связи и навигация должны быть формализованы.
+- Документы должны быть пригодны для чтения человеком и для RAG.
+- Документы должны быть пригодны для частичного обновления без деградации структуры.
+
+## Типы документов
+
+На уровне проекта поддерживаются типы:
+- `api_method`
+- `logic_block`
+- `architecture_overview`
+- `domain_entity`
+- `ui_page`
+- `integration_doc`
+- `index_page`
+- `glossary_item`
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/global/frontmatter.md b/src/app/core/agent/processes/v2/doc_rules_v2/global/frontmatter.md
new file mode 100644
index 0000000..2b4dee5
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/global/frontmatter.md
@@ -0,0 +1,67 @@
+# Frontmatter Rules
+
+## Назначение
+
+Этот файл описывает единый контракт YAML frontmatter для всех документов.
+
+## Обязательные поля
+
+```yaml
+id: string
+title: string
+doc_type: string
+domain: string
+sub_domain: string
+related_docs: []
+status: string
+```
+
+## Поля совместимости и рекомендуемые поля
+
+```yaml
+type: string
+name: string
+module: string
+layer: string
+updated_at: YYYY-MM-DD
+tags: []
+entities: []
+parent: string | null
+children: []
+links: {}
+source_of_truth: string
+related_code: []
+system_analytics_refs: []
+```
+
+## Правила
+
+- `id` должен быть стабильным и уникальным в пределах документации проекта.
+- `title` — человекочитаемый заголовок.
+- `doc_type` — канонический тип документа.
+- `domain` и `sub_domain` определяют бизнес-контекст документа.
+- `related_docs` хранит явные связи с другими markdown-документами.
+- `status` хранит жизненный цикл документа: например `draft`, `approved`, `active`.
+- `type` допустимо дублировать как alias для tooling-совместимости с индексаторами.
+- `name` — короткое системное имя документа.
+- `module` — модуль или подсистема.
+- `layer` — слой системы.
+- `updated_at` хранится в формате `YYYY-MM-DD`.
+
+## Связи и навигация
+
+- `entities` описывает сущности, связанные с документом.
+- `parent` и `children` описывают иерархию.
+- `links` описывает typed graph связей между документами, кодом и интеграциями.
+
+## Формат links
+
+```yaml
+links:
+ called_by:
+ - ext.health_probe
+ uses_logic:
+ - logic.some_flow
+ integrates_with:
+ - ext.some_system
+```
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/global/linking.md b/src/app/core/agent/processes/v2/doc_rules_v2/global/linking.md
new file mode 100644
index 0000000..6e49171
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/global/linking.md
@@ -0,0 +1,33 @@
+# Linking Rules
+
+## Назначение
+
+Этот файл описывает, как связывать документы между собой.
+
+## Иерархия
+
+- `parent` используется для родительского документа.
+- `children` используется для прямых дочерних документов.
+- Иерархия должна быть осмысленной и стабильной.
+- Для общей точки входа допустим `index_page`.
+
+## Графовые связи
+
+Для `related_docs` используются ссылки на соседние документы.
+
+Для `links` рекомендуется использовать typed-ключи:
+- `called_by`
+- `uses_logic`
+- `reads_db`
+- `writes_db`
+- `integrates_with`
+- `used_by`
+- `exposes_api`
+- `uses_entities`
+
+## Правила использования
+
+- Если документ логически входит в другой, использовать `parent`/`children`.
+- Если связь нужна для навигации между равноправными документами, дублировать ее в `related_docs`.
+- Если связь отражает поведение, интеграции или переиспользование, фиксировать ее в `links`.
+- Детальное описание интеграций хранить в body документа, а не только во frontmatter.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/global/naming.md b/src/app/core/agent/processes/v2/doc_rules_v2/global/naming.md
new file mode 100644
index 0000000..c722416
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/global/naming.md
@@ -0,0 +1,24 @@
+# Naming Rules
+
+## Назначение
+
+Этот файл описывает правила именования документов, файлов и идентификаторов.
+
+## Правила для файлов
+
+- Имена файлов должны быть в kebab-case.
+- Имя файла должно отражать одну тему.
+- Для шаблонов использовать суффикс `.template.md`.
+
+## Правила для id
+
+- `id` строится в формате `.`.
+- Примеры:
+ - `api.send_message_endpoint`
+ - `logic.telegram_notification_loop`
+ - `architecture.telegram_notify_app`
+
+## Правила для title
+
+- `title` должен быть кратким и человекочитаемым.
+- В `title` допускаются пробелы и естественный язык.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/global/writing-style.md b/src/app/core/agent/processes/v2/doc_rules_v2/global/writing-style.md
new file mode 100644
index 0000000..6c1caec
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/global/writing-style.md
@@ -0,0 +1,19 @@
+# Writing Style
+
+## Назначение
+
+Этот файл задает правила стиля для текстового наполнения документации.
+
+## Правила стиля
+
+- Текст должен быть лаконичным.
+- Формулировки должны быть точными и техническими.
+- Summary должен быть кратким explain-слоем.
+- Details должен раскрывать суть без лишней воды.
+- Нежелательно смешивать несколько тем в одном документе.
+- Если детали относятся к другому артефакту, их нужно выносить в отдельный документ.
+
+## Язык
+
+- Основной язык документации — русский.
+- Технические термины, названия классов, API, RAG, OpenAPI, runtime и другие устоявшиеся identifiers можно оставлять на английском.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/templates/api_method.template.md b/src/app/core/agent/processes/v2/doc_rules_v2/templates/api_method.template.md
new file mode 100644
index 0000000..ba2ac07
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/templates/api_method.template.md
@@ -0,0 +1,84 @@
+---
+id: api.example_method
+type: api_method
+doc_type: api_method
+name: example_method
+title: HTTP API /example
+module: example_module
+layer: application
+domain: example_domain
+sub_domain: example_subdomain
+related_docs: []
+status: draft
+updated_at: 2026-03-20
+source_of_truth: code
+parent: null
+children: []
+tags: []
+entities: []
+links: {}
+---
+
+# HTTP API /example
+
+## Summary
+
+Краткое описание метода.
+
+## Details
+
+## Описание
+
+Короткое описание сути метода.
+
+## Сценарий
+
+**Название:**
+
+**Предусловия:**
+-
+
+**Триггер:**
+-
+
+**Основной сценарий:**
+1.
+
+**Альтернативный сценарий:**
+1.
+
+**Обработка ошибок:**
+1.
+
+**Постусловие:**
+-
+
+## Функциональные требования
+
+**FR-1.**
+
+## Нефункциональные требования
+
+**NFR-1.**
+
+## Контракт
+
+### Входные параметры
+
+| Параметр | Где передается | Тип | Обязательность | Ограничения | Описание | Пример |
+|---|---|---|---|---|---|---|
+| | | | | | | |
+
+### Выходные параметры
+
+| Поле | Тип | Обязательность | Ограничения | Описание | Заполнение | Пример |
+|---|---|---|---|---|---|---|
+| | | | | | | |
+
+### Интеграции
+
+### Ошибки
+
+### Связанный код
+
+### История изменений
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/templates/architecture_overview.template.md b/src/app/core/agent/processes/v2/doc_rules_v2/templates/architecture_overview.template.md
new file mode 100644
index 0000000..21c7319
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/templates/architecture_overview.template.md
@@ -0,0 +1,48 @@
+---
+id: architecture.example_system
+type: architecture_overview
+doc_type: architecture_overview
+name: example_system
+title: Обзор архитектуры Example System
+module: example_module
+layer: system
+domain: example_domain
+sub_domain: example_subdomain
+related_docs: []
+status: draft
+updated_at: 2026-03-20
+source_of_truth: mixed
+parent: null
+children: []
+tags: []
+entities: []
+links: {}
+---
+
+# Обзор архитектуры Example System
+
+## Summary
+
+Краткое описание архитектуры.
+
+## Details
+
+### Описание
+
+### Контекст
+
+### Границы системы
+
+### Компоненты
+
+### Интеграционные сценарии
+
+### Интеграции
+
+### Ограничения
+
+### Связанный код
+
+### Связанные документы
+
+### История изменений
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/templates/domain_entity.template.md b/src/app/core/agent/processes/v2/doc_rules_v2/templates/domain_entity.template.md
new file mode 100644
index 0000000..f8fd65e
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/templates/domain_entity.template.md
@@ -0,0 +1,48 @@
+---
+id: domain.example_entity
+type: domain_entity
+doc_type: domain_entity
+name: example_entity
+title: Пример доменной сущности
+module: example_module
+layer: domain
+domain: example_domain
+sub_domain: example_subdomain
+related_docs: []
+status: draft
+updated_at: 2026-03-20
+source_of_truth: code
+parent: null
+children: []
+tags: []
+entities: []
+links: {}
+---
+
+# Пример доменной сущности
+
+## Summary
+
+Краткое описание сущности.
+
+## Details
+
+### Описание
+
+### Модель данных
+
+### Состояния и инварианты
+
+### Технический use case
+
+### Функциональные требования
+
+### Нефункциональные требования
+
+### Интеграции
+
+### Связанный код
+
+### Связанные документы
+
+### История изменений
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/templates/logic_block.template.md b/src/app/core/agent/processes/v2/doc_rules_v2/templates/logic_block.template.md
new file mode 100644
index 0000000..36e1d5d
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/templates/logic_block.template.md
@@ -0,0 +1,50 @@
+---
+id: logic.example_block
+type: logic_block
+doc_type: logic_block
+name: example_block
+title: Пример блока логики
+module: example_module
+layer: application
+domain: example_domain
+sub_domain: example_subdomain
+related_docs: []
+status: draft
+updated_at: 2026-03-20
+source_of_truth: code
+parent: null
+children: []
+tags: []
+entities: []
+links: {}
+---
+
+# Пример блока логики
+
+## Summary
+
+Краткое описание блока логики.
+
+## Details
+
+### Описание
+
+### Контекст
+
+### Технический use case
+
+### Функциональные требования
+
+### Нефункциональные требования
+
+### Интеграции
+
+### Ограничения и условия вызова
+
+### Ошибки и деградации
+
+### Связанные API
+
+### Связанный код
+
+### История изменений
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/templates/ui_page.template.md b/src/app/core/agent/processes/v2/doc_rules_v2/templates/ui_page.template.md
new file mode 100644
index 0000000..5bd32fe
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/templates/ui_page.template.md
@@ -0,0 +1,50 @@
+---
+id: ui.example_page
+type: ui_page
+doc_type: ui_page
+name: example_page
+title: Пример UI-страницы
+module: example_module
+layer: presentation
+domain: example_domain
+sub_domain: example_subdomain
+related_docs: []
+status: draft
+updated_at: 2026-03-20
+source_of_truth: mixed
+parent: null
+children: []
+tags: []
+entities: []
+links: {}
+---
+
+# Пример UI-страницы
+
+## Summary
+
+Краткое описание страницы и её назначения.
+
+## Details
+
+### Назначение страницы
+
+### Пользовательский сценарий
+
+### Основные блоки интерфейса
+
+### Связанные API и сущности
+
+### Функциональные требования
+
+### Нефункциональные требования
+
+### Ограничения и граничные случаи
+
+### Ошибки и валидации
+
+### Связанный код
+
+### Связанные документы
+
+### История изменений
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/types/api_method.md b/src/app/core/agent/processes/v2/doc_rules_v2/types/api_method.md
new file mode 100644
index 0000000..bfc6428
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/types/api_method.md
@@ -0,0 +1,39 @@
+# API Method Rules
+
+## Назначение
+
+Этот файл задает правила для документов типа `api_method`.
+
+## Когда использовать
+
+Использовать для описания одного HTTP endpoint или одного отдельного API метода.
+
+## Обязательная структура
+
+Документ должен содержать:
+- YAML frontmatter
+- `# `
+- `## Summary`
+- `## Details`
+
+Внутри `## Details` обязательны:
+- `### Описание`
+- `### Сценарий`
+- `### Функциональные требования`
+- `### Нефункциональные требования`
+- `### Контракт`
+
+## Особые правила
+
+- Сценарий оформляется как технический use case.
+- Функциональные требования маркируются `FR-*`.
+- Нефункциональные требования маркируются `NFR-*`.
+- Контракт должен быть пригоден для последующей сборки OpenAPI.
+- Если у метода есть интеграции, они выносятся в `### Интеграции`.
+- Ошибки и HTTP-коды либо описываются в `### Ошибки`, либо ссылаются на централизованный каталог ошибок.
+
+## Ошибки оформления
+
+- Нельзя заменять контракт общим текстовым описанием.
+- Нельзя смешивать несколько endpoint в одном документе.
+- Нельзя хранить связи и навигацию вне frontmatter.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/types/architecture_overview.md b/src/app/core/agent/processes/v2/doc_rules_v2/types/architecture_overview.md
new file mode 100644
index 0000000..e4b146e
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/types/architecture_overview.md
@@ -0,0 +1,31 @@
+# Architecture Overview Rules
+
+## Назначение
+
+Этот файл задает правила для документов типа `architecture_overview`.
+
+## Когда использовать
+
+Использовать как входной документ для понимания системы, модуля или сервиса.
+
+## Обязательная структура
+
+Документ должен содержать:
+- YAML frontmatter
+- `# `
+- `## Summary`
+- `## Details`
+
+## Что описывать в Details
+
+- границы системы
+- основные компоненты
+- ключевые взаимодействия
+- интеграционные сценарии
+- главные ограничения
+- ссылки на дочерние документы по API, logic, domain и другим артефактам
+
+## Ошибки оформления
+
+- Нельзя дублировать в архитектурном обзоре полные API-контракты.
+- Нельзя делать архитектурный обзор единственным документом на всю систему без декомпозиции.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/types/domain_entity.md b/src/app/core/agent/processes/v2/doc_rules_v2/types/domain_entity.md
new file mode 100644
index 0000000..c533266
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/types/domain_entity.md
@@ -0,0 +1,30 @@
+# Domain Entity Rules
+
+## Назначение
+
+Этот файл задает правила для документов типа `domain_entity`.
+
+## Когда использовать
+
+Использовать для описания одной доменной сущности, ее смысла, состояния и роли в системе.
+
+## Обязательная структура
+
+Документ должен содержать:
+- YAML frontmatter
+- `# `
+- `## Summary`
+- `## Details`
+
+## Что описывать в Details
+
+- смысл сущности
+- ключевые атрибуты
+- состояния или инварианты
+- использование сущности в системе
+- интеграции с API, workflow или внешними потребителями, если они важны для понимания модели
+
+## Ошибки оформления
+
+- Нельзя смешивать несколько независимых сущностей в одном документе.
+- Нельзя подменять доменную сущность описанием endpoint или workflow.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/types/integration_doc.md b/src/app/core/agent/processes/v2/doc_rules_v2/types/integration_doc.md
new file mode 100644
index 0000000..7f1fe35
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/types/integration_doc.md
@@ -0,0 +1,25 @@
+# Integration Doc Rules
+
+## Назначение
+
+Этот файл задает правила для документов типа `integration_doc`.
+
+## Когда использовать
+
+Использовать для описания интеграции между системами, сервисами или внешними провайдерами.
+
+## Обязательная структура
+
+Документ должен содержать:
+- YAML frontmatter
+- `# `
+- `## Summary`
+- `## Details`
+
+## Что описывать в Details
+
+- цель интеграции
+- участвующие стороны
+- направление обмена
+- ключевой сценарий взаимодействия
+- ограничения и риски
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/types/logic_block.md b/src/app/core/agent/processes/v2/doc_rules_v2/types/logic_block.md
new file mode 100644
index 0000000..788e4f7
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/types/logic_block.md
@@ -0,0 +1,31 @@
+# Logic Block Rules
+
+## Назначение
+
+Этот файл задает правила для документов типа `logic_block`.
+
+## Когда использовать
+
+Использовать для описания одного законченного блока логики, workflow или процесса.
+
+## Обязательная структура
+
+Документ должен содержать:
+- YAML frontmatter
+- `# `
+- `## Summary`
+- `## Details`
+
+## Что описывать в Details
+
+- назначение логического блока
+- входы и выходы
+- последовательность выполнения
+- интеграции
+- ключевые ограничения
+- состояние и ошибки, если они важны для понимания блока
+
+## Ошибки оформления
+
+- Нельзя описывать весь модуль целиком, если логика распадается на несколько независимых блоков.
+- Нельзя превращать документ в пересказ исходного кода построчно.
diff --git a/src/app/core/agent/processes/v2/doc_rules_v2/types/ui_page.md b/src/app/core/agent/processes/v2/doc_rules_v2/types/ui_page.md
new file mode 100644
index 0000000..9640671
--- /dev/null
+++ b/src/app/core/agent/processes/v2/doc_rules_v2/types/ui_page.md
@@ -0,0 +1,24 @@
+# UI Page Rules
+
+## Назначение
+
+Этот файл задает правила для документов типа `ui_page`.
+
+## Когда использовать
+
+Использовать для описания одной пользовательской страницы, экрана или отдельного UI-сценария.
+
+## Обязательная структура
+
+Документ должен содержать:
+- YAML frontmatter
+- `# `
+- `## Summary`
+- `## Details`
+
+## Что описывать в Details
+
+- назначение страницы
+- пользовательский сценарий
+- основные блоки интерфейса
+- связанные API и сущности
diff --git a/src/app/core/agent/processes/v2/workflows/doc_update_from_feature/doc_rules_pipeline/loader.py b/src/app/core/agent/processes/v2/workflows/doc_update_from_feature/doc_rules_pipeline/loader.py
index 20dc788..857572d 100644
--- a/src/app/core/agent/processes/v2/workflows/doc_update_from_feature/doc_rules_pipeline/loader.py
+++ b/src/app/core/agent/processes/v2/workflows/doc_update_from_feature/doc_rules_pipeline/loader.py
@@ -1,5 +1,6 @@
from __future__ import annotations
+import os
from pathlib import Path
from app.core.agent.processes.v2.workflows.doc_update_from_feature.doc_rules_pipeline.models import DocRulesBundle
@@ -7,20 +8,45 @@ from app.core.agent.processes.v2.workflows.doc_update_from_feature.doc_rules_pip
class DocRulesLoader:
def __init__(self, root: Path | None = None) -> None:
- base = root or (Path(__file__).resolve().parents[3] / "doc_rules")
- self._root = base
+ base_dir = Path(__file__).resolve().parents[3]
+ if root is not None:
+ self._root = root
+ return
+ profile = os.getenv("DOC_RULES_PROFILE", "legacy").strip().lower()
+ if profile == "legacy":
+ self._root = base_dir / "doc_rules"
+ return
+ self._root = base_dir / "doc_rules_v2"
@property
def root(self) -> Path:
return self._root
def load(self) -> DocRulesBundle:
+ bundle = self._load_from_root(self._root)
+ if bundle.supported_doc_types:
+ return bundle
+ # Safe fallback for quick rollback or incomplete v2 setup.
+ fallback = self._root.parent / "doc_rules"
+ if fallback != self._root:
+ fallback_bundle = self._load_from_root(fallback)
+ if fallback_bundle.supported_doc_types:
+ return fallback_bundle
+ return bundle
+
+ def _load_from_root(self, root: Path) -> DocRulesBundle:
+ artifact_rules = self._read_folder(root / "artifact-types", suffix=".md")
+ if not artifact_rules:
+ artifact_rules = self._read_folder(root / "types", suffix=".md")
+ sections = self._read_folder(root / "sections", suffix=".md")
+ if not sections:
+ sections = self._read_folder(root / "common-elements", suffix=".md")
return DocRulesBundle(
- documentation_rules=self._read_file(self._root / "documentation-rules.md"),
- global_rules=self._read_folder(self._root / "global", suffix=".md"),
- artifact_rules=self._read_folder(self._root / "artifact-types", suffix=".md"),
- templates=self._read_templates(self._root / "templates"),
- sections=self._read_folder(self._root / "sections", suffix=".md"),
+ documentation_rules=self._read_file(root / "documentation-rules.md"),
+ global_rules=self._read_folder(root / "global", suffix=".md"),
+ artifact_rules=artifact_rules,
+ templates=self._read_templates(root / "templates"),
+ sections=sections,
)
def _read_templates(self, folder: Path) -> dict[str, str]:
diff --git a/src/app/core/agent/processes/v2/workflows/doc_update_from_feature/doc_rules_pipeline/selector.py b/src/app/core/agent/processes/v2/workflows/doc_update_from_feature/doc_rules_pipeline/selector.py
index 44930ab..0a254e1 100644
--- a/src/app/core/agent/processes/v2/workflows/doc_update_from_feature/doc_rules_pipeline/selector.py
+++ b/src/app/core/agent/processes/v2/workflows/doc_update_from_feature/doc_rules_pipeline/selector.py
@@ -5,14 +5,14 @@ from app.core.agent.processes.v2.workflows.doc_update_from_feature.doc_rules_pip
class DocRulesSelector:
- _DEFAULT_SECTIONS: tuple[str, ...] = ("summary", "details", "requirements-format")
+ _DEFAULT_SECTIONS: tuple[str, ...] = ("summary", "details", "tech-use-case", "fr", "requirements-format")
_SECTIONS_BY_TYPE: dict[str, tuple[str, ...]] = {
- "api_method": ("summary", "details", "api-scenario", "api-contract", "requirements-format"),
- "integration_doc": ("summary", "details", "api-contract", "requirements-format"),
- "ui_page": ("summary", "details", "requirements-format"),
- "logic_block": ("summary", "details", "requirements-format"),
- "architecture_overview": ("summary", "details", "requirements-format"),
- "domain_entity": ("summary", "details", "requirements-format"),
+ "api_method": ("summary", "details", "tech-use-case", "fr", "api-contract", "requirements-format"),
+ "integration_doc": ("summary", "details", "tech-use-case", "fr", "api-contract", "requirements-format"),
+ "ui_page": ("summary", "details", "tech-use-case", "fr", "requirements-format"),
+ "logic_block": ("summary", "details", "tech-use-case", "fr", "requirements-format"),
+ "architecture_overview": ("summary", "details", "tech-use-case", "fr", "requirements-format"),
+ "domain_entity": ("summary", "details", "tech-use-case", "fr", "requirements-format"),
}
def select(self, bundle: DocRulesBundle, doc_type: str) -> SelectedDocRules | None:
diff --git a/src/app/core/rag/indexing/job_store.py b/src/app/core/rag/indexing/job_store.py
index 8aeeaff..0f99269 100644
--- a/src/app/core/rag/indexing/job_store.py
+++ b/src/app/core/rag/indexing/job_store.py
@@ -61,8 +61,8 @@ class IndexJobStore:
cache_miss_files=row.cache_miss_files,
error=payload,
)
- stale_timeout_sec = max(1, int(os.getenv("RAG_RUNNING_STALE_TIMEOUT_SEC", "8")))
- if job.status == IndexJobStatus.RUNNING and self._is_stale(row.updated_at, stale_timeout_sec):
+ stale_timeout_sec = int(os.getenv("RAG_RUNNING_STALE_TIMEOUT_SEC", "0"))
+ if stale_timeout_sec > 0 and job.status == IndexJobStatus.RUNNING and self._is_stale(row.updated_at, stale_timeout_sec):
payload = ErrorPayload(
code="index_stalled",
desc="Indexing stalled in running state; likely blocked network call during embedding/auth.",
diff --git a/src/app/core/rag/indexing/orchestrator.py b/src/app/core/rag/indexing/orchestrator.py
index 28f0744..98ea332 100644
--- a/src/app/core/rag/indexing/orchestrator.py
+++ b/src/app/core/rag/indexing/orchestrator.py
@@ -117,7 +117,7 @@ class IndexingOrchestrator:
},
)
- timeout_sec = max(1, int(os.getenv("RAG_INDEX_JOB_TIMEOUT_SEC", "15")))
+ timeout_sec = max(1, int(os.getenv("RAG_INDEX_JOB_TIMEOUT_SEC", "180")))
indexed, failed, cache_hits, cache_misses = await asyncio.wait_for(
operation(progress_cb),
timeout=timeout_sec,
diff --git a/src/app/core/rag/indexing/service.py b/src/app/core/rag/indexing/service.py
index 70a2513..c4db0b1 100644
--- a/src/app/core/rag/indexing/service.py
+++ b/src/app/core/rag/indexing/service.py
@@ -217,11 +217,23 @@ class RagService:
batch_size = max(1, int(os.getenv("RAG_EMBED_BATCH_SIZE", "16")))
request_timeout_sec = max(1, int(os.getenv("RAG_EMBED_REQUEST_TIMEOUT_SEC", "5")))
request_retries = max(1, int(os.getenv("RAG_EMBED_REQUEST_MAX_RETRIES", "1")))
+ max_chars = max(200, int(os.getenv("RAG_EMBED_MAX_CHARS", "1200")))
+ overlap_chars = max(0, int(os.getenv("RAG_EMBED_OVERLAP_CHARS", "120")))
+ prepared = self._prepare_docs_for_embedding(docs, max_chars=max_chars, overlap_chars=overlap_chars)
+ if len(prepared) != len(docs):
+ LOGGER.warning(
+ "rag embed doc split: path=%s original_docs=%s prepared_docs=%s max_chars=%s overlap_chars=%s",
+ file.get("path", ""),
+ len(docs),
+ len(prepared),
+ max_chars,
+ overlap_chars,
+ )
metadata = self._document_metadata(file, repo_id, blob_sha)
- for doc in docs:
+ for doc in prepared:
doc.metadata.update(metadata)
- for start in range(0, len(docs), batch_size):
- batch = docs[start : start + batch_size]
+ for start in range(0, len(prepared), batch_size):
+ batch = prepared[start : start + batch_size]
LOGGER.warning(
"rag embed batch start: path=%s batch_start=%s batch_size=%s timeout_sec=%s retries=%s",
file.get("path", ""),
@@ -243,7 +255,67 @@ class RagService:
)
for doc, vector in zip(batch, vectors):
doc.embedding = vector
- return docs
+ return prepared
+
+ def _prepare_docs_for_embedding(
+ self,
+ docs: list[RagDocument],
+ *,
+ max_chars: int,
+ overlap_chars: int,
+ ) -> list[RagDocument]:
+ prepared: list[RagDocument] = []
+ for doc in docs:
+ text = str(doc.text or "")
+ if len(text) <= max_chars:
+ prepared.append(doc)
+ continue
+ parts = self._split_text_for_embedding(text, max_chars=max_chars, overlap_chars=overlap_chars)
+ if len(parts) <= 1:
+ prepared.append(doc)
+ continue
+ for idx, part in enumerate(parts, start=1):
+ metadata = dict(doc.metadata)
+ metadata["embed_part_index"] = idx
+ metadata["embed_part_total"] = len(parts)
+ if doc.doc_id:
+ metadata["embed_original_doc_id"] = doc.doc_id
+ prepared.append(
+ RagDocument(
+ layer=doc.layer,
+ source=doc.source,
+ title=f"{doc.title} [part {idx}/{len(parts)}]",
+ text=part,
+ metadata=metadata,
+ links=list(doc.links),
+ span=doc.span,
+ doc_id=f"{doc.doc_id}:part:{idx}" if doc.doc_id else None,
+ lang=doc.lang,
+ )
+ )
+ return prepared
+
+ def _split_text_for_embedding(self, text: str, *, max_chars: int, overlap_chars: int) -> list[str]:
+ normalized = text.replace("\r\n", "\n").replace("\r", "\n")
+ parts: list[str] = []
+ start = 0
+ length = len(normalized)
+ while start < length:
+ hard_end = min(length, start + max_chars)
+ end = hard_end
+ if hard_end < length:
+ soft_start = min(length, start + max_chars // 2)
+ pivot = normalized.rfind("\n", soft_start, hard_end)
+ if pivot > start:
+ end = pivot + 1
+ chunk = normalized[start:end].strip()
+ if chunk:
+ parts.append(chunk)
+ if end >= length:
+ break
+ next_start = max(start + 1, end - overlap_chars)
+ start = next_start
+ return parts or [normalized]
def _with_file_metadata(self, docs: list[RagDocument], file: dict, repo_id: str, blob_sha: str) -> list[RagDocument]:
metadata = self._document_metadata(file, repo_id, blob_sha)
diff --git a/src/app/core/shared/gigachat/token_provider.py b/src/app/core/shared/gigachat/token_provider.py
index 98df2cf..804ca4e 100644
--- a/src/app/core/shared/gigachat/token_provider.py
+++ b/src/app/core/shared/gigachat/token_provider.py
@@ -35,7 +35,7 @@ class GigaChatTokenProvider:
def _fetch_token(self) -> tuple[str, float]:
if not self._settings.credentials:
raise GigaChatError("GIGACHAT_TOKEN is not set")
- timeout_sec = max(1, int(os.getenv("GIGACHAT_AUTH_TIMEOUT_SEC", "5")))
+ timeout_sec = max(1, int(os.getenv("GIGACHAT_AUTH_TIMEOUT_SEC", "20")))
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json",