TZ_Assistant_Mode_vNext2.md

Да, даю уже в формате **жёсткой вставки в ТЗ**.

Ниже блок, который логично добавлять как отдельный раздел после текущего `Final Answer Composer / answer policy`, потому что в текущем контуре уже есть правильная базовая архитектура, но composer пока остаётся operational, retrieval — sandbox/stubbed, а пользовательский ответ не обязан доказывать основание отбора и полноту покрытия вопроса. Это прямо следует из текущего vNext ТЗ и архитектурного отчёта.  

---

# Дополнение к ТЗ: explainable answer layer и контроль полноты декомпозиции

## 1. Цель дополнения

Закрыть два критических продуктовых дефекта Assistant Mode:

1. ассистент выдаёт формально человекочитаемый, но смыслово пустой ответ без объяснения, почему именно эти объекты, записи или цепочки были отобраны;
2. ассистент теряет части многосоставного пользовательского запроса на этапе decomposition/routing и отвечает только на отдельный фрагмент, создавая ложное ощущение, что задача решена.

Цель этого этапа — сделать так, чтобы Assistant Mode:

* отвечал **по смыслу бухгалтерского вопроса**;
* объяснял **основания отбора и вывода**;
* гарантировал **покрытие всех существенных частей запроса**;
* не подменял пользовательский вопрос ближайшим технически доступным маршрутом.

---

## 2. Что фиксируем как обязательный продуктовый контракт

Считать ответ ассистента корректным можно только тогда, когда одновременно выполнены четыре условия:

1. ответ относится именно к предмету вопроса пользователя, а не к соседнему маршруту;
2. ответ объясняет, **почему** найденные записи/объекты/контрагенты попали в результат;
3. ответ показывает, **на каких признаках и фактах** основан вывод;
4. ответ закрывает **все существенные части** многосоставного запроса либо явно помечает, что часть вопроса не покрыта.

Если хотя бы одно из этих условий не выполнено, ответ считается непригодным даже при технически успешном pipeline.

---

## 3. Новый обязательный слой: Explainable Answer Layer

После `Result Normalization` и до финального `Assistant Reply` должен быть отдельный обязательный слой:

**Explainable Answer Layer**

Новый полный контур:

**User message → Normalizer → Requirement Extraction → Execution Planning → Route-specific Retrieval → Result Normalization → Explainable Answer Layer → Final Answer Composer → Assistant Reply**

Задача этого слоя:

* восстановить пользовательское намерение в нормальной человекочитаемой форме;
* проверить полноту покрытия вопроса;
* проверить предметную релевантность ответа;
* собрать не просто summary, а **объяснимый вывод**.

---

## 4. Новый обязательный контракт декомпозиции

### 4.1. Декомпозиция должна выделять не только fragments, но и requirements

Нужно разделить два уровня:

### A. `requirements`

Смысловые требования пользователя.

Примеры:

* найти поставщиков с хвостами;
* объяснить, почему они считаются проблемными;
* показать, где именно разрыв по цепочке;
* отделить аномалии по риску от аномалий по сумме.

### B. `execution_fragments`

Технические единицы исполнения, которые маршрутизируются по route.

Важно:
один `requirement` может порождать несколько `execution_fragments`;
несколько fragments могут обслуживать один requirement.

Без этого разделения многосоставные вопросы будут и дальше схлопываться в один ближайший route.

---

### 4.2. Для каждого пользовательского сообщения нужен coverage report

После decomposition система обязана формировать объект:

```json
{
  "requirements_total": 0,
  "requirements_covered": 0,
  "requirements_uncovered": [],
  "requirements_partially_covered": [],
  "clarification_needed_for": [],
  "out_of_scope_requirements": []
}
```

Это внутренний контракт pipeline.

Без него нельзя считать, что система поняла вопрос.

---

### 4.3. Запрещён silent loss of intent

Если в исходном сообщении было несколько требований, а в execution plan попала только часть, система не имеет права:

* молча проигнорировать остальные части;
* выдавать ответ так, будто задача полностью выполнена;
* считать вопрос закрытым.

В этом случае допустимы только три режима:

1. **полный ответ** — если покрыто всё;
2. **partial answer** — если покрыта только часть и это явно сказано;
3. **clarification** — если без уточнения нельзя корректно закрыть все требования.

---

## 5. Новый обязательный контракт retrieval result

