# Address Runtime Contracts V1 (M2.3c) Дата: 2026-03-29 Reference: - `address_architecture_contract_v1.md` (architecture guardrails and stage boundaries). ## Runtime Policy - Runtime lane is `data-agnostic`: no hardcoded counterparties/contracts/accounts from one concrete base. - Acceptance lane is `data-aware`: positive cases are curated after exploratory live pass. - Address lane remains MCP/live-first, whitelist-only, read-only. - Runtime execution is MSP-only in production; snapshot usage is explicit fallback only. - Canonical pipeline boundary: `Decompose -> Resolve -> Execute -> Compose` (no cross-stage leakage). - LLM decompose stage interprets question structure only; company entities are resolved only in live resolver stage. ## Input Contract - `question_mode`: `address_query | deep_analysis | unsupported` - `address_intent`: nullable enum - `resolved_filters`: object - `missing_filters`: string[] ## Debug Contract - `detected_mode` - `query_shape` - `detected_intent` - `runtime_readiness` - `is_compound_query` - `subqueries_count` - `resolved_entities` - `resolved_filters` - `missing_filters` - `selected_recipe_ids` - `selected_recipe` - `account_scope_mode` - `account_scope_fallback_applied` - resolver block: - `anchor_type` - `anchor_value_raw` - `anchor_value_resolved` - `resolver_confidence` - `ambiguity_count` - MCP/evidence flow block: - `mcp_call_status` - `mcp_call_status_legacy` - `match_failure_stage` - `match_failure_reason` - `rows_fetched` - `raw_rows_received` - `rows_after_account_scope` - `rows_materialized` - `rows_after_recipe_filter` - `rows_matched` - `raw_row_keys_sample` - `materialization_drop_reason` - account-scope audit block: - `account_token_raw` - `account_token_normalized` - `account_scope_fields_checked` - `account_scope_match_strategy` - `account_scope_drop_reason` - `response_type` - `limited_reason_category` - `fallback_reason` ## Output Contract ### FACTUAL_LIST - short summary - rows[] - totals ### FACTUAL_SUMMARY - aggregate summary - top rows - optional drilldown hints ### LIMITED_WITH_REASON - explicit reason code - missing filters / data availability note ## Limited Reason Taxonomy - `empty_match` - live-запрос выполнен, но по фильтру нет строк. - `missing_anchor` - не хватает обязательного якоря (контрагент/договор/счет/период). - `recipe_visibility_gap` - текущий recipe не материализует нужную аналитику. - `execution_error` - ошибка MCP/инфраструктуры/feature-flag. - `unsupported` - вопрос не покрыт address-intent V1. ## Runtime Readiness Status - `LIVE_QUERYABLE` - `LIVE_QUERYABLE_WITH_LIMITS` - `REQUIRES_SPECIALIZED_RECIPE` - `DEEP_ONLY` - `UNKNOWN` ## MCP Stage Status Taxonomy (M2.3c) - `skipped` - `error` - `no_raw_rows` - `raw_rows_received_but_not_materialized` - `materialized_but_not_anchor_matched` - `materialized_but_filtered_out_by_recipe` - `matched_non_empty` Legacy compatibility: - `mcp_call_status_legacy` may still report `materialized_but_not_matched` for backward-compatible analytics. ## Materialization Drop Reasons (M2.3c) - `none` - `dropped_by_account_scope_filter` - `missing_period_and_registrator_fields` - `missing_period_field` - `missing_registrator_field` - `unknown_row_shape` ## Account Scope Strategy (M2.3c) - `strict` - account scope is mandatory and applied as a hard filter. - `preferred` - account scope is applied first; if it yields zero rows while raw rows exist, runtime falls back to raw rows and continues matching. ## M2.3c Runtime Snapshot - Counterparty intents now have confirmed `matched_non_empty` cases in curated live suite. - Account intents still mostly stop at `raw_rows_received_but_not_materialized`. - Guardrails remain unchanged: no free query generation, no false factual outputs. ## Compound Query Note - `COMPOUND_FACTUAL_QUERY` currently remains detection-only. - Multi-intent decomposition execution is planned for the next increment. ## Guardrails - whitelist recipes only - read-only MCP - no free-form query generation - no silent source substitution