@ -0,0 +1,478 @@
{
"schema_version" : "active_domain_contract_v1" ,
"status" : "active" ,
"domain_id" : "inventory_stock_supplier_provenance" ,
"title" : "Складские остатки, происхождение товара и связь с поставщиком" ,
"source_of_truth_policy" : {
"purpose" : "single mutable domain source for the current orchestration target" ,
"switching_rule" : "when the project switches to another domain, replace this file instead of rewriting the stable agent canon" ,
"stable_layers" : [
"AGENTS.md" ,
".codex/skills/domain-case-loop" ,
".codex/agents/domain_analyst.toml" ,
".codex/agents/orchestrator.toml"
] ,
"mutable_layer" : [
"docs/orchestration/active_domain_contract.json"
]
} ,
"domain_goal" : "Показать остатки товаров на складе на дату, затем по выбранной позиции или по связанному срезу пройти в происхождение товара, поставщика, закупочные документы, возраст закупки и дальнейшую продажу без потери контекста." ,
"business_value" : [
"Пользователь должен сначала получить подтвержденный срез остатков на дату." ,
"Пользователь должен затем выбрать реальную позицию из ответа и углубиться без ручного переписывания сущности." ,
"Система должна понимать не только канонический вопрос, но и разговорные follow-up формулировки." ,
"Для сценария склада acceptance определяется не одиночным ответом, а проходимостью дерева от root snapshot к критическим drilldown-веткам."
] ,
"observed_anchors" : {
"warehouse" : "Основной склад" ,
"organization" : "О О О \\Альтернатива Плюс\\" ,
"historical_as_of_date" : "2019-03-31" ,
"current_as_of_date_example" : "2021-09-30" ,
"focus_item_current" : "Диван трехместный" ,
"focus_item_historical" : "Столешница 600*3050*26 дуб ниагара" ,
"focus_item_small_residue" : "Четки Пост (84*117)" ,
"supplier_candidate" : "Торговый дом \\Союз" ,
"supplier_candidate_alt" : "Гамма-мебель, О О О " ,
"buyer_candidate" : "Департамент капитального ремонта города Москвы"
} ,
"question_pool" : {
"total_questions" : 20 ,
"core_questions_total" : 17 ,
"followup_checkpoints_total" : 3 ,
"questions" : [
{
"question_id" : "Q01" ,
"text" : "Какие товары сейчас лежат на складе" ,
"layer" : "root_snapshot" ,
"node_id" : "N01_stock_snapshot" ,
"role" : "root" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить актуальный item-level срез остатков на складе"
} ,
{
"question_id" : "Q02" ,
"text" : "Какие товары лежат на складе на дату ..." ,
"layer" : "root_snapshot" ,
"node_id" : "N01_stock_snapshot" ,
"role" : "root" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить item-level срез остатков на конкретную дату"
} ,
{
"question_id" : "Q03" ,
"text" : "Из каких товаров состоит остаток по 41 счету" ,
"layer" : "root_snapshot" ,
"node_id" : "N02_account_41_snapshot" ,
"role" : "root_variant" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить item-level состав остатка по 41.01"
} ,
{
"question_id" : "Q04" ,
"text" : "Какие товары числятся на 41 счете на дату ..." ,
"layer" : "root_snapshot" ,
"node_id" : "N02_account_41_snapshot" ,
"role" : "root_variant" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить датированный item-level состав остатка по 41.01"
} ,
{
"question_id" : "Q05" ,
"text" : "Какие конкретно номенклатуры формируют остаток по складу на дату ..." ,
"layer" : "root_snapshot" ,
"node_id" : "N01_stock_snapshot" ,
"role" : "root_variant" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить номенклатурный состав складского остатка на дату"
} ,
{
"question_id" : "Q06" ,
"text" : "От какого поставщика куплен товар ..." ,
"layer" : "selected_item_provenance" ,
"node_id" : "N03_selected_item_supplier" ,
"role" : "critical_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить прямой ответ о поставщике выбранного товара"
} ,
{
"question_id" : "Q07" ,
"text" : "У какого поставщика были куплены товары, которые сейчас лежат на складе" ,
"layer" : "supplier_overlap" ,
"node_id" : "N06_supplier_overlap_now" ,
"role" : "critical_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "понять supplier coverage по текущему складскому срезу"
} ,
{
"question_id" : "Q08" ,
"text" : "По какому поставщику проходит текущий товарный остаток" ,
"layer" : "supplier_overlap" ,
"node_id" : "N06_supplier_overlap_now" ,
"role" : "supporting_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "атрибутировать текущий остаток по поставщику без потери item/slice контекста"
} ,
{
"question_id" : "Q09" ,
"text" : "Когда был куплен товар ..." ,
"layer" : "selected_item_provenance" ,
"node_id" : "N04_selected_item_purchase_date" ,
"role" : "critical_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить дату первой/наблюдаемой закупки выбранного товара"
} ,
{
"question_id" : "Q10" ,
"text" : "По каким документам был куплен товар ..." ,
"layer" : "selected_item_provenance" ,
"node_id" : "N05_selected_item_purchase_documents" ,
"role" : "critical_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить закупочные документы для выбранного товара"
} ,
{
"question_id" : "Q11" ,
"text" : "Какие товары от поставщика ... сейчас еще лежат на складе" ,
"layer" : "supplier_overlap" ,
"node_id" : "N07_supplier_items_on_stock" ,
"role" : "supporting_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить item-level пересечение supplier -> current stock"
} ,
{
"question_id" : "Q12" ,
"text" : "Какие товары по состоянию на дату ... были куплены у поставщика ..." ,
"layer" : "supplier_overlap" ,
"node_id" : "N08_supplier_items_on_date" ,
"role" : "supporting_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить датированное item-level пересечение supplier -> stock slice"
} ,
{
"question_id" : "Q13" ,
"text" : "Какие остатки по товарам на эту дату относятся к старым закупкам" ,
"layer" : "aging" ,
"node_id" : "N09_old_purchase_aging" ,
"role" : "critical_child" ,
"wording_family" : "followup_date_carryover" ,
"semantic_goal" : "показать item-level старые закупки в рамках уже выбранной даты, а не на текущий момент"
} ,
{
"question_id" : "Q14" ,
"text" : "Какие товары сейчас висят в остатке без понятной привязки к поставщику" ,
"layer" : "aging" ,
"node_id" : "N10_unresolved_supplier_link" ,
"role" : "supporting_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "найти остатки без надежной supplier attribution"
} ,
{
"question_id" : "Q15" ,
"text" : "Есть ли остатки товара, которые закупались очень давно" ,
"layer" : "aging" ,
"node_id" : "N09_old_purchase_aging" ,
"role" : "supporting_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "показать very-old stock в item-level виде"
} ,
{
"question_id" : "Q16" ,
"text" : "Кому был продан товар ..." ,
"layer" : "sale_trace" ,
"node_id" : "N11_selected_item_buyer" ,
"role" : "critical_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить покупателя выбранного товара"
} ,
{
"question_id" : "Q17" ,
"text" : "Через какие документы прошел путь товара: закупка -> склад -> продажа" ,
"layer" : "sale_trace" ,
"node_id" : "N12_purchase_to_sale_chain" ,
"role" : "critical_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "получить полную документальную цепочку purchase -> stock -> sale"
} ,
{
"question_id" : "Q18" ,
"text" : "Какие товары были куплены у поставщика ... и позже проданы покупателю ..." ,
"layer" : "sale_trace" ,
"node_id" : "N13_supplier_to_buyer_overlap" ,
"role" : "supporting_child" ,
"wording_family" : "canonical" ,
"semantic_goal" : "проверить supplier -> item -> buyer overlap"
} ,
{
"question_id" : "Q19" ,
"text" : "По выбранному объекту \"...\": кто это поставил нам" ,
"layer" : "selected_item_provenance" ,
"node_id" : "N03_selected_item_supplier" ,
"role" : "critical_child" ,
"wording_family" : "ui_selected_object_colloquial" ,
"semantic_goal" : "проверить, что selected-object follow-up и разговорная supplier-фраза идут в exact provenance contour"
} ,
{
"question_id" : "Q20" ,
"text" : "По выбранному объекту \"...\": по каким документам это купили" ,
"layer" : "selected_item_provenance" ,
"node_id" : "N05_selected_item_purchase_documents" ,
"role" : "critical_child" ,
"wording_family" : "ui_selected_object_colloquial" ,
"semantic_goal" : "проверить selected-object follow-up в закупочные документы без ручного переписывания item"
}
]
} ,
"wording_families" : [
{
"family_id" : "canonical" ,
"description" : "нормальная каноническая формулировка доменного вопроса"
} ,
{
"family_id" : "colloquial" ,
"description" : "разговорная или короткая пользовательская формулировка"
} ,
{
"family_id" : "ui_selected_object" ,
"description" : "follow-up, собранный через выбор объекта из ответа"
} ,
{
"family_id" : "ui_selected_object_colloquial" ,
"description" : "выбранный объект + разговорная формулировка drilldown-вопроса"
} ,
{
"family_id" : "followup_date_carryover" ,
"description" : "follow-up с фразой `на эту дату` или `на ту дату`, где дата обязана тянуться из предыдущего шага"
}
] ,
"scenario_tree" : {
"root_nodes" : [
{
"node_id" : "N01_stock_snapshot" ,
"title" : "Складской snapshot на дату" ,
"covers_question_ids" : [ "Q01" , "Q02" , "Q05" ] ,
"expected_intents" : [ "inventory_on_hand_as_of_date" ] ,
"expected_answer_shape" : "item_list_with_quantity_cost_warehouse_organization" ,
"required_wording_families" : [ "canonical" , "colloquial" ] ,
"children" : [ "N03_selected_item_supplier" , "N06_supplier_overlap_now" , "N09_old_purchase_aging" ]
} ,
{
"node_id" : "N02_account_41_snapshot" ,
"title" : "Состав остатка по 41.01 на дату" ,
"covers_question_ids" : [ "Q03" , "Q04" ] ,
"expected_intents" : [ "inventory_on_hand_as_of_date" ] ,
"expected_answer_shape" : "item_list_with_account_41_scope" ,
"required_wording_families" : [ "canonical" , "colloquial" ] ,
"children" : [ "N03_selected_item_supplier" , "N11_selected_item_buyer" ]
}
] ,
"critical_nodes" : [
{
"node_id" : "N03_selected_item_supplier" ,
"title" : "Поставщик выбранного товара" ,
"covers_question_ids" : [ "Q06" , "Q19" ] ,
"expected_intents" : [ "inventory_purchase_provenance_for_item" ] ,
"expected_answer_shape" : "direct_supplier_answer_first_then_evidence" ,
"required_wording_families" : [ "canonical" , "colloquial" , "ui_selected_object" , "ui_selected_object_colloquial" ] ,
"required_carryover_invariants" : [ "selected_object" , "date_scope" , "warehouse_scope" , "organization_scope" ] ,
"children" : [ "N04_selected_item_purchase_date" , "N05_selected_item_purchase_documents" , "N09_old_purchase_aging" ]
} ,
{
"node_id" : "N04_selected_item_purchase_date" ,
"title" : "Дата закупки выбранного товара" ,
"covers_question_ids" : [ "Q09" ] ,
"expected_intents" : [ "inventory_purchase_provenance_for_item" ] ,
"expected_answer_shape" : "direct_date_answer_first_then_evidence" ,
"required_wording_families" : [ "canonical" , "ui_selected_object" ] ,
"required_carryover_invariants" : [ "selected_object" , "date_scope" ]
} ,
{
"node_id" : "N05_selected_item_purchase_documents" ,
"title" : "Закупочные документы выбранного товара" ,
"covers_question_ids" : [ "Q10" , "Q20" ] ,
"expected_intents" : [ "inventory_purchase_documents_for_item" ] ,
"expected_answer_shape" : "document_list_for_selected_item" ,
"required_wording_families" : [ "canonical" , "ui_selected_object" , "ui_selected_object_colloquial" ] ,
"required_carryover_invariants" : [ "selected_object" , "date_scope" , "warehouse_scope" ]
} ,
{
"node_id" : "N09_old_purchase_aging" ,
"title" : "Старые закупки по остаткам на выбранную дату" ,
"covers_question_ids" : [ "Q13" , "Q15" ] ,
"expected_intents" : [ "inventory_aging_by_purchase_date" ] ,
"expected_answer_shape" : "item_level_oldest_first_stock_aging_list" ,
"required_wording_families" : [ "canonical" , "followup_date_carryover" ] ,
"required_carryover_invariants" : [ "date_scope" , "warehouse_scope" , "organization_scope" ] ,
"ordering_rule" : "oldest_first"
} ,
{
"node_id" : "N11_selected_item_buyer" ,
"title" : "Покупатель выбранного товара" ,
"covers_question_ids" : [ "Q16" ] ,
"expected_intents" : [ "inventory_sale_trace_for_item" ] ,
"expected_answer_shape" : "direct_buyer_answer_first_then_evidence" ,
"required_wording_families" : [ "canonical" , "ui_selected_object" ] ,
"required_carryover_invariants" : [ "selected_object" , "date_scope" ]
} ,
{
"node_id" : "N12_purchase_to_sale_chain" ,
"title" : "Документальная цепочка purchase -> stock -> sale" ,
"covers_question_ids" : [ "Q17" ] ,
"expected_intents" : [ "inventory_purchase_to_sale_chain" ] ,
"expected_answer_shape" : "ordered_chain_with_purchase_stock_sale_documents" ,
"required_wording_families" : [ "canonical" , "ui_selected_object" ] ,
"required_carryover_invariants" : [ "selected_object" , "date_scope" ]
}
] ,
"supporting_nodes" : [
{
"node_id" : "N06_supplier_overlap_now" ,
"title" : "Supplier overlap по текущему stock slice" ,
"covers_question_ids" : [ "Q07" , "Q08" ] ,
"expected_intents" : [ "inventory_supplier_stock_overlap_as_of_date" ] ,
"expected_answer_shape" : "supplier_to_stock_slice_summary"
} ,
{
"node_id" : "N07_supplier_items_on_stock" ,
"title" : "Какие товары поставщика лежат на складе сейчас" ,
"covers_question_ids" : [ "Q11" ] ,
"expected_intents" : [ "inventory_supplier_stock_overlap_as_of_date" ] ,
"expected_answer_shape" : "item_list_filtered_by_supplier"
} ,
{
"node_id" : "N08_supplier_items_on_date" ,
"title" : "Какие товары поставщика были в остатке на дату" ,
"covers_question_ids" : [ "Q12" ] ,
"expected_intents" : [ "inventory_supplier_stock_overlap_as_of_date" ] ,
"expected_answer_shape" : "dated_item_list_filtered_by_supplier"
} ,
{
"node_id" : "N10_unresolved_supplier_link" ,
"title" : "Остатки без понятной supplier attribution" ,
"covers_question_ids" : [ "Q14" ] ,
"expected_intents" : [ "inventory_supplier_stock_overlap_as_of_date" ] ,
"expected_answer_shape" : "item_list_with_unresolved_supplier_linkage"
} ,
{
"node_id" : "N13_supplier_to_buyer_overlap" ,
"title" : "Supplier -> item -> buyer overlap" ,
"covers_question_ids" : [ "Q18" ] ,
"expected_intents" : [ "inventory_purchase_to_sale_chain" ] ,
"expected_answer_shape" : "confirmed_or_honestly_limited_supplier_item_buyer_overlap"
}
] ,
"critical_edges" : [
{
"edge_id" : "E01_snapshot_to_selected_item_supplier" ,
"from_node" : "N01_stock_snapshot" ,
"to_node" : "N03_selected_item_supplier" ,
"transition_type" : "selected_object_drilldown" ,
"primary_user_path" : true ,
"required_carryover_invariants" : [ "selected_object" , "date_scope" , "warehouse_scope" , "organization_scope" ] ,
"failure_means" : "домен не принят, даже если root snapshot уже exact"
} ,
{
"edge_id" : "E02_selected_item_supplier_to_purchase_documents" ,
"from_node" : "N03_selected_item_supplier" ,
"to_node" : "N05_selected_item_purchase_documents" ,
"transition_type" : "selected_object_deeper_trace" ,
"primary_user_path" : true ,
"required_carryover_invariants" : [ "selected_object" , "date_scope" ] ,
"failure_means" : "сломано углубление из поставщика в документы закупки"
} ,
{
"edge_id" : "E03_snapshot_or_provenance_to_aging" ,
"from_node" : "N01_stock_snapshot" ,
"to_node" : "N09_old_purchase_aging" ,
"transition_type" : "date_sensitive_followup" ,
"primary_user_path" : true ,
"required_carryover_invariants" : [ "date_scope" , "warehouse_scope" , "organization_scope" ] ,
"ordering_rule" : "oldest_first" ,
"failure_means" : "сломано понимание `на эту дату` или неверная answer shape по старым закупкам"
} ,
{
"edge_id" : "E04_snapshot_to_sale_trace" ,
"from_node" : "N02_account_41_snapshot" ,
"to_node" : "N11_selected_item_buyer" ,
"transition_type" : "historical_selected_object_drilldown" ,
"primary_user_path" : false ,
"required_carryover_invariants" : [ "selected_object" , "date_scope" ] ,
"failure_means" : "sale-trace ветка незакрыта"
}
] ,
"primary_user_paths" : [
{
"path_id" : "P01_snapshot_to_supplier" ,
"nodes" : [ "N01_stock_snapshot" , "N03_selected_item_supplier" ] ,
"description" : "Самый типичный живой путь: получить список остатков, выбрать позицию, спросить кто поставил."
} ,
{
"path_id" : "P02_snapshot_to_supplier_to_documents" ,
"nodes" : [ "N01_stock_snapshot" , "N03_selected_item_supplier" , "N05_selected_item_purchase_documents" ] ,
"description" : "После поставщика пользователь углубляется в закупочные документы."
} ,
{
"path_id" : "P03_snapshot_to_aging_on_same_date" ,
"nodes" : [ "N01_stock_snapshot" , "N09_old_purchase_aging" ] ,
"description" : "Пользователь спрашивает про старые закупки на ту же дату, что и исходный snapshot."
}
]
} ,
"acceptance_contract" : {
"acceptance_unit" : "scenario_tree" ,
"do_not_accept_if" : [
"работает только root snapshot, но ломается critical selected-object edge" ,
"работает только canonical wording, но ломается colloquial или ui_selected_object wording" ,
"теряется date_scope на follow-up с `на эту дату` или `на ту дату`" ,
"ответ меняет business object, например вместо item-level ответа отдаёт dump документов" ,
"нарушается ordering semantics, например `старые закупки` идут не oldest-first"
] ,
"required_green_for_acceptance" : [
"root nodes" ,
"critical edges on primary_user_paths" ,
"canonical coverage on critical nodes" ,
"colloquial coverage on critical nodes" ,
"ui_selected_object coverage where UI supports object selection"
] ,
"required_defect_classes" : [
"semantic_understanding_gap" ,
"edge_carryover_gap" ,
"answer_shape_mismatch" ,
"ordering_semantics_mismatch" ,
"runtime_capability_gap" ,
"loop_coverage_gap"
] ,
"minimum_score_rule" : "accepted only if analyst score >= 80 and no unresolved P0 remains"
} ,
"known_failure_patterns_to_watch" : [
{
"pattern_id" : "F01_selected_object_colloquial_supplier" ,
"symptom" : "selected-object follow-up `кто это поставил нам` падает в clarification instead of provenance exact route" ,
"defect_class" : "semantic_understanding_gap"
} ,
{
"pattern_id" : "F02_numeric_tail_account_poisoning" ,
"symptom" : "numeric fragments inside item names such as `600*3050*26` contaminate account/domain inference" ,
"defect_class" : "semantic_understanding_gap"
} ,
{
"pattern_id" : "F03_date_carryover_loss" ,
"symptom" : "follow-up `на эту дату` loses the originating date and silently switches to current date" ,
"defect_class" : "edge_carryover_gap"
} ,
{
"pattern_id" : "F04_answer_shape_downgrade" ,
"symptom" : "user asks for item-level stock aging but runtime returns raw purchase documents" ,
"defect_class" : "answer_shape_mismatch"
} ,
{
"pattern_id" : "F05_oldest_first_violation" ,
"symptom" : "`старые закупки` are listed newest-first or in another non-business order" ,
"defect_class" : "ordering_semantics_mismatch"
}
] ,
"legacy_references" : [
"docs/orchestration/domain_inventory_stock_supplier_trace.md" ,
"docs/orchestration/domain_inventory_stock_supplier_trace_pool.md" ,
"docs/orchestration/domain_inventory_stock_supplier_trace_pack.json"
]
}