# Region Resolver ## Purpose TZ-08 adds an offline Kazakhstan Region Resolver for the dialogue layer. It normalizes user text, maps Russian/Kazakh/Latin aliases to stable `region_code` values, and prevents the conversation from reaching `READY_TO_HELP` until a supported region is selected. The resolver does not call external APIs, does not infer region from caller number, and does not use default region fallback. ## Supported Active Regions Active catalog size: 20 regions. Republic cities: - `astana_city` - Астана / Астана - `almaty_city` - город Алматы / Алматы қаласы - `shymkent_city` - Шымкент / Шымкент Oblasts: - `akmola_region` - Акмолинская область / Ақмола облысы - `aktobe_region` - Актюбинская область / Ақтөбе облысы - `almaty_region` - Алматинская область / Алматы облысы - `atyrau_region` - Атырауская область / Атырау облысы - `east_kazakhstan_region` - Восточно-Казахстанская область / Шығыс Қазақстан облысы - `zhambyl_region` - Жамбылская область / Жамбыл облысы - `west_kazakhstan_region` - Западно-Казахстанская область / Батыс Қазақстан облысы - `karaganda_region` - Карагандинская область / Қарағанды облысы - `kostanay_region` - Костанайская область / Қостанай облысы - `kyzylorda_region` - Кызылординская область / Қызылорда облысы - `mangystau_region` - Мангистауская область / Маңғыстау облысы - `pavlodar_region` - Павлодарская область / Павлодар облысы - `north_kazakhstan_region` - Северо-Казахстанская область / Солтүстік Қазақстан облысы - `turkistan_region` - Туркестанская область / Түркістан облысы - `abai_region` - область Абай / Абай облысы - `jetisu_region` - область Жетісу / Жетісу облысы - `ulytau_region` - область Ұлытау / Ұлытау облысы Optional disabled special region: - `baikonur_special` - Байконур / Байқоңыр, disabled by default. ## Aliases And Normalization The resolver supports RU, KK, Latin, abbreviations, legacy names, and ASR-ish spellings. Examples include `нурсултан`, `нұр-сұлтан`, `alma-ata`, `shymkent`, `chimkent`, `ВКО`, `ЗКО`, `СКО`, `vko`, `zko`, and `sko`. Normalization trims spaces, lowercases, converts `ё` to `е`, treats hyphens as spaces, collapses repeated spaces, removes harmless punctuation, preserves Kazakh Cyrillic letters, and handles forms like `г. Алматы`, `Алматы қаласы`, and `Алматинская обл.`. ## Ambiguity Bare `Алматы` and `almaty` are intentionally ambiguous because they can mean the city or Almaty region. The orchestrator stores pending candidates and asks: - RU: `Вы имеете в виду город Алматы или Алматинскую область?` - KK: `Алматы қаласын айттыңыз ба, әлде Алматы облысын ба?` Then these clarifications are accepted: - `город`, `қала`, `Алматы қаласы` -> `almaty_city` - `область`, `облыс`, `Алматинская область`, `Алматы облысы` -> `almaty_region` ## Selection Policy - `LANGUAGE_SELECTION`: region mentions are ignored; language must be selected first. - `REGION_SELECTION`: clear enabled region applies; ambiguous input asks clarification; unsupported region is denied. - `READY_TO_HELP` and `QUESTION_ANSWERING`: region changes only on explicit request such as `сменить регион на Астану`. - `HANDOFF`, `CLOSING`, `ENDED`: region changes are denied. The hard guardrail remains in code: `search_knowledge_base` is denied unless language is `ru` or `kk`, region status is `selected`, `region_code` is non-empty, and state is `READY_TO_HELP` or `QUESTION_ANSWERING`. ## Integration `Dialogue Orchestrator` calls the resolver from `HandleUserText` and `set_region` tool handling. Stored region display names come from the catalog, not from tool arguments. `VoiceEventUserTranscriptDone` continues to route through `HandleUserText`, so future ASR transcripts use the same resolver path. Assistant transcript and audio events do not trigger region changes. ## CLI Run resolver checks: ```bash ./bin/ai-operator doctor --env /etc/ai-operator/ai-operator.env --check-region ``` Run deterministic self-test without Asterisk, OpenAI, or DB: ```bash ./bin/ai-operator region-self-test --env /etc/ai-operator/ai-operator.env ``` ## Safety TZ-08 does not change Asterisk configs, does not reload/restart Asterisk, does not call OpenAI, does not install PostgreSQL, and does not switch production routing. ## Not Implemented Yet - Knowledge Base / RAG - final business prompt - real business tools - production route switching ## TZ-09 Knowledge Base Update TZ-09 adds PostgreSQL + pgvector, KGA JSONL ingestion, fake embeddings, hybrid KB search, cross-language fallback for KK queries, citations, and `search_knowledge_base` integration behind the existing language/region guardrail. OpenAI is not called automatically and production routing remains disabled. ## TZ-10 Agent Integration The agent prompt keeps region selection as the second required action. Business questions in `REGION_SELECTION` must repeat the region request and must not trigger KB search. Region changes after readiness remain explicit-only.