Фисирую состояние

This commit is contained in:
2026-04-10 15:15:13 +03:00
parent eab98ca388
commit 02eaab6bce
46 changed files with 13346 additions and 44 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,649 @@
# Runtime Trace: 20260410-105744-60a847d31356
- active_rag_session_id: ff0b0f32-4d2a-48dc-9774-60a847d31356
## request
```json
{
"request_id": "req_584447665c2241b09898744020bd6e94",
"session_id": "as_192902d97ee44c569ab45fd508890092",
"active_rag_session_id": "ff0b0f32-4d2a-48dc-9774-60a847d31356",
"process_version": "v2",
"created_at": "2026-04-10T10:57:44.691409+00:00",
"message": "Какие методы апи есть в проекте?"
}
```
## process.v2
```json
{
"event": "intent_routed",
"routing_domain": "DOCS",
"intent": "DOC_EXPLAIN",
"subintent": "API_EXPOSED",
"normalized_query": "Какие методы апи есть в проекте?",
"target_terms": [],
"anchors": {
"entity_names": [],
"file_names": [],
"endpoint_paths": [],
"target_doc_hints": [],
"matched_aliases": [],
"process_domain": null,
"process_subdomain": null,
"scope_type": "global",
"candidate_domains": [],
"candidate_subdomains": [],
"candidate_entities": [],
"candidate_apis": [],
"signal_types": []
},
"confidence": 0.8500000000000001,
"routing_mode": "llm_default",
"llm_router_used": true,
"reason_short": "Запрос явно касается списка доступных API-методов.",
"rag_session_id": "ff0b0f32-4d2a-48dc-9774-60a847d31356"
}
```
## process.v2.pipeline
```json
{
"event": "router_resolved",
"domain": "DOCS",
"intent": "DOC_EXPLAIN",
"subintent": "API_EXPOSED",
"confidence": 0.8500000000000001
}
```
## process.v2.pipeline
```json
{
"event": "anchors_extracted",
"signal_types": [],
"endpoint_paths": [],
"target_doc_hints": [],
"matched_aliases": [],
"target_terms": []
}
```
## process.v2.pipeline
```json
{
"event": "alias_resolution",
"resolved_aliases": [],
"target_doc_hints": []
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_started",
"workflow_id": "v2.docs_explain.api_exposed"
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "require_rag_session",
"title": "Проверка RAG-сессии"
},
"input": {},
"output": {
"has_rag_session": true
}
}
```
## process.v2.retrieval_policy
```json
{
"event": "retrieval_plan_resolved",
"profile": "api_exposed",
"layers": [
"D1_DOCUMENT_CATALOG"
],
"limit": 400,
"filters": {
"metadata.type": "api_method",
"prefer_path_prefixes": [
"docs/api/",
"docs/endpoints/",
"docs/methods/",
"api/",
"endpoints/",
"methods/"
],
"target_doc_hints": [],
"prefer_like_patterns": [
"%api%",
"%endpoint%",
"%method%",
"%эндпоинт%",
"%метод%"
]
}
}
```
## process.v2.pipeline
```json
{
"event": "retrieval_profile_selected",
"profile": "api_exposed",
"layers": [
"D1_DOCUMENT_CATALOG"
],
"filters": {
"metadata.type": "api_method",
"prefer_path_prefixes": [
"docs/api/",
"docs/endpoints/",
"docs/methods/",
"api/",
"endpoints/",
"methods/"
],
"target_doc_hints": [],
"prefer_like_patterns": [
"%api%",
"%endpoint%",
"%method%",
"%эндпоинт%",
"%метод%"
]
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "resolve_retrieval_plan",
"title": "Выбор retrieval-плана"
},
"input": {},
"output": {
"profile": "api_exposed"
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "fetch_rag_rows",
"title": "Получение строк из RAG"
},
"input": {},
"output": {
"retrieved_row_count": 3
}
}
```
## process.v2.evidence
```json
{
"event": "evidence_assembled",
"mode": "api_exposed",
"endpoint_count": 2,
"endpoints": [
"GET /api/v1/clients/contacts-dgr",
"GET /api/v1/clients/contacts-dgr/{contactid}"
]
}
```
## process.v2.pipeline
```json
{
"event": "evidence_assembled",
"mode": "api_exposed",
"endpoint_count": 2
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "build_api_exposed_evidence",
"title": "Сборка списка API"
},
"input": {},
"output": {
"endpoint_count": 2
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "finalize_api_exposed_answer",
"title": "Формирование ответа со списком API"
},
"input": {},
"output": {
"answer_length": 77
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_trace_flushed",
"workflow_id": "v2.docs_explain.api_exposed",
"steps": [
{
"step_id": "require_rag_session",
"title": "Проверка RAG-сессии",
"input": {},
"output": {
"has_rag_session": true
}
},
{
"step_id": "resolve_retrieval_plan",
"title": "Выбор retrieval-плана",
"input": {},
"output": {
"profile": "api_exposed"
}
},
{
"step_id": "fetch_rag_rows",
"title": "Получение строк из RAG",
"input": {},
"output": {
"retrieved_row_count": 3
}
},
{
"step_id": "build_api_exposed_evidence",
"title": "Сборка списка API",
"input": {},
"output": {
"endpoint_count": 2
}
},
{
"step_id": "finalize_api_exposed_answer",
"title": "Формирование ответа со списком API",
"input": {},
"output": {
"answer_length": 77
}
}
]
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_completed",
"workflow_id": "v2.docs_explain.api_exposed"
}
```
## process.v2.pipeline
```json
{
"event": "answer_generated",
"answer_mode": "deterministic",
"answer_length": 77
}
```
## result
```json
{
"status": "done",
"answer": "GET /api/v1/clients/contacts-dgr\nGET /api/v1/clients/contacts-dgr/{contactid}",
"completed_at": "2026-04-10T10:57:46.741492+00:00"
}
```
## request
```json
{
"request_id": "req_c4c41fc4dfe34104a2d6a23dc9b5a5af",
"session_id": "as_192902d97ee44c569ab45fd508890092",
"active_rag_session_id": "ff0b0f32-4d2a-48dc-9774-60a847d31356",
"process_version": "v2",
"created_at": "2026-04-10T10:57:51.052891+00:00",
"message": "Какие методы апи есть в проекте?"
}
```
## process.v2
```json
{
"event": "intent_routed",
"routing_domain": "DOCS",
"intent": "DOC_EXPLAIN",
"subintent": "API_EXPOSED",
"normalized_query": "Какие методы апи есть в проекте?",
"target_terms": [],
"anchors": {
"entity_names": [],
"file_names": [],
"endpoint_paths": [],
"target_doc_hints": [],
"matched_aliases": [],
"process_domain": null,
"process_subdomain": null,
"scope_type": "global",
"candidate_domains": [],
"candidate_subdomains": [],
"candidate_entities": [],
"candidate_apis": [],
"signal_types": []
},
"confidence": 0.8500000000000001,
"routing_mode": "llm_default",
"llm_router_used": true,
"reason_short": "Запрос явно касается списка доступных API-методов.",
"rag_session_id": "ff0b0f32-4d2a-48dc-9774-60a847d31356"
}
```
## process.v2.pipeline
```json
{
"event": "router_resolved",
"domain": "DOCS",
"intent": "DOC_EXPLAIN",
"subintent": "API_EXPOSED",
"confidence": 0.8500000000000001
}
```
## process.v2.pipeline
```json
{
"event": "anchors_extracted",
"signal_types": [],
"endpoint_paths": [],
"target_doc_hints": [],
"matched_aliases": [],
"target_terms": []
}
```
## process.v2.pipeline
```json
{
"event": "alias_resolution",
"resolved_aliases": [],
"target_doc_hints": []
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_started",
"workflow_id": "v2.docs_explain.api_exposed"
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "require_rag_session",
"title": "Проверка RAG-сессии"
},
"input": {},
"output": {
"has_rag_session": true
}
}
```
## process.v2.retrieval_policy
```json
{
"event": "retrieval_plan_resolved",
"profile": "api_exposed",
"layers": [
"D1_DOCUMENT_CATALOG"
],
"limit": 400,
"filters": {
"metadata.type": "api_method",
"prefer_path_prefixes": [
"docs/api/",
"docs/endpoints/",
"docs/methods/",
"api/",
"endpoints/",
"methods/"
],
"target_doc_hints": [],
"prefer_like_patterns": [
"%api%",
"%endpoint%",
"%method%",
"%эндпоинт%",
"%метод%"
]
}
}
```
## process.v2.pipeline
```json
{
"event": "retrieval_profile_selected",
"profile": "api_exposed",
"layers": [
"D1_DOCUMENT_CATALOG"
],
"filters": {
"metadata.type": "api_method",
"prefer_path_prefixes": [
"docs/api/",
"docs/endpoints/",
"docs/methods/",
"api/",
"endpoints/",
"methods/"
],
"target_doc_hints": [],
"prefer_like_patterns": [
"%api%",
"%endpoint%",
"%method%",
"%эндпоинт%",
"%метод%"
]
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "resolve_retrieval_plan",
"title": "Выбор retrieval-плана"
},
"input": {},
"output": {
"profile": "api_exposed"
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "fetch_rag_rows",
"title": "Получение строк из RAG"
},
"input": {},
"output": {
"retrieved_row_count": 3
}
}
```
## process.v2.evidence
```json
{
"event": "evidence_assembled",
"mode": "api_exposed",
"endpoint_count": 2,
"endpoints": [
"GET /api/v1/clients/contacts-dgr",
"GET /api/v1/clients/contacts-dgr/{contactid}"
]
}
```
## process.v2.pipeline
```json
{
"event": "evidence_assembled",
"mode": "api_exposed",
"endpoint_count": 2
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "build_api_exposed_evidence",
"title": "Сборка списка API"
},
"input": {},
"output": {
"endpoint_count": 2
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "finalize_api_exposed_answer",
"title": "Формирование ответа со списком API"
},
"input": {},
"output": {
"answer_length": 77
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_trace_flushed",
"workflow_id": "v2.docs_explain.api_exposed",
"steps": [
{
"step_id": "require_rag_session",
"title": "Проверка RAG-сессии",
"input": {},
"output": {
"has_rag_session": true
}
},
{
"step_id": "resolve_retrieval_plan",
"title": "Выбор retrieval-плана",
"input": {},
"output": {
"profile": "api_exposed"
}
},
{
"step_id": "fetch_rag_rows",
"title": "Получение строк из RAG",
"input": {},
"output": {
"retrieved_row_count": 3
}
},
{
"step_id": "build_api_exposed_evidence",
"title": "Сборка списка API",
"input": {},
"output": {
"endpoint_count": 2
}
},
{
"step_id": "finalize_api_exposed_answer",
"title": "Формирование ответа со списком API",
"input": {},
"output": {
"answer_length": 77
}
}
]
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_completed",
"workflow_id": "v2.docs_explain.api_exposed"
}
```
## process.v2.pipeline
```json
{
"event": "answer_generated",
"answer_mode": "deterministic",
"answer_length": 77
}
```
## result
```json
{
"status": "done",
"answer": "GET /api/v1/clients/contacts-dgr\nGET /api/v1/clients/contacts-dgr/{contactid}",
"completed_at": "2026-04-10T10:57:52.887621+00:00"
}
```
@@ -0,0 +1,326 @@
# Runtime Trace: 20260410-112313-5e81a827ea36
- active_rag_session_id: eaded8e6-68f4-41b4-a4ac-5e81a827ea36
## request
```json
{
"request_id": "req_4c84fafeba0b4b1eaa7f8a30442b1281",
"session_id": "as_b47105603b6640b28577ab27083b1499",
"active_rag_session_id": "eaded8e6-68f4-41b4-a4ac-5e81a827ea36",
"process_version": "v2",
"created_at": "2026-04-10T11:23:13.818952+00:00",
"message": "какие методы апи есть в проекте?"
}
```
## process.v2
```json
{
"event": "intent_routed",
"routing_domain": "DOCS",
"intent": "DOC_EXPLAIN",
"subintent": "API_EXPOSED",
"normalized_query": "какие методы апи есть в проекте?",
"target_terms": [],
"anchors": {
"entity_names": [],
"file_names": [],
"endpoint_paths": [],
"target_doc_hints": [],
"matched_aliases": [],
"process_domain": null,
"process_subdomain": null,
"scope_type": "global",
"candidate_domains": [],
"candidate_subdomains": [],
"candidate_entities": [],
"candidate_apis": [],
"signal_types": []
},
"confidence": 0.8500000000000001,
"routing_mode": "llm_default",
"llm_router_used": true,
"reason_short": "Запрос явно касается перечисления доступных API-методов проекта.",
"rag_session_id": "eaded8e6-68f4-41b4-a4ac-5e81a827ea36"
}
```
## process.v2.pipeline
```json
{
"event": "router_resolved",
"domain": "DOCS",
"intent": "DOC_EXPLAIN",
"subintent": "API_EXPOSED",
"confidence": 0.8500000000000001
}
```
## process.v2.pipeline
```json
{
"event": "anchors_extracted",
"signal_types": [],
"endpoint_paths": [],
"target_doc_hints": [],
"matched_aliases": [],
"target_terms": []
}
```
## process.v2.pipeline
```json
{
"event": "alias_resolution",
"resolved_aliases": [],
"target_doc_hints": []
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_started",
"workflow_id": "v2.docs_explain.api_exposed"
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "require_rag_session",
"title": "Проверка RAG-сессии"
},
"input": {},
"output": {
"has_rag_session": true
}
}
```
## process.v2.retrieval_policy
```json
{
"event": "retrieval_plan_resolved",
"profile": "api_exposed",
"layers": [
"D1_DOCUMENT_CATALOG"
],
"limit": 400,
"filters": {
"metadata.type": "api_method",
"prefer_path_prefixes": [
"docs/api/",
"docs/endpoints/",
"docs/methods/",
"api/",
"endpoints/",
"methods/"
],
"target_doc_hints": [],
"prefer_like_patterns": [
"%api%",
"%endpoint%",
"%method%",
"%эндпоинт%",
"%метод%"
]
}
}
```
## process.v2.pipeline
```json
{
"event": "retrieval_profile_selected",
"profile": "api_exposed",
"layers": [
"D1_DOCUMENT_CATALOG"
],
"filters": {
"metadata.type": "api_method",
"prefer_path_prefixes": [
"docs/api/",
"docs/endpoints/",
"docs/methods/",
"api/",
"endpoints/",
"methods/"
],
"target_doc_hints": [],
"prefer_like_patterns": [
"%api%",
"%endpoint%",
"%method%",
"%эндпоинт%",
"%метод%"
]
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "resolve_retrieval_plan",
"title": "Выбор retrieval-плана"
},
"input": {},
"output": {
"profile": "api_exposed"
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "fetch_rag_rows",
"title": "Получение строк из RAG"
},
"input": {},
"output": {
"retrieved_row_count": 3
}
}
```
## process.v2.evidence
```json
{
"event": "evidence_assembled",
"mode": "api_exposed",
"endpoint_count": 2,
"endpoints": [
"GET /api/v1/clients/contacts-dgr",
"GET /api/v1/clients/contacts-dgr/{contactid}"
]
}
```
## process.v2.pipeline
```json
{
"event": "evidence_assembled",
"mode": "api_exposed",
"endpoint_count": 2
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "build_api_exposed_evidence",
"title": "Сборка списка API"
},
"input": {},
"output": {
"endpoint_count": 2
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "finalize_api_exposed_answer",
"title": "Формирование ответа со списком API"
},
"input": {},
"output": {
"answer_length": 77
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_trace_flushed",
"workflow_id": "v2.docs_explain.api_exposed",
"steps": [
{
"step_id": "require_rag_session",
"title": "Проверка RAG-сессии",
"input": {},
"output": {
"has_rag_session": true
}
},
{
"step_id": "resolve_retrieval_plan",
"title": "Выбор retrieval-плана",
"input": {},
"output": {
"profile": "api_exposed"
}
},
{
"step_id": "fetch_rag_rows",
"title": "Получение строк из RAG",
"input": {},
"output": {
"retrieved_row_count": 3
}
},
{
"step_id": "build_api_exposed_evidence",
"title": "Сборка списка API",
"input": {},
"output": {
"endpoint_count": 2
}
},
{
"step_id": "finalize_api_exposed_answer",
"title": "Формирование ответа со списком API",
"input": {},
"output": {
"answer_length": 77
}
}
]
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_completed",
"workflow_id": "v2.docs_explain.api_exposed"
}
```
## process.v2.pipeline
```json
{
"event": "answer_generated",
"answer_mode": "deterministic",
"answer_length": 77
}
```
## result
```json
{
"status": "done",
"answer": "GET /api/v1/clients/contacts-dgr\nGET /api/v1/clients/contacts-dgr/{contactid}",
"completed_at": "2026-04-10T11:23:16.382407+00:00"
}
```
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,327 @@
# Runtime Trace: 20260410-121449-0ddfbe598bd9
- active_rag_session_id: 87655eaf-302b-409d-946c-0ddfbe598bd9
## request
```json
{
"request_id": "req_299f353019a2465e84c88909c8903a31",
"session_id": "as_31564e5fcf6e4048b5cb0496f53b8fee",
"active_rag_session_id": "87655eaf-302b-409d-946c-0ddfbe598bd9",
"process_version": "v2",
"created_at": "2026-04-10T12:14:49.260081+00:00",
"message": "Какие методы апи есть в проекте?"
}
```
## process.v2
```json
{
"event": "intent_routed",
"routing_domain": "DOCS",
"intent": "DOC_EXPLAIN",
"subintent": "API_EXPOSED",
"normalized_query": "Какие методы апи есть в проекте?",
"target_terms": [],
"anchors": {
"entity_names": [],
"file_names": [],
"endpoint_paths": [],
"target_doc_hints": [],
"matched_aliases": [],
"process_domain": null,
"process_subdomain": null,
"scope_type": "global",
"candidate_domains": [],
"candidate_subdomains": [],
"candidate_entities": [],
"candidate_apis": [],
"signal_types": []
},
"confidence": 0.8500000000000001,
"routing_mode": "llm_default",
"llm_router_used": true,
"reason_short": "Запрос явно касается списка доступных API-методов.",
"rag_session_id": "87655eaf-302b-409d-946c-0ddfbe598bd9"
}
```
## process.v2.pipeline
```json
{
"event": "router_resolved",
"domain": "DOCS",
"intent": "DOC_EXPLAIN",
"subintent": "API_EXPOSED",
"confidence": 0.8500000000000001
}
```
## process.v2.pipeline
```json
{
"event": "anchors_extracted",
"signal_types": [],
"endpoint_paths": [],
"target_doc_hints": [],
"matched_aliases": [],
"target_terms": []
}
```
## process.v2.pipeline
```json
{
"event": "alias_resolution",
"resolved_aliases": [],
"target_doc_hints": []
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_started",
"workflow_id": "v2.docs_explain.api_exposed"
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "require_rag_session",
"title": "Проверка RAG-сессии"
},
"input": {},
"output": {
"has_rag_session": true
}
}
```
## process.v2.retrieval_policy
```json
{
"event": "retrieval_plan_resolved",
"profile": "api_exposed",
"layers": [
"D1_DOCUMENT_CATALOG"
],
"limit": 400,
"filters": {
"metadata.type": "api_method",
"prefer_path_prefixes": [
"docs/api/",
"docs/endpoints/",
"docs/methods/",
"api/",
"endpoints/",
"methods/"
],
"target_doc_hints": [],
"prefer_like_patterns": [
"%api%",
"%endpoint%",
"%method%",
"%эндпоинт%",
"%метод%"
]
}
}
```
## process.v2.pipeline
```json
{
"event": "retrieval_profile_selected",
"profile": "api_exposed",
"layers": [
"D1_DOCUMENT_CATALOG"
],
"filters": {
"metadata.type": "api_method",
"prefer_path_prefixes": [
"docs/api/",
"docs/endpoints/",
"docs/methods/",
"api/",
"endpoints/",
"methods/"
],
"target_doc_hints": [],
"prefer_like_patterns": [
"%api%",
"%endpoint%",
"%method%",
"%эндпоинт%",
"%метод%"
]
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "resolve_retrieval_plan",
"title": "Выбор retrieval-плана"
},
"input": {},
"output": {
"profile": "api_exposed"
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "fetch_rag_rows",
"title": "Получение строк из RAG"
},
"input": {},
"output": {
"retrieved_row_count": 3
}
}
```
## process.v2.evidence
```json
{
"event": "evidence_assembled",
"mode": "api_exposed",
"endpoint_count": 3,
"endpoints": [
"GET /api/v1/clients/contacts-dgr",
"GET /api/v1/clients/contacts-dgr/{contactid}",
"POST /api/v1/clients/contacts-dgr"
]
}
```
## process.v2.pipeline
```json
{
"event": "evidence_assembled",
"mode": "api_exposed",
"endpoint_count": 3
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "build_api_exposed_evidence",
"title": "Сборка списка API"
},
"input": {},
"output": {
"endpoint_count": 3
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_step_traced",
"workflow_id": "v2.docs_explain.api_exposed",
"step": {
"id": "finalize_api_exposed_answer",
"title": "Формирование ответа со списком API"
},
"input": {},
"output": {
"answer_length": 111
}
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_trace_flushed",
"workflow_id": "v2.docs_explain.api_exposed",
"steps": [
{
"step_id": "require_rag_session",
"title": "Проверка RAG-сессии",
"input": {},
"output": {
"has_rag_session": true
}
},
{
"step_id": "resolve_retrieval_plan",
"title": "Выбор retrieval-плана",
"input": {},
"output": {
"profile": "api_exposed"
}
},
{
"step_id": "fetch_rag_rows",
"title": "Получение строк из RAG",
"input": {},
"output": {
"retrieved_row_count": 3
}
},
{
"step_id": "build_api_exposed_evidence",
"title": "Сборка списка API",
"input": {},
"output": {
"endpoint_count": 3
}
},
{
"step_id": "finalize_api_exposed_answer",
"title": "Формирование ответа со списком API",
"input": {},
"output": {
"answer_length": 111
}
}
]
}
```
## workflow.v2.api_exposed
```json
{
"event": "workflow_completed",
"workflow_id": "v2.docs_explain.api_exposed"
}
```
## process.v2.pipeline
```json
{
"event": "answer_generated",
"answer_mode": "deterministic",
"answer_length": 111
}
```
## result
```json
{
"status": "done",
"answer": "GET /api/v1/clients/contacts-dgr\nGET /api/v1/clients/contacts-dgr/{contactid}\nPOST /api/v1/clients/contacts-dgr",
"completed_at": "2026-04-10T12:14:51.286117+00:00"
}
```
@@ -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`
@@ -25,6 +25,7 @@
## Особые правила
- Во frontmatter обязательно указывать `endpoint` (например: `POST /api/v1/clients/contacts-dgr`).
- Сценарий оформляется как технический use case.
- Функциональные требования маркируются `FR-*`.
- Нефункциональные требования маркируются `NFR-*`.
@@ -47,6 +47,7 @@ system_analytics_refs: []
- `module` — модуль или подсистема.
- `layer` — слой системы.
- `updated_at` хранится в формате `YYYY-MM-DD`.
- Для документов с `doc_type: api_method` поле `endpoint` является обязательным.
## Связи и навигация
@@ -1,21 +0,0 @@
# API Scenario Rules
## Назначение
Этот файл описывает, как оформлять подраздел `### Сценарий` в API-документах.
## Обязательные части
- название
- предусловия
- триггер
- основной сценарий
- альтернативный сценарий
- обработка ошибок
- постусловие
## Правила
- Сценарий должен быть лаконичным.
- Сценарий должен отражать суть шага.
- Сложные технические детали надо выносить в `FR-*`.
@@ -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 критерии успешного ответа >
@@ -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
- Получение данных клиента из АС ЕПК
- Проверка уровня доступа
- Сценарий построения списка связанных предложений
@@ -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
@@ -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`.
@@ -0,0 +1,24 @@
# API Contract Rules
## Назначение
Этот файл описывает, как оформлять подраздел `## Контракт` в API-документах.
## Что должно быть описано
- входные параметры
- выходные параметры
- JSON-структуры запросов и ответов
- обязательность полей
- типы полей
- ограничения
- описание назначения полей
- примеры данных
- auth
- idempotency
- timeout
- ошибки и их HTTP-коды
## Правило качества
Контракт должен быть достаточно формальным, чтобы по нему можно было собрать OpenAPI-спецификацию.
@@ -0,0 +1,13 @@
# Details Section Rules
## Назначение
Этот файл задает общие правила для секции `## Details`.
## Правила
- `Details` оформляется как `## Details`.
- Внутри `Details` используются заголовки уровня `###` и ниже.
- Структура Details зависит от типа документа.
- В Details не нужно повторно дублировать навигацию и связи, если они уже есть во frontmatter.
- Интеграции, ошибки и кодовые привязки должны быть выделены в отдельные подразделы, если они существенны для понимания документа.
@@ -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 критерии успешного ответа >
@@ -0,0 +1,16 @@
# Requirements Format Rules
## Назначение
Этот файл задает формат для функциональных и нефункциональных требований.
## Функциональные требования
- Использовать коды `FR-1`, `FR-2`, `FR-3` и так далее.
- Каждое требование должно описывать отдельный обязательный аспект поведения.
- Идентификаторы локальны в пределах одного документа.
## Нефункциональные требования
- Использовать коды `NFR-1`, `NFR-2`, `NFR-3` и так далее.
- Требования должны описывать характеристики качества, ограничения и эксплуатационные свойства.
@@ -0,0 +1,13 @@
# Summary Section Rules
## Назначение
Этот файл задает правила для секции `## Summary`.
## Правила
- Summary должен быть коротким explain-слоем быстрого контекста.
- Summary должен объяснять суть документа без лишних деталей.
- Summary должен быть пригоден для explain и быстрого чтения.
- Предпочтительный формат: список ключевых фактов `Purpose`, `Actor`, `Trigger`, `Errors`, `Related ...` и т.д.
- Для крупных документов допустим более длинный summary, если он остается структурированным.
@@ -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
- Получение данных клиента из АС ЕПК
- Проверка уровня доступа
- Сценарий построения списка связанных предложений
@@ -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-коды
@@ -0,0 +1,38 @@
# Documentation System
## Назначение
Этот файл задает общую модель документации проекта.
## Базовая модель
Каждый документ должен состоять из двух слоев:
- YAML frontmatter
- контент
Контент всегда состоит из двух обязательных разделов:
- `## Summary`
- `## Details`
Над ними должен быть один заголовок `# <title>`, совпадающий со значением `title` во frontmatter.
## Принципы
- Документы должны быть атомарными.
- Один документ описывает одну тему.
- Вместо дублирования между документами используются явные ссылки.
- Связи и навигация должны быть формализованы.
- Документы должны быть пригодны для чтения человеком и для RAG.
- Документы должны быть пригодны для частичного обновления без деградации структуры.
## Типы документов
На уровне проекта поддерживаются типы:
- `api_method`
- `logic_block`
- `architecture_overview`
- `domain_entity`
- `ui_page`
- `integration_doc`
- `index_page`
- `glossary_item`
@@ -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
```
@@ -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.
@@ -0,0 +1,24 @@
# Naming Rules
## Назначение
Этот файл описывает правила именования документов, файлов и идентификаторов.
## Правила для файлов
- Имена файлов должны быть в kebab-case.
- Имя файла должно отражать одну тему.
- Для шаблонов использовать суффикс `.template.md`.
## Правила для id
- `id` строится в формате `<type-group>.<name>`.
- Примеры:
- `api.send_message_endpoint`
- `logic.telegram_notification_loop`
- `architecture.telegram_notify_app`
## Правила для title
- `title` должен быть кратким и человекочитаемым.
- В `title` допускаются пробелы и естественный язык.
@@ -0,0 +1,19 @@
# Writing Style
## Назначение
Этот файл задает правила стиля для текстового наполнения документации.
## Правила стиля
- Текст должен быть лаконичным.
- Формулировки должны быть точными и техническими.
- Summary должен быть кратким explain-слоем.
- Details должен раскрывать суть без лишней воды.
- Нежелательно смешивать несколько тем в одном документе.
- Если детали относятся к другому артефакту, их нужно выносить в отдельный документ.
## Язык
- Основной язык документации — русский.
- Технические термины, названия классов, API, RAG, OpenAPI, runtime и другие устоявшиеся identifiers можно оставлять на английском.
@@ -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.**
## Контракт
### Входные параметры
| Параметр | Где передается | Тип | Обязательность | Ограничения | Описание | Пример |
|---|---|---|---|---|---|---|
| | | | | | | |
### Выходные параметры
| Поле | Тип | Обязательность | Ограничения | Описание | Заполнение | Пример |
|---|---|---|---|---|---|---|
| | | | | | | |
### Интеграции
### Ошибки
### Связанный код
### История изменений
@@ -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
### Описание
### Контекст
### Границы системы
### Компоненты
### Интеграционные сценарии
### Интеграции
### Ограничения
### Связанный код
### Связанные документы
### История изменений
@@ -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
### Функциональные требования
### Нефункциональные требования
### Интеграции
### Связанный код
### Связанные документы
### История изменений
@@ -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
### Связанный код
### История изменений
@@ -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 и сущности
### Функциональные требования
### Нефункциональные требования
### Ограничения и граничные случаи
### Ошибки и валидации
### Связанный код
### Связанные документы
### История изменений
@@ -0,0 +1,39 @@
# API Method Rules
## Назначение
Этот файл задает правила для документов типа `api_method`.
## Когда использовать
Использовать для описания одного HTTP endpoint или одного отдельного API метода.
## Обязательная структура
Документ должен содержать:
- YAML frontmatter
- `# <title>`
- `## Summary`
- `## Details`
Внутри `## Details` обязательны:
- `### Описание`
- `### Сценарий`
- `### Функциональные требования`
- `### Нефункциональные требования`
- `### Контракт`
## Особые правила
- Сценарий оформляется как технический use case.
- Функциональные требования маркируются `FR-*`.
- Нефункциональные требования маркируются `NFR-*`.
- Контракт должен быть пригоден для последующей сборки OpenAPI.
- Если у метода есть интеграции, они выносятся в `### Интеграции`.
- Ошибки и HTTP-коды либо описываются в `### Ошибки`, либо ссылаются на централизованный каталог ошибок.
## Ошибки оформления
- Нельзя заменять контракт общим текстовым описанием.
- Нельзя смешивать несколько endpoint в одном документе.
- Нельзя хранить связи и навигацию вне frontmatter.
@@ -0,0 +1,31 @@
# Architecture Overview Rules
## Назначение
Этот файл задает правила для документов типа `architecture_overview`.
## Когда использовать
Использовать как входной документ для понимания системы, модуля или сервиса.
## Обязательная структура
Документ должен содержать:
- YAML frontmatter
- `# <title>`
- `## Summary`
- `## Details`
## Что описывать в Details
- границы системы
- основные компоненты
- ключевые взаимодействия
- интеграционные сценарии
- главные ограничения
- ссылки на дочерние документы по API, logic, domain и другим артефактам
## Ошибки оформления
- Нельзя дублировать в архитектурном обзоре полные API-контракты.
- Нельзя делать архитектурный обзор единственным документом на всю систему без декомпозиции.
@@ -0,0 +1,30 @@
# Domain Entity Rules
## Назначение
Этот файл задает правила для документов типа `domain_entity`.
## Когда использовать
Использовать для описания одной доменной сущности, ее смысла, состояния и роли в системе.
## Обязательная структура
Документ должен содержать:
- YAML frontmatter
- `# <title>`
- `## Summary`
- `## Details`
## Что описывать в Details
- смысл сущности
- ключевые атрибуты
- состояния или инварианты
- использование сущности в системе
- интеграции с API, workflow или внешними потребителями, если они важны для понимания модели
## Ошибки оформления
- Нельзя смешивать несколько независимых сущностей в одном документе.
- Нельзя подменять доменную сущность описанием endpoint или workflow.
@@ -0,0 +1,25 @@
# Integration Doc Rules
## Назначение
Этот файл задает правила для документов типа `integration_doc`.
## Когда использовать
Использовать для описания интеграции между системами, сервисами или внешними провайдерами.
## Обязательная структура
Документ должен содержать:
- YAML frontmatter
- `# <title>`
- `## Summary`
- `## Details`
## Что описывать в Details
- цель интеграции
- участвующие стороны
- направление обмена
- ключевой сценарий взаимодействия
- ограничения и риски
@@ -0,0 +1,31 @@
# Logic Block Rules
## Назначение
Этот файл задает правила для документов типа `logic_block`.
## Когда использовать
Использовать для описания одного законченного блока логики, workflow или процесса.
## Обязательная структура
Документ должен содержать:
- YAML frontmatter
- `# <title>`
- `## Summary`
- `## Details`
## Что описывать в Details
- назначение логического блока
- входы и выходы
- последовательность выполнения
- интеграции
- ключевые ограничения
- состояние и ошибки, если они важны для понимания блока
## Ошибки оформления
- Нельзя описывать весь модуль целиком, если логика распадается на несколько независимых блоков.
- Нельзя превращать документ в пересказ исходного кода построчно.
@@ -0,0 +1,24 @@
# UI Page Rules
## Назначение
Этот файл задает правила для документов типа `ui_page`.
## Когда использовать
Использовать для описания одной пользовательской страницы, экрана или отдельного UI-сценария.
## Обязательная структура
Документ должен содержать:
- YAML frontmatter
- `# <title>`
- `## Summary`
- `## Details`
## Что описывать в Details
- назначение страницы
- пользовательский сценарий
- основные блоки интерфейса
- связанные API и сущности
@@ -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]:
@@ -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:
+2 -2
View File
@@ -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.",
+1 -1
View File
@@ -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,
+76 -4
View File
@@ -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)
@@ -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",