Текущий unified result schema нужно расширить. Сейчас в нём есть хороший базовый каркас, но для объяснимого ответа его недостаточно. 

Каждый route executor должен возвращать не только данные, но и признаки, объясняющие включение объекта в ответ.

### Обязательные поля результата

```json
{
  "fragment_id": "F1",
  "requirement_ids": ["R1"],
  "route": "store_feature_risk",
  "status": "ok | empty | partial | error",
  "result_type": "list | summary | object | chain | ranking",
  "items": [],
  "summary": {},
  "evidence": [],
  "why_included": [],
  "selection_reason": [],
  "risk_factors": [],
  "business_interpretation": [],
  "confidence": "high | medium | low",
  "limitations": [],
  "errors": []
}
```

---

### 5.1. Смысл новых полей

`why_included`
Почему объект вообще попал в выборку.

`selection_reason`
По каким конкретным правилам, фильтрам, признакам или сопоставлениям он был отобран.

`risk_factors`
Какие именно признаки риска, расхождения, аномалии или разрыва цепочки обнаружены.

`business_interpretation`
Как это интерпретируется в бухгалтерском или операционном смысле.

`confidence`
Оценка уверенности результата.

`limitations`
Что система не смогла подтвердить или где данные неполны.

---

## 6. Новый обязательный слой: Answer Grounding Check

Перед выдачей финального ответа должен выполняться `Answer Grounding Check`.

### Его задача:

проверить, что итоговый ответ действительно опирается на retrieval results и не съехал по предметной области.

### Проверяемые условия:

1. ключевые сущности ответа присутствуют в retrieval results;
2. ключевые выводы ответа подтверждены `evidence` и `selection_reason`;
3. предмет ответа совпадает с предметом вопроса;
4. если пользователь спрашивал про ОС, ответ не может быть собран по НДС;
5. если пользователь спрашивал про 97 счёт, ответ не может уйти в общий рейтинг контрагентов без объяснения связи;
6. если пользователь спрашивал про аномалию, ответ обязан назвать признак аномалии.

Если проверка не проходит, ответ не отправляется в user-facing канал и должен перейти в один из fallback-режимов:

* clarification;
* partial with limitation;
* technical error;
* no-grounded-answer.

---

## 7. Новый обязательный стандарт user-facing ответа

Каждый нормальный factual answer должен содержать не просто summary, а следующие смысловые элементы:

### 7.1. Итоговый вывод

Короткий ответ на главный вопрос.

### 7.2. Основание отбора

Почему именно эти объекты попали в ответ.

### 7.3. Подтверждающие признаки

Какие факты, поля, несоответствия, связи или разрывы обнаружены.

### 7.4. Практический смысл

Что это означает для бухгалтера или что именно здесь выглядит проблемным.

### 7.5. Ограничения

Что не удалось проверить полностью, если такое есть.

### 7.6. Следующее действие

Что стоит посмотреть или проверить дальше.

---

### 7.2. Требование к стилю ответа

Ответ должен быть:

* на русском;
* коротким, но содержательным;
* предметным;
* без route names;
* без debug-лексики;
* без пустых формулировок типа “по запросу найдены данные”;
* без перечисления ссылок без пояснения, зачем они показаны.

---

## 8. Обязательные шаблоны смысловой структуры ответа

### 8.1. Для anomaly / risk / suspicious scan

Ответ обязан содержать:

* что именно признано аномалией;
* по каким признакам это признано аномалией;
* чем запись отличается от нормального поведения;
* какие объекты наиболее рискованные;
* в чём риск состоит практически.

### 8.2. Для chain / causal / cross-entity explanation

Ответ обязан содержать:

* какую цепочку система проверяла;
* где именно найден разрыв или конфликт;
* какие сущности участвуют в цепочке;
* почему это считается хвостом, разрывом или зависшей ситуацией.

### 8.3. Для ranking / overview / top

Ответ обязан содержать:

* принцип ранжирования;
* почему верхние позиции оказались наверху;
* какие признаки сильнее всего влияли на приоритет.

### 8.4. Для canonical factual reply

Ответ обязан содержать:

* прямой ответ по объекту;
* источник/основание;
* при необходимости — уточнение статуса, периода, документа, связанной записи.

---

## 9. Новый обязательный формат partial answer

Если закрыта не вся задача, partial reply обязан быть структурирован так:

