From 9f0f7f3e7946337ec1fd219e6dc0912d07236dfe Mon Sep 17 00:00:00 2001 From: dctouch Date: Fri, 17 Apr 2026 12:54:47 +0300 Subject: [PATCH] =?UTF-8?q?=D0=90=D0=A0=D0=A7=20=D0=90=D0=9F11=20-=20?= =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82=D1=8C=20builder=20?= =?UTF-8?q?=D1=81=D0=BC=D0=B5=D1=88=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20AGENT-?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B3=D0=BE=D0=BD=D0=BE=D0=B2=20=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=87=D0=B8=D0=BD=D0=B8=D1=82=D1=8C=20meta-memory?= =?UTF-8?q?=20recall=20=D0=B2=20turnaround=2011?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ..._truth_harness_phase7_meta_domain_mix.json | 342 ++ .../agent_semantic_source_catalog.json | 3894 +++++++++++++++++ .../agent_semantic_source_catalog.md | 166 + .../services/assistantLivingModePolicy.js | 7 +- .../services/assistantMemoryRecapPolicy.js | 7 +- .../dist/services/assistantRoutePolicy.js | 58 +- .../src/services/assistantLivingModePolicy.ts | 7 +- .../services/assistantMemoryRecapPolicy.ts | 12 +- .../src/services/assistantRoutePolicy.ts | 58 +- .../tests/assistantLivingModePolicy.test.ts | 8 + .../tests/assistantMemoryRecapPolicy.test.ts | 19 + .../tests/assistantRoutePolicy.test.ts | 37 + .../data/autorun_generators/history.json | 84 + ..._20260417093144_gen-ag04170931-6bb7e5.json | 173 + ..._20260417094132_gen-ag04170941-87680e.json | 173 + ..._20260417093144_gen-ag04170931-6bb7e5.json | 67 + ..._20260417094132_gen-ag04170941-87680e.json | 67 + scripts/agent_semantic_pack_builder.py | 505 +++ scripts/domain_truth_harness.py | 2 + scripts/scenario_acceptance_policy.py | 52 +- scripts/test_agent_semantic_pack_builder.py | 38 + scripts/test_scenario_acceptance_policy.py | 54 + 22 files changed, 5765 insertions(+), 65 deletions(-) create mode 100644 docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json create mode 100644 docs/orchestration/agent_semantic_source_catalog.json create mode 100644 docs/orchestration/agent_semantic_source_catalog.md create mode 100644 llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json create mode 100644 llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417094132_gen-ag04170941-87680e.json create mode 100644 llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260417093144_gen-ag04170931-6bb7e5.json create mode 100644 llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260417094132_gen-ag04170941-87680e.json create mode 100644 scripts/agent_semantic_pack_builder.py create mode 100644 scripts/test_agent_semantic_pack_builder.py diff --git a/docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json b/docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json new file mode 100644 index 0000000..ec32e14 --- /dev/null +++ b/docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json @@ -0,0 +1,342 @@ +{ + "schema_version": "domain_truth_harness_spec_v1", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "description": "Mixed AGENT replay for turnaround 11. The pack interleaves counterparty documents, inventory root and selected-object continuity, meta-space interruptions, memory recap, receivables to inventory same-date pivot, and an account 60 tail check.", + "bindings": {}, + "steps": [ + { + "step_id": "step_01_smalltalk", + "title": "Casual chat stays human and non-technical", + "question": "привет, как дела?", + "required_answer_patterns_any": [ + "(?i)привет|дела|помочь|норм" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)address_mode", + "(?i)hard_meta_mode", + "(?i)living_reason" + ], + "criticality": "info", + "semantic_tags": [ + "meta_smalltalk" + ], + "notes": "[mixed_pack_slot=slot_01_smalltalk source=address_truth_harness_phase6_provider_axis_mix:step_01_smalltalk]" + }, + { + "step_id": "step_01_counterparty_documents", + "title": "Counterparty documents use the normalized legal name", + "question": "покажи все документы по чепурнову", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "list_documents_by_counterparty" + ], + "required_direct_answer_patterns_any": [ + "(?i)контрагент:", + "(?i)чепурнов" + ], + "criticality": "critical", + "semantic_tags": [ + "counterparty_documents" + ], + "notes": "[mixed_pack_slot=slot_03_counterparty_documents source=address_truth_harness_phase4_coverage_evidence_mix:step_01_counterparty_documents]" + }, + { + "step_id": "step_02_counterparty_shipments_or_fallback", + "title": "Supplier shipment question stays human even when exact supply rows are absent", + "question": "что нам отгружал чепурнов, какой товар или услугу?", + "allowed_reply_types": [ + "factual", + "partial_coverage" + ], + "expected_intents": [ + "list_documents_by_counterparty" + ], + "required_direct_answer_patterns_any": [ + "(?i)чепурнов", + "(?i)постав", + "(?i)оплат|возврат|товар|услуг" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)^в текущем адресном контуре этот запрос лучше не закрывать в лоб" + ], + "criticality": "critical", + "semantic_tags": [ + "counterparty_shipment_fallback" + ], + "notes": "[mixed_pack_slot=slot_04_counterparty_shipment_fallback source=address_truth_harness_phase4_coverage_evidence_mix:step_02_counterparty_shipments_or_fallback]" + }, + { + "step_id": "step_01_inventory_march_2021", + "title": "Inventory root snapshot at March 2021", + "criticality": "critical", + "question": "какие остатки на складе на март 2021", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2021", + "(?i)на складе", + "(?i)столешница 600\\*3050\\*26 альмандин" + ], + "semantic_tags": [ + "inventory_root" + ], + "notes": "[mixed_pack_slot=slot_05_inventory_root source=address_truth_harness_phase7_acceptance_gate_mix:step_01_inventory_march_2021]" + }, + { + "step_id": "step_02_selected_item_supplier", + "title": "Selected-object supplier provenance", + "criticality": "critical", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "required_direct_answer_patterns_any": [ + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)поставщик|поставил|куплен", + "(?i)союз|торговый дом" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^на 31\\.03\\.2021 на складе", + "(?i)^сейчас не дам прямой адресный ответ" + ], + "semantic_tags": [ + "selected_object", + "selected_object_supplier" + ], + "notes": "[mixed_pack_slot=slot_06_selected_object_supplier source=address_truth_harness_phase7_acceptance_gate_mix:step_02_selected_item_supplier]" + }, + { + "step_id": "step_05_capability_meta_interrupt", + "title": "Capability meta question does not break the address context", + "question": "что ты умеешь?", + "required_answer_patterns_any": [ + "(?i)могу|умею", + "(?i)остатк|документ|контрагент|ндс" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)address_mode" + ], + "criticality": "warning", + "semantic_tags": [ + "meta_capability" + ], + "notes": "[mixed_pack_slot=slot_07_meta_capability source=address_truth_harness_phase5_meta_memory_mix:step_05_capability_meta_interrupt]" + }, + { + "step_id": "step_03_selected_item_documents", + "title": "Selected-object documents stay in the same contour", + "criticality": "critical", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_documents_for_item" + ], + "required_direct_answer_patterns_any": [ + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)документ", + "(?i)союз|торговый дом" + ], + "semantic_tags": [ + "selected_object", + "selected_object_documents" + ], + "notes": "[mixed_pack_slot=slot_08_selected_object_documents source=address_truth_harness_phase7_acceptance_gate_mix:step_03_selected_item_documents]" + }, + { + "step_id": "step_06_memory_recap_after_interrupts", + "title": "Memory recap still remembers the selected object after meta interruptions", + "question": "а ты помнишь, что мы по этой позиции уже выяснили?", + "required_answer_patterns_any": [ + "(?i)помню", + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)позици" + ], + "forbidden_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)^в текущем адресном контуре этот запрос лучше не закрывать в лоб" + ], + "criticality": "warning", + "semantic_tags": [ + "meta_memory" + ], + "required_answer_patterns_all": [ + "(?i)помню", + "(?i)столешница 600\\*3050\\*26 альмандин" + ], + "notes": "[mixed_pack_slot=slot_09_meta_memory source=address_truth_harness_phase5_meta_memory_mix:step_06_memory_recap_after_interrupts]" + }, + { + "step_id": "step_04_inventory_same_date_restore", + "title": "Same-date restore returns to the March root snapshot", + "criticality": "critical", + "question": "покажи еще раз остатки на эту же дату", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2021", + "(?i)на складе" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)transition_not_supported_by_capability" + ], + "semantic_tags": [ + "inventory_root", + "same_date_restore" + ], + "notes": "[mixed_pack_slot=slot_10_same_date_restore source=address_truth_harness_phase7_acceptance_gate_mix:step_04_inventory_same_date_restore]" + }, + { + "step_id": "step_02_receivables_march_2020", + "title": "Receivables at March 2020", + "question": "кто нам должен на март 2020", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "receivables_confirmed_as_of_date" + ], + "expected_capability": "confirmed_receivables_as_of_date", + "expected_result_mode": "confirmed_balance", + "required_filters": { + "as_of_date": "2020-03-31", + "period_from": "2020-03-01", + "period_to": "2020-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2020", + "(?i)дебиторск" + ], + "notes": "Базовый корневой финансовый вопрос должен отработать точно и задать март 2020 как carryover-якорь. [mixed_pack_slot=slot_11_receivables_root source=address_truth_harness_test2:step_02_receivables_march_2020]", + "criticality": "critical", + "semantic_tags": [ + "settlements_receivables" + ] + }, + { + "step_id": "step_03_inventory_same_date", + "title": "Inventory on the same date", + "question": "остатки по складу на эту же дату", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "expected_capability": "confirmed_inventory_on_hand_as_of_date", + "expected_result_mode": "confirmed_balance", + "required_filters": { + "as_of_date": "{{step_02_receivables_march_2020.filters.as_of_date}}", + "period_from": "{{step_02_receivables_march_2020.filters.period_from}}", + "period_to": "{{step_02_receivables_march_2020.filters.period_to}}" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2020", + "(?i)на складе" + ], + "notes": "Смена контура receivables -> inventory должна сохранить ту же дату, без дополнительного ручного уточнения. [mixed_pack_slot=slot_12_same_date_pivot source=address_truth_harness_test2:step_03_inventory_same_date]", + "criticality": "critical", + "semantic_tags": [ + "inventory_root", + "same_date_pivot" + ] + }, + { + "step_id": "step_06_historical_capability_followup", + "title": "Historical capability follow-up stays human", + "criticality": "warning", + "question": "а исторические остатки тоже можешь?", + "required_answer_patterns_any": [ + "(?i)историческ|история", + "(?i)могу|умею" + ], + "forbidden_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)^в текущем адресном контуре этот запрос лучше не закрывать в лоб", + "(?i)tool_gate_reason", + "(?i)hard_meta_mode" + ], + "semantic_tags": [ + "meta_historical_capability", + "inventory_root" + ], + "notes": "[mixed_pack_slot=slot_13_meta_historical source=address_truth_harness_phase7_acceptance_gate_mix:step_06_historical_capability_followup]" + }, + { + "step_id": "step_04_open_items_account_60", + "title": "Account 60 tails for August 2022", + "question": "хвосты покажи по счету 60 на август 2022", + "allowed_reply_types": [ + "factual", + "factual_with_explanation" + ], + "expected_intents": [ + "open_items_by_counterparty_or_contract" + ], + "required_filters": { + "account": "60", + "period_from": "2022-08-01", + "period_to": "2022-08-31", + "as_of_date": "2022-08-31" + }, + "required_direct_answer_patterns_any": [ + "(?i)счету 60", + "(?i)хвост" + ], + "criticality": "critical", + "semantic_tags": [ + "settlements_account_60" + ], + "notes": "[mixed_pack_slot=slot_14_account_60 source=address_truth_harness_targeted_counterparty_tails:step_04_open_items_account_60]" + }, + { + "step_id": "step_02_data_scope_meta", + "title": "Data-scope meta question stays deterministic and non-technical", + "question": "по какой компании мы сейчас работаем?", + "required_answer_patterns_any": [ + "(?i)компан|организац|контур", + "(?i)работ" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)hard_meta_mode", + "(?i)living_reason" + ], + "criticality": "warning", + "semantic_tags": [ + "meta_scope" + ], + "notes": "[mixed_pack_slot=slot_15_meta_scope source=address_truth_harness_phase6_provider_axis_mix:step_02_data_scope_meta]" + } + ] +} diff --git a/docs/orchestration/agent_semantic_source_catalog.json b/docs/orchestration/agent_semantic_source_catalog.json new file mode 100644 index 0000000..216c0fe --- /dev/null +++ b/docs/orchestration/agent_semantic_source_catalog.json @@ -0,0 +1,3894 @@ +{ + "schema_version": "agent_semantic_source_catalog_v1", + "generated_at": "2026-04-17T09:41:32+00:00", + "summary": { + "truth_harness_steps_total": 58, + "saved_session_questions_total": 81, + "reusable_truth_harness_tags": { + "counterparty_documents": 3, + "counterparty_shipment_fallback": 3, + "inventory_root": 21, + "meta_capability": 3, + "meta_historical_capability": 4, + "meta_memory": 2, + "meta_scope": 4, + "meta_smalltalk": 3, + "same_date_pivot": 3, + "same_date_restore": 4, + "selected_object": 11, + "selected_object_documents": 3, + "selected_object_sale": 1, + "selected_object_supplier": 7, + "settlements_account_60": 2, + "settlements_receivables": 4, + "vat": 3 + }, + "all_tags": { + "counterparty_documents": 7, + "counterparty_shipment_fallback": 7, + "inventory_root": 45, + "meta_capability": 8, + "meta_historical_capability": 9, + "meta_memory": 4, + "meta_scope": 10, + "meta_smalltalk": 7, + "same_date_pivot": 3, + "same_date_restore": 4, + "selected_object": 20, + "selected_object_documents": 3, + "selected_object_sale": 1, + "selected_object_supplier": 7, + "settlements_account_60": 3, + "settlements_receivables": 6, + "vat": 7 + } + }, + "truth_harness_entries": [ + { + "entry_id": "address_truth_harness_inventory_provenance_restore:step_01_inventory_march_2021", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_inventory_provenance_restore.json", + "source_title": "Targeted live replay for selected-object supplier provenance and root restore", + "scenario_id": "address_truth_harness_inventory_provenance_restore", + "domain": "inventory_selected_object_provenance_restore", + "reusable_in_agent_pack": true, + "step_id": "step_01_inventory_march_2021", + "title": "Inventory stock snapshot at March 2021", + "question": "какие остатки на складе на март 2021", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root" + ], + "step_payload": { + "step_id": "step_01_inventory_march_2021", + "title": "Inventory stock snapshot at March 2021", + "question": "какие остатки на складе на март 2021", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2021", + "(?i)на складе", + "(?i)столешница 600\\*3050\\*26 альмандин" + ] + } + }, + { + "entry_id": "address_truth_harness_inventory_provenance_restore:step_02_selected_item_supplier", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_inventory_provenance_restore.json", + "source_title": "Targeted live replay for selected-object supplier provenance and root restore", + "scenario_id": "address_truth_harness_inventory_provenance_restore", + "domain": "inventory_selected_object_provenance_restore", + "reusable_in_agent_pack": true, + "step_id": "step_02_selected_item_supplier", + "title": "Selected-object supplier provenance", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "criticality": "critical", + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "semantic_tags": [ + "selected_object", + "selected_object_supplier" + ], + "step_payload": { + "step_id": "step_02_selected_item_supplier", + "title": "Selected-object supplier provenance", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "required_direct_answer_patterns_any": [ + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)поставщик|поставил|куплен", + "(?i)союз|торговый дом" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^на 31\\.03\\.2021 на складе", + "(?i)^не могу надежно подтвердить ответ" + ] + } + }, + { + "entry_id": "address_truth_harness_inventory_provenance_restore:step_03_selected_item_documents", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_inventory_provenance_restore.json", + "source_title": "Targeted live replay for selected-object supplier provenance and root restore", + "scenario_id": "address_truth_harness_inventory_provenance_restore", + "domain": "inventory_selected_object_provenance_restore", + "reusable_in_agent_pack": true, + "step_id": "step_03_selected_item_documents", + "title": "Selected-object purchase documents", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "criticality": "critical", + "expected_intents": [ + "inventory_purchase_documents_for_item" + ], + "semantic_tags": [ + "selected_object", + "selected_object_documents" + ], + "step_payload": { + "step_id": "step_03_selected_item_documents", + "title": "Selected-object purchase documents", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_documents_for_item" + ], + "required_direct_answer_patterns_any": [ + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)документ", + "(?i)союз|торговый дом" + ] + } + }, + { + "entry_id": "address_truth_harness_inventory_provenance_restore:step_04_inventory_same_date_restore", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_inventory_provenance_restore.json", + "source_title": "Targeted live replay for selected-object supplier provenance and root restore", + "scenario_id": "address_truth_harness_inventory_provenance_restore", + "domain": "inventory_selected_object_provenance_restore", + "reusable_in_agent_pack": true, + "step_id": "step_04_inventory_same_date_restore", + "title": "Restore root inventory snapshot on the same date", + "question": "покажи еще раз остатки на эту же дату", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root", + "same_date_restore" + ], + "step_payload": { + "step_id": "step_04_inventory_same_date_restore", + "title": "Restore root inventory snapshot on the same date", + "question": "покажи еще раз остатки на эту же дату", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2021", + "(?i)на складе" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^не могу надежно подтвердить ответ", + "(?i)transition_not_supported_by_capability" + ] + } + }, + { + "entry_id": "address_truth_harness_phase4_coverage_evidence_mix:step_01_counterparty_documents", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase4_coverage_evidence_mix.json", + "source_title": "Phase 4 coverage/evidence replay for counterparty fallback, inventory reset, and selected-object provenance", + "scenario_id": "address_truth_harness_phase4_coverage_evidence_mix", + "domain": "address_phase4_coverage_evidence_mix", + "reusable_in_agent_pack": true, + "step_id": "step_01_counterparty_documents", + "title": "Counterparty documents use the normalized legal name", + "question": "покажи все документы по чепурнову", + "criticality": "critical", + "expected_intents": [ + "list_documents_by_counterparty" + ], + "semantic_tags": [ + "counterparty_documents" + ], + "step_payload": { + "step_id": "step_01_counterparty_documents", + "title": "Counterparty documents use the normalized legal name", + "question": "покажи все документы по чепурнову", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "list_documents_by_counterparty" + ], + "required_direct_answer_patterns_any": [ + "(?i)контрагент:", + "(?i)чепурнов" + ] + } + }, + { + "entry_id": "address_truth_harness_phase4_coverage_evidence_mix:step_02_counterparty_shipments_or_fallback", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase4_coverage_evidence_mix.json", + "source_title": "Phase 4 coverage/evidence replay for counterparty fallback, inventory reset, and selected-object provenance", + "scenario_id": "address_truth_harness_phase4_coverage_evidence_mix", + "domain": "address_phase4_coverage_evidence_mix", + "reusable_in_agent_pack": true, + "step_id": "step_02_counterparty_shipments_or_fallback", + "title": "Supplier shipment question stays human even when exact supply rows are absent", + "question": "что нам отгружал чепурнов, какой товар или услугу?", + "criticality": "critical", + "expected_intents": [ + "list_documents_by_counterparty" + ], + "semantic_tags": [ + "counterparty_shipment_fallback" + ], + "step_payload": { + "step_id": "step_02_counterparty_shipments_or_fallback", + "title": "Supplier shipment question stays human even when exact supply rows are absent", + "question": "что нам отгружал чепурнов, какой товар или услугу?", + "allowed_reply_types": [ + "factual", + "partial_coverage" + ], + "expected_intents": [ + "list_documents_by_counterparty" + ], + "required_direct_answer_patterns_any": [ + "(?i)чепурнов", + "(?i)постав", + "(?i)оплат|возврат|товар|услуг" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)^в текущем адресном контуре этот запрос лучше не закрывать в лоб" + ] + } + }, + { + "entry_id": "address_truth_harness_phase4_coverage_evidence_mix:step_03_inventory_reset_march_2021", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase4_coverage_evidence_mix.json", + "source_title": "Phase 4 coverage/evidence replay for counterparty fallback, inventory reset, and selected-object provenance", + "scenario_id": "address_truth_harness_phase4_coverage_evidence_mix", + "domain": "address_phase4_coverage_evidence_mix", + "reusable_in_agent_pack": true, + "step_id": "step_03_inventory_reset_march_2021", + "title": "Inventory root resets cleanly after the counterparty branch", + "question": "какие остатки на складе на март 2021", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root" + ], + "step_payload": { + "step_id": "step_03_inventory_reset_march_2021", + "title": "Inventory root resets cleanly after the counterparty branch", + "question": "какие остатки на складе на март 2021", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2021", + "(?i)на складе" + ], + "forbidden_direct_answer_patterns": [ + "(?i)чепурнов", + "(?i)контрагент:" + ] + } + }, + { + "entry_id": "address_truth_harness_phase4_coverage_evidence_mix:step_04_selected_item_supplier_temporal_limit", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase4_coverage_evidence_mix.json", + "source_title": "Phase 4 coverage/evidence replay for counterparty fallback, inventory reset, and selected-object provenance", + "scenario_id": "address_truth_harness_phase4_coverage_evidence_mix", + "domain": "address_phase4_coverage_evidence_mix", + "reusable_in_agent_pack": true, + "step_id": "step_04_selected_item_supplier_temporal_limit", + "title": "Selected-object supplier provenance remains direct-answer-first under temporal limit", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "criticality": "critical", + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "semantic_tags": [ + "selected_object", + "selected_object_supplier" + ], + "step_payload": { + "step_id": "step_04_selected_item_supplier_temporal_limit", + "title": "Selected-object supplier provenance remains direct-answer-first under temporal limit", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "required_direct_answer_patterns_any": [ + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)поставщик|поставил|куплен", + "(?i)союз|торговый дом" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^на 31\\.03\\.2021 на складе", + "(?i)^сейчас не дам прямой адресный ответ" + ] + } + }, + { + "entry_id": "address_truth_harness_phase4_coverage_evidence_mix:step_05_inventory_same_date_restore", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase4_coverage_evidence_mix.json", + "source_title": "Phase 4 coverage/evidence replay for counterparty fallback, inventory reset, and selected-object provenance", + "scenario_id": "address_truth_harness_phase4_coverage_evidence_mix", + "domain": "address_phase4_coverage_evidence_mix", + "reusable_in_agent_pack": true, + "step_id": "step_05_inventory_same_date_restore", + "title": "Same-date restore returns to the March 2021 root snapshot", + "question": "покажи еще раз остатки на эту же дату", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root", + "same_date_restore" + ], + "step_payload": { + "step_id": "step_05_inventory_same_date_restore", + "title": "Same-date restore returns to the March 2021 root snapshot", + "question": "покажи еще раз остатки на эту же дату", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2021", + "(?i)на складе" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)transition_not_supported_by_capability" + ] + } + }, + { + "entry_id": "address_truth_harness_phase5_meta_memory_mix:step_01_inventory_root_march_2021", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase5_meta_memory_mix.json", + "source_title": "Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "address_truth_harness_phase5_meta_memory_mix", + "domain": "address_phase5_meta_memory_mix", + "reusable_in_agent_pack": true, + "step_id": "step_01_inventory_root_march_2021", + "title": "Inventory root establishes grounded March 2021 context", + "question": "какие остатки на складе на март 2021", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root" + ], + "step_payload": { + "step_id": "step_01_inventory_root_march_2021", + "title": "Inventory root establishes grounded March 2021 context", + "question": "какие остатки на складе на март 2021", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2021", + "(?i)на складе" + ] + } + }, + { + "entry_id": "address_truth_harness_phase5_meta_memory_mix:step_02_inventory_history_capability_followup", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase5_meta_memory_mix.json", + "source_title": "Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "address_truth_harness_phase5_meta_memory_mix", + "domain": "address_phase5_meta_memory_mix", + "reusable_in_agent_pack": true, + "step_id": "step_02_inventory_history_capability_followup", + "title": "Historical capability follow-up stays contextual and human", + "question": "а исторические остатки тоже можешь?", + "criticality": "critical", + "expected_intents": [], + "semantic_tags": [ + "meta_historical_capability", + "inventory_root" + ], + "step_payload": { + "step_id": "step_02_inventory_history_capability_followup", + "title": "Historical capability follow-up stays contextual and human", + "question": "а исторические остатки тоже можешь?", + "required_answer_patterns_any": [ + "(?i)историческ", + "(?i)могу", + "(?i)март 2020|июнь 2016|2017" + ], + "forbidden_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)^в текущем адресном контуре этот запрос лучше не закрывать в лоб" + ] + } + }, + { + "entry_id": "address_truth_harness_phase5_meta_memory_mix:step_03_data_scope_meta_interrupt", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase5_meta_memory_mix.json", + "source_title": "Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "address_truth_harness_phase5_meta_memory_mix", + "domain": "address_phase5_meta_memory_mix", + "reusable_in_agent_pack": true, + "step_id": "step_03_data_scope_meta_interrupt", + "title": "Data-scope meta question stays deterministic and non-technical", + "question": "по какой компании мы сейчас работаем?", + "criticality": "critical", + "expected_intents": [], + "semantic_tags": [ + "meta_scope" + ], + "step_payload": { + "step_id": "step_03_data_scope_meta_interrupt", + "title": "Data-scope meta question stays deterministic and non-technical", + "question": "по какой компании мы сейчас работаем?", + "required_answer_patterns_any": [ + "(?i)компан|организац|контур", + "(?i)работ", + "(?i)альтернатив|доступн|выбран" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)hard_meta_mode", + "(?i)living_router_reason" + ] + } + }, + { + "entry_id": "address_truth_harness_phase5_meta_memory_mix:step_04_selected_item_supplier", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase5_meta_memory_mix.json", + "source_title": "Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "address_truth_harness_phase5_meta_memory_mix", + "domain": "address_phase5_meta_memory_mix", + "reusable_in_agent_pack": true, + "step_id": "step_04_selected_item_supplier", + "title": "Selected-object provenance survives the meta interrupt", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "criticality": "critical", + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "semantic_tags": [ + "selected_object", + "selected_object_supplier" + ], + "step_payload": { + "step_id": "step_04_selected_item_supplier", + "title": "Selected-object provenance survives the meta interrupt", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "required_direct_answer_patterns_any": [ + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)поставщик|поставил|куплен", + "(?i)союз|торговый дом" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^на 31\\.03\\.2021 на складе", + "(?i)^сейчас не дам прямой адресный ответ" + ] + } + }, + { + "entry_id": "address_truth_harness_phase5_meta_memory_mix:step_05_capability_meta_interrupt", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase5_meta_memory_mix.json", + "source_title": "Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "address_truth_harness_phase5_meta_memory_mix", + "domain": "address_phase5_meta_memory_mix", + "reusable_in_agent_pack": true, + "step_id": "step_05_capability_meta_interrupt", + "title": "Capability meta question does not break the address context", + "question": "что ты умеешь?", + "criticality": "critical", + "expected_intents": [], + "semantic_tags": [ + "meta_capability" + ], + "step_payload": { + "step_id": "step_05_capability_meta_interrupt", + "title": "Capability meta question does not break the address context", + "question": "что ты умеешь?", + "required_answer_patterns_any": [ + "(?i)могу|умею", + "(?i)остатк|документ|контрагент|ндс" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)address_mode" + ] + } + }, + { + "entry_id": "address_truth_harness_phase5_meta_memory_mix:step_06_memory_recap_after_interrupts", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase5_meta_memory_mix.json", + "source_title": "Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "address_truth_harness_phase5_meta_memory_mix", + "domain": "address_phase5_meta_memory_mix", + "reusable_in_agent_pack": true, + "step_id": "step_06_memory_recap_after_interrupts", + "title": "Memory recap still remembers the selected object after meta interruptions", + "question": "а ты помнишь, что мы по этой позиции уже выяснили?", + "criticality": "critical", + "expected_intents": [], + "semantic_tags": [ + "meta_memory" + ], + "step_payload": { + "step_id": "step_06_memory_recap_after_interrupts", + "title": "Memory recap still remembers the selected object after meta interruptions", + "question": "а ты помнишь, что мы по этой позиции уже выяснили?", + "required_answer_patterns_any": [ + "(?i)помню", + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)позици" + ], + "forbidden_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)^в текущем адресном контуре этот запрос лучше не закрывать в лоб" + ] + } + }, + { + "entry_id": "address_truth_harness_phase6_provider_axis_mix:step_01_smalltalk", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase6_provider_axis_mix.json", + "source_title": "Phase 6 provider/runtime replay across chat, meta, and address boundaries", + "scenario_id": "address_truth_harness_phase6_provider_axis_mix", + "domain": "address_phase6_provider_axis_mix", + "reusable_in_agent_pack": true, + "step_id": "step_01_smalltalk", + "title": "Casual chat stays human and non-technical", + "question": "привет, как дела?", + "criticality": "critical", + "expected_intents": [], + "semantic_tags": [ + "meta_smalltalk" + ], + "step_payload": { + "step_id": "step_01_smalltalk", + "title": "Casual chat stays human and non-technical", + "question": "привет, как дела?", + "required_answer_patterns_any": [ + "(?i)привет|дела|помочь|норм" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)address_mode", + "(?i)hard_meta_mode", + "(?i)living_reason" + ] + } + }, + { + "entry_id": "address_truth_harness_phase6_provider_axis_mix:step_02_data_scope_meta", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase6_provider_axis_mix.json", + "source_title": "Phase 6 provider/runtime replay across chat, meta, and address boundaries", + "scenario_id": "address_truth_harness_phase6_provider_axis_mix", + "domain": "address_phase6_provider_axis_mix", + "reusable_in_agent_pack": true, + "step_id": "step_02_data_scope_meta", + "title": "Data-scope meta question stays deterministic and non-technical", + "question": "по какой компании мы сейчас работаем?", + "criticality": "critical", + "expected_intents": [], + "semantic_tags": [ + "meta_scope" + ], + "step_payload": { + "step_id": "step_02_data_scope_meta", + "title": "Data-scope meta question stays deterministic and non-technical", + "question": "по какой компании мы сейчас работаем?", + "required_answer_patterns_any": [ + "(?i)компан|организац|контур", + "(?i)работ" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)hard_meta_mode", + "(?i)living_reason" + ] + } + }, + { + "entry_id": "address_truth_harness_phase6_provider_axis_mix:step_03_capability_meta", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase6_provider_axis_mix.json", + "source_title": "Phase 6 provider/runtime replay across chat, meta, and address boundaries", + "scenario_id": "address_truth_harness_phase6_provider_axis_mix", + "domain": "address_phase6_provider_axis_mix", + "reusable_in_agent_pack": true, + "step_id": "step_03_capability_meta", + "title": "Capability meta question stays chat-like and useful", + "question": "что ты можешь по 1С?", + "criticality": "critical", + "expected_intents": [], + "semantic_tags": [ + "meta_capability" + ], + "step_payload": { + "step_id": "step_03_capability_meta", + "title": "Capability meta question stays chat-like and useful", + "question": "что ты можешь по 1С?", + "required_answer_patterns_any": [ + "(?i)могу|умею", + "(?i)остатк|документ|контрагент|ндс" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)address_mode", + "(?i)hard_meta_mode" + ] + } + }, + { + "entry_id": "address_truth_harness_phase6_provider_axis_mix:step_04_inventory_root_march_2021", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase6_provider_axis_mix.json", + "source_title": "Phase 6 provider/runtime replay across chat, meta, and address boundaries", + "scenario_id": "address_truth_harness_phase6_provider_axis_mix", + "domain": "address_phase6_provider_axis_mix", + "reusable_in_agent_pack": true, + "step_id": "step_04_inventory_root_march_2021", + "title": "Inventory root stays human and asks for organization instead of leaking technical routing", + "question": "какие остатки на складе на март 2021", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root" + ], + "step_payload": { + "step_id": "step_04_inventory_root_march_2021", + "title": "Inventory root stays human and asks for organization instead of leaking technical routing", + "question": "какие остатки на складе на март 2021", + "allowed_reply_types": [ + "partial_coverage" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_answer_patterns_any": [ + "(?i)уточн", + "(?i)организац|компан", + "(?i)смешиват" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)hard_meta_mode", + "(?i)living_reason" + ] + } + }, + { + "entry_id": "address_truth_harness_phase6_provider_axis_mix:step_05_historical_capability_followup", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase6_provider_axis_mix.json", + "source_title": "Phase 6 provider/runtime replay across chat, meta, and address boundaries", + "scenario_id": "address_truth_harness_phase6_provider_axis_mix", + "domain": "address_phase6_provider_axis_mix", + "reusable_in_agent_pack": true, + "step_id": "step_05_historical_capability_followup", + "title": "Historical capability follow-up remains human after grounded inventory turn", + "question": "а исторические остатки тоже можешь?", + "criticality": "critical", + "expected_intents": [], + "semantic_tags": [ + "meta_historical_capability", + "inventory_root" + ], + "step_payload": { + "step_id": "step_05_historical_capability_followup", + "title": "Historical capability follow-up remains human after grounded inventory turn", + "question": "а исторические остатки тоже можешь?", + "required_answer_patterns_any": [ + "(?i)историческ|история", + "(?i)могу|умею" + ], + "forbidden_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)^в текущем адресном контуре этот запрос лучше не закрывать в лоб", + "(?i)tool_gate_reason", + "(?i)hard_meta_mode" + ] + } + }, + { + "entry_id": "address_truth_harness_phase7_acceptance_gate_mix:step_01_inventory_march_2021", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_acceptance_gate_mix.json", + "source_title": "Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "address_truth_harness_phase7_acceptance_gate_mix", + "domain": "address_phase7_acceptance_gate_mix", + "reusable_in_agent_pack": true, + "step_id": "step_01_inventory_march_2021", + "title": "Inventory root snapshot at March 2021", + "question": "какие остатки на складе на март 2021", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root" + ], + "step_payload": { + "step_id": "step_01_inventory_march_2021", + "title": "Inventory root snapshot at March 2021", + "criticality": "critical", + "question": "какие остатки на складе на март 2021", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2021", + "(?i)на складе", + "(?i)столешница 600\\*3050\\*26 альмандин" + ] + } + }, + { + "entry_id": "address_truth_harness_phase7_acceptance_gate_mix:step_02_selected_item_supplier", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_acceptance_gate_mix.json", + "source_title": "Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "address_truth_harness_phase7_acceptance_gate_mix", + "domain": "address_phase7_acceptance_gate_mix", + "reusable_in_agent_pack": true, + "step_id": "step_02_selected_item_supplier", + "title": "Selected-object supplier provenance", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "criticality": "critical", + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "semantic_tags": [ + "selected_object", + "selected_object_supplier" + ], + "step_payload": { + "step_id": "step_02_selected_item_supplier", + "title": "Selected-object supplier provenance", + "criticality": "critical", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "required_direct_answer_patterns_any": [ + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)поставщик|поставил|куплен", + "(?i)союз|торговый дом" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^на 31\\.03\\.2021 на складе", + "(?i)^сейчас не дам прямой адресный ответ" + ] + } + }, + { + "entry_id": "address_truth_harness_phase7_acceptance_gate_mix:step_03_selected_item_documents", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_acceptance_gate_mix.json", + "source_title": "Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "address_truth_harness_phase7_acceptance_gate_mix", + "domain": "address_phase7_acceptance_gate_mix", + "reusable_in_agent_pack": true, + "step_id": "step_03_selected_item_documents", + "title": "Selected-object documents stay in the same contour", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "criticality": "critical", + "expected_intents": [ + "inventory_purchase_documents_for_item" + ], + "semantic_tags": [ + "selected_object", + "selected_object_documents" + ], + "step_payload": { + "step_id": "step_03_selected_item_documents", + "title": "Selected-object documents stay in the same contour", + "criticality": "critical", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_documents_for_item" + ], + "required_direct_answer_patterns_any": [ + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)документ", + "(?i)союз|торговый дом" + ] + } + }, + { + "entry_id": "address_truth_harness_phase7_acceptance_gate_mix:step_04_inventory_same_date_restore", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_acceptance_gate_mix.json", + "source_title": "Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "address_truth_harness_phase7_acceptance_gate_mix", + "domain": "address_phase7_acceptance_gate_mix", + "reusable_in_agent_pack": true, + "step_id": "step_04_inventory_same_date_restore", + "title": "Same-date restore returns to the March root snapshot", + "question": "покажи еще раз остатки на эту же дату", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root", + "same_date_restore" + ], + "step_payload": { + "step_id": "step_04_inventory_same_date_restore", + "title": "Same-date restore returns to the March root snapshot", + "criticality": "critical", + "question": "покажи еще раз остатки на эту же дату", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2021", + "(?i)на складе" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)transition_not_supported_by_capability" + ] + } + }, + { + "entry_id": "address_truth_harness_phase7_acceptance_gate_mix:step_05_data_scope_meta_interrupt", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_acceptance_gate_mix.json", + "source_title": "Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "address_truth_harness_phase7_acceptance_gate_mix", + "domain": "address_phase7_acceptance_gate_mix", + "reusable_in_agent_pack": true, + "step_id": "step_05_data_scope_meta_interrupt", + "title": "Data-scope meta question remains human and non-technical", + "question": "по какой компании мы сейчас работаем?", + "criticality": "warning", + "expected_intents": [], + "semantic_tags": [ + "meta_scope" + ], + "step_payload": { + "step_id": "step_05_data_scope_meta_interrupt", + "title": "Data-scope meta question remains human and non-technical", + "criticality": "warning", + "question": "по какой компании мы сейчас работаем?", + "required_answer_patterns_any": [ + "(?i)компан|организац|контур", + "(?i)работ" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)hard_meta_mode", + "(?i)living_reason" + ] + } + }, + { + "entry_id": "address_truth_harness_phase7_acceptance_gate_mix:step_06_historical_capability_followup", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_acceptance_gate_mix.json", + "source_title": "Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "address_truth_harness_phase7_acceptance_gate_mix", + "domain": "address_phase7_acceptance_gate_mix", + "reusable_in_agent_pack": true, + "step_id": "step_06_historical_capability_followup", + "title": "Historical capability follow-up stays human", + "question": "а исторические остатки тоже можешь?", + "criticality": "warning", + "expected_intents": [], + "semantic_tags": [ + "meta_historical_capability", + "inventory_root" + ], + "step_payload": { + "step_id": "step_06_historical_capability_followup", + "title": "Historical capability follow-up stays human", + "criticality": "warning", + "question": "а исторические остатки тоже можешь?", + "required_answer_patterns_any": [ + "(?i)историческ|история", + "(?i)могу|умею" + ], + "forbidden_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)^в текущем адресном контуре этот запрос лучше не закрывать в лоб", + "(?i)tool_gate_reason", + "(?i)hard_meta_mode" + ] + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_01_smalltalk", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_01_smalltalk", + "title": "Casual chat stays human and non-technical", + "question": "привет, как дела?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_smalltalk" + ], + "step_payload": { + "step_id": "step_01_smalltalk", + "title": "Casual chat stays human and non-technical", + "question": "привет, как дела?", + "required_answer_patterns_any": [ + "(?i)привет|дела|помочь|норм" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)address_mode", + "(?i)hard_meta_mode", + "(?i)living_reason" + ], + "criticality": "info", + "semantic_tags": [ + "meta_smalltalk" + ], + "notes": "[mixed_pack_slot=slot_01_smalltalk source=address_truth_harness_phase6_provider_axis_mix:step_01_smalltalk]" + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_02_data_scope_meta", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_02_data_scope_meta", + "title": "Data-scope meta question stays deterministic and non-technical", + "question": "по какой компании мы сейчас работаем?", + "criticality": "warning", + "expected_intents": [], + "semantic_tags": [ + "meta_scope" + ], + "step_payload": { + "step_id": "step_02_data_scope_meta", + "title": "Data-scope meta question stays deterministic and non-technical", + "question": "по какой компании мы сейчас работаем?", + "required_answer_patterns_any": [ + "(?i)компан|организац|контур", + "(?i)работ" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)hard_meta_mode", + "(?i)living_reason" + ], + "criticality": "warning", + "semantic_tags": [ + "meta_scope" + ], + "notes": "[mixed_pack_slot=slot_02_meta_scope source=address_truth_harness_phase6_provider_axis_mix:step_02_data_scope_meta]" + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_01_counterparty_documents", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_01_counterparty_documents", + "title": "Counterparty documents use the normalized legal name", + "question": "покажи все документы по чепурнову", + "criticality": "critical", + "expected_intents": [ + "list_documents_by_counterparty" + ], + "semantic_tags": [ + "counterparty_documents" + ], + "step_payload": { + "step_id": "step_01_counterparty_documents", + "title": "Counterparty documents use the normalized legal name", + "question": "покажи все документы по чепурнову", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "list_documents_by_counterparty" + ], + "required_direct_answer_patterns_any": [ + "(?i)контрагент:", + "(?i)чепурнов" + ], + "criticality": "critical", + "semantic_tags": [ + "counterparty_documents" + ], + "notes": "[mixed_pack_slot=slot_03_counterparty_documents source=address_truth_harness_phase4_coverage_evidence_mix:step_01_counterparty_documents]" + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_02_counterparty_shipments_or_fallback", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_02_counterparty_shipments_or_fallback", + "title": "Supplier shipment question stays human even when exact supply rows are absent", + "question": "что нам отгружал чепурнов, какой товар или услугу?", + "criticality": "critical", + "expected_intents": [ + "list_documents_by_counterparty" + ], + "semantic_tags": [ + "counterparty_shipment_fallback" + ], + "step_payload": { + "step_id": "step_02_counterparty_shipments_or_fallback", + "title": "Supplier shipment question stays human even when exact supply rows are absent", + "question": "что нам отгружал чепурнов, какой товар или услугу?", + "allowed_reply_types": [ + "factual", + "partial_coverage" + ], + "expected_intents": [ + "list_documents_by_counterparty" + ], + "required_direct_answer_patterns_any": [ + "(?i)чепурнов", + "(?i)постав", + "(?i)оплат|возврат|товар|услуг" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)^в текущем адресном контуре этот запрос лучше не закрывать в лоб" + ], + "criticality": "critical", + "semantic_tags": [ + "counterparty_shipment_fallback" + ], + "notes": "[mixed_pack_slot=slot_04_counterparty_shipment_fallback source=address_truth_harness_phase4_coverage_evidence_mix:step_02_counterparty_shipments_or_fallback]" + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_01_inventory_march_2021", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_01_inventory_march_2021", + "title": "Inventory root snapshot at March 2021", + "question": "какие остатки на складе на март 2021", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root" + ], + "step_payload": { + "step_id": "step_01_inventory_march_2021", + "title": "Inventory root snapshot at March 2021", + "criticality": "critical", + "question": "какие остатки на складе на март 2021", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2021", + "(?i)на складе", + "(?i)столешница 600\\*3050\\*26 альмандин" + ], + "semantic_tags": [ + "inventory_root" + ], + "notes": "[mixed_pack_slot=slot_05_inventory_root source=address_truth_harness_phase7_acceptance_gate_mix:step_01_inventory_march_2021]" + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_02_selected_item_supplier", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_02_selected_item_supplier", + "title": "Selected-object supplier provenance", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "criticality": "critical", + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "semantic_tags": [ + "selected_object", + "selected_object_supplier" + ], + "step_payload": { + "step_id": "step_02_selected_item_supplier", + "title": "Selected-object supplier provenance", + "criticality": "critical", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "required_direct_answer_patterns_any": [ + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)поставщик|поставил|куплен", + "(?i)союз|торговый дом" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^на 31\\.03\\.2021 на складе", + "(?i)^сейчас не дам прямой адресный ответ" + ], + "semantic_tags": [ + "selected_object", + "selected_object_supplier" + ], + "notes": "[mixed_pack_slot=slot_06_selected_object_supplier source=address_truth_harness_phase7_acceptance_gate_mix:step_02_selected_item_supplier]" + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_05_capability_meta_interrupt", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_05_capability_meta_interrupt", + "title": "Capability meta question does not break the address context", + "question": "что ты умеешь?", + "criticality": "warning", + "expected_intents": [], + "semantic_tags": [ + "meta_capability" + ], + "step_payload": { + "step_id": "step_05_capability_meta_interrupt", + "title": "Capability meta question does not break the address context", + "question": "что ты умеешь?", + "required_answer_patterns_any": [ + "(?i)могу|умею", + "(?i)остатк|документ|контрагент|ндс" + ], + "forbidden_answer_patterns": [ + "(?i)tool_gate_reason", + "(?i)address_mode" + ], + "criticality": "warning", + "semantic_tags": [ + "meta_capability" + ], + "notes": "[mixed_pack_slot=slot_07_meta_capability source=address_truth_harness_phase5_meta_memory_mix:step_05_capability_meta_interrupt]" + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_03_selected_item_documents", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_03_selected_item_documents", + "title": "Selected-object documents stay in the same contour", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "criticality": "critical", + "expected_intents": [ + "inventory_purchase_documents_for_item" + ], + "semantic_tags": [ + "selected_object", + "selected_object_documents" + ], + "step_payload": { + "step_id": "step_03_selected_item_documents", + "title": "Selected-object documents stay in the same contour", + "criticality": "critical", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_documents_for_item" + ], + "required_direct_answer_patterns_any": [ + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)документ", + "(?i)союз|торговый дом" + ], + "semantic_tags": [ + "selected_object", + "selected_object_documents" + ], + "notes": "[mixed_pack_slot=slot_08_selected_object_documents source=address_truth_harness_phase7_acceptance_gate_mix:step_03_selected_item_documents]" + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_06_memory_recap_after_interrupts", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_06_memory_recap_after_interrupts", + "title": "Memory recap still remembers the selected object after meta interruptions", + "question": "а ты помнишь, что мы по этой позиции уже выяснили?", + "criticality": "warning", + "expected_intents": [], + "semantic_tags": [ + "meta_memory" + ], + "step_payload": { + "step_id": "step_06_memory_recap_after_interrupts", + "title": "Memory recap still remembers the selected object after meta interruptions", + "question": "а ты помнишь, что мы по этой позиции уже выяснили?", + "required_answer_patterns_any": [ + "(?i)помню", + "(?i)столешница 600\\*3050\\*26 альмандин", + "(?i)позици" + ], + "forbidden_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)^в текущем адресном контуре этот запрос лучше не закрывать в лоб" + ], + "criticality": "warning", + "semantic_tags": [ + "meta_memory" + ], + "notes": "[mixed_pack_slot=slot_09_meta_memory source=address_truth_harness_phase5_meta_memory_mix:step_06_memory_recap_after_interrupts]" + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_04_inventory_same_date_restore", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_04_inventory_same_date_restore", + "title": "Same-date restore returns to the March root snapshot", + "question": "покажи еще раз остатки на эту же дату", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root", + "same_date_restore" + ], + "step_payload": { + "step_id": "step_04_inventory_same_date_restore", + "title": "Same-date restore returns to the March root snapshot", + "criticality": "critical", + "question": "покажи еще раз остатки на эту же дату", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_filters": { + "as_of_date": "2021-03-31", + "period_from": "2021-03-01", + "period_to": "2021-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2021", + "(?i)на складе" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)transition_not_supported_by_capability" + ], + "semantic_tags": [ + "inventory_root", + "same_date_restore" + ], + "notes": "[mixed_pack_slot=slot_10_same_date_restore source=address_truth_harness_phase7_acceptance_gate_mix:step_04_inventory_same_date_restore]" + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_02_receivables_march_2020", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_02_receivables_march_2020", + "title": "Receivables at March 2020", + "question": "кто нам должен на март 2020", + "criticality": "critical", + "expected_intents": [ + "receivables_confirmed_as_of_date" + ], + "semantic_tags": [ + "settlements_receivables" + ], + "step_payload": { + "step_id": "step_02_receivables_march_2020", + "title": "Receivables at March 2020", + "question": "кто нам должен на март 2020", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "receivables_confirmed_as_of_date" + ], + "expected_capability": "confirmed_receivables_as_of_date", + "expected_result_mode": "confirmed_balance", + "required_filters": { + "as_of_date": "2020-03-31", + "period_from": "2020-03-01", + "period_to": "2020-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2020", + "(?i)дебиторск" + ], + "notes": "Базовый корневой финансовый вопрос должен отработать точно и задать март 2020 как carryover-якорь. [mixed_pack_slot=slot_11_receivables_root source=address_truth_harness_test2:step_02_receivables_march_2020]", + "criticality": "critical", + "semantic_tags": [ + "settlements_receivables" + ] + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_03_inventory_same_date", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_03_inventory_same_date", + "title": "Inventory on the same date", + "question": "остатки по складу на эту же дату", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root", + "same_date_pivot" + ], + "step_payload": { + "step_id": "step_03_inventory_same_date", + "title": "Inventory on the same date", + "question": "остатки по складу на эту же дату", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "expected_capability": "confirmed_inventory_on_hand_as_of_date", + "expected_result_mode": "confirmed_balance", + "required_filters": { + "as_of_date": "{{step_02_receivables_march_2020.filters.as_of_date}}", + "period_from": "{{step_02_receivables_march_2020.filters.period_from}}", + "period_to": "{{step_02_receivables_march_2020.filters.period_to}}" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2020", + "(?i)на складе" + ], + "notes": "Смена контура receivables -> inventory должна сохранить ту же дату, без дополнительного ручного уточнения. [mixed_pack_slot=slot_12_same_date_pivot source=address_truth_harness_test2:step_03_inventory_same_date]", + "criticality": "critical", + "semantic_tags": [ + "inventory_root", + "same_date_pivot" + ] + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_06_historical_capability_followup", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_06_historical_capability_followup", + "title": "Historical capability follow-up stays human", + "question": "а исторические остатки тоже можешь?", + "criticality": "warning", + "expected_intents": [], + "semantic_tags": [ + "meta_historical_capability", + "inventory_root" + ], + "step_payload": { + "step_id": "step_06_historical_capability_followup", + "title": "Historical capability follow-up stays human", + "criticality": "warning", + "question": "а исторические остатки тоже можешь?", + "required_answer_patterns_any": [ + "(?i)историческ|история", + "(?i)могу|умею" + ], + "forbidden_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ", + "(?i)^в текущем адресном контуре этот запрос лучше не закрывать в лоб", + "(?i)tool_gate_reason", + "(?i)hard_meta_mode" + ], + "semantic_tags": [ + "meta_historical_capability", + "inventory_root" + ], + "notes": "[mixed_pack_slot=slot_13_meta_historical source=address_truth_harness_phase7_acceptance_gate_mix:step_06_historical_capability_followup]" + } + }, + { + "entry_id": "address_truth_harness_phase7_meta_domain_mix:step_04_open_items_account_60", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + "source_title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "reusable_in_agent_pack": true, + "step_id": "step_04_open_items_account_60", + "title": "Account 60 tails for August 2022", + "question": "хвосты покажи по счету 60 на август 2022", + "criticality": "critical", + "expected_intents": [ + "open_items_by_counterparty_or_contract" + ], + "semantic_tags": [ + "settlements_account_60" + ], + "step_payload": { + "step_id": "step_04_open_items_account_60", + "title": "Account 60 tails for August 2022", + "question": "хвосты покажи по счету 60 на август 2022", + "allowed_reply_types": [ + "factual", + "factual_with_explanation" + ], + "expected_intents": [ + "open_items_by_counterparty_or_contract" + ], + "required_filters": { + "account": "60", + "period_from": "2022-08-01", + "period_to": "2022-08-31", + "as_of_date": "2022-08-31" + }, + "required_direct_answer_patterns_any": [ + "(?i)счету 60", + "(?i)хвост" + ], + "criticality": "critical", + "semantic_tags": [ + "settlements_account_60" + ], + "notes": "[mixed_pack_slot=slot_14_account_60 source=address_truth_harness_targeted_counterparty_tails:step_04_open_items_account_60]" + } + }, + { + "entry_id": "address_truth_harness_targeted_counterparty_tails:step_01_documents_by_counterparty", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_targeted_counterparty_tails.json", + "source_title": "Targeted live replay for counterparty documents, shipment items, inventory reset, and account-60 tails", + "scenario_id": "address_truth_harness_targeted_counterparty_tails", + "domain": "address_targeted_counterparty_tails", + "reusable_in_agent_pack": true, + "step_id": "step_01_documents_by_counterparty", + "title": "Counterparty documents with normalized name", + "question": "покажи все документы по чапурнову", + "criticality": "critical", + "expected_intents": [ + "list_documents_by_counterparty" + ], + "semantic_tags": [ + "counterparty_documents" + ], + "step_payload": { + "step_id": "step_01_documents_by_counterparty", + "title": "Counterparty documents with normalized name", + "question": "покажи все документы по чапурнову", + "allowed_reply_types": [ + "factual", + "factual_with_explanation" + ], + "expected_intents": [ + "list_documents_by_counterparty" + ], + "required_direct_answer_patterns_any": [ + "(?i)контрагент:", + "(?i)чапурнов" + ] + } + }, + { + "entry_id": "address_truth_harness_targeted_counterparty_tails:step_02_counterparty_item_flow", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_targeted_counterparty_tails.json", + "source_title": "Targeted live replay for counterparty documents, shipment items, inventory reset, and account-60 tails", + "scenario_id": "address_truth_harness_targeted_counterparty_tails", + "domain": "address_targeted_counterparty_tails", + "reusable_in_agent_pack": true, + "step_id": "step_02_counterparty_item_flow", + "title": "Counterparty shipment items", + "question": "что нам отгружал чапурнов? какой товар или услугу?", + "criticality": "critical", + "expected_intents": [ + "list_documents_by_counterparty" + ], + "semantic_tags": [ + "counterparty_shipment_fallback" + ], + "step_payload": { + "step_id": "step_02_counterparty_item_flow", + "title": "Counterparty shipment items", + "question": "что нам отгружал чапурнов? какой товар или услугу?", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "list_documents_by_counterparty" + ], + "required_direct_answer_patterns_any": [ + "(?i)контрагент:", + "(?i)позиции:", + "(?i)чапурнов" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^по текущим условиям в доступном срезе данных совпадений не нашлось", + "(?i)^сейчас не дам прямой адресный ответ" + ] + } + }, + { + "entry_id": "address_truth_harness_targeted_counterparty_tails:step_03_inventory_reset", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_targeted_counterparty_tails.json", + "source_title": "Targeted live replay for counterparty documents, shipment items, inventory reset, and account-60 tails", + "scenario_id": "address_truth_harness_targeted_counterparty_tails", + "domain": "address_targeted_counterparty_tails", + "reusable_in_agent_pack": true, + "step_id": "step_03_inventory_reset", + "title": "Inventory root after counterparty thread", + "question": "какие остатки на складе на сегодня?", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root" + ], + "step_payload": { + "step_id": "step_03_inventory_reset", + "title": "Inventory root after counterparty thread", + "question": "какие остатки на складе на сегодня?", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "required_direct_answer_patterns_any": [ + "(?i)на складе", + "(?i)остат" + ], + "forbidden_direct_answer_patterns": [ + "(?i)чапурнов", + "(?i)контрагент:" + ] + } + }, + { + "entry_id": "address_truth_harness_targeted_counterparty_tails:step_04_open_items_account_60", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_targeted_counterparty_tails.json", + "source_title": "Targeted live replay for counterparty documents, shipment items, inventory reset, and account-60 tails", + "scenario_id": "address_truth_harness_targeted_counterparty_tails", + "domain": "address_targeted_counterparty_tails", + "reusable_in_agent_pack": true, + "step_id": "step_04_open_items_account_60", + "title": "Account 60 tails for August 2022", + "question": "хвосты покажи по счету 60 на август 2022", + "criticality": "critical", + "expected_intents": [ + "open_items_by_counterparty_or_contract" + ], + "semantic_tags": [ + "settlements_account_60" + ], + "step_payload": { + "step_id": "step_04_open_items_account_60", + "title": "Account 60 tails for August 2022", + "question": "хвосты покажи по счету 60 на август 2022", + "allowed_reply_types": [ + "factual", + "factual_with_explanation" + ], + "expected_intents": [ + "open_items_by_counterparty_or_contract" + ], + "required_filters": { + "account": "60", + "period_from": "2022-08-01", + "period_to": "2022-08-31", + "as_of_date": "2022-08-31" + }, + "required_direct_answer_patterns_any": [ + "(?i)счету 60", + "(?i)хвост" + ] + } + }, + { + "entry_id": "address_truth_harness_test2:step_01_chat_opening", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_01_chat_opening", + "title": "Casual opener", + "question": "йо чо как", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_smalltalk" + ], + "step_payload": { + "step_id": "step_01_chat_opening", + "title": "Casual opener", + "question": "йо чо как", + "criticality": "info", + "allowed_reply_types": [ + "factual_with_explanation", + "factual" + ], + "required_answer_patterns_any": [ + "(?i)1с", + "(?i)помогаю", + "(?i)готов" + ], + "notes": "Информационный шаг: важно не ломать живой режим, но это не главный бизнес-блокер." + } + }, + { + "entry_id": "address_truth_harness_test2:step_02_receivables_march_2020", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_02_receivables_march_2020", + "title": "Receivables at March 2020", + "question": "кто нам должен на март 2020", + "criticality": "critical", + "expected_intents": [ + "receivables_confirmed_as_of_date" + ], + "semantic_tags": [ + "settlements_receivables" + ], + "step_payload": { + "step_id": "step_02_receivables_march_2020", + "title": "Receivables at March 2020", + "question": "кто нам должен на март 2020", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "receivables_confirmed_as_of_date" + ], + "expected_capability": "confirmed_receivables_as_of_date", + "expected_result_mode": "confirmed_balance", + "required_filters": { + "as_of_date": "2020-03-31", + "period_from": "2020-03-01", + "period_to": "2020-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2020", + "(?i)дебиторск" + ], + "notes": "Базовый корневой финансовый вопрос должен отработать точно и задать март 2020 как carryover-якорь." + } + }, + { + "entry_id": "address_truth_harness_test2:step_03_inventory_same_date", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_03_inventory_same_date", + "title": "Inventory on the same date", + "question": "остатки по складу на эту же дату", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root", + "same_date_pivot" + ], + "step_payload": { + "step_id": "step_03_inventory_same_date", + "title": "Inventory on the same date", + "question": "остатки по складу на эту же дату", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "expected_capability": "confirmed_inventory_on_hand_as_of_date", + "expected_result_mode": "confirmed_balance", + "required_filters": { + "as_of_date": "{{step_02_receivables_march_2020.filters.as_of_date}}", + "period_from": "{{step_02_receivables_march_2020.filters.period_from}}", + "period_to": "{{step_02_receivables_march_2020.filters.period_to}}" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2020", + "(?i)на складе" + ], + "notes": "Смена контура receivables -> inventory должна сохранить ту же дату, без дополнительного ручного уточнения." + } + }, + { + "entry_id": "address_truth_harness_test2:step_04_selected_item_seller", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_04_selected_item_seller", + "title": "Selected item purchase provenance", + "question": "По выбранному объекту \"Четки Пост (84*117)\": кто продавец", + "criticality": "critical", + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "semantic_tags": [ + "selected_object", + "selected_object_supplier" + ], + "step_payload": { + "step_id": "step_04_selected_item_seller", + "title": "Selected item purchase provenance", + "question": "По выбранному объекту \"Четки Пост (84*117)\": кто продавец", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "required_state_objects": [ + "focus_object" + ], + "required_carryover_invariants": [ + "focus_object" + ], + "forbidden_capabilities": [ + "confirmed_inventory_on_hand_as_of_date" + ], + "forbidden_recipes": [ + "address_inventory_on_hand_as_of_date_v1" + ], + "forbidden_filter_keys": [ + "as_of_date", + "period_from", + "period_to" + ], + "forbidden_direct_answer_patterns": [ + "^На 31\\.03\\.2020 на складе", + "(?i)^сейчас не дам прямой адресный ответ" + ], + "notes": "Выбранная позиция не должна реплеить складской срез; нужен именно ответ про поставщика/продавца." + } + }, + { + "entry_id": "address_truth_harness_test2:step_05_selected_item_sale_trace", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_05_selected_item_sale_trace", + "title": "Selected item buyer", + "question": "По выбранному объекту \"Четки Пост (84*117)\": кому мы продали эту хуйню", + "criticality": "critical", + "expected_intents": [ + "inventory_sale_trace_for_item" + ], + "semantic_tags": [ + "selected_object", + "selected_object_sale" + ], + "step_payload": { + "step_id": "step_05_selected_item_sale_trace", + "title": "Selected item buyer", + "question": "По выбранному объекту \"Четки Пост (84*117)\": кому мы продали эту хуйню", + "allowed_reply_types": [ + "factual", + "partial_coverage" + ], + "allowed_limited_reason_categories": [ + "empty_match" + ], + "expected_intents": [ + "inventory_sale_trace_for_item" + ], + "required_state_objects": [ + "focus_object" + ], + "required_carryover_invariants": [ + "focus_object" + ], + "forbidden_filter_keys": [ + "as_of_date", + "period_from", + "period_to" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^по текущим условиям в доступном срезе данных совпадений не нашлось", + "(?i)^сейчас не дам прямой адресный ответ" + ], + "notes": "След продажи по выбранной позиции не должен быть зажат складским snapshot-окном. Если по live данным подтвержденных продаж нет, честный partial_coverage с empty_match допустим, но только при правильном sale-trace routing и сохраненном focus_object." + } + }, + { + "entry_id": "address_truth_harness_test2:step_06_selected_item_purchase_followup", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_06_selected_item_purchase_followup", + "title": "Selected item purchase follow-up", + "question": "а купили у кого известно?", + "criticality": "critical", + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "semantic_tags": [ + "selected_object", + "selected_object_supplier" + ], + "step_payload": { + "step_id": "step_06_selected_item_purchase_followup", + "title": "Selected item purchase follow-up", + "question": "а купили у кого известно?", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_purchase_provenance_for_item" + ], + "required_state_objects": [ + "focus_object" + ], + "required_carryover_invariants": [ + "focus_object" + ], + "forbidden_filter_keys": [ + "as_of_date", + "period_from", + "period_to" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^для такого формата запроса нужен более широкий аналитический контур", + "(?i)^сейчас не дам прямой адресный ответ" + ], + "notes": "Короткий follow-up после выбранной позиции должен остаться в том же item-contour, а не свалиться в unknown." + } + }, + { + "entry_id": "address_truth_harness_test2:step_07_inventory_july_2019", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_07_inventory_july_2019", + "title": "Inventory at July 2019", + "question": "остатки на июль 2019", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root" + ], + "step_payload": { + "step_id": "step_07_inventory_july_2019", + "title": "Inventory at July 2019", + "question": "остатки на июль 2019", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "expected_capability": "confirmed_inventory_on_hand_as_of_date", + "expected_result_mode": "confirmed_balance", + "required_filters": { + "as_of_date": "2019-07-31", + "period_from": "2019-07-01", + "period_to": "2019-07-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.07\\.2019", + "(?i)на складе" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ" + ], + "notes": "После провала provenance-среза система все равно должна уметь коротко вернуть root inventory frame по явному месяцу." + } + }, + { + "entry_id": "address_truth_harness_test2:step_08_inventory_september_2019", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_08_inventory_september_2019", + "title": "Inventory at September 2019", + "question": "сентябрь 2019", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root" + ], + "step_payload": { + "step_id": "step_08_inventory_september_2019", + "title": "Inventory at September 2019", + "question": "сентябрь 2019", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "expected_capability": "confirmed_inventory_on_hand_as_of_date", + "expected_result_mode": "confirmed_balance", + "required_filters": { + "as_of_date": "2019-09-30", + "period_from": "2019-09-01", + "period_to": "2019-09-30" + }, + "required_direct_answer_patterns_any": [ + "30\\.09\\.2019", + "(?i)на складе" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ" + ], + "notes": "Короткое bare-month follow-up должно удерживать складской корень без дополнительной расшифровки." + } + }, + { + "entry_id": "address_truth_harness_test2:step_09_inventory_march_2020", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_09_inventory_march_2020", + "title": "Inventory at March 2020", + "question": "март 2020", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root" + ], + "step_payload": { + "step_id": "step_09_inventory_march_2020", + "title": "Inventory at March 2020", + "question": "март 2020", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "expected_capability": "confirmed_inventory_on_hand_as_of_date", + "expected_result_mode": "confirmed_balance", + "required_filters": { + "as_of_date": "2020-03-31", + "period_from": "2020-03-01", + "period_to": "2020-03-31" + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2020", + "(?i)на складе" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ" + ], + "notes": "Возврат на март 2020 должен снова дать точный складской срез, а не unknown/partial." + } + }, + { + "entry_id": "address_truth_harness_test2:step_10_inventory_same_date_negative_wording", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_10_inventory_same_date_negative_wording", + "title": "Inventory same date with noisy wording", + "question": "остатков на складе нет на эту дату?", + "criticality": "critical", + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "semantic_tags": [ + "inventory_root", + "same_date_pivot" + ], + "step_payload": { + "step_id": "step_10_inventory_same_date_negative_wording", + "title": "Inventory same date with noisy wording", + "question": "остатков на складе нет на эту дату?", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "inventory_on_hand_as_of_date" + ], + "expected_capability": "confirmed_inventory_on_hand_as_of_date", + "expected_result_mode": "confirmed_balance", + "required_filters": { + "as_of_date": "{{step_09_inventory_march_2020.filters.as_of_date}}", + "period_from": "{{step_09_inventory_march_2020.filters.period_from}}", + "period_to": "{{step_09_inventory_march_2020.filters.period_to}}" + }, + "forbidden_filter_values": { + "warehouse": [ + "нет на эту дату" + ] + }, + "required_direct_answer_patterns_any": [ + "31\\.03\\.2020", + "(?i)на складе" + ], + "forbidden_direct_answer_patterns": [ + "(?i)^сейчас не дам прямой адресный ответ" + ], + "notes": "Разговорная частица `нет на эту дату` не должна становиться warehouse-anchor." + } + }, + { + "entry_id": "address_truth_harness_test2:step_11_vat_same_date", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_11_vat_same_date", + "title": "VAT on the same date", + "question": "ндс какой надо заплатить на эту же дату", + "criticality": "critical", + "expected_intents": [ + "vat_liability_confirmed_for_tax_period" + ], + "semantic_tags": [ + "vat" + ], + "step_payload": { + "step_id": "step_11_vat_same_date", + "title": "VAT on the same date", + "question": "ндс какой надо заплатить на эту же дату", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "vat_liability_confirmed_for_tax_period" + ], + "expected_capability": "confirmed_vat_liability_for_tax_period", + "required_filters": { + "period_from": "{{step_09_inventory_march_2020.filters.period_from}}", + "period_to": "{{step_09_inventory_march_2020.filters.period_to}}" + }, + "required_direct_answer_patterns_any": [ + "(?i)ндс" + ], + "notes": "Pivot inventory -> VAT по `на эту же дату` должен привязаться к марту 2020, а не к мусорному складскому anchor." + } + }, + { + "entry_id": "address_truth_harness_test2:step_12_vat_may_2016", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_12_vat_may_2016", + "title": "VAT at May 2016", + "question": "а на май 2016", + "criticality": "critical", + "expected_intents": [ + "vat_liability_confirmed_for_tax_period" + ], + "semantic_tags": [ + "vat" + ], + "step_payload": { + "step_id": "step_12_vat_may_2016", + "title": "VAT at May 2016", + "question": "а на май 2016", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "vat_liability_confirmed_for_tax_period" + ], + "expected_capability": "confirmed_vat_liability_for_tax_period", + "forbidden_filter_values": { + "period_from": [ + "{{step_11_vat_same_date.filters.period_from}}" + ], + "period_to": [ + "{{step_11_vat_same_date.filters.period_to}}" + ] + }, + "required_answer_patterns_any": [ + "2016", + "(?i)налоговый период" + ], + "required_direct_answer_patterns_any": [ + "(?i)ндс" + ], + "notes": "Короткий temporal follow-up внутри VAT-frame должен уйти с марта 2020 на май 2016." + } + }, + { + "entry_id": "address_truth_harness_test2:step_13_receivables_same_date_after_vat_2016", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_13_receivables_same_date_after_vat_2016", + "title": "Receivables on the carried 2016 date", + "question": "кто нам должен денег на эту дату", + "criticality": "critical", + "expected_intents": [ + "receivables_confirmed_as_of_date" + ], + "semantic_tags": [ + "settlements_receivables", + "vat" + ], + "step_payload": { + "step_id": "step_13_receivables_same_date_after_vat_2016", + "title": "Receivables on the carried 2016 date", + "question": "кто нам должен денег на эту дату", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "receivables_confirmed_as_of_date" + ], + "expected_capability": "confirmed_receivables_as_of_date", + "required_filter_within_previous_step_period": { + "as_of_date": "step_12_vat_may_2016" + }, + "required_answer_patterns_any": [ + "2016" + ], + "required_direct_answer_patterns_any": [ + "(?i)дебиторск" + ], + "forbidden_direct_answer_patterns": [ + "31\\.03\\.2020" + ], + "notes": "Фраза `на эту дату` после VAT 2016 не должна откатываться обратно на март 2020." + } + }, + { + "entry_id": "address_truth_harness_test2:step_14_receivables_today", + "source_type": "truth_harness_step", + "source_file": "docs/orchestration/address_truth_harness_test2.json", + "source_title": "Exact replay and truth review for test2 mixed follow-up chain", + "scenario_id": "address_truth_harness_test2", + "domain": "address_mixed_followup", + "reusable_in_agent_pack": true, + "step_id": "step_14_receivables_today", + "title": "Receivables today", + "question": "а на сегодня", + "criticality": "critical", + "expected_intents": [ + "receivables_confirmed_as_of_date" + ], + "semantic_tags": [ + "settlements_receivables" + ], + "step_payload": { + "step_id": "step_14_receivables_today", + "title": "Receivables today", + "question": "а на сегодня", + "allowed_reply_types": [ + "factual" + ], + "expected_intents": [ + "receivables_confirmed_as_of_date" + ], + "expected_capability": "confirmed_receivables_as_of_date", + "required_filters": { + "as_of_date": "{{runtime.today_iso}}" + }, + "required_direct_answer_patterns_any": [ + "{{runtime.today_dot_regex}}", + "(?i)дебиторск" + ], + "notes": "Последний шаг нужен как sanity-check: `на сегодня` должен честно пересчитать уже на текущую дату прогона." + } + } + ], + "saved_session_entries": [ + { + "entry_id": "assistant_saved_session_20260416175150_gen-mo1s0m9z-ndf56a3:q01", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416175150_gen-mo1s0m9z-ndf56a3.json", + "source_title": "Ручная сессия 16.04.2026, 20:51:30", + "scenario_id": "gen-mo1s0m9z-ndf56a3", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q01", + "title": "Saved session question 1", + "question": "привет как дела", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_smalltalk" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q01", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q01", + "title": "Saved session question 1", + "question": "приветик - че как там дела", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_smalltalk" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q02", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q02", + "title": "Saved session question 2", + "question": "расскажи что можешь интересного", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_capability" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q03", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q03", + "title": "Saved session question 3", + "question": "кайф - что там на складе по остаткам?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q04", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q04", + "title": "Saved session question 4", + "question": "а исторические остатки на другие даты умеешь?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_capability", + "meta_historical_capability", + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q05", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q05", + "title": "Saved session question 5", + "question": "давай на июль 2017", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q06", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q06", + "title": "Saved session question 6", + "question": "март 2016", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q07", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q07", + "title": "Saved session question 7", + "question": "По выбранному объекту \"Рабочая станция универсального специалиста (индивидуальное изготовление)\": где взяли это?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "selected_object" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q08", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q08", + "title": "Saved session question 8", + "question": "а кому продали?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q09", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q09", + "title": "Saved session question 9", + "question": "у тебя написано кто контрагент: рабочая станция - это ошибка?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q10", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q10", + "title": "Saved session question 10", + "question": "ндс можешь прикинуть на дату покупки рабочей станции?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "vat" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q11", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q11", + "title": "Saved session question 11", + "question": "а какой ндс мы должны сгрузить на март 2020?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "vat" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q12", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q12", + "title": "Saved session question 12", + "question": "прикинь какой ндс нам надо заплатить на февраль 2017", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "vat" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q13", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q13", + "title": "Saved session question 13", + "question": "кто у нас самый доходный клиент за все время", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q14", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q14", + "title": "Saved session question 14", + "question": "кто нам должен денег на май 2017", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "settlements_receivables" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q15", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q15", + "title": "Saved session question 15", + "question": "а какой ндс мы должны примерно заплатить за этот период?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "vat" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q16", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q16", + "title": "Saved session question 16", + "question": "мы должны комуто денег на сегодня?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q17", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q17", + "title": "Saved session question 17", + "question": "а нам?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q18", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q18", + "title": "Saved session question 18", + "question": "какой у нас самый доходный год", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q19", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q19", + "title": "Saved session question 19", + "question": "а за 2017 мы скок заработали?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q20", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q20", + "title": "Saved session question 20", + "question": "сколько вообще денег мы заработали за все время?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q21", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q21", + "title": "Saved session question 21", + "question": "ты умеешь считать дельту по договорам?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_capability" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q22", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q22", + "title": "Saved session question 22", + "question": "по чепурнову покажи все доки", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "counterparty_documents" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q23", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q23", + "title": "Saved session question 23", + "question": "а по свк", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q24", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q24", + "title": "Saved session question 24", + "question": "а сейчас у нас есть что на складе?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q25", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q25", + "title": "Saved session question 25", + "question": "что нам отгружать чепурнов? какой товар или услугу?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "counterparty_shipment_fallback" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q26", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q26", + "title": "Saved session question 26", + "question": "какие остатки на складе на сегодня", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q27", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q27", + "title": "Saved session question 27", + "question": "остатки на март 2016", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q28", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q28", + "title": "Saved session question 28", + "question": "это по общей базе уже нужен вывод не по чепурнову", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_scope" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q29", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q29", + "title": "Saved session question 29", + "question": "хвосты покажи по счету 60 на август 2022", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q30", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q30", + "title": "Saved session question 30", + "question": "Есть ли остатки товара, которые закупались очень давно", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q31", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e.json", + "source_title": "БОЛЬШОЙ ОБЩИЙ Ручная сессия 16.04.2026, 21:26:06", + "scenario_id": "gen-mo1t93wq-jy0453e", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q31", + "title": "Saved session question 31", + "question": "Какие конкретно номенклатуры формируют остаток по складу на май 2020", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q01", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q01", + "title": "Saved session question 1", + "question": "покажи все документы по чепурнову", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "counterparty_documents" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q02", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q02", + "title": "Saved session question 2", + "question": "что нам отгружал чепурнов, какой товар или услугу?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "counterparty_shipment_fallback" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q03", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q03", + "title": "Saved session question 3", + "question": "какие остатки на складе на сегодня?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q04", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q04", + "title": "Saved session question 4", + "question": "хвосты по счету 60 на август 2022", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "settlements_account_60" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q05", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q05", + "title": "Saved session question 5", + "question": "какие остатки на складе на март 2021", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q06", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q06", + "title": "Saved session question 6", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "selected_object" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q07", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q07", + "title": "Saved session question 7", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "selected_object" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q08", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q08", + "title": "Saved session question 8", + "question": "покажи еще раз остатки на эту же дату", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q09", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q09", + "title": "Saved session question 9", + "question": "какие остатки на складе на март 2016", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q10", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q10", + "title": "Saved session question 10", + "question": "на июль 2019", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q11", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q11", + "title": "Saved session question 11", + "question": "на сентябрь", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q12", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q12", + "title": "Saved session question 12", + "question": "а на март", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q13", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng.json", + "source_title": "Ручная сессия 17.04.2026, 10:04:19 ТЕМП", + "scenario_id": "gen-mo2kcds2-tlqmvng", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q13", + "title": "Saved session question 13", + "question": "это по общей базе", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_scope" + ], + "session_mode": "saved_user_sessions", + "agent_run": false + }, + { + "entry_id": "assistant_saved_session_20260417080808_gen-ag04170808-1907fa:q01", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417080808_gen-ag04170808-1907fa.json", + "source_title": "AGENT | Phase 4 coverage/evidence replay for counterparty fallback, inventory reset, and selected-object provenance", + "scenario_id": "gen-ag04170808-1907fa", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q01", + "title": "Saved session question 1", + "question": "покажи все документы по чепурнову", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "counterparty_documents" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417080808_gen-ag04170808-1907fa:q02", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417080808_gen-ag04170808-1907fa.json", + "source_title": "AGENT | Phase 4 coverage/evidence replay for counterparty fallback, inventory reset, and selected-object provenance", + "scenario_id": "gen-ag04170808-1907fa", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q02", + "title": "Saved session question 2", + "question": "что нам отгружал чепурнов, какой товар или услугу?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "counterparty_shipment_fallback" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417080808_gen-ag04170808-1907fa:q03", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417080808_gen-ag04170808-1907fa.json", + "source_title": "AGENT | Phase 4 coverage/evidence replay for counterparty fallback, inventory reset, and selected-object provenance", + "scenario_id": "gen-ag04170808-1907fa", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q03", + "title": "Saved session question 3", + "question": "какие остатки на складе на март 2021", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417080808_gen-ag04170808-1907fa:q04", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417080808_gen-ag04170808-1907fa.json", + "source_title": "AGENT | Phase 4 coverage/evidence replay for counterparty fallback, inventory reset, and selected-object provenance", + "scenario_id": "gen-ag04170808-1907fa", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q04", + "title": "Saved session question 4", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "selected_object" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417080808_gen-ag04170808-1907fa:q05", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417080808_gen-ag04170808-1907fa.json", + "source_title": "AGENT | Phase 4 coverage/evidence replay for counterparty fallback, inventory reset, and selected-object provenance", + "scenario_id": "gen-ag04170808-1907fa", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q05", + "title": "Saved session question 5", + "question": "покажи еще раз остатки на эту же дату", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q01", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417083044_gen-ag04170830-5f771d.json", + "source_title": "AGENT | Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "gen-ag04170830-5f771d", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q01", + "title": "Saved session question 1", + "question": "какие остатки на складе на март 2021", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q02", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417083044_gen-ag04170830-5f771d.json", + "source_title": "AGENT | Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "gen-ag04170830-5f771d", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q02", + "title": "Saved session question 2", + "question": "а исторические остатки тоже можешь?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_historical_capability", + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q03", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417083044_gen-ag04170830-5f771d.json", + "source_title": "AGENT | Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "gen-ag04170830-5f771d", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q03", + "title": "Saved session question 3", + "question": "по какой компании мы сейчас работаем?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_scope" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q04", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417083044_gen-ag04170830-5f771d.json", + "source_title": "AGENT | Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "gen-ag04170830-5f771d", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q04", + "title": "Saved session question 4", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "selected_object" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q05", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417083044_gen-ag04170830-5f771d.json", + "source_title": "AGENT | Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "gen-ag04170830-5f771d", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q05", + "title": "Saved session question 5", + "question": "что ты умеешь?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_capability" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q06", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417083044_gen-ag04170830-5f771d.json", + "source_title": "AGENT | Phase 5 meta and memory recap replay over interrupted address context", + "scenario_id": "gen-ag04170830-5f771d", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q06", + "title": "Saved session question 6", + "question": "а ты помнишь, что мы по этой позиции уже выяснили?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_memory" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417085550_gen-ag04170855-d13dd3:q01", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417085550_gen-ag04170855-d13dd3.json", + "source_title": "AGENT | Phase 6 provider/runtime replay across chat, meta, and address boundaries", + "scenario_id": "gen-ag04170855-d13dd3", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q01", + "title": "Saved session question 1", + "question": "привет, как дела?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_smalltalk" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417085550_gen-ag04170855-d13dd3:q02", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417085550_gen-ag04170855-d13dd3.json", + "source_title": "AGENT | Phase 6 provider/runtime replay across chat, meta, and address boundaries", + "scenario_id": "gen-ag04170855-d13dd3", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q02", + "title": "Saved session question 2", + "question": "по какой компании мы сейчас работаем?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_scope" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417085550_gen-ag04170855-d13dd3:q03", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417085550_gen-ag04170855-d13dd3.json", + "source_title": "AGENT | Phase 6 provider/runtime replay across chat, meta, and address boundaries", + "scenario_id": "gen-ag04170855-d13dd3", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q03", + "title": "Saved session question 3", + "question": "что ты можешь по 1С?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417085550_gen-ag04170855-d13dd3:q04", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417085550_gen-ag04170855-d13dd3.json", + "source_title": "AGENT | Phase 6 provider/runtime replay across chat, meta, and address boundaries", + "scenario_id": "gen-ag04170855-d13dd3", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q04", + "title": "Saved session question 4", + "question": "какие остатки на складе на март 2021", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417085550_gen-ag04170855-d13dd3:q05", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417085550_gen-ag04170855-d13dd3.json", + "source_title": "AGENT | Phase 6 provider/runtime replay across chat, meta, and address boundaries", + "scenario_id": "gen-ag04170855-d13dd3", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q05", + "title": "Saved session question 5", + "question": "а исторические остатки тоже можешь?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_historical_capability", + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q01", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417091127_gen-ag04170911-ff51e1.json", + "source_title": "AGENT | Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "gen-ag04170911-ff51e1", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q01", + "title": "Saved session question 1", + "question": "какие остатки на складе на март 2021", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q02", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417091127_gen-ag04170911-ff51e1.json", + "source_title": "AGENT | Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "gen-ag04170911-ff51e1", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q02", + "title": "Saved session question 2", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "selected_object" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q03", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417091127_gen-ag04170911-ff51e1.json", + "source_title": "AGENT | Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "gen-ag04170911-ff51e1", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q03", + "title": "Saved session question 3", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "selected_object" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q04", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417091127_gen-ag04170911-ff51e1.json", + "source_title": "AGENT | Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "gen-ag04170911-ff51e1", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q04", + "title": "Saved session question 4", + "question": "покажи еще раз остатки на эту же дату", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q05", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417091127_gen-ag04170911-ff51e1.json", + "source_title": "AGENT | Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "gen-ag04170911-ff51e1", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q05", + "title": "Saved session question 5", + "question": "по какой компании мы сейчас работаем?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_scope" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q06", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417091127_gen-ag04170911-ff51e1.json", + "source_title": "AGENT | Phase 7 acceptance replay for inventory root, selected-object continuity, and human meta boundaries", + "scenario_id": "gen-ag04170911-ff51e1", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q06", + "title": "Saved session question 6", + "question": "а исторические остатки тоже можешь?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_historical_capability", + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q01", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q01", + "title": "Saved session question 1", + "question": "привет, как дела?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_smalltalk" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q02", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q02", + "title": "Saved session question 2", + "question": "по какой компании мы сейчас работаем?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_scope" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q03", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q03", + "title": "Saved session question 3", + "question": "покажи все документы по чепурнову", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "counterparty_documents" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q04", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q04", + "title": "Saved session question 4", + "question": "что нам отгружал чепурнов, какой товар или услугу?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "counterparty_shipment_fallback" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q05", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q05", + "title": "Saved session question 5", + "question": "какие остатки на складе на март 2021", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q06", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q06", + "title": "Saved session question 6", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "selected_object" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q07", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q07", + "title": "Saved session question 7", + "question": "что ты умеешь?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_capability" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q08", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q08", + "title": "Saved session question 8", + "question": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "selected_object" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q09", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q09", + "title": "Saved session question 9", + "question": "а ты помнишь, что мы по этой позиции уже выяснили?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_memory" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q10", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q10", + "title": "Saved session question 10", + "question": "покажи еще раз остатки на эту же дату", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q11", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q11", + "title": "Saved session question 11", + "question": "кто нам должен на март 2020", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "settlements_receivables" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q12", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q12", + "title": "Saved session question 12", + "question": "остатки по складу на эту же дату", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q13", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q13", + "title": "Saved session question 13", + "question": "а исторические остатки тоже можешь?", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [ + "meta_historical_capability", + "inventory_root" + ], + "session_mode": "saved_user_sessions", + "agent_run": true + }, + { + "entry_id": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q14", + "source_type": "saved_session_question", + "source_file": "llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "source_title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "scenario_id": "gen-ag04170931-6bb7e5", + "domain": null, + "reusable_in_agent_pack": false, + "step_id": "saved_session_q14", + "title": "Saved session question 14", + "question": "хвосты покажи по счету 60 на август 2022", + "criticality": "info", + "expected_intents": [], + "semantic_tags": [], + "session_mode": "saved_user_sessions", + "agent_run": true + } + ] +} diff --git a/docs/orchestration/agent_semantic_source_catalog.md b/docs/orchestration/agent_semantic_source_catalog.md new file mode 100644 index 0000000..13e794a --- /dev/null +++ b/docs/orchestration/agent_semantic_source_catalog.md @@ -0,0 +1,166 @@ +# Agent semantic source catalog + +- truth_harness_steps_total: `58` +- saved_session_questions_total: `81` + +## Reusable truth-harness tags +- `counterparty_documents`: `3` +- `counterparty_shipment_fallback`: `3` +- `inventory_root`: `21` +- `meta_capability`: `3` +- `meta_historical_capability`: `4` +- `meta_memory`: `2` +- `meta_scope`: `4` +- `meta_smalltalk`: `3` +- `same_date_pivot`: `3` +- `same_date_restore`: `4` +- `selected_object`: `11` +- `selected_object_documents`: `3` +- `selected_object_sale`: `1` +- `selected_object_supplier`: `7` +- `settlements_account_60`: `2` +- `settlements_receivables`: `4` +- `vat`: `3` + +## Reusable truth-harness steps +- `address_truth_harness_inventory_provenance_restore:step_01_inventory_march_2021` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `address_truth_harness_inventory_provenance_restore:step_02_selected_item_supplier` | tags: selected_object, selected_object_supplier | question: По выбранному объекту "Столешница 600*3050*26 альмандин": кто нам это поставил? +- `address_truth_harness_inventory_provenance_restore:step_03_selected_item_documents` | tags: selected_object, selected_object_documents | question: По выбранному объекту "Столешница 600*3050*26 альмандин": покажи документы по этой позиции +- `address_truth_harness_inventory_provenance_restore:step_04_inventory_same_date_restore` | tags: inventory_root, same_date_restore | question: покажи еще раз остатки на эту же дату +- `address_truth_harness_phase4_coverage_evidence_mix:step_01_counterparty_documents` | tags: counterparty_documents | question: покажи все документы по чепурнову +- `address_truth_harness_phase4_coverage_evidence_mix:step_02_counterparty_shipments_or_fallback` | tags: counterparty_shipment_fallback | question: что нам отгружал чепурнов, какой товар или услугу? +- `address_truth_harness_phase4_coverage_evidence_mix:step_03_inventory_reset_march_2021` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `address_truth_harness_phase4_coverage_evidence_mix:step_04_selected_item_supplier_temporal_limit` | tags: selected_object, selected_object_supplier | question: По выбранному объекту "Столешница 600*3050*26 альмандин": кто нам это поставил? +- `address_truth_harness_phase4_coverage_evidence_mix:step_05_inventory_same_date_restore` | tags: inventory_root, same_date_restore | question: покажи еще раз остатки на эту же дату +- `address_truth_harness_phase5_meta_memory_mix:step_01_inventory_root_march_2021` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `address_truth_harness_phase5_meta_memory_mix:step_02_inventory_history_capability_followup` | tags: meta_historical_capability, inventory_root | question: а исторические остатки тоже можешь? +- `address_truth_harness_phase5_meta_memory_mix:step_03_data_scope_meta_interrupt` | tags: meta_scope | question: по какой компании мы сейчас работаем? +- `address_truth_harness_phase5_meta_memory_mix:step_04_selected_item_supplier` | tags: selected_object, selected_object_supplier | question: По выбранному объекту "Столешница 600*3050*26 альмандин": кто нам это поставил? +- `address_truth_harness_phase5_meta_memory_mix:step_05_capability_meta_interrupt` | tags: meta_capability | question: что ты умеешь? +- `address_truth_harness_phase5_meta_memory_mix:step_06_memory_recap_after_interrupts` | tags: meta_memory | question: а ты помнишь, что мы по этой позиции уже выяснили? +- `address_truth_harness_phase6_provider_axis_mix:step_01_smalltalk` | tags: meta_smalltalk | question: привет, как дела? +- `address_truth_harness_phase6_provider_axis_mix:step_02_data_scope_meta` | tags: meta_scope | question: по какой компании мы сейчас работаем? +- `address_truth_harness_phase6_provider_axis_mix:step_03_capability_meta` | tags: meta_capability | question: что ты можешь по 1С? +- `address_truth_harness_phase6_provider_axis_mix:step_04_inventory_root_march_2021` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `address_truth_harness_phase6_provider_axis_mix:step_05_historical_capability_followup` | tags: meta_historical_capability, inventory_root | question: а исторические остатки тоже можешь? +- `address_truth_harness_phase7_acceptance_gate_mix:step_01_inventory_march_2021` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `address_truth_harness_phase7_acceptance_gate_mix:step_02_selected_item_supplier` | tags: selected_object, selected_object_supplier | question: По выбранному объекту "Столешница 600*3050*26 альмандин": кто нам это поставил? +- `address_truth_harness_phase7_acceptance_gate_mix:step_03_selected_item_documents` | tags: selected_object, selected_object_documents | question: По выбранному объекту "Столешница 600*3050*26 альмандин": покажи документы по этой позиции +- `address_truth_harness_phase7_acceptance_gate_mix:step_04_inventory_same_date_restore` | tags: inventory_root, same_date_restore | question: покажи еще раз остатки на эту же дату +- `address_truth_harness_phase7_acceptance_gate_mix:step_05_data_scope_meta_interrupt` | tags: meta_scope | question: по какой компании мы сейчас работаем? +- `address_truth_harness_phase7_acceptance_gate_mix:step_06_historical_capability_followup` | tags: meta_historical_capability, inventory_root | question: а исторические остатки тоже можешь? +- `address_truth_harness_phase7_meta_domain_mix:step_01_smalltalk` | tags: meta_smalltalk | question: привет, как дела? +- `address_truth_harness_phase7_meta_domain_mix:step_02_data_scope_meta` | tags: meta_scope | question: по какой компании мы сейчас работаем? +- `address_truth_harness_phase7_meta_domain_mix:step_01_counterparty_documents` | tags: counterparty_documents | question: покажи все документы по чепурнову +- `address_truth_harness_phase7_meta_domain_mix:step_02_counterparty_shipments_or_fallback` | tags: counterparty_shipment_fallback | question: что нам отгружал чепурнов, какой товар или услугу? +- `address_truth_harness_phase7_meta_domain_mix:step_01_inventory_march_2021` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `address_truth_harness_phase7_meta_domain_mix:step_02_selected_item_supplier` | tags: selected_object, selected_object_supplier | question: По выбранному объекту "Столешница 600*3050*26 альмандин": кто нам это поставил? +- `address_truth_harness_phase7_meta_domain_mix:step_05_capability_meta_interrupt` | tags: meta_capability | question: что ты умеешь? +- `address_truth_harness_phase7_meta_domain_mix:step_03_selected_item_documents` | tags: selected_object, selected_object_documents | question: По выбранному объекту "Столешница 600*3050*26 альмандин": покажи документы по этой позиции +- `address_truth_harness_phase7_meta_domain_mix:step_06_memory_recap_after_interrupts` | tags: meta_memory | question: а ты помнишь, что мы по этой позиции уже выяснили? +- `address_truth_harness_phase7_meta_domain_mix:step_04_inventory_same_date_restore` | tags: inventory_root, same_date_restore | question: покажи еще раз остатки на эту же дату +- `address_truth_harness_phase7_meta_domain_mix:step_02_receivables_march_2020` | tags: settlements_receivables | question: кто нам должен на март 2020 +- `address_truth_harness_phase7_meta_domain_mix:step_03_inventory_same_date` | tags: inventory_root, same_date_pivot | question: остатки по складу на эту же дату +- `address_truth_harness_phase7_meta_domain_mix:step_06_historical_capability_followup` | tags: meta_historical_capability, inventory_root | question: а исторические остатки тоже можешь? +- `address_truth_harness_phase7_meta_domain_mix:step_04_open_items_account_60` | tags: settlements_account_60 | question: хвосты покажи по счету 60 на август 2022 +- `address_truth_harness_targeted_counterparty_tails:step_01_documents_by_counterparty` | tags: counterparty_documents | question: покажи все документы по чапурнову +- `address_truth_harness_targeted_counterparty_tails:step_02_counterparty_item_flow` | tags: counterparty_shipment_fallback | question: что нам отгружал чапурнов? какой товар или услугу? +- `address_truth_harness_targeted_counterparty_tails:step_03_inventory_reset` | tags: inventory_root | question: какие остатки на складе на сегодня? +- `address_truth_harness_targeted_counterparty_tails:step_04_open_items_account_60` | tags: settlements_account_60 | question: хвосты покажи по счету 60 на август 2022 +- `address_truth_harness_test2:step_01_chat_opening` | tags: meta_smalltalk | question: йо чо как +- `address_truth_harness_test2:step_02_receivables_march_2020` | tags: settlements_receivables | question: кто нам должен на март 2020 +- `address_truth_harness_test2:step_03_inventory_same_date` | tags: inventory_root, same_date_pivot | question: остатки по складу на эту же дату +- `address_truth_harness_test2:step_04_selected_item_seller` | tags: selected_object, selected_object_supplier | question: По выбранному объекту "Четки Пост (84*117)": кто продавец +- `address_truth_harness_test2:step_05_selected_item_sale_trace` | tags: selected_object, selected_object_sale | question: По выбранному объекту "Четки Пост (84*117)": кому мы продали эту хуйню +- `address_truth_harness_test2:step_06_selected_item_purchase_followup` | tags: selected_object, selected_object_supplier | question: а купили у кого известно? +- `address_truth_harness_test2:step_07_inventory_july_2019` | tags: inventory_root | question: остатки на июль 2019 +- `address_truth_harness_test2:step_08_inventory_september_2019` | tags: inventory_root | question: сентябрь 2019 +- `address_truth_harness_test2:step_09_inventory_march_2020` | tags: inventory_root | question: март 2020 +- `address_truth_harness_test2:step_10_inventory_same_date_negative_wording` | tags: inventory_root, same_date_pivot | question: остатков на складе нет на эту дату? +- `address_truth_harness_test2:step_11_vat_same_date` | tags: vat | question: ндс какой надо заплатить на эту же дату +- `address_truth_harness_test2:step_12_vat_may_2016` | tags: vat | question: а на май 2016 +- `address_truth_harness_test2:step_13_receivables_same_date_after_vat_2016` | tags: settlements_receivables, vat | question: кто нам должен денег на эту дату +- `address_truth_harness_test2:step_14_receivables_today` | tags: settlements_receivables | question: а на сегодня + +## Saved session questions +- `assistant_saved_session_20260416175150_gen-mo1s0m9z-ndf56a3:q01` | tags: meta_smalltalk | question: привет как дела +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q01` | tags: meta_smalltalk | question: приветик - че как там дела +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q02` | tags: meta_capability | question: расскажи что можешь интересного +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q03` | tags: inventory_root | question: кайф - что там на складе по остаткам? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q04` | tags: meta_capability, meta_historical_capability, inventory_root | question: а исторические остатки на другие даты умеешь? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q05` | tags: none | question: давай на июль 2017 +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q06` | tags: none | question: март 2016 +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q07` | tags: selected_object | question: По выбранному объекту "Рабочая станция универсального специалиста (индивидуальное изготовление)": где взяли это? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q08` | tags: none | question: а кому продали? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q09` | tags: none | question: у тебя написано кто контрагент: рабочая станция - это ошибка? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q10` | tags: vat | question: ндс можешь прикинуть на дату покупки рабочей станции? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q11` | tags: vat | question: а какой ндс мы должны сгрузить на март 2020? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q12` | tags: vat | question: прикинь какой ндс нам надо заплатить на февраль 2017 +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q13` | tags: none | question: кто у нас самый доходный клиент за все время +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q14` | tags: settlements_receivables | question: кто нам должен денег на май 2017 +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q15` | tags: vat | question: а какой ндс мы должны примерно заплатить за этот период? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q16` | tags: none | question: мы должны комуто денег на сегодня? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q17` | tags: none | question: а нам? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q18` | tags: none | question: какой у нас самый доходный год +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q19` | tags: none | question: а за 2017 мы скок заработали? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q20` | tags: none | question: сколько вообще денег мы заработали за все время? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q21` | tags: meta_capability | question: ты умеешь считать дельту по договорам? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q22` | tags: counterparty_documents | question: по чепурнову покажи все доки +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q23` | tags: none | question: а по свк +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q24` | tags: inventory_root | question: а сейчас у нас есть что на складе? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q25` | tags: counterparty_shipment_fallback | question: что нам отгружать чепурнов? какой товар или услугу? +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q26` | tags: inventory_root | question: какие остатки на складе на сегодня +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q27` | tags: inventory_root | question: остатки на март 2016 +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q28` | tags: meta_scope | question: это по общей базе уже нужен вывод не по чепурнову +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q29` | tags: none | question: хвосты покажи по счету 60 на август 2022 +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q30` | tags: inventory_root | question: Есть ли остатки товара, которые закупались очень давно +- `assistant_saved_session_20260416182626_gen-mo1t93wq-jy0453e:q31` | tags: inventory_root | question: Какие конкретно номенклатуры формируют остаток по складу на май 2020 +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q01` | tags: counterparty_documents | question: покажи все документы по чепурнову +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q02` | tags: counterparty_shipment_fallback | question: что нам отгружал чепурнов, какой товар или услугу? +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q03` | tags: inventory_root | question: какие остатки на складе на сегодня? +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q04` | tags: settlements_account_60 | question: хвосты по счету 60 на август 2022 +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q05` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q06` | tags: selected_object | question: По выбранному объекту "Столешница 600*3050*26 альмандин": кто нам это поставил? +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q07` | tags: selected_object | question: По выбранному объекту "Столешница 600*3050*26 альмандин": покажи документы по этой позиции +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q08` | tags: inventory_root | question: покажи еще раз остатки на эту же дату +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q09` | tags: inventory_root | question: какие остатки на складе на март 2016 +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q10` | tags: none | question: на июль 2019 +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q11` | tags: none | question: на сентябрь +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q12` | tags: none | question: а на март +- `assistant_saved_session_20260417070448_gen-mo2kcds2-tlqmvng:q13` | tags: meta_scope | question: это по общей базе +- `assistant_saved_session_20260417080808_gen-ag04170808-1907fa:q01` | tags: counterparty_documents | question: покажи все документы по чепурнову +- `assistant_saved_session_20260417080808_gen-ag04170808-1907fa:q02` | tags: counterparty_shipment_fallback | question: что нам отгружал чепурнов, какой товар или услугу? +- `assistant_saved_session_20260417080808_gen-ag04170808-1907fa:q03` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `assistant_saved_session_20260417080808_gen-ag04170808-1907fa:q04` | tags: selected_object | question: По выбранному объекту "Столешница 600*3050*26 альмандин": кто нам это поставил? +- `assistant_saved_session_20260417080808_gen-ag04170808-1907fa:q05` | tags: inventory_root | question: покажи еще раз остатки на эту же дату +- `assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q01` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q02` | tags: meta_historical_capability, inventory_root | question: а исторические остатки тоже можешь? +- `assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q03` | tags: meta_scope | question: по какой компании мы сейчас работаем? +- `assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q04` | tags: selected_object | question: По выбранному объекту "Столешница 600*3050*26 альмандин": кто нам это поставил? +- `assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q05` | tags: meta_capability | question: что ты умеешь? +- `assistant_saved_session_20260417083044_gen-ag04170830-5f771d:q06` | tags: meta_memory | question: а ты помнишь, что мы по этой позиции уже выяснили? +- `assistant_saved_session_20260417085550_gen-ag04170855-d13dd3:q01` | tags: meta_smalltalk | question: привет, как дела? +- `assistant_saved_session_20260417085550_gen-ag04170855-d13dd3:q02` | tags: meta_scope | question: по какой компании мы сейчас работаем? +- `assistant_saved_session_20260417085550_gen-ag04170855-d13dd3:q03` | tags: none | question: что ты можешь по 1С? +- `assistant_saved_session_20260417085550_gen-ag04170855-d13dd3:q04` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `assistant_saved_session_20260417085550_gen-ag04170855-d13dd3:q05` | tags: meta_historical_capability, inventory_root | question: а исторические остатки тоже можешь? +- `assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q01` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q02` | tags: selected_object | question: По выбранному объекту "Столешница 600*3050*26 альмандин": кто нам это поставил? +- `assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q03` | tags: selected_object | question: По выбранному объекту "Столешница 600*3050*26 альмандин": покажи документы по этой позиции +- `assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q04` | tags: inventory_root | question: покажи еще раз остатки на эту же дату +- `assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q05` | tags: meta_scope | question: по какой компании мы сейчас работаем? +- `assistant_saved_session_20260417091127_gen-ag04170911-ff51e1:q06` | tags: meta_historical_capability, inventory_root | question: а исторические остатки тоже можешь? +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q01` | tags: meta_smalltalk | question: привет, как дела? +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q02` | tags: meta_scope | question: по какой компании мы сейчас работаем? +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q03` | tags: counterparty_documents | question: покажи все документы по чепурнову +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q04` | tags: counterparty_shipment_fallback | question: что нам отгружал чепурнов, какой товар или услугу? +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q05` | tags: inventory_root | question: какие остатки на складе на март 2021 +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q06` | tags: selected_object | question: По выбранному объекту "Столешница 600*3050*26 альмандин": кто нам это поставил? +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q07` | tags: meta_capability | question: что ты умеешь? +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q08` | tags: selected_object | question: По выбранному объекту "Столешница 600*3050*26 альмандин": покажи документы по этой позиции +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q09` | tags: meta_memory | question: а ты помнишь, что мы по этой позиции уже выяснили? +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q10` | tags: inventory_root | question: покажи еще раз остатки на эту же дату +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q11` | tags: settlements_receivables | question: кто нам должен на март 2020 +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q12` | tags: inventory_root | question: остатки по складу на эту же дату +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q13` | tags: meta_historical_capability, inventory_root | question: а исторические остатки тоже можешь? +- `assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5:q14` | tags: none | question: хвосты покажи по счету 60 на август 2022 diff --git a/llm_normalizer/backend/dist/services/assistantLivingModePolicy.js b/llm_normalizer/backend/dist/services/assistantLivingModePolicy.js index 4cdb1fe..9424c2f 100644 --- a/llm_normalizer/backend/dist/services/assistantLivingModePolicy.js +++ b/llm_normalizer/backend/dist/services/assistantLivingModePolicy.js @@ -107,9 +107,14 @@ function createAssistantLivingModePolicy(deps) { } const hasMemoryCue = samples.some((sample) => /(?:помни(?:шь|те|м)?|remember|recall)/iu.test(sample)); const hasDiscussionCue = samples.some((sample) => /(?:обсуждал[аи]?|говорил[аи]?|смотрел[аи]?|разбирал[аи]?|спрашивал[аи]?)/iu.test(sample)); - if (!hasMemoryCue || !hasDiscussionCue) { + const hasExplicitRecapPrompt = samples.some((sample) => /(?:что\s+мы\s+.*(?:обсуждали|выяснили)|что\s+уже\s+выяснили|напомни\s+что\s+мы|what\s+we\s+already\s+(?:discussed|figured\s+out))/iu.test(sample)); + if (!hasMemoryCue || !(hasDiscussionCue || hasExplicitRecapPrompt)) { return false; } + if (hasExplicitRecapPrompt) { + return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) || + shouldHandleAsAssistantCapabilityMetaQuery(sample)); + } return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) || shouldHandleAsAssistantCapabilityMetaQuery(sample) || hasDataRetrievalRequestSignal(sample) || diff --git a/llm_normalizer/backend/dist/services/assistantMemoryRecapPolicy.js b/llm_normalizer/backend/dist/services/assistantMemoryRecapPolicy.js index b455969..107f618 100644 --- a/llm_normalizer/backend/dist/services/assistantMemoryRecapPolicy.js +++ b/llm_normalizer/backend/dist/services/assistantMemoryRecapPolicy.js @@ -27,6 +27,9 @@ function collectMessageSamples(input) { function hasSignalAcrossSamples(samples, detector) { return samples.some((sample) => detector(sample)); } +function hasExplicitRecapPromptSignal(samples) { + return samples.some((sample) => /(?:что\s+мы\s+.*(?:обсуждали|выяснили)|что\s+уже\s+выяснили|что\s+уже\s+поняли|напомни\s+что\s+мы)/iu.test(sample)); +} function findLastGroundedInventoryAddressDebug(items) { if (!Array.isArray(items)) { return null; @@ -182,6 +185,7 @@ function createAssistantMemoryRecapPolicy(deps) { const samples = collectMessageSamples(input); const historicalCapabilitySignal = hasSignalAcrossSamples(samples, deps.hasHistoricalCapabilityFollowupSignal); const memoryRecapSignal = hasSignalAcrossSamples(samples, deps.hasConversationMemoryRecallFollowupSignal); + const explicitRecapPromptSignal = hasExplicitRecapPromptSignal(samples); return { contextualHistoricalCapabilityFollowupDetected: Boolean(input.capabilityMetaQuery && !input.dataScopeMetaQuery && @@ -190,10 +194,9 @@ function createAssistantMemoryRecapPolicy(deps) { deps.isGroundedInventoryContextDebug(input.lastGroundedAddressDebug)), contextualMemoryRecapFollowupDetected: Boolean(!input.dataScopeMetaQuery && !input.capabilityMetaQuery && - !input.dataRetrievalSignal && - !input.strongDataSignal && !input.aggregateBusinessAnalyticsSignal && memoryRecapSignal && + (explicitRecapPromptSignal || (!input.dataRetrievalSignal && !input.strongDataSignal)) && input.hasPriorAddressDebug) }; } diff --git a/llm_normalizer/backend/dist/services/assistantRoutePolicy.js b/llm_normalizer/backend/dist/services/assistantRoutePolicy.js index a29ea12..1b464c1 100644 --- a/llm_normalizer/backend/dist/services/assistantRoutePolicy.js +++ b/llm_normalizer/backend/dist/services/assistantRoutePolicy.js @@ -304,36 +304,36 @@ function createAssistantRoutePolicy(deps) { } }; } - if (nonDomainQueryIndexed) { - if (contextualMemoryRecapFollowupDetected) { - return { - runAddressLane: false, - toolGateDecision: "skip_address_lane", - toolGateReason: "memory_recap_followup_detected", - livingMode: "chat", - livingReason: "memory_recap_followup_detected", - orchestrationContract: { - schema_version: "assistant_orchestration_contract_v1", - hard_meta_mode: "non_domain", - provider_execution: providerExecution, - address_mode: resolvedModeDetection.mode, - address_mode_confidence: resolvedModeDetection.confidence, - address_intent: resolvedIntentResolution.intent, - address_intent_confidence: resolvedIntentResolution.confidence, - strong_data_signal_detected: strongDataSignal, - data_retrieval_signal_detected: dataRetrievalSignal, - followup_context_detected: Boolean(followupContext || lastGroundedAddressDebug), - unsupported_address_intent_fallback_to_deep: false, - final_decision: { - run_address_lane: false, - tool_gate_decision: "skip_address_lane", - tool_gate_reason: "memory_recap_followup_detected", - living_mode: "chat", - living_reason: "memory_recap_followup_detected" - } + if (contextualMemoryRecapFollowupDetected) { + return { + runAddressLane: false, + toolGateDecision: "skip_address_lane", + toolGateReason: "memory_recap_followup_detected", + livingMode: "chat", + livingReason: "memory_recap_followup_detected", + orchestrationContract: { + schema_version: "assistant_orchestration_contract_v1", + hard_meta_mode: nonDomainQueryIndexed ? "non_domain" : null, + provider_execution: providerExecution, + address_mode: resolvedModeDetection.mode, + address_mode_confidence: resolvedModeDetection.confidence, + address_intent: resolvedIntentResolution.intent, + address_intent_confidence: resolvedIntentResolution.confidence, + strong_data_signal_detected: strongDataSignal, + data_retrieval_signal_detected: dataRetrievalSignal, + followup_context_detected: Boolean(followupContext || lastGroundedAddressDebug || lastAddressAssistantDebug), + unsupported_address_intent_fallback_to_deep: false, + final_decision: { + run_address_lane: false, + tool_gate_decision: "skip_address_lane", + tool_gate_reason: "memory_recap_followup_detected", + living_mode: "chat", + living_reason: "memory_recap_followup_detected" } - }; - } + } + }; + } + if (nonDomainQueryIndexed) { return { runAddressLane: false, toolGateDecision: "skip_address_lane", diff --git a/llm_normalizer/backend/src/services/assistantLivingModePolicy.ts b/llm_normalizer/backend/src/services/assistantLivingModePolicy.ts index 173a89e..d005d87 100644 --- a/llm_normalizer/backend/src/services/assistantLivingModePolicy.ts +++ b/llm_normalizer/backend/src/services/assistantLivingModePolicy.ts @@ -171,9 +171,14 @@ export function createAssistantLivingModePolicy(deps: AssistantLivingModePolicyD } const hasMemoryCue = samples.some((sample) => /(?:помни(?:шь|те|м)?|remember|recall)/iu.test(sample)); const hasDiscussionCue = samples.some((sample) => /(?:обсуждал[аи]?|говорил[аи]?|смотрел[аи]?|разбирал[аи]?|спрашивал[аи]?)/iu.test(sample)); - if (!hasMemoryCue || !hasDiscussionCue) { + const hasExplicitRecapPrompt = samples.some((sample) => /(?:что\s+мы\s+.*(?:обсуждали|выяснили)|что\s+уже\s+выяснили|напомни\s+что\s+мы|what\s+we\s+already\s+(?:discussed|figured\s+out))/iu.test(sample)); + if (!hasMemoryCue || !(hasDiscussionCue || hasExplicitRecapPrompt)) { return false; } + if (hasExplicitRecapPrompt) { + return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) || + shouldHandleAsAssistantCapabilityMetaQuery(sample)); + } return !samples.some((sample) => hasAssistantDataScopeMetaQuestionSignal(sample) || shouldHandleAsAssistantCapabilityMetaQuery(sample) || hasDataRetrievalRequestSignal(sample) || diff --git a/llm_normalizer/backend/src/services/assistantMemoryRecapPolicy.ts b/llm_normalizer/backend/src/services/assistantMemoryRecapPolicy.ts index eee78b1..a40b652 100644 --- a/llm_normalizer/backend/src/services/assistantMemoryRecapPolicy.ts +++ b/llm_normalizer/backend/src/services/assistantMemoryRecapPolicy.ts @@ -69,6 +69,14 @@ function hasSignalAcrossSamples( return samples.some((sample) => detector(sample)); } +function hasExplicitRecapPromptSignal(samples: string[]): boolean { + return samples.some((sample) => + /(?:что\s+мы\s+.*(?:обсуждали|выяснили)|что\s+уже\s+выяснили|что\s+уже\s+поняли|напомни\s+что\s+мы)/iu.test( + sample + ) + ); +} + function findLastGroundedInventoryAddressDebug(items: unknown[]): Record | null { if (!Array.isArray(items)) { return null; @@ -269,6 +277,7 @@ export function createAssistantMemoryRecapPolicy( samples, deps.hasConversationMemoryRecallFollowupSignal ); + const explicitRecapPromptSignal = hasExplicitRecapPromptSignal(samples); return { contextualHistoricalCapabilityFollowupDetected: Boolean( input.capabilityMetaQuery && @@ -280,10 +289,9 @@ export function createAssistantMemoryRecapPolicy( contextualMemoryRecapFollowupDetected: Boolean( !input.dataScopeMetaQuery && !input.capabilityMetaQuery && - !input.dataRetrievalSignal && - !input.strongDataSignal && !input.aggregateBusinessAnalyticsSignal && memoryRecapSignal && + (explicitRecapPromptSignal || (!input.dataRetrievalSignal && !input.strongDataSignal)) && input.hasPriorAddressDebug ) }; diff --git a/llm_normalizer/backend/src/services/assistantRoutePolicy.ts b/llm_normalizer/backend/src/services/assistantRoutePolicy.ts index fc7b53f..0708ce2 100644 --- a/llm_normalizer/backend/src/services/assistantRoutePolicy.ts +++ b/llm_normalizer/backend/src/services/assistantRoutePolicy.ts @@ -338,36 +338,36 @@ export function createAssistantRoutePolicy(deps) { } }; } - if (nonDomainQueryIndexed) { - if (contextualMemoryRecapFollowupDetected) { - return { - runAddressLane: false, - toolGateDecision: "skip_address_lane", - toolGateReason: "memory_recap_followup_detected", - livingMode: "chat", - livingReason: "memory_recap_followup_detected", - orchestrationContract: { - schema_version: "assistant_orchestration_contract_v1", - hard_meta_mode: "non_domain", - provider_execution: providerExecution, - address_mode: resolvedModeDetection.mode, - address_mode_confidence: resolvedModeDetection.confidence, - address_intent: resolvedIntentResolution.intent, - address_intent_confidence: resolvedIntentResolution.confidence, - strong_data_signal_detected: strongDataSignal, - data_retrieval_signal_detected: dataRetrievalSignal, - followup_context_detected: Boolean(followupContext || lastGroundedAddressDebug), - unsupported_address_intent_fallback_to_deep: false, - final_decision: { - run_address_lane: false, - tool_gate_decision: "skip_address_lane", - tool_gate_reason: "memory_recap_followup_detected", - living_mode: "chat", - living_reason: "memory_recap_followup_detected" - } + if (contextualMemoryRecapFollowupDetected) { + return { + runAddressLane: false, + toolGateDecision: "skip_address_lane", + toolGateReason: "memory_recap_followup_detected", + livingMode: "chat", + livingReason: "memory_recap_followup_detected", + orchestrationContract: { + schema_version: "assistant_orchestration_contract_v1", + hard_meta_mode: nonDomainQueryIndexed ? "non_domain" : null, + provider_execution: providerExecution, + address_mode: resolvedModeDetection.mode, + address_mode_confidence: resolvedModeDetection.confidence, + address_intent: resolvedIntentResolution.intent, + address_intent_confidence: resolvedIntentResolution.confidence, + strong_data_signal_detected: strongDataSignal, + data_retrieval_signal_detected: dataRetrievalSignal, + followup_context_detected: Boolean(followupContext || lastGroundedAddressDebug || lastAddressAssistantDebug), + unsupported_address_intent_fallback_to_deep: false, + final_decision: { + run_address_lane: false, + tool_gate_decision: "skip_address_lane", + tool_gate_reason: "memory_recap_followup_detected", + living_mode: "chat", + living_reason: "memory_recap_followup_detected" } - }; - } + } + }; + } + if (nonDomainQueryIndexed) { return { runAddressLane: false, toolGateDecision: "skip_address_lane", diff --git a/llm_normalizer/backend/tests/assistantLivingModePolicy.test.ts b/llm_normalizer/backend/tests/assistantLivingModePolicy.test.ts index 155099b..00d4466 100644 --- a/llm_normalizer/backend/tests/assistantLivingModePolicy.test.ts +++ b/llm_normalizer/backend/tests/assistantLivingModePolicy.test.ts @@ -34,6 +34,14 @@ function buildPolicy() { } describe("assistantLivingModePolicy", () => { + it("detects explicit recap wording as memory signal even when selected-object words are present", () => { + const policy = buildPolicy(); + + expect( + policy.hasConversationMemoryRecallFollowupSignal("а ты помнишь, что мы по этой позиции уже выяснили?") + ).toBe(true); + }); + it("routes casual small-talk to chat mode", () => { const policy = buildPolicy(); diff --git a/llm_normalizer/backend/tests/assistantMemoryRecapPolicy.test.ts b/llm_normalizer/backend/tests/assistantMemoryRecapPolicy.test.ts index a25b9eb..d12ced6 100644 --- a/llm_normalizer/backend/tests/assistantMemoryRecapPolicy.test.ts +++ b/llm_normalizer/backend/tests/assistantMemoryRecapPolicy.test.ts @@ -55,6 +55,25 @@ describe("assistantMemoryRecapPolicy", () => { expect(signals.contextualMemoryRecapFollowupDetected).toBe(true); }); + it("treats explicit recap wording over selected-object phrasing as memory follow-up even when data cues are present", () => { + const signals = policy.resolveRouteMemorySignals({ + rawUserMessage: "а ты помнишь, что мы по этой позиции уже выяснили?", + repairedRawUserMessage: "", + effectiveAddressUserMessage: "", + repairedEffectiveAddressUserMessage: "", + dataScopeMetaQuery: false, + capabilityMetaQuery: false, + dataRetrievalSignal: true, + strongDataSignal: true, + aggregateBusinessAnalyticsSignal: false, + lastGroundedAddressDebug: null, + hasPriorAddressDebug: true + }); + + expect(signals.contextualHistoricalCapabilityFollowupDetected).toBe(false); + expect(signals.contextualMemoryRecapFollowupDetected).toBe(true); + }); + it("builds deterministic recap from prior selected object context", () => { const context = resolveAssistantLivingChatMemoryContext({ modeDecisionReason: "memory_recap_followup_detected", diff --git a/llm_normalizer/backend/tests/assistantRoutePolicy.test.ts b/llm_normalizer/backend/tests/assistantRoutePolicy.test.ts index b5a4298..9265d70 100644 --- a/llm_normalizer/backend/tests/assistantRoutePolicy.test.ts +++ b/llm_normalizer/backend/tests/assistantRoutePolicy.test.ts @@ -187,6 +187,43 @@ describe("assistantRoutePolicy", () => { expect(decision.livingReason).toBe("memory_recap_followup_detected"); }); + it("routes explicit recap wording with selected-object phrasing to chat even when address-like cues exist", () => { + const policy = buildPolicy({ + hasStrongDataIntentSignal: () => true, + hasDataRetrievalRequestSignal: () => true, + resolveRouteMemorySignals: () => ({ + contextualHistoricalCapabilityFollowupDetected: false, + contextualMemoryRecapFollowupDetected: true + }), + findLastGroundedAddressAnswerDebug: () => ({ + execution_lane: "address_query", + detected_intent: "inventory_purchase_provenance_for_item" + }) + }); + + const decision = policy.resolveAssistantOrchestrationDecision({ + rawUserMessage: "а ты помнишь, что мы по этой позиции уже выяснили?", + effectiveAddressUserMessage: "а ты помнишь, что мы по этой позиции уже выяснили?", + followupContext: null, + llmPreDecomposeMeta: { + applied: false, + reason: "normalized_fragment_rejected_semantic_guard", + predecomposeContract: { + mode: "unsupported", + mode_confidence: "low", + intent: "unknown", + intent_confidence: "low" + } + }, + useMock: false + }); + + expect(decision.runAddressLane).toBe(false); + expect(decision.toolGateReason).toBe("memory_recap_followup_detected"); + expect(decision.livingMode).toBe("chat"); + expect(decision.livingReason).toBe("memory_recap_followup_detected"); + }); + it("does not force unsupported-intent fallback when predecompose runtime is unavailable", () => { const policy = buildPolicy({ hasStrongDataIntentSignal: () => true, diff --git a/llm_normalizer/data/autorun_generators/history.json b/llm_normalizer/data/autorun_generators/history.json index b19ab8a..bc81e4b 100644 --- a/llm_normalizer/data/autorun_generators/history.json +++ b/llm_normalizer/data/autorun_generators/history.json @@ -1,4 +1,88 @@ [ + { + "generation_id": "gen-ag04170941-87680e", + "created_at": "2026-04-17T09:41:32+00:00", + "mode": "saved_user_sessions", + "title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "count": 14, + "domain": "address_phase7_meta_domain_mix", + "questions": [ + "привет, как дела?", + "по какой компании мы сейчас работаем?", + "покажи все документы по чепурнову", + "что нам отгружал чепурнов, какой товар или услугу?", + "какие остатки на складе на март 2021", + "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "что ты умеешь?", + "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "а ты помнишь, что мы по этой позиции уже выяснили?", + "покажи еще раз остатки на эту же дату", + "кто нам должен на март 2020", + "остатки по складу на эту же дату", + "а исторические остатки тоже можешь?", + "хвосты покажи по счету 60 на август 2022" + ], + "generated_by": "codex_agent", + "saved_case_set_file": "assistant_autogen_saved_user_sessions_20260417094132_gen-ag04170941-87680e.json", + "context": { + "llm_provider": null, + "model": null, + "assistant_prompt_version": null, + "decomposition_prompt_version": null, + "prompt_fingerprint": null, + "autogen_personality_id": null, + "autogen_personality_prompt": null, + "source_session_id": null, + "saved_session_file": "assistant_saved_session_20260417094132_gen-ag04170941-87680e.json", + "saved_case_set_kind": "agent_semantic_scenario", + "agent_run": true, + "agent_focus": "mixed documents meta and cross-domain replay for turnaround 11", + "architecture_phase": "turnaround_11_phase7", + "source_spec_file": "X:\\1C\\NDC_1C\\docs\\orchestration\\address_truth_harness_phase7_meta_domain_mix.json" + } + }, + { + "generation_id": "gen-ag04170931-6bb7e5", + "created_at": "2026-04-17T09:31:44+00:00", + "mode": "saved_user_sessions", + "title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "count": 14, + "domain": "address_phase7_meta_domain_mix", + "questions": [ + "привет, как дела?", + "по какой компании мы сейчас работаем?", + "покажи все документы по чепурнову", + "что нам отгружал чепурнов, какой товар или услугу?", + "какие остатки на складе на март 2021", + "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "что ты умеешь?", + "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "а ты помнишь, что мы по этой позиции уже выяснили?", + "покажи еще раз остатки на эту же дату", + "кто нам должен на март 2020", + "остатки по складу на эту же дату", + "а исторические остатки тоже можешь?", + "хвосты покажи по счету 60 на август 2022" + ], + "generated_by": "codex_agent", + "saved_case_set_file": "assistant_autogen_saved_user_sessions_20260417093144_gen-ag04170931-6bb7e5.json", + "context": { + "llm_provider": null, + "model": null, + "assistant_prompt_version": null, + "decomposition_prompt_version": null, + "prompt_fingerprint": null, + "autogen_personality_id": null, + "autogen_personality_prompt": null, + "source_session_id": null, + "saved_session_file": "assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json", + "saved_case_set_kind": "agent_semantic_scenario", + "agent_run": true, + "agent_focus": "mixed documents meta and cross-domain replay for turnaround 11", + "architecture_phase": "turnaround_11_phase7", + "source_spec_file": "X:\\1C\\NDC_1C\\docs\\orchestration\\address_truth_harness_phase7_meta_domain_mix.json" + } + }, { "generation_id": "gen-ag04170911-ff51e1", "created_at": "2026-04-17T09:11:27+00:00", diff --git a/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json b/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json new file mode 100644 index 0000000..0c71868 --- /dev/null +++ b/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417093144_gen-ag04170931-6bb7e5.json @@ -0,0 +1,173 @@ +{ + "saved_at": "2026-04-17T09:31:44+00:00", + "generation_id": "gen-ag04170931-6bb7e5", + "mode": "saved_user_sessions", + "title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "agent_run": true, + "questions": [ + "привет, как дела?", + "по какой компании мы сейчас работаем?", + "покажи все документы по чепурнову", + "что нам отгружал чепурнов, какой товар или услугу?", + "какие остатки на складе на март 2021", + "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "что ты умеешь?", + "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "а ты помнишь, что мы по этой позиции уже выяснили?", + "покажи еще раз остатки на эту же дату", + "кто нам должен на март 2020", + "остатки по складу на эту же дату", + "а исторические остатки тоже можешь?", + "хвосты покажи по счету 60 на август 2022" + ], + "metadata": { + "assistant_prompt_version": null, + "decomposition_prompt_version": null, + "prompt_fingerprint": null, + "agent_focus": "mixed documents meta and cross-domain replay for turnaround 11", + "architecture_phase": "turnaround_11_phase7", + "source_spec_file": "X:\\1C\\NDC_1C\\docs\\orchestration\\address_truth_harness_phase7_meta_domain_mix.json" + }, + "source_session_id": null, + "session": { + "session_id": null, + "mode": "agent_semantic_run", + "items": [ + { + "message_id": "agent-user-001", + "role": "user", + "text": "привет, как дела?", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-002", + "role": "user", + "text": "по какой компании мы сейчас работаем?", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-003", + "role": "user", + "text": "покажи все документы по чепурнову", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-004", + "role": "user", + "text": "что нам отгружал чепурнов, какой товар или услугу?", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-005", + "role": "user", + "text": "какие остатки на складе на март 2021", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-006", + "role": "user", + "text": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-007", + "role": "user", + "text": "что ты умеешь?", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-008", + "role": "user", + "text": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-009", + "role": "user", + "text": "а ты помнишь, что мы по этой позиции уже выяснили?", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-010", + "role": "user", + "text": "покажи еще раз остатки на эту же дату", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-011", + "role": "user", + "text": "кто нам должен на март 2020", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-012", + "role": "user", + "text": "остатки по складу на эту же дату", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-013", + "role": "user", + "text": "а исторические остатки тоже можешь?", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-014", + "role": "user", + "text": "хвосты покажи по счету 60 на август 2022", + "created_at": "2026-04-17T09:31:44+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + } + ], + "agent_run": true, + "metadata": { + "assistant_prompt_version": null, + "decomposition_prompt_version": null, + "prompt_fingerprint": null, + "agent_focus": "mixed documents meta and cross-domain replay for turnaround 11", + "architecture_phase": "turnaround_11_phase7", + "source_spec_file": "X:\\1C\\NDC_1C\\docs\\orchestration\\address_truth_harness_phase7_meta_domain_mix.json" + } + } +} diff --git a/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417094132_gen-ag04170941-87680e.json b/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417094132_gen-ag04170941-87680e.json new file mode 100644 index 0000000..a69bca0 --- /dev/null +++ b/llm_normalizer/data/autorun_generators/saved_sessions/assistant_saved_session_20260417094132_gen-ag04170941-87680e.json @@ -0,0 +1,173 @@ +{ + "saved_at": "2026-04-17T09:41:32+00:00", + "generation_id": "gen-ag04170941-87680e", + "mode": "saved_user_sessions", + "title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "agent_run": true, + "questions": [ + "привет, как дела?", + "по какой компании мы сейчас работаем?", + "покажи все документы по чепурнову", + "что нам отгружал чепурнов, какой товар или услугу?", + "какие остатки на складе на март 2021", + "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "что ты умеешь?", + "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "а ты помнишь, что мы по этой позиции уже выяснили?", + "покажи еще раз остатки на эту же дату", + "кто нам должен на март 2020", + "остатки по складу на эту же дату", + "а исторические остатки тоже можешь?", + "хвосты покажи по счету 60 на август 2022" + ], + "metadata": { + "assistant_prompt_version": null, + "decomposition_prompt_version": null, + "prompt_fingerprint": null, + "agent_focus": "mixed documents meta and cross-domain replay for turnaround 11", + "architecture_phase": "turnaround_11_phase7", + "source_spec_file": "X:\\1C\\NDC_1C\\docs\\orchestration\\address_truth_harness_phase7_meta_domain_mix.json" + }, + "source_session_id": null, + "session": { + "session_id": null, + "mode": "agent_semantic_run", + "items": [ + { + "message_id": "agent-user-001", + "role": "user", + "text": "привет, как дела?", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-002", + "role": "user", + "text": "по какой компании мы сейчас работаем?", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-003", + "role": "user", + "text": "покажи все документы по чепурнову", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-004", + "role": "user", + "text": "что нам отгружал чепурнов, какой товар или услугу?", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-005", + "role": "user", + "text": "какие остатки на складе на март 2021", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-006", + "role": "user", + "text": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-007", + "role": "user", + "text": "что ты умеешь?", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-008", + "role": "user", + "text": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-009", + "role": "user", + "text": "а ты помнишь, что мы по этой позиции уже выяснили?", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-010", + "role": "user", + "text": "покажи еще раз остатки на эту же дату", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-011", + "role": "user", + "text": "кто нам должен на март 2020", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-012", + "role": "user", + "text": "остатки по складу на эту же дату", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-013", + "role": "user", + "text": "а исторические остатки тоже можешь?", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + }, + { + "message_id": "agent-user-014", + "role": "user", + "text": "хвосты покажи по счету 60 на август 2022", + "created_at": "2026-04-17T09:41:32+00:00", + "reply_type": null, + "trace_id": null, + "debug": null + } + ], + "agent_run": true, + "metadata": { + "assistant_prompt_version": null, + "decomposition_prompt_version": null, + "prompt_fingerprint": null, + "agent_focus": "mixed documents meta and cross-domain replay for turnaround 11", + "architecture_phase": "turnaround_11_phase7", + "source_spec_file": "X:\\1C\\NDC_1C\\docs\\orchestration\\address_truth_harness_phase7_meta_domain_mix.json" + } + } +} diff --git a/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260417093144_gen-ag04170931-6bb7e5.json b/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260417093144_gen-ag04170931-6bb7e5.json new file mode 100644 index 0000000..067174d --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260417093144_gen-ag04170931-6bb7e5.json @@ -0,0 +1,67 @@ +{ + "suite_id": "assistant_saved_session_gen-ag04170931-6bb7e5", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_suite_v0_1", + "generated_at": "2026-04-17T09:31:44+00:00", + "generation_id": "gen-ag04170931-6bb7e5", + "mode": "saved_user_sessions", + "title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "domain": "address_phase7_meta_domain_mix", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "agent_saved_user_sessions", + "title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "привет, как дела?" + }, + { + "user_message": "по какой компании мы сейчас работаем?" + }, + { + "user_message": "покажи все документы по чепурнову" + }, + { + "user_message": "что нам отгружал чепурнов, какой товар или услугу?" + }, + { + "user_message": "какие остатки на складе на март 2021" + }, + { + "user_message": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?" + }, + { + "user_message": "что ты умеешь?" + }, + { + "user_message": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции" + }, + { + "user_message": "а ты помнишь, что мы по этой позиции уже выяснили?" + }, + { + "user_message": "покажи еще раз остатки на эту же дату" + }, + { + "user_message": "кто нам должен на март 2020" + }, + { + "user_message": "остатки по складу на эту же дату" + }, + { + "user_message": "а исторические остатки тоже можешь?" + }, + { + "user_message": "хвосты покажи по счету 60 на август 2022" + } + ] + } + ] +} diff --git a/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260417094132_gen-ag04170941-87680e.json b/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260417094132_gen-ag04170941-87680e.json new file mode 100644 index 0000000..3074686 --- /dev/null +++ b/llm_normalizer/data/eval_cases/assistant_autogen_saved_user_sessions_20260417094132_gen-ag04170941-87680e.json @@ -0,0 +1,67 @@ +{ + "suite_id": "assistant_saved_session_gen-ag04170941-87680e", + "suite_version": "0.1.0", + "schema_version": "assistant_saved_session_suite_v0_1", + "generated_at": "2026-04-17T09:41:32+00:00", + "generation_id": "gen-ag04170941-87680e", + "mode": "saved_user_sessions", + "title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "domain": "address_phase7_meta_domain_mix", + "scenario_count": 1, + "case_ids": [ + "SAVED-001" + ], + "cases": [ + { + "case_id": "SAVED-001", + "scenario_tag": "agent_saved_user_sessions", + "title": "AGENT | Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "question_type": "followup", + "broadness_level": "medium", + "turns": [ + { + "user_message": "привет, как дела?" + }, + { + "user_message": "по какой компании мы сейчас работаем?" + }, + { + "user_message": "покажи все документы по чепурнову" + }, + { + "user_message": "что нам отгружал чепурнов, какой товар или услугу?" + }, + { + "user_message": "какие остатки на складе на март 2021" + }, + { + "user_message": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": кто нам это поставил?" + }, + { + "user_message": "что ты умеешь?" + }, + { + "user_message": "По выбранному объекту \"Столешница 600*3050*26 альмандин\": покажи документы по этой позиции" + }, + { + "user_message": "а ты помнишь, что мы по этой позиции уже выяснили?" + }, + { + "user_message": "покажи еще раз остатки на эту же дату" + }, + { + "user_message": "кто нам должен на март 2020" + }, + { + "user_message": "остатки по складу на эту же дату" + }, + { + "user_message": "а исторические остатки тоже можешь?" + }, + { + "user_message": "хвосты покажи по счету 60 на август 2022" + } + ] + } + ] +} diff --git a/scripts/agent_semantic_pack_builder.py b/scripts/agent_semantic_pack_builder.py new file mode 100644 index 0000000..7348d52 --- /dev/null +++ b/scripts/agent_semantic_pack_builder.py @@ -0,0 +1,505 @@ +from __future__ import annotations + +import argparse +import json +from collections import Counter +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + + +REPO_ROOT = Path(__file__).resolve().parent.parent +ORCHESTRATION_DIR = REPO_ROOT / "docs" / "orchestration" +SAVED_SESSIONS_DIR = REPO_ROOT / "llm_normalizer" / "data" / "autorun_generators" / "saved_sessions" +TRUTH_HARNESS_GLOB = "address_truth_harness*.json" +CATALOG_SCHEMA_VERSION = "agent_semantic_source_catalog_v1" + +INVENTORY_KEYWORDS = ("остатк", "склад", "41 счет") +META_SCOPE_KEYWORDS = ("по какой компании", "по какой организации", "по общей базе", "по какой базе") +META_CAPABILITY_KEYWORDS = ("что ты умеешь", "что можешь", "умеешь") +META_MEMORY_KEYWORDS = ("ты помнишь", "что мы уже выяснили", "по этой позиции уже") +META_HISTORICAL_KEYWORDS = ("историческ",) +SMALLTALK_KEYWORDS = ("привет", "как дела", "йо", "че как", "приветик") +COUNTERPARTY_DOCS_KEYWORDS = ("покажи все документы", "покажи все доки") +COUNTERPARTY_SHIPMENT_KEYWORDS = ("что нам отгружал", "какой товар или услугу") +ACCOUNT_60_KEYWORDS = ("хвосты по счету 60",) +RECEIVABLES_KEYWORDS = ("кто нам должен",) +VAT_KEYWORDS = ("ндс",) + +RECIPE_LIBRARY: dict[str, dict[str, Any]] = { + "turnaround_11_phase7_meta_domain_mix": { + "scenario_id": "address_truth_harness_phase7_meta_domain_mix", + "domain": "address_phase7_meta_domain_mix", + "title": "Phase 7 mixed replay for documents, selected-object continuity, meta context, and cross-domain pivots", + "description": ( + "Mixed AGENT replay for turnaround 11. The pack interleaves counterparty documents, " + "inventory root and selected-object continuity, meta-space interruptions, memory recap, " + "receivables to inventory same-date pivot, and an account 60 tail check." + ), + "bindings": {}, + "step_plan": [ + { + "slot_id": "slot_01_smalltalk", + "criticality": "info", + "preferred_candidate_ids": [ + "address_truth_harness_phase6_provider_axis_mix:step_01_smalltalk", + "address_truth_harness_test2:step_01_chat_opening", + ], + "required_tags": ["meta_smalltalk"], + }, + { + "slot_id": "slot_03_counterparty_documents", + "criticality": "critical", + "preferred_candidate_ids": [ + "address_truth_harness_phase4_coverage_evidence_mix:step_01_counterparty_documents", + "address_truth_harness_targeted_counterparty_tails:step_01_documents_by_counterparty", + ], + "required_tags": ["counterparty_documents"], + }, + { + "slot_id": "slot_04_counterparty_shipment_fallback", + "criticality": "critical", + "preferred_candidate_ids": [ + "address_truth_harness_phase4_coverage_evidence_mix:step_02_counterparty_shipments_or_fallback", + "address_truth_harness_targeted_counterparty_tails:step_02_counterparty_item_flow", + ], + "required_tags": ["counterparty_shipment_fallback"], + }, + { + "slot_id": "slot_05_inventory_root", + "criticality": "critical", + "preferred_candidate_ids": [ + "address_truth_harness_phase7_acceptance_gate_mix:step_01_inventory_march_2021", + "address_truth_harness_phase5_meta_memory_mix:step_01_inventory_root_march_2021", + ], + "required_tags": ["inventory_root"], + }, + { + "slot_id": "slot_06_selected_object_supplier", + "criticality": "critical", + "preferred_candidate_ids": [ + "address_truth_harness_phase7_acceptance_gate_mix:step_02_selected_item_supplier", + "address_truth_harness_inventory_provenance_restore:step_02_selected_item_supplier", + ], + "required_tags": ["selected_object_supplier"], + }, + { + "slot_id": "slot_07_meta_capability", + "criticality": "warning", + "preferred_candidate_ids": [ + "address_truth_harness_phase5_meta_memory_mix:step_05_capability_meta_interrupt", + "address_truth_harness_phase6_provider_axis_mix:step_03_capability_meta", + ], + "required_tags": ["meta_capability"], + }, + { + "slot_id": "slot_08_selected_object_documents", + "criticality": "critical", + "preferred_candidate_ids": [ + "address_truth_harness_phase7_acceptance_gate_mix:step_03_selected_item_documents", + "address_truth_harness_inventory_provenance_restore:step_03_selected_item_documents", + ], + "required_tags": ["selected_object_documents"], + }, + { + "slot_id": "slot_09_meta_memory", + "criticality": "warning", + "preferred_candidate_ids": [ + "address_truth_harness_phase5_meta_memory_mix:step_06_memory_recap_after_interrupts", + ], + "required_tags": ["meta_memory"], + "override_fields": { + "required_answer_patterns_all": [ + "(?i)помню", + "(?i)столешница 600\\*3050\\*26 альмандин" + ] + }, + }, + { + "slot_id": "slot_10_same_date_restore", + "criticality": "critical", + "preferred_candidate_ids": [ + "address_truth_harness_phase7_acceptance_gate_mix:step_04_inventory_same_date_restore", + "address_truth_harness_phase4_coverage_evidence_mix:step_05_inventory_same_date_restore", + ], + "required_tags": ["same_date_restore"], + }, + { + "slot_id": "slot_11_receivables_root", + "criticality": "critical", + "preferred_candidate_ids": [ + "address_truth_harness_test2:step_02_receivables_march_2020", + ], + "required_tags": ["settlements_receivables"], + }, + { + "slot_id": "slot_12_same_date_pivot", + "criticality": "critical", + "preferred_candidate_ids": [ + "address_truth_harness_test2:step_03_inventory_same_date", + ], + "required_tags": ["same_date_pivot"], + }, + { + "slot_id": "slot_13_meta_historical", + "criticality": "warning", + "preferred_candidate_ids": [ + "address_truth_harness_phase7_acceptance_gate_mix:step_06_historical_capability_followup", + "address_truth_harness_phase5_meta_memory_mix:step_02_inventory_history_capability_followup", + ], + "required_tags": ["meta_historical_capability"], + }, + { + "slot_id": "slot_14_account_60", + "criticality": "critical", + "preferred_candidate_ids": [ + "address_truth_harness_targeted_counterparty_tails:step_04_open_items_account_60", + ], + "required_tags": ["settlements_account_60"], + }, + { + "slot_id": "slot_15_meta_scope", + "criticality": "warning", + "preferred_candidate_ids": [ + "address_truth_harness_phase6_provider_axis_mix:step_02_data_scope_meta", + "address_truth_harness_phase5_meta_memory_mix:step_03_data_scope_meta_interrupt", + ], + "required_tags": ["meta_scope"], + }, + ], + } +} + + +def read_json(path: Path) -> Any: + return json.loads(path.read_text(encoding="utf-8-sig")) + + +def write_json(path: Path, payload: Any) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8", newline="\n") + + +def write_text(path: Path, content: str) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content, encoding="utf-8", newline="\n") + + +def _now_iso() -> str: + return datetime.now(timezone.utc).replace(microsecond=0).isoformat() + + +def _normalize_tags(raw_tags: list[str]) -> list[str]: + ordered: list[str] = [] + seen: set[str] = set() + for raw_tag in raw_tags: + tag = str(raw_tag or "").strip().lower() + if not tag or tag in seen: + continue + seen.add(tag) + ordered.append(tag) + return ordered + + +def _contains_any(text: str, needles: tuple[str, ...]) -> bool: + normalized = text.casefold() + return any(needle.casefold() in normalized for needle in needles) + + +def _base_step_tags(question: str, step_id: str, title: str, expected_intents: list[str]) -> list[str]: + haystack = " | ".join([question, step_id, title, " ".join(expected_intents)]) + tags: list[str] = [] + if _contains_any(haystack, SMALLTALK_KEYWORDS): + tags.append("meta_smalltalk") + if _contains_any(haystack, META_SCOPE_KEYWORDS) or "data_scope" in step_id: + tags.append("meta_scope") + if _contains_any(haystack, META_CAPABILITY_KEYWORDS) or "capability_meta" in step_id: + tags.append("meta_capability") + if _contains_any(haystack, META_MEMORY_KEYWORDS) or "memory" in step_id: + tags.append("meta_memory") + if _contains_any(haystack, META_HISTORICAL_KEYWORDS) or "historical" in step_id: + tags.append("meta_historical_capability") + if _contains_any(haystack, COUNTERPARTY_DOCS_KEYWORDS) or "counterparty_documents" in step_id or "documents_by_counterparty" in step_id: + tags.append("counterparty_documents") + if _contains_any(haystack, COUNTERPARTY_SHIPMENT_KEYWORDS) or "counterparty_shipments" in step_id or "counterparty_item_flow" in step_id: + tags.append("counterparty_shipment_fallback") + if any(intent == "inventory_on_hand_as_of_date" for intent in expected_intents) or _contains_any(haystack, INVENTORY_KEYWORDS): + tags.append("inventory_root") + if "same_date_restore" in step_id or "same_date_restore" in title.casefold(): + tags.append("same_date_restore") + if "inventory_same_date" in step_id and "restore" not in step_id: + tags.append("same_date_pivot") + if any(intent == "receivables_confirmed_as_of_date" for intent in expected_intents) or _contains_any(haystack, RECEIVABLES_KEYWORDS): + tags.append("settlements_receivables") + if "open_items_account_60" in step_id or _contains_any(haystack, ACCOUNT_60_KEYWORDS): + tags.append("settlements_account_60") + if "vat" in step_id or _contains_any(haystack, VAT_KEYWORDS): + tags.append("vat") + if any(intent == "inventory_purchase_provenance_for_item" for intent in expected_intents): + tags.extend(["selected_object", "selected_object_supplier"]) + if any(intent == "inventory_purchase_documents_for_item" for intent in expected_intents): + tags.extend(["selected_object", "selected_object_documents"]) + if any(intent == "inventory_sale_trace_for_item" for intent in expected_intents): + tags.extend(["selected_object", "selected_object_sale"]) + if "selected_item" in step_id or "по выбранному объекту" in question.casefold(): + tags.append("selected_object") + return _normalize_tags(tags) + + +def classify_truth_harness_step(spec_path: Path, spec: dict[str, Any], step: dict[str, Any]) -> dict[str, Any]: + question = str(step.get("question") or "").strip() + step_id = str(step.get("step_id") or "").strip() + title = str(step.get("title") or step_id).strip() or step_id + expected_intents = [str(item).strip() for item in (step.get("expected_intents") or []) if str(item).strip()] + semantic_tags = _normalize_tags( + [*step.get("semantic_tags", []), *_base_step_tags(question, step_id, title, expected_intents)] + ) + return { + "entry_id": f"{spec_path.stem}:{step_id}", + "source_type": "truth_harness_step", + "source_file": str(spec_path.relative_to(REPO_ROOT)).replace("\\", "/"), + "source_title": spec.get("title"), + "scenario_id": spec.get("scenario_id"), + "domain": spec.get("domain"), + "reusable_in_agent_pack": True, + "step_id": step_id, + "title": title, + "question": question, + "criticality": str(step.get("criticality") or "critical"), + "expected_intents": expected_intents, + "semantic_tags": semantic_tags, + "step_payload": step, + } + + +def classify_saved_session_question(session_path: Path, session: dict[str, Any], question: str, index: int) -> dict[str, Any]: + tags = _base_step_tags( + question=question, + step_id=f"saved_session_q{index:02d}", + title=str(session.get("title") or ""), + expected_intents=[], + ) + return { + "entry_id": f"{session_path.stem}:q{index:02d}", + "source_type": "saved_session_question", + "source_file": str(session_path.relative_to(REPO_ROOT)).replace("\\", "/"), + "source_title": session.get("title"), + "scenario_id": session.get("generation_id"), + "domain": session.get("domain"), + "reusable_in_agent_pack": False, + "step_id": f"saved_session_q{index:02d}", + "title": f"Saved session question {index}", + "question": question, + "criticality": "info", + "expected_intents": [], + "semantic_tags": tags, + "session_mode": session.get("mode"), + "agent_run": bool(session.get("agent_run") or (session.get("context") or {}).get("agent_run")), + } + + +def build_source_catalog() -> dict[str, Any]: + truth_harness_entries: list[dict[str, Any]] = [] + saved_session_entries: list[dict[str, Any]] = [] + for spec_path in sorted(ORCHESTRATION_DIR.glob(TRUTH_HARNESS_GLOB)): + spec = read_json(spec_path) + for step in spec.get("steps") or []: + if isinstance(step, dict) and step.get("question"): + truth_harness_entries.append(classify_truth_harness_step(spec_path, spec, step)) + for session_path in sorted(SAVED_SESSIONS_DIR.glob("*.json")): + session = read_json(session_path) + for index, question in enumerate(session.get("questions") or [], start=1): + text = str(question or "").strip() + if text: + saved_session_entries.append(classify_saved_session_question(session_path, session, text, index)) + + tag_counter: Counter[str] = Counter() + reusable_tag_counter: Counter[str] = Counter() + for entry in [*truth_harness_entries, *saved_session_entries]: + for tag in entry.get("semantic_tags") or []: + tag_counter[tag] += 1 + if entry.get("reusable_in_agent_pack"): + reusable_tag_counter[tag] += 1 + + return { + "schema_version": CATALOG_SCHEMA_VERSION, + "generated_at": _now_iso(), + "summary": { + "truth_harness_steps_total": len(truth_harness_entries), + "saved_session_questions_total": len(saved_session_entries), + "reusable_truth_harness_tags": dict(sorted(reusable_tag_counter.items())), + "all_tags": dict(sorted(tag_counter.items())), + }, + "truth_harness_entries": truth_harness_entries, + "saved_session_entries": saved_session_entries, + } + + +def _catalog_markdown(catalog: dict[str, Any]) -> str: + summary = catalog.get("summary") if isinstance(catalog.get("summary"), dict) else {} + lines = [ + "# Agent semantic source catalog", + "", + f"- truth_harness_steps_total: `{summary.get('truth_harness_steps_total', 0)}`", + f"- saved_session_questions_total: `{summary.get('saved_session_questions_total', 0)}`", + "", + "## Reusable truth-harness tags", + ] + reusable_tags = summary.get("reusable_truth_harness_tags") or {} + for tag, count in reusable_tags.items(): + lines.append(f"- `{tag}`: `{count}`") + lines.extend(["", "## Reusable truth-harness steps"]) + for entry in catalog.get("truth_harness_entries") or []: + tags = ", ".join(entry.get("semantic_tags") or []) or "none" + lines.append( + f"- `{entry.get('entry_id')}` | tags: {tags} | question: {entry.get('question')}" + ) + lines.extend(["", "## Saved session questions"]) + for entry in catalog.get("saved_session_entries") or []: + tags = ", ".join(entry.get("semantic_tags") or []) or "none" + lines.append( + f"- `{entry.get('entry_id')}` | tags: {tags} | question: {entry.get('question')}" + ) + return "\n".join(lines).strip() + "\n" + + +def _find_catalog_entry(catalog: dict[str, Any], entry_id: str) -> dict[str, Any] | None: + for entry in catalog.get("truth_harness_entries") or []: + if entry.get("entry_id") == entry_id: + return entry + return None + + +def _entry_matches_tags(entry: dict[str, Any], required_tags: list[str]) -> bool: + entry_tags = set(entry.get("semantic_tags") or []) + return all(tag in entry_tags for tag in required_tags) + + +def _select_recipe_entry( + catalog: dict[str, Any], + slot: dict[str, Any], + used_entry_ids: set[str], +) -> dict[str, Any]: + preferred_ids = [str(item).strip() for item in (slot.get("preferred_candidate_ids") or []) if str(item).strip()] + required_tags = [str(item).strip().lower() for item in (slot.get("required_tags") or []) if str(item).strip()] + for entry_id in preferred_ids: + entry = _find_catalog_entry(catalog, entry_id) + if entry and entry.get("reusable_in_agent_pack") and entry_id not in used_entry_ids: + if not required_tags or _entry_matches_tags(entry, required_tags): + return entry + candidates = [ + entry + for entry in catalog.get("truth_harness_entries") or [] + if entry.get("reusable_in_agent_pack") + and entry.get("entry_id") not in used_entry_ids + and _entry_matches_tags(entry, required_tags) + ] + if not candidates: + raise RuntimeError( + f"Could not resolve slot `{slot.get('slot_id')}` with tags {required_tags or ['']}" + ) + return candidates[0] + + +def build_recipe_spec(catalog: dict[str, Any], recipe_name: str) -> dict[str, Any]: + recipe = RECIPE_LIBRARY.get(recipe_name) + if recipe is None: + supported = ", ".join(sorted(RECIPE_LIBRARY)) + raise RuntimeError(f"Unknown recipe `{recipe_name}`. Supported recipes: {supported}") + used_entry_ids: set[str] = set() + steps: list[dict[str, Any]] = [] + for slot_index, slot in enumerate(recipe.get("step_plan") or [], start=1): + entry = _select_recipe_entry(catalog, slot, used_entry_ids) + used_entry_ids.add(str(entry["entry_id"])) + payload = dict(entry["step_payload"]) + payload["criticality"] = str(slot.get("criticality") or payload.get("criticality") or "critical") + payload["semantic_tags"] = _normalize_tags( + [*payload.get("semantic_tags", []), *(entry.get("semantic_tags") or [])] + ) + override_fields = slot.get("override_fields") + if isinstance(override_fields, dict): + payload.update(override_fields) + payload["notes"] = ( + f"{str(payload.get('notes') or '').strip()} " + f"[mixed_pack_slot={slot.get('slot_id')} source={entry.get('entry_id')}]" + ).strip() + steps.append(payload) + return { + "schema_version": "domain_truth_harness_spec_v1", + "scenario_id": recipe["scenario_id"], + "domain": recipe["domain"], + "title": recipe["title"], + "description": recipe["description"], + "bindings": recipe.get("bindings") or {}, + "steps": steps, + } + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Inventory reusable semantic sources and build mixed AGENT replay packs.") + subparsers = parser.add_subparsers(dest="command", required=True) + + inventory_parser = subparsers.add_parser("inventory", help="Build a source catalog from harness specs and saved sessions.") + inventory_parser.add_argument( + "--output-json", + default="docs/orchestration/agent_semantic_source_catalog.json", + help="Where to write the catalog JSON.", + ) + inventory_parser.add_argument( + "--output-md", + default="docs/orchestration/agent_semantic_source_catalog.md", + help="Where to write the catalog markdown summary.", + ) + + build_parser = subparsers.add_parser("build-pack", help="Build a mixed truth-harness pack from catalogued sources.") + build_parser.add_argument("--recipe", required=True, help="Recipe name to build.") + build_parser.add_argument( + "--output-spec", + default="docs/orchestration/address_truth_harness_phase7_meta_domain_mix.json", + help="Where to write the generated truth-harness spec.", + ) + return parser.parse_args() + + +def _resolve_repo_path(raw_path: str) -> Path: + path = Path(raw_path) + return path if path.is_absolute() else (REPO_ROOT / path).resolve() + + +def run_inventory(args: argparse.Namespace) -> int: + catalog = build_source_catalog() + output_json = _resolve_repo_path(args.output_json) + output_md = _resolve_repo_path(args.output_md) + write_json(output_json, catalog) + write_text(output_md, _catalog_markdown(catalog)) + print(f"Catalog written to {output_json}") + print(f"Summary written to {output_md}") + print( + "Reusable truth-harness tags:", + ", ".join(sorted((catalog.get("summary") or {}).get("reusable_truth_harness_tags", {}).keys())), + ) + return 0 + + +def run_build_pack(args: argparse.Namespace) -> int: + catalog = build_source_catalog() + spec = build_recipe_spec(catalog, args.recipe) + output_spec = _resolve_repo_path(args.output_spec) + write_json(output_spec, spec) + print(f"Mixed pack written to {output_spec}") + print(f"scenario_id={spec['scenario_id']}") + print(f"steps={len(spec['steps'])}") + return 0 + + +def main() -> int: + args = parse_args() + if args.command == "inventory": + return run_inventory(args) + if args.command == "build-pack": + return run_build_pack(args) + raise RuntimeError(f"Unsupported command: {args.command}") + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/domain_truth_harness.py b/scripts/domain_truth_harness.py index 54fca34..2825b5d 100644 --- a/scripts/domain_truth_harness.py +++ b/scripts/domain_truth_harness.py @@ -84,6 +84,7 @@ def normalize_step_spec(index: int, raw_step: Any) -> dict[str, Any]: normalized_step = dcl.normalize_step_definition(index, raw_step) step = raw_step if isinstance(raw_step, dict) else {} normalized_step["criticality"] = normalize_criticality(step.get("criticality")) + normalized_step["semantic_tags"] = dcl.normalize_string_list(step.get("semantic_tags")) normalized_step["allowed_reply_types"] = normalize_pattern_list(step.get("allowed_reply_types")) normalized_step["allowed_limited_reason_categories"] = normalize_pattern_list( step.get("allowed_limited_reason_categories") @@ -219,6 +220,7 @@ def build_generated_manifest(spec: dict[str, Any]) -> dict[str, Any]: } for field_name in TECHNICAL_QUESTION_FIELDS: manifest_step[field_name] = step.get(field_name) + manifest_step["semantic_tags"] = step.get("semantic_tags") or [] manifest_steps.append(manifest_step) previous_step_id = step["step_id"] return { diff --git a/scripts/scenario_acceptance_policy.py b/scripts/scenario_acceptance_policy.py index 23c5b33..69c519d 100644 --- a/scripts/scenario_acceptance_policy.py +++ b/scripts/scenario_acceptance_policy.py @@ -21,6 +21,13 @@ SELECTED_OBJECT_INTENTS = { "inventory_profitability_for_item", "inventory_purchase_to_sale_chain", } +META_CONTEXT_TAGS = { + "meta_smalltalk", + "meta_scope", + "meta_capability", + "meta_memory", + "meta_historical_capability", +} def _now_iso() -> str: @@ -44,18 +51,28 @@ def _priority_from_finding(finding: dict[str, Any]) -> str: def _highest_priority(findings: list[dict[str, Any]]) -> str: if not findings: - return "none" + return "none" priorities = [_priority_from_finding(item) for item in findings] return sorted(priorities, key=lambda item: PRIORITY_RANK.get(item, 99))[0] +def _normalize_semantic_tags(step: dict[str, Any]) -> set[str]: + raw = step.get("semantic_tags") + if not isinstance(raw, list): + return set() + return {str(item).strip().lower() for item in raw if str(item).strip()} + + def _has_selected_object_signal(step: dict[str, Any]) -> bool: question = str(step.get("question_template") or "").lower() + semantic_tags = _normalize_semantic_tags(step) expected_intents = { str(item).strip() for item in (step.get("expected_intents") or []) if str(item).strip() } + if "selected_object" in semantic_tags: + return True if expected_intents & SELECTED_OBJECT_INTENTS: return True return any( @@ -70,6 +87,19 @@ def _has_selected_object_signal(step: dict[str, Any]) -> bool: ) +def _has_meta_context_signal(step: dict[str, Any]) -> bool: + semantic_tags = _normalize_semantic_tags(step) + if semantic_tags & META_CONTEXT_TAGS: + return True + title = str(step.get("title") or "").lower() + step_id = str(step.get("step_id") or "").lower() + question = str(step.get("question_template") or "").lower() + return any( + marker in f"{step_id} {title} {question}" + for marker in ("meta", "memory", "smalltalk", "историческ", "что ты умеешь", "что можешь", "по какой компании", "по какой базе") + ) + + def _is_direct_answer_code(code: str) -> bool: return code.startswith("required_direct_answer_") or code.startswith("forbidden_direct_answer_") @@ -105,15 +135,26 @@ def _is_human_answer_quality_code(code: str) -> bool: } +def _is_meta_context_code(code: str) -> bool: + return ( + _is_route_code(code) + or _is_truth_gate_code(code) + or _is_human_answer_quality_code(code) + or _is_direct_answer_code(code) + ) + + def _derive_step_invariant_failures(step: dict[str, Any], findings: list[dict[str, Any]]) -> dict[str, bool]: codes = [str(item.get("code") or "").strip() for item in findings] selected_object_step = _has_selected_object_signal(step) + meta_context_step = _has_meta_context_signal(step) return { "direct_answer": any(_is_direct_answer_code(code) for code in codes), "temporal_honesty": any(_is_temporal_code(code) for code in codes), "selected_object_continuity": selected_object_step and any(_is_route_code(code) for code in codes), "truth_gate": any(_is_truth_gate_code(code) for code in codes), "human_answer_quality": any(_is_human_answer_quality_code(code) for code in codes), + "meta_context_integrity": meta_context_step and any(_is_meta_context_code(code) for code in codes), } @@ -129,6 +170,7 @@ def build_scenario_acceptance_matrix( "selected_object_continuity": 0, "truth_gate": 0, "human_answer_quality": 0, + "meta_context_integrity": 0, } for index, step in enumerate(spec.get("steps") or [], start=1): @@ -151,11 +193,13 @@ def build_scenario_acceptance_matrix( "title": step.get("title"), "question": step.get("question_template"), "criticality": str(step.get("criticality") or "critical"), + "semantic_tags": sorted(_normalize_semantic_tags(step)), "review_status": str(step_state.get("review_status") or "unknown"), "reply_type": step_state.get("reply_type"), "detected_intent": step_state.get("detected_intent"), "capability_id": step_state.get("capability_id"), "selected_object_step": _has_selected_object_signal(step), + "meta_context_step": _has_meta_context_signal(step), "highest_unresolved_priority": highest_priority, "unresolved_findings_count": len(findings), "invariant_failures": [name for name, failed in invariant_failures.items() if failed], @@ -169,6 +213,7 @@ def build_scenario_acceptance_matrix( "selected_object_continuity_ok": invariant_failure_counts["selected_object_continuity"] == 0, "truth_gate_ok": invariant_failure_counts["truth_gate"] == 0, "human_answer_quality_ok": invariant_failure_counts["human_answer_quality"] == 0, + "meta_context_integrity_ok": invariant_failure_counts["meta_context_integrity"] == 0, } critical_rows = [row for row in rows if row["criticality"] == "critical"] critical_path_green = bool(critical_rows) and all(row["review_status"] == "pass" for row in critical_rows) @@ -274,6 +319,7 @@ def build_scenario_acceptance_matrix_markdown(acceptance_matrix: dict[str, Any]) f"- selected_object_continuity_ok: `{invariants.get('selected_object_continuity_ok')}`", f"- truth_gate_ok: `{invariants.get('truth_gate_ok')}`", f"- human_answer_quality_ok: `{invariants.get('human_answer_quality_ok')}`", + f"- meta_context_integrity_ok: `{invariants.get('meta_context_integrity_ok')}`", "", "## Steps", ] @@ -283,8 +329,10 @@ def build_scenario_acceptance_matrix_markdown(acceptance_matrix: dict[str, Any]) f"- `{row.get('step_id')}`", f" review_status: `{row.get('review_status')}`", f" criticality: `{row.get('criticality')}`", + f" semantic_tags: {', '.join(row.get('semantic_tags') or []) or 'none'}", f" highest_unresolved_priority: `{row.get('highest_unresolved_priority')}`", f" selected_object_step: `{row.get('selected_object_step')}`", + f" meta_context_step: `{row.get('meta_context_step')}`", f" invariant_failures: {', '.join(row.get('invariant_failures') or []) or 'none'}", ] ) @@ -303,4 +351,6 @@ def build_truth_harness_final_status_markdown(pack_state: dict[str, Any]) -> str f"- temporal_honesty_ok: `{invariants.get('temporal_honesty_ok')}`\n" f"- selected_object_continuity_ok: `{invariants.get('selected_object_continuity_ok')}`\n" f"- truth_gate_ok: `{invariants.get('truth_gate_ok')}`\n" + f"- human_answer_quality_ok: `{invariants.get('human_answer_quality_ok')}`\n" + f"- meta_context_integrity_ok: `{invariants.get('meta_context_integrity_ok')}`\n" ) diff --git a/scripts/test_agent_semantic_pack_builder.py b/scripts/test_agent_semantic_pack_builder.py new file mode 100644 index 0000000..9461578 --- /dev/null +++ b/scripts/test_agent_semantic_pack_builder.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import sys +import unittest +from pathlib import Path + + +sys.path.insert(0, str(Path(__file__).resolve().parent)) + +import agent_semantic_pack_builder as builder + + +class AgentSemanticPackBuilderTests(unittest.TestCase): + def test_build_source_catalog_finds_reusable_meta_and_selected_object_tags(self) -> None: + catalog = builder.build_source_catalog() + summary = catalog["summary"] + + self.assertGreater(summary["truth_harness_steps_total"], 0) + self.assertIn("meta_scope", summary["reusable_truth_harness_tags"]) + self.assertIn("selected_object_supplier", summary["reusable_truth_harness_tags"]) + self.assertIn("counterparty_documents", summary["reusable_truth_harness_tags"]) + + def test_build_recipe_spec_creates_mixed_phase7_pack(self) -> None: + catalog = builder.build_source_catalog() + spec = builder.build_recipe_spec(catalog, "turnaround_11_phase7_meta_domain_mix") + + self.assertEqual(spec["scenario_id"], "address_truth_harness_phase7_meta_domain_mix") + self.assertGreaterEqual(len(spec["steps"]), 10) + all_tags = {tag for step in spec["steps"] for tag in step.get("semantic_tags", [])} + self.assertIn("meta_scope", all_tags) + self.assertIn("meta_capability", all_tags) + self.assertIn("selected_object_supplier", all_tags) + self.assertIn("same_date_restore", all_tags) + self.assertIn("settlements_receivables", all_tags) + + +if __name__ == "__main__": + unittest.main() diff --git a/scripts/test_scenario_acceptance_policy.py b/scripts/test_scenario_acceptance_policy.py index dcb684c..63a9d52 100644 --- a/scripts/test_scenario_acceptance_policy.py +++ b/scripts/test_scenario_acceptance_policy.py @@ -1,6 +1,11 @@ from __future__ import annotations +import sys import unittest +from pathlib import Path + + +sys.path.insert(0, str(Path(__file__).resolve().parent)) import scenario_acceptance_policy as sap @@ -18,6 +23,7 @@ class ScenarioAcceptancePolicyTests(unittest.TestCase): "question_template": 'По выбранному объекту "Стол": кто поставил?', "criticality": "critical", "expected_intents": ["inventory_purchase_provenance_for_item"], + "semantic_tags": ["selected_object"], } ], } @@ -52,6 +58,7 @@ class ScenarioAcceptancePolicyTests(unittest.TestCase): self.assertFalse(pack_state["invariants"]["selected_object_continuity_ok"]) self.assertFalse(pack_state["invariants"]["temporal_honesty_ok"]) self.assertEqual(pack_state["unresolved_p0_count"], 2) + self.assertTrue(pack_state["invariants"]["meta_context_integrity_ok"]) def test_accepts_when_all_review_and_acceptance_invariants_are_green(self) -> None: spec = { @@ -65,6 +72,7 @@ class ScenarioAcceptancePolicyTests(unittest.TestCase): "question_template": "какие остатки на складе на март 2021", "criticality": "critical", "expected_intents": ["inventory_on_hand_as_of_date"], + "semantic_tags": ["inventory_root"], } ], } @@ -97,6 +105,52 @@ class ScenarioAcceptancePolicyTests(unittest.TestCase): self.assertTrue(pack_state["critical_path_green"]) self.assertTrue(all(pack_state["invariants"].values())) + def test_flags_meta_context_integrity_when_meta_step_leaks_technical_answer_shape(self) -> None: + spec = { + "scenario_id": "demo_phase7_meta", + "domain": "inventory_demo", + "title": "Demo meta", + "steps": [ + { + "step_id": "step_meta", + "title": "Capability meta", + "question_template": "что ты умеешь?", + "criticality": "warning", + "semantic_tags": ["meta_capability"], + } + ], + } + scenario_state = { + "session_id": "asst-meta", + "step_outputs": { + "step_meta": { + "review_status": "warning", + "reply_type": "factual_with_explanation", + "detected_intent": None, + "capability_id": None, + "review_findings": [ + {"code": "forbidden_answer_pattern_hit", "severity": "warning"}, + ], + } + }, + } + review_summary = { + "review_source": "live_strict_replay", + "overall_status": "warning", + "steps_total": 1, + "steps_passed": 0, + "steps_with_warning": 1, + "steps_failed": 0, + } + + acceptance_matrix = sap.build_scenario_acceptance_matrix(spec, scenario_state, review_summary) + pack_state = sap.derive_truth_harness_pack_state(spec, scenario_state, review_summary, acceptance_matrix) + + self.assertFalse(pack_state["invariants"]["meta_context_integrity_ok"]) + row = acceptance_matrix["rows"][0] + self.assertTrue(row["meta_context_step"]) + self.assertIn("meta_context_integrity", row["invariant_failures"]) + if __name__ == "__main__": unittest.main()