# Address Runtime Contracts V1 (Code Sync) Дата: 2026-04-02 Reference: - `address_architecture_contract_v1.md` (guardrails and stage boundaries) - `llm_normalizer/backend/src/types/addressQuery.ts` - `llm_normalizer/backend/src/services/addressQueryService.ts` - `llm_normalizer/backend/src/services/assistantService.ts` (`buildAddressDebugPayload`) ## Runtime Policy - Runtime lane is `data-agnostic`: без company-specific словарей в коде. - Acceptance lane is `data-aware`: позитивные live-кейсы подбираются отдельно. - Address lane: MCP/live-first, whitelist-only, read-only. - Canonical boundary: `Decompose -> Resolve -> Execute -> Compose`. - LLM pre-decompose интерпретирует текст, но не подменяет whitelist execution. ## Input Contract - `question_mode`: `address_query | deep_analysis | unsupported` - `address_intent`: enum intents + `unknown` - `extracted_filters`: object - `missing_required_filters`: string[] ## Debug Contract (actual payload) Core detection: - `detected_mode` - `detected_mode_confidence` - `query_shape` - `query_shape_confidence` - `detected_intent` - `detected_intent_confidence` Filter + recipe: - `extracted_filters` - `missing_required_filters` - `selected_recipe` 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_scope_mode` - `account_scope_fallback_applied` - `account_token_raw` - `account_token_normalized` - `account_scope_fields_checked` - `account_scope_match_strategy` - `account_scope_drop_reason` Result block: - `runtime_readiness` - `limited_reason_category` - `response_type` - `limitations` - `reasons` Assistant-level metadata (added in `buildAddressDebugPayload`): - `llm_decomposition_attempted` - `llm_decomposition_applied` - `llm_provider_used` - `llm_decomposition_trace_id` - `llm_decomposition_effective_message` - `llm_decomposition_reason` - `fallback_rule_hit` - `sanitized_user_message` - `tool_gate_decision` - `tool_gate_reason` - `execution_lane` (`address_query`) ## Output Contract ### FACTUAL_LIST - short factual summary - rows list - optional hints ### FACTUAL_SUMMARY - aggregate summary - compact top rows ### LIMITED_WITH_REASON - explicit reason code - missing filters / data visibility note ## Limited Reason Taxonomy - `empty_match` - live запрос выполнен, но по фильтрам нет строк. - `missing_anchor` - не хватает обязательного якоря или якорь не подтвердился. - `recipe_visibility_gap` - текущий recipe не дает нужной видимости. - `execution_error` - ошибка MCP/feature-flag/инфраструктуры. - `unsupported` - intent не поддержан в Address V1. ## Runtime Readiness Status - `LIVE_QUERYABLE` - `LIVE_QUERYABLE_WITH_LIMITS` - `REQUIRES_SPECIALIZED_RECIPE` - `DEEP_ONLY` - `UNKNOWN` ## MCP Stage Status Taxonomy - `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` может быть `materialized_but_not_matched` для backward-compatible аналитики. ## Materialization Drop Reasons - `none` - `dropped_by_account_scope_filter` - `missing_period_and_registrator_fields` - `missing_period_field` - `missing_registrator_field` - `unknown_row_shape` ## Account Scope Strategy - `strict` - account scope обязателен и работает как hard filter. - `preferred` - account scope применяется first-pass; если дал 0 строк при наличии raw rows, runtime может fallback к raw rows. ## Compound Query Note - `COMPOUND_FACTUAL_QUERY` пока detection-only. - Multi-intent decomposition execution в runtime V1 не включен. ## Guardrails - whitelist recipes only - read-only MCP - no free-form query generation - no silent source substitution - false factuals are forbidden (`rows_matched > 0` required for factual)