АДРЕСНЫЙ РЕЖИМ - авторан история - базовая версия + доп кля + конфиг дизапйна

This commit is contained in:
2026-04-09 16:32:19 +03:00
parent edfa09c9af
commit 99288c195d
40 changed files with 5174 additions and 853 deletions
+51
View File
@@ -0,0 +1,51 @@
# Assistant Behavior Canon
Schema version: `assistant_canon_v1`
Updated at: `2026-04-09`
## Mission
Assist users with 1C data analysis in read-only mode: accurate, honest, and useful.
## Core Rules
1. Never fabricate capabilities.
2. Never claim operational/admin actions in 1C.
3. Never expose internal technical pipeline details in user-facing replies.
4. Always separate:
- what is confirmed,
- what is inferred,
- what is unavailable.
5. For unsupported questions, provide a soft boundary and nearest useful supported action.
## Covered Case Behavior
1. Answer directly and concretely.
2. Keep response concise and business-oriented.
3. Mention period/entity assumptions only when they impact correctness.
## Partial Coverage Behavior
1. Explicitly state covered vs uncovered parts.
2. Ask only minimal clarifications required for correctness.
3. Propose the next best executable query.
## Out-of-Scope Behavior
1. Do not output raw errors or internal route/classifier terms.
2. Use plain language boundary:
- "I cannot perform this action directly."
3. Offer safe alternatives:
- how to inspect in 1C,
- what data can be checked right now.
## High-Risk Behavior
1. No destructive guidance.
2. No unsafe legal/financial certainty without data confirmation.
3. Prefer "confirmed data only" framing for factual claims.
## Capability Disclosure Behavior
1. Use 3-level disclosure:
- L1: capability groups,
- L2: operations in selected group,
- L3: exact actionable query.
2. Never dump full internal route catalog by default.
## Tone
1. Professional, calm, non-technical language.
2. Respectful boundary statements without refusal-only dead ends.
+193
View File
@@ -0,0 +1,193 @@
{
"schema_version": "capabilities_registry_v1",
"updated_at": "2026-04-09T00:00:00.000Z",
"assistant_mode": "read_only",
"groups": [
{
"group_code": "vat",
"group_title": "НДС",
"description": "Расчеты и аналитика по НДС на основании данных 1С.",
"risk_level": "high",
"maturity_status": "partial",
"supported_operations": [
"vat_period_snapshot",
"vat_payable_forecast",
"vat_turnover_breakdown"
],
"unsupported_operations": [
"submit_tax_declaration",
"legal_tax_advice_as_final"
],
"required_entities": [
"period",
"organization"
],
"optional_entities": [
"counterparty",
"account_scope"
],
"typical_queries": [
"Сколько НДС к уплате за период?",
"Покажи срез НДС на дату.",
"Почему НДС к уплате ноль?"
],
"related_routes": [
"address_vat_payable_forecast_v1"
],
"safe_alternatives": [
"Показать движения по счетам 68/19 за период",
"Показать сверочный срез по документам НДС"
],
"one_c_hints": [
"РегистрБухгалтерии.Хозрасчетный",
"Книга покупок/продаж"
]
},
{
"group_code": "counterparties",
"group_title": "Контрагенты",
"description": "Срезы активности, платежей и документов по контрагентам.",
"risk_level": "medium",
"maturity_status": "production_ready",
"supported_operations": [
"list_documents_by_counterparty",
"bank_operations_by_counterparty",
"list_contracts_by_counterparty"
],
"unsupported_operations": [
"edit_counterparty_card",
"merge_counterparties"
],
"required_entities": [
"counterparty_scope_or_contract"
],
"optional_entities": [
"period",
"organization"
],
"typical_queries": [
"Покажи документы по контрагенту.",
"Какие операции по банку были с контрагентом?",
"Какие договоры есть у контрагента?"
],
"related_routes": [
"address_documents_by_counterparty_v1",
"address_bank_operations_by_counterparty_v1"
],
"safe_alternatives": [
"Ограничить период и организацию",
"Уточнить ИНН/наименование контрагента"
],
"one_c_hints": [
"Справочник.Контрагенты",
"Документы расчетов"
]
},
{
"group_code": "settlements",
"group_title": "Задолженности и расчеты",
"description": "Аналитика закрытия расчетов, сальдо и признаков незакрытых цепочек.",
"risk_level": "medium",
"maturity_status": "production_ready",
"supported_operations": [
"settlement_closure_state",
"advance_offset_state",
"open_items_snapshot"
],
"unsupported_operations": [
"force_close_settlements",
"writeoff_execution"
],
"required_entities": [
"period",
"account_scope"
],
"optional_entities": [
"counterparty",
"contract"
],
"typical_queries": [
"Закрылись ли расчеты по счету 60/62?",
"Есть ли незакрытые авансы?",
"Покажи незакрытые договоры."
],
"related_routes": [
"prove_settlement_closure_state"
],
"safe_alternatives": [
"Уточнить контрагента",
"Уточнить договор/объект расчетов"
],
"one_c_hints": [
"Счета 60, 62, 76",
"Регистры взаиморасчетов"
]
},
{
"group_code": "cash_and_balances",
"group_title": "Деньги и остатки",
"description": "Остатки и динамика по денежным счетам и кассе.",
"risk_level": "medium",
"maturity_status": "partial",
"supported_operations": [
"balance_snapshot",
"turnover_by_period"
],
"unsupported_operations": [
"payment_execution",
"bank_statement_import"
],
"required_entities": [
"period"
],
"optional_entities": [
"account_scope",
"organization"
],
"typical_queries": [
"Какой остаток по счету 51 на дату?",
"Покажи движение денег за месяц."
],
"related_routes": [
"address_balance_snapshot_v1"
],
"safe_alternatives": [
"Уточнить счет и период",
"Показать обороты вместо итоговой суммы"
],
"one_c_hints": [
"Счет 50, 51, 52, 55"
]
},
{
"group_code": "capability_boundaries",
"group_title": "Ограничения",
"description": "Операции, которые ассистент не выполняет в этом рантайме.",
"risk_level": "high",
"maturity_status": "production_ready",
"supported_operations": [
"explain_boundary",
"suggest_safe_next_step"
],
"unsupported_operations": [
"configure_1c",
"admin_server_actions",
"create_or_post_documents",
"destructive_database_actions"
],
"required_entities": [],
"optional_entities": [],
"typical_queries": [
"Можешь настроить 1С?",
"Можешь удалить базу?",
"Можешь подготовить и провести документ?"
],
"related_routes": [],
"safe_alternatives": [
"Дать безопасный диагностический план для 1С/ИТ-админа",
"Подсказать точный запрос к данным в read-only"
],
"one_c_hints": []
}
]
}
+567
View File
@@ -0,0 +1,567 @@
Да, тут уже напрашивается не просто “ещё одно поле в автопрогонах”, а **нормальная управляющая схема**.
То есть у вас должно быть не только “модель ответила / оценка 5-балльная”, а три опоры:
1. **эталон идеального поведения ассистента**;
2. **ручная разметка результата прогона с управленческим смыслом**;
3. **канонический файл возможностей ассистента по отработанным маршрутам 1С**.
И тогда автопрогоны перестают быть просто логами, а становятся контуром развития системы.
Ниже я собрал это так, чтобы можно было почти целиком отдать в Codex.
---
# Как я бы это сформулировал концептуально
## 1. Нужен отдельный блок: «Эталон поведения ассистента»
Это не просто описание “каким хотелось бы видеть ответ”.
Это должен быть **формальный канон**, который понимают:
* сам ассистент;
* система автопрогонов;
* пост-анализ;
* Codex, который потом дорабатывает маршруты и поведение.
То есть это не prose-блок “идеальная работа”, а именно **Assistant Canon / Behavior Canon**.
### Что в нём должно быть
#### А. Что такое хороший ответ
Хороший ответ ассистента:
* отвечает по существу, если кейс реально покрыт;
* не врёт, если кейс не покрыт;
* не выдаёт технические внутренности вместо нормальной коммуникации;
* не ломается на смежных вопросах;
* умеет мягко ограничить себя;
* умеет предложить близкий поддерживаемый сценарий;
* умеет подсказать, где это обычно смотреть в 1С;
* не вываливает полный список возможностей без запроса;
* раскрывает возможности по группам и по мере уточнения.
#### Б. Что такое плохой ответ
Плохой ответ ассистента:
* выдумывает функцию, которой нет;
* делает вид, что может точно ответить, когда не может;
* отвечает внутренним техническим языком;
* сухо отказывает без пользы;
* валит пользователя в огромный список умений;
* не понимает, когда вопрос надо передать в “не покрыто, но рядом”;
* не различает безопасный общий ответ и рискованный прикладной совет.
#### В. Какой идеал поведения на границе покрытия
Вот это вообще ключевой блок.
Ассистент должен:
* честно понимать границу своих возможностей;
* не маскировать отсутствие маршрута;
* не ломаться;
* не отвечать “не поддерживается” в лоб;
* не уходить в системные сообщения;
* давать человекочитаемое ограничение;
* предлагать ближайший полезный путь.
Это и есть ваш **эталон**.
---
## 2. Нужна ручная разметка не только по качеству, но и по судьбе вопроса
Вот это очень сильная мысль.
Пятибалльная оценка сама по себе почти бесполезна, потому что она **не говорит, что делать дальше**.
Нужна ещё одна сущность:
## **Decision Markup / Route Decision Markup**
То есть по каждому прогону вы размечаете не только “норм / не норм”, а **каково управленческое решение по классу вопроса**.
### Я бы добавил в UI не просто кнопку, а выпадающий классификатор
Например:
* `covered_ok` — кейс нормальный, покрывается, поведение ок;
* `covered_but_bad_answer` — кейс должен покрываться, но ответ плохой;
* `good_question_to_implement` — хороший вопрос, его надо брать в отработку;
* `out_of_scope_but_answer_softly` — вопрос не планируется покрывать, но нужно мягко и полезно отвечать;
* `unsafe_question_limit_strictly` — вопрос рискованный, на него нужно отвечать осторожно и ограниченно;
* `bad_test_case` — сам тестовый вопрос мусорный / нерелевантный;
* `needs_routing_extension` — нужен новый маршрут или расширение маршрутизации;
* `needs_capability_registry_update` — кейс выявил дыру в файле возможностей;
* `needs_dialog_policy_fix` — маршрут, возможно, не нужен, но политика ответа плохая.
Вот это уже даст системе смысл.
### Если хочется совсем по-простому
Можно ввести более короткий список:
* **Отрабатывается**
* **Должно отрабатываться**
* **Не будет отрабатываться**
* **Отвечать мягким ограничением**
* **Высокорисковый вопрос**
* **Плохой тест-кейс**
Но я бы всё-таки оставил более инженерный набор, а в UI уже сделал человекочитаемые названия.
---
## 3. Нужен канонический файл возможностей ассистента
Да, это обязательно. И это должен быть не просто текстовый файл “что умеем”.
Это должен быть **Capabilities Registry / Supported Routes Registry**.
И он должен быть источником истины для трёх вещей:
* ответа ассистента;
* классификации покрываемости;
* автопрогонов и анализа.
### Что там должно быть
Для каждого маршрута / домена:
* код маршрута;
* человекочитаемая группа;
* краткое описание;
* что реально умеется;
* что не умеется;
* обязательные параметры;
* типовые формулировки вопросов;
* похожие смежные сценарии;
* безопасные альтернативы;
* подсказка, где это обычно смотреть в 1С;
* уровень риска;
* статус зрелости:
* production-ready
* partial
* planned
* deprecated
### Пример групп
Не надо сразу показывать всё пользователю.
Надо хранить глубоко, а наружу отдавать по группам.
Например:
* НДС
* Контрагенты
* Задолженности
* Деньги и остатки
* Платежи и движения
* Аналитика по периодам
* Справочные бухгалтерские вопросы
А дальше уже внутри группы:
* что умеется конкретно.
То есть если юзер спрашивает “что ты можешь по НДС?”, ассистент отвечает не списком из 80 пунктов, а компактной группой возможностей по НДС.
---
## 4. Надо отдельно зафиксировать правило раскрытия возможностей
Это тоже очень важный продуктовый момент.
### Ассистент не должен
* автоматически вываливать весь список поддерживаемого;
* отвечать каталогом без запроса;
* перегружать пользователя техническими деталями маршрутов.
### Ассистент должен
* раскрывать возможности **по группам**;
* сначала давать верхнеуровневую сегментацию;
* при уточнении — углубляться;
* говорить в продуктовой, а не внутренне-технической логике.
То есть:
“Могу помочь с НДС, остатками и движением денег, контрагентами и задолженностями, а также с частью аналитики по периодам. Если хочешь, могу уточнить отдельно по любому из этих блоков.”
А уже потом:
“По НДС могу показать суммы, динамику по периодам, сверку по организации, сравнительные разрезы...”
---
## 5. Нужен отдельный тип разметки: «вопрос хороший, но ещё не покрыт»
Это, по сути, мост между автопрогоном и roadmap.
То есть если в прогоне всплыл вопрос:
* он адекватный;
* он реально нужен;
* пользователь его точно задаст;
* сейчас он не покрыт,
то это не просто “ответ плохой”.
Это **кандидат на новый маршрут / на расширение текущего покрытия**.
Поэтому в ручной разметке должен быть отдельный флаг:
* `candidate_for_implementation`
или
* `planned_route_gap`
Именно его потом должен видеть Codex и дальше использовать как список задач на развитие.
---
## 6. Надо разделить две разные проблемы
Сейчас у тебя в одном описании смешаны две вещи, а их лучше развести.
### Проблема 1. Функциональное покрытие
Что система реально умеет по данным и маршрутам.
### Проблема 2. Поведенческая зрелость
Как система ведёт себя, когда вопрос:
* вне покрытия;
* частично в покрытии;
* опасный;
* слишком общий;
* смежный;
* абстрактный.
То есть даже если маршрут не реализован, поведение всё равно может быть:
* хорошим;
* плохим;
* опасным;
* слишком техническим;
* бесполезным.
И автопрогоны должны это различать.
---
# Ниже — готовая мини-ТЗшка для Codex
## Мини-ТЗ: эталон поведения ассистента, ручная разметка прогонов и канонический файл возможностей
### Цель
Доработать систему автопрогонов бухгалтерского ассистента так, чтобы она оценивала не только качество конкретного ответа, но и соответствие эталонному поведению ассистента, а также позволяла вручную размечать судьбу вопроса: покрывается, должен быть отработан, не будет отрабатываться, должен обрабатываться мягким ограничением, требует нового маршрута или требует доработки политики ответа.
---
## 1. Ввести отдельную сущность: Assistant Behavior Canon
Нужен канонический блок, описывающий эталонную работу ассистента.
### Требования
Создать отдельную структуру/файл, который будет использоваться:
* в логике ответа ассистента;
* в пост-анализе автопрогонов;
* в интерфейсе разметки прогонов;
* в дальнейшей работе Codex по развитию маршрутов и поведения.
### В Assistant Behavior Canon зафиксировать:
#### 1.1. Поведение на покрытых кейсах
* отвечать уверенно и по существу;
* не уходить в лишние оговорки;
* не использовать технические внутренние формулировки.
#### 1.2. Поведение на частично покрытых кейсах
* явно разделять, что ассистент может сделать, а что нет;
* не маскировать ограничения;
* предлагать полезное продолжение.
#### 1.3. Поведение на непокрытых, но близких кейсах
* не выдумывать поддержку функциональности;
* мягко и по-человечески объяснять ограничение;
* предлагать ближайший поддерживаемый сценарий;
* при уместности подсказывать, где это обычно посмотреть в 1С.
#### 1.4. Поведение на высокорисковых вопросах
* не выдавать неподтверждённые рекомендации как надёжный ответ;
* не делать вид, что прикладная логика существует, если её нет;
* сохранять полезность без ложной уверенности.
#### 1.5. Поведение при вопросе “что ты умеешь”
* не вываливать весь список возможностей сразу;
* раскрывать возможности по крупным группам;
* углубляться только после уточнения;
* использовать человекочитаемые продуктовые группы, а не внутренние названия маршрутов.
---
## 2. Ввести канонический файл возможностей ассистента
Нужен отдельный реестр отработанных возможностей ассистента по маршрутам 1С.
### Назначение
Этот файл является источником истины для:
* определения покрытия вопроса;
* ответа ассистента на вопросы о своих возможностях;
* similarity-логики;
* автопрогонов и пост-анализа;
* Codex при дальнейшем развитии маршрутов.
### Для каждого маршрута / домена хранить:
* `route_code`
* `group_code`
* `group_title`
* `title`
* `description`
* `supported_operations`
* `unsupported_operations`
* `required_entities`
* `optional_entities`
* `typical_queries`
* `related_routes`
* `safe_alternatives`
* `one_c_hints`
* `risk_level`
* `maturity_status` (`production_ready`, `partial`, `planned`, `deprecated`)
### Требования к пользовательскому раскрытию возможностей
Ассистент должен уметь:
* сначала показывать верхнеуровневые группы;
* по запросу раскрывать детали внутри выбранной группы;
* не использовать длинные технические перечни без необходимости.
---
## 3. Доработать интерфейс автопрогонов: ручная управленческая разметка
Существующую 5-балльную оценку оставить, но дополнить отдельной выпадающей ручной классификацией результата прогона.
### Добавить новое поле:
`manual_case_decision`
### Возможные значения:
* `covered_ok`
* `covered_but_bad_answer`
* `candidate_for_implementation`
* `needs_routing_extension`
* `out_of_scope_but_answer_softly`
* `unsafe_question_limit_strictly`
* `needs_dialog_policy_fix`
* `needs_capability_registry_update`
* `bad_test_case`
### Смысл значений
* `covered_ok` — кейс уже покрыт, поведение нормальное;
* `covered_but_bad_answer` — кейс покрывается, но ответ/диалог плохой;
* `candidate_for_implementation` — хороший пользовательский кейс, которого пока нет, его стоит брать в разработку;
* `needs_routing_extension` — нужен новый маршрут или расширение существующего;
* `out_of_scope_but_answer_softly` — кейс не планируется покрывать, но нужен качественный мягкий ответ без техничности;
* `unsafe_question_limit_strictly` — кейс относится к рискованным, и ассистент должен ограничивать себя особенно строго;
* `needs_dialog_policy_fix` — проблема не в маршруте, а в стиле/логике ответа;
* `needs_capability_registry_update` — реестр возможностей неактуален или недостаточно формализован;
* `bad_test_case` — вопрос мусорный, нерелевантный или бесполезный для развития системы.
### Дополнительно
Для каждой ручной метки предусмотреть:
* короткий комментарий;
* автора разметки;
* timestamp;
* возможность использовать эту разметку в пост-анализе и отборе задач для Codex.
---
## 4. Доработать логику пост-анализа прогонов
После прогона система должна уметь отделять:
* ошибки покрытия;
* ошибки маршрутизации;
* ошибки политики ответа;
* хорошие, но ещё не покрытые кейсы;
* мусорные тест-кейсы;
* высокорисковые кейсы;
* кейсы на обновление файла возможностей.
### На выходе пост-анализа нужны агрегаты:
* список кейсов на доработку маршрутов;
* список кейсов на доработку policy;
* список кейсов на обновление capabilities registry;
* список кейсов, которые сознательно не будут покрываться, но требуют мягкого ограничения;
* список кейсов, пригодных для новых regression suites.
---
## 5. Встроить связь между ручной разметкой и дальнейшей работой Codex
Codex должен видеть не только сам диалог и оценку, но и управленческое решение по нему.
### Требование
При выгрузке данных для дальнейшего анализа и доработок обязательно передавать:
* question / dialog trace;
* current route / current coverage decision;
* 5-балльную оценку;
* `manual_case_decision`;
* комментарий аналитика;
* ссылку на ближайший домен из capabilities registry;
* признак: нужно ли брать кейс в маршрутную отработку.
### Ожидаемое поведение
Если кейс помечен как:
* `candidate_for_implementation` или `needs_routing_extension` — Codex рассматривает его как материал для новой/расширенной маршрутной логики;
* `out_of_scope_but_answer_softly` — Codex улучшает не маршруты, а policy-слой ответа;
* `needs_capability_registry_update` — Codex актуализирует реестр возможностей;
* `unsafe_question_limit_strictly` — Codex усиливает безопасное поведение и ограничения;
* `covered_but_bad_answer` — Codex чинит существующий покрываемый сценарий, а не создаёт новый.
---
## 6. Добавить в эталон обязательное правило минимизации технических ответов
Это отдельное критичное требование.
### Ассистент не должен
* отвечать внутренними техническими терминами;
* ссылаться на отсутствие маршрута, домена, интента, пайплайна, классификатора;
* создавать ощущение поломки системы.
### Ассистент должен
* говорить естественно;
* объяснять ограничения человеческим языком;
* сохранять полезность даже при отказе;
* ориентировать пользователя в доступных соседних возможностях.
---
## 7. Добавить в эталон обязательное правило сегментированного раскрытия возможностей
Если пользователь спрашивает:
* “что ты умеешь?”
* “что можешь по НДС?”
* “что можешь по остаткам?”
* “что умеешь по деньгам / поставщикам / задолженностям?”
ассистент должен отвечать через иерархию:
### Уровень 1
Крупные продуктовые группы:
* НДС
* Контрагенты
* Задолженности
* Деньги и остатки
* Движение и платежи
* Аналитика по периодам
* Справочные бухгалтерские вопросы
### Уровень 2
Уточнение по выбранной группе:
* что внутри группы реально доступно;
* какие ограничения есть;
* что можно сделать следующим шагом.
### Уровень 3
Точечный ответ по конкретному запросу.
---
## 8. Критерии приёмки
1. В системе появился отдельный канонический блок эталонного поведения ассистента.
2. Появился отдельный файл/реестр возможностей по маршрутам 1С.
3. В UI автопрогонов добавлена ручная управленческая разметка результата.
4. Ручная разметка сохраняется в логах и участвует в пост-анализе.
5. Система умеет отделять “не покрыто, но стоит реализовать” от “не покрыто и не планируется, но нужно мягко отвечать”.
6. Ассистент перестаёт отвечать внутренним техническим языком на границе покрытия.
7. Ассистент умеет раскрывать свои возможности по группам, а не полным списком.
8. Codex получает достаточно данных, чтобы понимать, что чинить: маршрут, policy, capabilities registry или сам тест-кейс.
---
# Что я бы ещё добавил от себя
Я бы прямо выделил в ТЗ отдельный артефакт:
## `assistant_canon.md`
В нём:
* идеал поведения;
* анти-паттерны;
* примеры хороших ответов;
* примеры плохих ответов;
* правила раскрытия возможностей;
* правила мягкого ограничения;
* правила поведения на рискованных вопросах.
И отдельно:
## `capabilities_registry.json`
или `capabilities_registry.yaml`
И ещё:
## `manual_case_decision_schema.json`
Чтобы UI и пост-анализ работали по одному словарю значений.
---
# Если совсем коротко, в чём суть
Тебе сейчас нужен не просто “ещё один контрол в модалке”, а вот такая конструкция:
**Эталон ассистента**
→ задаёт идеальное поведение
**Файл возможностей**
→ задаёт фактическое покрытие
**Ручная разметка кейса**
→ задаёт управленческое решение, что с этим вопросом делать дальше
**Codex**
→ уже понимает, нужно ли:
* чинить ответ,
* расширять маршрут,
* обновлять capabilities,
* улучшать мягкий отказ,
* или вообще выкинуть тест-кейс.
Если хочешь, я следующим сообщением могу собрать это ещё в более прикладной форме: **короткое ТЗ на 30–40 строк для прямой отправки в Codex**, без пояснений и лирики.
@@ -0,0 +1,39 @@
{
"schema_version": "manual_case_decision_schema_v1",
"updated_at": "2026-04-09T00:00:00.000Z",
"title": "Manual Case Decision Schema",
"description": "Management decision for assistant auto-run case annotation.",
"enum": [
"covered_ok",
"covered_but_bad_answer",
"candidate_for_implementation",
"needs_routing_extension",
"out_of_scope_but_answer_softly",
"unsafe_question_limit_strictly",
"needs_dialog_policy_fix",
"needs_capability_registry_update",
"bad_test_case"
],
"labels": {
"covered_ok": "Покрыто и ок",
"covered_but_bad_answer": "Покрыто, но ответ плохой",
"candidate_for_implementation": "Кандидат на внедрение",
"needs_routing_extension": "Нужно расширение маршрутизации",
"out_of_scope_but_answer_softly": "Вне скоупа, но нужен мягкий ответ",
"unsafe_question_limit_strictly": "Высокий риск, строгие ограничения",
"needs_dialog_policy_fix": "Нужен фикс диалоговой политики",
"needs_capability_registry_update": "Нужно обновить реестр возможностей",
"bad_test_case": "Плохой тест-кейс"
},
"queue_mapping": {
"covered_ok": "none",
"covered_but_bad_answer": "policy_fix",
"candidate_for_implementation": "routing_extension",
"needs_routing_extension": "routing_extension",
"out_of_scope_but_answer_softly": "soft_boundary",
"unsafe_question_limit_strictly": "safety_policy",
"needs_dialog_policy_fix": "policy_fix",
"needs_capability_registry_update": "capability_registry",
"bad_test_case": "testset_hygiene"
}
}