АДРЕСНЫЙ РЕЖИМ - M2.3b тюнинг account-scope и диагностика стадий адресного рантайма

This commit is contained in:
2026-03-29 20:57:55 +03:00
parent c82ebd70b7
commit 2bf16de4ea
498 changed files with 2619075 additions and 3 deletions
@@ -0,0 +1,123 @@
# Этап 4 — Архитектурный аудит под MCP-first адресные запросы
Дата: 2026-03-29
Контур: `X:\1C\NDC_1C`
## 1) Цель аудита
Понять, в каком состоянии проект перед переходом на новый класс задач:
- "покажи незакрытые договоры";
- "найди, кому мы должны";
- "найди, кто должен нам";
- "покажи остаток по счету".
И зафиксировать, что нужно поменять в рантайме, чтобы это работало как **LLM-интерфейс к живой 1С через MCP**.
## 2) Подтвержденные факты (as-is)
### 2.1 Assistant runtime сейчас snapshot-first
Текущий `AssistantDataLayer` поднимает данные из фиксированного набора JSON-файлов из `docs/ARCH/2020экспорт`, а не из полного корпуса:
- `llm_normalizer/backend/src/services/assistantDataLayer.ts:3379-3386`
- `llm_normalizer/backend/src/services/assistantDataLayer.ts:3401`
Размер подключенного snapshot-пакета:
- `docs/ARCH/2020экспорт` = **1.82 MB** (10 файлов).
### 2.2 Полный monthly-корпус есть, но в assistant runtime не используется
Объем полного корпуса:
- `docs/ARCH/2020_monthly_company_asof_full/_tmp_ndjson` = **6732 MB** (12 файлов),
- средний файл ≈ **561 MB**.
Итог: по текущему коду assistant работает по сильно урезанному слою данных относительно доступного объема.
### 2.3 MCP/live есть, но как overlay и только на части маршрутов
Live-путь в assistant включается только если:
- `FEATURE_ASSISTANT_MCP_RUNTIME_V1=true`
(`llm_normalizer/backend/src/config.ts:90-100`)
и только для маршрутов:
- `hybrid_store_plus_live`
- `live_mcp_drilldown`
(`llm_normalizer/backend/src/services/assistantDataLayer.ts:2863`)
Для `store_canonical` live не используется.
### 2.4 Claim-bound live план в `assistantDataLayer` ориентирован на 3 семейства
`buildLiveMcpCallPlan(...)` имеет claim-ветки:
- `prove_fixed_asset_amortization_coverage` (`assistantDataLayer.ts:348`)
- `prove_vat_chain_completeness` (`assistantDataLayer.ts:396`)
- `prove_rbp_tail_state` (`assistantDataLayer.ts:460`)
Остальное уходит в `claim_type: null` + generic live probe (`assistantDataLayer.ts:444`).
Это не покрывает "простые адресные запросы" как отдельный runtime-класс.
### 2.5 Route-дисциплина сейчас заточена под Stage 4 глубинные цепочки
В `routeHintAdapter` есть жесткие query-class rules:
- `exact_object_trace -> live_mcp_drilldown` (`routeHintAdapter.ts:86-87`)
- `canonical_fact_lookup -> store_canonical` (`routeHintAdapter.ts:149-150`)
В результате простые lookup-вопросы по умолчанию тяготеют к `store_canonical` (snapshot), а не к MCP-first.
### 2.6 Postgres в assistant runtime фактически не активен
По проекту:
- в `.env.example` дефолт `CANONICAL_DB_URL=sqlite:///...`
(`.env.example:18`, `README.md:89`)
- `canonical_layer/store.py` поддерживает и SQLite, и Postgres через SQLAlchemy
(`canonical_layer/store.py:55`, `canonical_layer/store.py:59`)
На момент аудита:
- локально есть `data/canonical_store.db` (SQLite);
- активного процесса `postgres` не обнаружено.
Важно: текущий `llm_normalizer/backend` **не использует** `canonical_layer` store напрямую в assistant execution path.
## 3) Главный технический вывод
Зафиксирован статус:
**SNAPSHOT_PRIMARY_WITH_OPTIONAL_LIVE_OVERLAY_CONFIRMED**
То есть:
- live-инфраструктура есть;
- но архитектурно основной путь ассистента по-прежнему snapshot-first;
- адресные "быстрые" бизнес-запросы как отдельный MCP-first runtime-класс пока не оформлены.
## 4) Что точно не бьется с новой задачей
1. `store_canonical` = snapshot path, а нам нужен live-first для адресных запросов.
2. Нет отдельного address-intent и address-query planner.
3. Нет acceptance-метрик для "быстрого доступа к сущностям" (не reasoning-heavy).
4. Нет отдельного answer contract под tabular/list-ответы для live lookup.
## 5) Рамка изменения (без слома Stage 4 deep path)
Меняем не всю архитектуру, а добавляем новый lane:
- `address_query_runtime` как отдельный класс в существующем assistant pipeline;
- приоритет источника для этого класса: `live_mcp` (mandatory), snapshot только как явно маркированный fallback;
- Stage 4 deep chain path оставляем как есть.
## 6) Финальный verdict аудита
**MCP_INFRA_EXISTS_BUT_ADDRESS_RUNTIME_NOT_IMPLEMENTED**
Новый функционал реализуем через отдельный MCP-first address lane, без тотального рефакторинга текущего Stage 4 chain runtime.
@@ -0,0 +1,125 @@
# Target Architecture — MCP-first Address Queries (Stage 4)
Дата: 2026-03-29
## 1) Что вводим
Добавляем в текущий assistant runtime новый режим:
- `question_mode = address_query`
Это не замена deep-chain логики Stage 4, а параллельный "быстрый" lane для адресных вопросов.
## 2) Типы вопросов для первого релиза (Address V1)
Минимальный набор:
1. `list_open_contracts`
2. `list_payables_counterparties` (кому мы должны)
3. `list_receivables_counterparties` (кто должен нам)
4. `account_balance_snapshot` (остатки по счету / счетам)
5. `open_items_by_counterparty_or_contract` (незакрытые хвосты по контрагенту/договору)
## 3) Принцип источников данных
Для `address_query`:
- primary source: `MCP/live` (обязательно);
- snapshot-source: только fallback с явной маркировкой;
- запрещено молча подменять live на snapshot.
Правило ответа:
- если live недоступен: честный `DATA_UNAVAILABLE_LIVE`;
- если live доступен, но пусто: честный `NO_MATCH_FOR_FILTERS`;
- если live дал строки: `FACTUAL_LIST`/`FACTUAL_SUMMARY`.
## 4) Pipeline (встраивание в текущую архитектуру)
Новая ветка поверх текущего пайплайна:
1. `Normalizer` -> определяет `question_mode=address_query` и `address_intent`.
2. `AddressIntentResolver` -> фиксирует intent + обязательные фильтры (period/account/counterparty/contract).
3. `AddressQueryPlanner` -> выбирает MCP recipe (query template + params).
4. `McpExecutor` -> исполняет 1..N live-вызовов.
5. `AddressResultMaterializer` -> нормализует строки в табличный вид + totals.
6. `AddressAnswerComposer` -> короткий ответ + список + ограничения.
## 5) MCP query recipes (контракт)
Для каждого intent хранится recipe:
- `recipe_id`
- `purpose`
- `query_template`
- `required_params`
- `optional_params`
- `output_schema`
- `sort/default_limit`
Примеры базовых рецептов:
- `address.open_contracts.by_period`
- `address.payables.counterparty_totals`
- `address.receivables.counterparty_totals`
- `address.balance.by_account`
- `address.open_items.by_counterparty_contract`
## 6) Контракт ответа (Address mode)
Форматы:
1. `FACTUAL_LIST`
Короткий вывод + список строк (N top) + totals.
2. `FACTUAL_SUMMARY`
Если строк много: агрегат + top контрагенты + рекомендация уточнить фильтры.
3. `LIMITED_WITH_REASON`
Если live недоступен/ошибка/нехватка фильтров.
Обязательные поля debug:
- `question_mode`
- `address_intent`
- `recipe_id`
- `required_filters`
- `resolved_filters`
- `mcp_calls[]`
- `rows_fetched`
- `rows_matched`
- `result_mode`
## 7) Совместимость с текущим Stage 4
Не ломаем текущие chain-ветки:
- `settlements_60_62`, `vat_document_register_book`, `month_close_costs_20_44`, `fixed_asset_amortization` остаются.
- `address_query` включается только при явном address-intent.
Приоритет:
- если вопрос "why/how/prove/chain" -> текущий deep path;
- если вопрос "show/list/find/open/balance" -> address path.
## 8) Границы (что не делаем)
1. Не вводим новый proof engine.
2. Не расширяем домены beyond P0/P1 для V1.
3. Не делаем большой redesign routing.
4. Не зависим от Postgres как обязательного prereq для Address V1.
## 9) Техническое решение по Postgres
Коротко:
- Postgres оставляем как optional storage path для canonical layer;
- Address V1 делаем MCP-first без блокировки на миграцию в Postgres;
- отдельный migration pack можно делать потом, когда будет нужна materialized аналитика/кеши.
## 10) Архитектурный verdict
**ADDRESS_LANE_MCP_FIRST_IS_COMPATIBLE_WITH_CURRENT_STAGE4_RUNTIME**
То есть новый функционал можно внедрить итеративно, не вынося проект в тяжелый рефактор.
@@ -0,0 +1,148 @@
# Execution Plan — Address Runtime (Wave A..D)
Дата: 2026-03-29
Фокус: быстрый LLM-интерфейс к 1С сущностям через MCP/live.
## Общий подход
Делаем отдельный пакет, без большого неразмеченного рефакторинга:
- Wave A: baseline + contracts
- Wave B: runtime lane + planner
- Wave C: recipes + answer contract
- Wave D: live rerun + acceptance
## Wave A — Baseline & Contracts
### Цель
Зафиксировать source-of-truth и контракты перед кодом.
### Что делаем
1. Вводим `question_mode=address_query`.
2. Фиксируем V1 intents (5 штук).
3. Фиксируем `address_query_recipe` контракт.
4. Фиксируем обязательные debug поля и run-артефакты.
### Артефакты
- `docs/ADDRESS/runs/<run_id>/README.md`
- `run_summary.json`
- `address_intent_contract.md`
- `address_recipe_contract.md`
## Wave B — Runtime Lane
### Цель
Встроить новый lane в текущий assistant pipeline.
### Что делаем
1. Добавляем `AddressIntentResolver`.
2. Добавляем `AddressQueryPlanner`.
3. Добавляем source policy:
- `address_query => live_required=true`
- fallback на snapshot только явно и с limitation.
4. Разводим маршруты:
- deep reasoning path не трогаем;
- address path идет отдельной веткой.
### Acceptance
- Address intent корректно выделяется на контрольном наборе.
- Для address-intent не происходит тихого ухода в snapshot-first.
## Wave C — Query Recipes & Answer Contract
### Цель
Сделать рабочие адресные ответы по MCP.
### Что делаем
1. Реализуем минимум 5 MCP recipes (по intent V1).
2. Делаем materializer:
- rows -> normalized list,
- totals,
- stable output schema.
3. Добавляем `AddressAnswerComposer`:
- `FACTUAL_LIST`,
- `FACTUAL_SUMMARY`,
- `LIMITED_WITH_REASON`.
### Acceptance
- На expected-positive вопросах есть непустой factual output.
- Ошибки live не маскируются, false factual = 0.
## Wave D — Live Replay & Acceptance
### Цель
Проверить live-сценарии на реальных адресных вопросах.
### Контрольный набор (минимум)
1. Покажи незакрытые договоры.
2. Кому мы должны денег.
3. Кто должен нам денег.
4. Остатки по счету 60 (или 62) на текущую дату.
5. Незакрытые позиции по конкретному контрагенту.
### Метрики
1. `address_intent_resolution_rate >= 0.95`
2. `address_live_call_success_rate >= 0.95`
3. `address_non_empty_result_rate > 0` на positive-кейсах
4. `address_false_factual_rate = 0`
5. `address_snapshot_fallback_rate` (должна быть низкой и явной)
### Обязательные артефакты
- `chat_export_address_live.md`
- `debug_payloads/`
- `live_call_inventory.json`
- `address_result_matrix.md`
- `address_failure_breakdown.json`
## Run-структура (обязательно)
Все прогоны только сюда:
- `docs/ADDRESS/runs/<YYYY-MM-DD>_<PackName>/`
## Риски и анти-риски
Риск:
- смешение deep-chain и address-lane в одном вопросе.
Контрмера:
- rule-based switch по `question_mode` + explicit fallback в mixed-mode.
Риск:
- деградация в silent snapshot.
Контрмера:
- mandatory debug flag `live_required_for_mode=true`,
- limitation если live недоступен.
## Финальный критерий пакета
Пакет считается принятым, когда:
1. Address intent стабильно маршрутизируется в MCP-first lane.
2. На части live-кейсов система дает быстрый factual ответ.
3. Нет ложной "доказанности" и нет молчаливой подмены источника.
Verdict:
- `ADDRESS_RUNTIME_V1_READY`
- или `ADDRESS_RUNTIME_V1_READY_WITH_LIMITATIONS`
- или `ADDRESS_RUNTIME_V1_NOT_READY`
@@ -0,0 +1,31 @@
# ADDRESS Track (MCP-first)
Этот раздел фиксирует разворот Stage 4 в сторону "адресных" пользовательских запросов:
- быстро найти сущности;
- показать список и статус (есть/нет, закрыто/не закрыто);
- получить остатки/долги/контрагентов по текущему состоянию базы.
Ключевой принцип трека: **MCP/live-first**, а не snapshot-first.
## Документы
1. `1 - architecture_audit_mcp_first_address_runtime_2026-03-29.md`
Технический аудит текущего состояния и ограничений.
2. `2 - target_architecture_mcp_first_address_queries_stage4_2026-03-29.md`
Целевая архитектура под адресные запросы.
3. `3 - execution_plan_address_runtime_waveA_waveD_2026-03-29.md`
Пошаговый план реализации без большого рефакторинга.
## Раны и артефакты
Все новые прогоны и доказательные артефакты складываются в:
- `docs/ADDRESS/runs/`
Базовый аудитный run:
- `docs/ADDRESS/runs/2026-03-29_Address_Runtime_Pivot_Baseline/`