ДОМЕНЫ - ВОПРОСЫ - ОРРКЕСТРАЦИЯ - БАЗА - Поднять внешний domain-case loop для Codex с baseline/rerun артефактами

This commit is contained in:
2026-04-13 19:37:57 +03:00
parent f64980fa13
commit 8e16bc1f01
59 changed files with 2663 additions and 46 deletions
+12 -1
View File
@@ -1,8 +1,19 @@
# 1CLLMARCH Fact Check And Stabilization Plan
Updated at: 2026-04-11
Updated at: 2026-04-13
Source baseline: `docs/TECH/1CLLMARCH.md`
## Update 2026-04-13
- Exact capability for open contracts as-of date is now implemented:
- `open_contracts_confirmed_as_of_date`
- `address_open_contracts_confirmed_as_of_date_v1`
- The former `list_open_contracts` path remains only as diagnostic heuristic-layer and is no longer the target final route for direct business wording.
- The main remaining gap for this domain is now presentation/entity quality, not route existence:
- net/gross aggregation,
- special vs dirty split,
- contract/counterparty identity quality.
## 1. Purpose
This document fixes the current factual state of the codebase against `1CLLMARCH` and records a production-focused stabilization plan that preserves:
+51 -28
View File
@@ -1,52 +1,75 @@
# Статус проекта на 2026-04-12
# Статус проекта на 2026-04-13
Файл сохранен под историческим именем `STATUS_2026-04-12.md`, но содержимое актуализировано по коду и тестам на 2026-04-13.
## 1) Что уже стабильно в compute-слое
- Введены и работают exact-маршруты подтвержденного среза на дату:
- В runtime закреплены exact-маршруты подтвержденного среза на дату:
- `payables_confirmed_as_of_date` (`address_payables_confirmed_as_of_date_v1`)
- `receivables_confirmed_as_of_date` (`address_receivables_confirmed_as_of_date_v1`)
- `vat_payable_confirmed_as_of_date` (`address_vat_payable_confirmed_as_of_date_v1`)
- Для этих интентов зафиксирован expected route/result mode в:
- `vat_liability_confirmed_for_tax_period` (`address_vat_liability_confirmed_tax_period_v1`)
- `open_contracts_confirmed_as_of_date` (`address_open_contracts_confirmed_as_of_date_v1`)
- Для exact-сценариев зафиксирован контракт:
- `requested_result_mode = confirmed_balance`
- `result_mode = confirmed_balance`
- `capability_route_mode = exact`
- Для открытых договоров прямой бизнес-вопрос больше не идет в heuristic shortlist:
- exact-вопросы маршрутизируются в `open_contracts_confirmed_as_of_date`;
- `list_open_contracts` сохранен как диагностический heuristic-слой, а не как substitute для exact-ответа.
- Для exact-интентов ожидания маршрутов закреплены в:
- `docs/TECH/address_route_expectations_v1.json`
- Режим результата для exact-сценариев закреплен как `confirmed_balance`.
## 2) Что исправлено в цепных (follow-up) вопросах
## 2) Что доведено в follow-up и presentation-слое
- Исправлен перенос даты среза в коротких продолжениях по долгам:
- после вопроса о долгах на дату follow-up по дебиторке наследует `as_of_date`, если новая дата не задана явно.
- Добавлен короткий follow-up для НДС:
- короткие реплики вида `а ндс?`/`по ндс` теперь корректно идут в VAT exact-route с переносом даты среза из контекста.
- Сохранена стратегия LLM-first нормализации с последующим детерминированным compute-роутингом.
- Короткие follow-up-вопросы продолжают использовать дату среза из контекста, если новая дата явно не задана.
- Для debt/VAT/open-contracts контуров сохранена схема `LLM-first normalize -> deterministic compute route`.
- Для exact-кейса открытых договоров presentation-слой стал бизнесовее:
- появился `net/gross` слой поверх точного среза;
- одна детальная строка = один договор, один контрагент, один тип открытого остатка;
- смешанные экономические смыслы не склеиваются в одну строку;
- отдельными блоками вынесены `финансовые/специальные` и `спорные/некачественно нормализованные` позиции.
- Для open-contracts exact-core отделен от heuristic diagnostics: улучшения бизнес-вывода больше не требуют менять сам route.
## 3) Что уже покрыто тестами
- Добавлены/актуализированы тесты на carryover и follow-up:
- Актуальный целевой regression-gate:
- `llm_normalizer/backend/tests/addressQueryRuntimeM23.test.ts`
- `llm_normalizer/backend/tests/assistantAddressFollowupContext.test.ts`
- Проверен маршрутный baseline:
- `llm_normalizer/backend/tests/addressRouteBaseline.test.ts`
- `llm_normalizer/backend/tests/assistantLivingRouter.test.ts`
- `llm_normalizer/backend/tests/assistantWave17RunRegression20260411.test.ts`
- Текущий кодовый результат:
- `367/367` PASS.
- В тестах отдельно закрыты:
- exact routing для `open_contracts_confirmed_as_of_date`;
- отсутствие silent degrade в heuristic для прямого exact-запроса;
- business-view блоков `net/gross` и вынос грязных сущностей в спорный блок.
## 4) Известные ограничения (не считать багом расчета)
## 4) Известные ограничения (не считать поломкой exact-core)
- В разговорных нерелевантных репликах (эмоции/брань/односложные сообщения) система может уйти в `clarification_required`; это относится к conversational-слою, не к compute-расчету.
- `query_shape` в части exact-кейсов может оставаться `UNKNOWN` при корректном `intent`; расчетный маршрут при этом работает корректно.
- Качество бизнес-категоризации контрагентов (особенно по счету 76) требует отдельной донастройки presentation-слоя.
- `query_shape` в части exact-кейсов может оставаться `UNKNOWN` при корректном `intent`; сам вычислительный маршрут при этом работает корректно.
- В exact-кейсе открытых договоров главный остаточный риск теперь не в маршрутизации, а в качестве бизнес-сущностей:
- неидеальная идентичность `contract_label` / `counterparty_label`;
- грязные аналитики по счету `76`;
- дальнейшее улучшение executive-summary поверх уже точного среза.
- `list_open_contracts` по-прежнему heuristic и должен использоваться только как диагностический слой.
- `COMPOUND_FACTUAL_QUERY` остается detection-only: multi-intent execution в runtime пока не включен.
## 5) Что в приоритете дальше
1. НДС-контур: усилить доказательную часть расчета "к уплате на дату" и добавить понятную детализацию оснований.
2. Цепные вопросы: закрепить перенос контекста между payables/receivables/VAT во всех коротких follow-up формулировках.
3. Ответы для UI: довести формат вывода до стабильной блочной структуры без markdown-зависимости.
4. Категоризация: отделить поставщиков/заказчиков от банков/госорганов/спецобязательств в итоговой выдаче.
1. НДС-контур: усилить exact evidence layer для ответов “НДС к уплате / обязательство за период/на дату”.
2. Открытые договоры: усилить quality gates для `contract/counterparty identity`, особенно на `76` и специальных расчетах.
3. UI-ответы: довести exact business view до executive-summary уровня без потери доказательности.
4. Compound factual queries: не расширять домены раньше, чем появится контролируемый multi-intent execution.
## 6) Быстрый smoke-check (ручной)
1. ому мы должны на сентябрь 2017`
2. `а нам кто должен?`
3. `кто нам должен на сентябрь 2017`
4. `а ндс?`
1. акие есть открытые договора на май 2020`
2. `а по ним кто нам должен и кому должны мы?`
3. `скок надо ндс платить на март 2020`
4. `а на эту же дату`
Ожидаемое поведение:
- для 1/3`confirmed_balance` в exact-route,
- для 2/4 — корректный follow-up с переносом даты среза, без ухода в эвристический shortlist для exact-интентов.
- для 1 — exact route `open_contracts_confirmed_as_of_date`, `confirmed_balance`, без подмены на heuristic shortlist;
- для 2 — follow-up c сохранением даты и корректным переключением домена;
- для 3/4 — exact VAT/payables route с переносом даты среза, если пользователь не задал новую.
@@ -0,0 +1,176 @@
# Address Query Spec: Confirmed Open Contracts As Of Date
## 1. Контекст проблемы
Запросы вида:
- `какие есть открытые договора на май 2020`
- `какие договоры открыты на 31.05.2020`
- `покажи открытые договоры на дату`
относятся к классу **балансных договорных запросов** и требуют точного среза открытых взаиморасчетов на дату.
Историческая проблема состояла в том, что сценарий `list_open_contracts` долгое время жил как heuristic shortlist по движениям `60/62/76`. Для диагностики это полезно, но для прямого бизнес-ответа недостаточно.
## 2. Цель
Ввести и зафиксировать exact-capability `open_contracts_confirmed_as_of_date`, который:
- строит подтвержденный срез договоров с ненулевым остатком взаиморасчетов на дату;
- не подменяется heuristic shortlist в финальном пользовательском ответе;
- показывает не только точные компоненты, но и управленческий `net/gross` view поверх них;
- отделяет специальные валидные позиции от грязных/некачественно нормализованных сущностей.
## 3. Базовая бизнес-дефиниция
`Открытый договор = договор, по которому на дату среза есть ненулевой остаток взаиморасчетов.`
По умолчанию это не означает:
- “активный по карточке договора”;
- “не исполненный по предмету договора”;
- “просроченный по сроку оплаты”.
Это именно балансный срез открытых расчетов.
## 4. Канонический runtime-контракт
- `intent = open_contracts_confirmed_as_of_date`
- `recipe_id = address_open_contracts_confirmed_as_of_date_v1`
- `requested_result_mode = confirmed_balance`
- `result_mode = confirmed_balance`
- `capability_route_mode = exact`
- `query_template = open_contracts_confirmed_as_of_balance_profile`
- `account_scope = 60/62/76`
- `account_scope_mode = strict`
## 5. Источник данных
Основной источник:
- `РегистрБухгалтерии.Хозрасчетный.Остатки(<as_of_date>)`
Контур включает остатки по счетам:
- `60*`
- `62*`
- `76*`
Сценарий использует exact snapshot по остаткам, а не только movement-shortlist.
## 6. Единицы агрегации
### 6.1 Exact component row
Минимальная детальная единица ответа:
- один договор;
- один контрагент;
- один тип открытого остатка.
Поддерживаемые типы компонентов:
- `receivable`
- `payable`
- `advance_issued`
- `advance_received`
- `other_receivable`
- `other_payable`
### 6.2 Management profile row
Поверх component-уровня собирается второй слой:
- `contract + counterparty`
- `net_open_balance`
- `gross_open_balance`
- `balance_components[]`
Именно этот слой нужен для бизнес-чтения, чтобы не воспринимать противоположные компоненты как дубли.
## 7. Категории результата
### 7.1 Commercial
Нормально нормализованный договорный профиль, пригодный для основного бизнес-списка.
### 7.2 Special valid
Позиция не коммерческая, но валидная по смыслу:
- финансовые/банковские договоры;
- специальные расчетные позиции.
### 7.3 Dirty unresolved
Позиция точная по балансу, но грязная по сущностям:
- не удалось надежно определить контрагента;
- договор не похож на устойчивый договорный реквизит;
- в поле договора похоже попал контрагент или чужая аналитика;
- по одному договору нашлось несколько конфликтующих контрагентов.
Такие строки не должны смешиваться с основным коммерческим блоком.
## 8. Quality gates
### 8.1 Contract identity gate
Строка не считается качественной коммерческой строкой, если `contract_label`:
- слишком короткий;
- похож на юрлицо, а не на договор;
- совпадает с `counterparty_label`;
- выглядит как служебная аналитика.
### 8.2 Counterparty identity gate
Строка не считается чистой, если:
- контрагент не определен;
- в поле контрагента попал текст договора/служебная аналитика;
- контрагент конфликтует между компонентами одного профиля.
## 9. Политика fallback
Для `open_contracts_confirmed_as_of_date` запрещено:
- тихо деградировать в `heuristic_candidates` как финальный ответ;
- выдавать diagnostic shortlist вместо точного snapshot без явной маркировки.
Допустимый fallback только один:
- `LIMITED_WITH_REASON`, если exact не удалось собрать.
`list_open_contracts` допускается только как отдельный heuristic diagnostic capability.
## 10. Контракт ответа
### 10.1 Exact business answer
Ответ должен содержать:
1. статус exact-результата;
2. дату среза;
3. `net` и `gross` summary;
4. блок `чистый открытый остаток по договорам`;
5. блоки детальных компонентов;
6. отдельный блок `финансовые/специальные позиции`;
7. отдельный блок `спорные/некачественно нормализованные позиции`.
### 10.2 Что пользователь не должен видеть
- `0` и пустые account placeholders;
- смешение противоположных остатков в одной строке;
- грязные entity labels в основном коммерческом блоке.
## 11. Acceptance criteria
1. Прямой вопрос про открытые договоры на дату идет в `open_contracts_confirmed_as_of_date`, а не в `list_open_contracts`.
2. Финальный exact-ответ имеет:
- `result_mode = confirmed_balance`
- `balance_confirmed = true`
- `capability_route_mode = exact`
3. Для одного договора возможны несколько component-строк, но management-view показывает также `net/gross` профиль.
4. Специальные валидные позиции и грязные сущности разведены в разные блоки.
5. Heuristic shortlist не подменяет exact output.