1. что удалось проверить;
2. что именно не покрыто;
3. почему не покрыто;
4. нужно ли уточнение;
5. можно ли продолжить по оставшейся части.

Недопустимо:
выдать ответ по одному фрагменту без явной маркировки того, что другие части вопроса потеряны.

---

## 10. Новые reply types

К текущему набору reply/fallback типов нужно добавить или закрепить отдельно:

* `factual`
* `factual_with_explanation`
* `partial_coverage`
* `clarification_required`
* `empty_but_valid`
* `no_grounded_answer`
* `route_mismatch_blocked`
* `backend_error`

Это нужно, чтобы различать:
просто технически успешный ответ и
семантически валидный ответ с объяснимым основанием.

---

## 11. Что нужно изменить в логировании

К уже существующим логам надо добавить поля, которые позволят анализировать именно смысловую пригодность ответа, а не только route/fallback. Сейчас логирование уже есть, но его надо расширить для field hardening. 

### Добавить в structured log:

* `requirements_extracted`
* `requirements_total`
* `requirements_covered`
* `requirements_uncovered`
* `coverage_status`
* `answer_grounding_status`
* `reply_semantic_type`
* `why_included_summary`
* `selection_reason_summary`
* `route_subject_match`
* `clarification_target`
* `dropped_intent_segments`

---

## 12. Что нужно изменить в UI

Debug drawer остаётся, но в основном ответе надо показывать не только итог, а и короткий explainable summary.

### В bubble ответа ассистента показывать:

* краткий вывод;
* короткий блок “почему это попало в ответ”;
* по необходимости — список объектов;
* по необходимости — блок “что проверить дальше”.

### В debug drawer переносить:

* raw fragments;
* route selection;
* trace id;
* fallback state;
* raw retrieval payloads;
* coverage report;
* grounding check result.

---

## 13. Новые критерии приёмки этапа

Этап считается принятым только если выполнены все условия:

1. ассистент отвечает по предмету вопроса, а не по ближайшему соседнему route;
2. каждый factual answer содержит объяснение, почему объект/запись/контрагент попал в ответ;
3. для каждого многосоставного вопроса система фиксирует coverage report;
4. система не теряет части вопроса молча;
5. если покрыта только часть — это явно отмечено в ответе;
6. если предмет ответа съехал — ответ блокируется как `route_mismatch_blocked` или `no_grounded_answer`;
7. anomaly-ответы объясняют признак аномалии, а не только выводят список сущностей;
8. chain-ответы объясняют разрыв цепочки, а не только перечисляют документы;
9. в основном ответе нет route names, trace, sandbox wording и другого внутреннего мусора;
10. debug остаётся доступен отдельно и не ломает основной UX.

---

## 14. Минимальный MVP этого дополнения

### MVP-1

Внедрить:

* `requirements` + `coverage report`;
* расширенный unified result schema;
* `Answer Grounding Check`;
* explainable answer contract хотя бы для:

  * `store_feature_risk`
  * `hybrid_store_plus_live`

### MVP-2

Добавить explainable templates для:

* `batch_refresh_then_store`
* `store_canonical`

### MVP-3

Дополировать:

* richer explanation formatting;
* confidence/limitations;
* better partial answer behavior;
* трассировку semantic failures.

---

## 15. Что считать провалом этапа

Этап не считается выполненным, если сохраняется хотя бы один из сценариев:

* пользователь спросил про аномалию, а получил список без признаков аномальности;
* пользователь задал многосоставной вопрос, а ассистент ответил только на один фрагмент без явной маркировки;
* ответ предметно съехал в другой участок учёта;
* ответ содержит ссылки, route names, trace или sandbox-пояснения вместо нормального объяснения;
* ассистент дал формально связный, но необоснованный вывод без основания отбора.

---

## 16. Короткий итог для разработчика

Задача следующего этапа — не просто улучшить текст ответа.

Задача этапа:

* сделать декомпозицию **полной**, а не частичной;
* сделать ответ **объяснимым**, а не декоративно-человекочитаемым;
* заставить ассистента **доказывать**, почему он выбрал именно эти записи;
* запретить выдачу ответа, если система не может подтвердить предметную релевантность и полноту покрытия вопроса.

---

Если хочешь, следующим сообщением я сразу соберу ещё и **сверхкороткую версию для Codex/разработчика на 1 экран**, без пояснений, только требования и acceptance criteria.
