NODEDC_1C/llm_normalizer/backend/tests/assistantMcpDiscoveryPlanne...

1205 lines
55 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, expect, it } from "vitest";
import { planAssistantMcpDiscovery } from "../src/services/assistantMcpDiscoveryPlanner";
describe("assistant MCP discovery planner", () => {
it("builds a catalog-compatible value-flow discovery plan from current turn meaning", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: ["SVK"],
business_fact_family: "value_flow",
action_family: "turnover",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: [
"resolve_entity_reference",
"collect_scoped_movements",
"aggregate_checked_amounts",
"probe_coverage"
],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built"]
},
turnMeaning: {
asked_domain_family: "counterparty_value",
asked_action_family: "turnover",
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.semantic_data_need).toBe("counterparty value-flow evidence");
expect(result.selected_chain_id).toBe("value_flow");
expect(result.selected_chain_summary).toContain("query scoped movements");
expect(result.proposed_primitives).toEqual([
"resolve_entity_reference",
"query_movements",
"aggregate_by_axis",
"probe_coverage"
]);
expect(result.required_axes).toEqual(["counterparty", "period", "aggregate_axis", "amount", "coverage_target"]);
expect(result.catalog_review.review_status).toBe("catalog_compatible");
expect(result.discovery_plan.answer_may_use_raw_model_claims).toBe(false);
expect(result.data_need_graph?.business_fact_family).toBe("value_flow");
expect(result.discovery_plan.execution_budget.max_probe_count).toBe(30);
expect(result.reason_codes).toContain("planner_enabled_chunked_coverage_probe_budget");
expect(result.reason_codes).toContain("planner_consumed_data_need_graph_v1");
expect(result.reason_codes).toContain("planner_selected_catalog_primitives_from_decomposition_candidates");
expect(result.reason_codes).toContain("planner_scored_catalog_chain_templates_from_fact_axis");
expect(result.reason_codes).toContain("planner_catalog_chain_template_search_top_value_flow");
});
it("keeps a value-flow plan in clarification state when period axis is missing", () => {
const result = planAssistantMcpDiscovery({
turnMeaning: {
asked_domain_family: "counterparty_value",
asked_action_family: "turnover",
explicit_entity_candidates: ["SVK"]
}
});
expect(result.planner_status).toBe("needs_clarification");
expect(result.catalog_review.review_status).toBe("needs_more_axes");
expect(result.catalog_review.missing_axes_by_primitive.query_movements).toContainEqual(["period", "counterparty"]);
expect(result.reason_codes).toContain("planner_needs_more_user_or_scope_context");
});
it("keeps requested monthly aggregation as an explicit planning axis for value-flow discovery", () => {
const result = planAssistantMcpDiscovery({
turnMeaning: {
asked_domain_family: "counterparty_value",
asked_action_family: "net_value_flow",
asked_aggregation_axis: "month",
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.proposed_primitives).toEqual([
"resolve_entity_reference",
"query_movements",
"aggregate_by_axis",
"probe_coverage"
]);
expect(result.required_axes).toEqual([
"counterparty",
"period",
"aggregate_axis",
"amount",
"coverage_target",
"calendar_month"
]);
expect(result.reason_codes).toContain("planner_selected_monthly_value_flow_recipe");
expect(result.discovery_plan.execution_budget.max_probe_count).toBe(30);
});
it("builds a document discovery plan without falling back to movement primitives", () => {
const result = planAssistantMcpDiscovery({
turnMeaning: {
asked_domain_family: "counterparty_documents",
asked_action_family: "list_documents",
explicit_entity_candidates: ["SVK"]
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]);
expect(result.proposed_primitives).not.toContain("query_movements");
expect(result.required_axes).toEqual(["counterparty", "coverage_target"]);
});
it("expands a document evidence chain from catalog fact-axis search when decomposition hints are absent", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: ["SVK"],
business_fact_family: "document_evidence",
action_family: "list_documents",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: [],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built"]
},
turnMeaning: {
asked_domain_family: "documents",
asked_action_family: "list_documents",
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020",
unsupported_but_understood_family: "document_evidence"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("document_evidence");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]);
expect(result.reason_codes).toContain("planner_selected_catalog_primitives_from_fact_axis_search");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_document_evidence");
expect(result.reason_codes).toContain("planner_catalog_chain_template_search_top_document_evidence");
expect(result.reason_codes).not.toContain("planner_fell_back_to_recipe_primitives_after_empty_catalog_search");
});
it("filters conflicting document-vs-movement primitives when confirmed metadata surface recommends documents", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: ["SVK"],
business_fact_family: "document_evidence",
action_family: "list_documents",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["fetch_scoped_documents", "fetch_scoped_movements", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built"]
},
metadataSurface: {
selected_entity_set: "Документ",
selected_surface_objects: ["Документ.СчетФактураВыданный"],
downstream_route_family: "document_evidence",
route_family_selection_basis: "selected_entity_set",
recommended_next_primitive: "query_documents",
ambiguity_detected: false,
ambiguity_entity_sets: []
},
turnMeaning: {
asked_domain_family: "documents",
asked_action_family: "list_documents",
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020",
unsupported_but_understood_family: "document_evidence"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.metadata_surface_ref?.recommended_next_primitive).toBe("query_documents");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]);
expect(result.proposed_primitives).not.toContain("query_movements");
expect(result.reason_codes).toContain("planner_consumed_metadata_surface_ref_v1");
expect(result.reason_codes).toContain("planner_filtered_catalog_primitives_by_confirmed_metadata_surface");
expect(result.reason_codes).toContain("planner_surface_aware_next_lane_from_confirmed_metadata_objects");
});
it("can select document evidence directly from a confirmed metadata surface when the follow-up itself is thin", () => {
const result = planAssistantMcpDiscovery({
metadataSurface: {
selected_entity_set: "Document",
selected_surface_objects: ["Document.InvoiceIssued"],
downstream_route_family: "document_evidence",
route_family_selection_basis: "selected_entity_set",
recommended_next_primitive: "query_documents",
ambiguity_detected: false,
ambiguity_entity_sets: []
},
turnMeaning: {
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("document_evidence");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]);
expect(result.required_axes).toEqual(["counterparty", "period", "coverage_target"]);
expect(result.reason_codes).toContain("planner_selected_document_from_confirmed_metadata_surface_ref");
expect(result.reason_codes).toContain("planner_selected_catalog_primitives_from_metadata_surface_search");
});
it("infers document evidence from an unambiguous document metadata surface even before a downstream lane is labeled", () => {
const result = planAssistantMcpDiscovery({
metadataSurface: {
selected_entity_set: "Document",
selected_surface_objects: ["Document.InvoiceIssued"],
downstream_route_family: null,
route_family_selection_basis: null,
recommended_next_primitive: null,
ambiguity_detected: false,
ambiguity_entity_sets: []
},
turnMeaning: {
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("document_evidence");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]);
expect(result.proposed_primitives).not.toContain("query_movements");
expect(result.reason_codes).toContain("planner_inferred_next_lane_from_unambiguous_metadata_surface");
expect(result.reason_codes).toContain("planner_surface_aware_next_lane_from_confirmed_metadata_objects");
});
it("builds a movement discovery plan without aggregating value-flow totals", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: ["SVK"],
business_fact_family: "movement_evidence",
action_family: "list_movements",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["resolve_entity_reference", "fetch_scoped_movements", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built"]
},
turnMeaning: {
asked_domain_family: "movements",
asked_action_family: "list_movements",
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020",
unsupported_but_understood_family: "movement_evidence"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.semantic_data_need).toBe("movement evidence");
expect(result.selected_chain_id).toBe("movement_evidence");
expect(result.selected_chain_summary).toContain("movement rows");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_movements", "probe_coverage"]);
expect(result.proposed_primitives).not.toContain("aggregate_by_axis");
expect(result.required_axes).toEqual(["counterparty", "period", "coverage_target"]);
expect(result.reason_codes).toContain("planner_selected_movement_from_data_need_graph");
expect(result.reason_codes).toContain("planner_selected_catalog_primitives_from_decomposition_candidates");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_movement_evidence");
});
it("filters conflicting document-vs-movement primitives when confirmed metadata surface recommends movements", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: ["SVK"],
business_fact_family: "movement_evidence",
action_family: "list_movements",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["fetch_scoped_documents", "fetch_scoped_movements", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built"]
},
metadataSurface: {
selected_entity_set: "РегистрНакопления",
selected_surface_objects: ["РегистрНакопления.ДвиженияДенежныхСредств"],
downstream_route_family: "movement_evidence",
route_family_selection_basis: "dominant_surface_objects",
recommended_next_primitive: "query_movements",
ambiguity_detected: false,
ambiguity_entity_sets: []
},
turnMeaning: {
asked_domain_family: "movements",
asked_action_family: "list_movements",
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020",
unsupported_but_understood_family: "movement_evidence"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.metadata_surface_ref?.recommended_next_primitive).toBe("query_movements");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_movements", "probe_coverage"]);
expect(result.proposed_primitives).not.toContain("query_documents");
expect(result.reason_codes).toContain("planner_filtered_catalog_primitives_by_confirmed_metadata_surface");
});
it("can select movement evidence directly from a confirmed metadata surface when the follow-up itself is thin", () => {
const result = planAssistantMcpDiscovery({
metadataSurface: {
selected_entity_set: "AccumulationRegister",
selected_surface_objects: ["Register.BankOperations"],
downstream_route_family: "movement_evidence",
route_family_selection_basis: "dominant_surface_objects",
recommended_next_primitive: "query_movements",
ambiguity_detected: false,
ambiguity_entity_sets: []
},
turnMeaning: {
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("movement_evidence");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_movements", "probe_coverage"]);
expect(result.required_axes).toEqual(["counterparty", "period", "coverage_target"]);
expect(result.reason_codes).toContain("planner_selected_movement_from_confirmed_metadata_surface_ref");
expect(result.reason_codes).toContain("planner_selected_catalog_primitives_from_metadata_surface_search");
});
it("infers movement evidence from an unambiguous register metadata surface even before a downstream lane is labeled", () => {
const result = planAssistantMcpDiscovery({
metadataSurface: {
selected_entity_set: "AccumulationRegister",
selected_surface_objects: ["AccumulationRegister.BankOperations"],
downstream_route_family: null,
route_family_selection_basis: null,
recommended_next_primitive: null,
ambiguity_detected: false,
ambiguity_entity_sets: []
},
turnMeaning: {
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("movement_evidence");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_movements", "probe_coverage"]);
expect(result.proposed_primitives).not.toContain("query_documents");
expect(result.reason_codes).toContain("planner_inferred_next_lane_from_unambiguous_metadata_surface");
expect(result.reason_codes).toContain("planner_surface_aware_next_lane_from_confirmed_metadata_objects");
});
it("can select catalog drilldown directly from a confirmed catalog metadata surface when the follow-up itself is thin", () => {
const result = planAssistantMcpDiscovery({
metadataSurface: {
selected_entity_set: "Catalog",
selected_surface_objects: ["Catalog.Counterparties"],
downstream_route_family: "catalog_drilldown",
route_family_selection_basis: "selected_entity_set",
recommended_next_primitive: "drilldown_related_objects",
ambiguity_detected: false,
ambiguity_entity_sets: []
},
turnMeaning: {
asked_domain_family: "metadata",
asked_action_family: "inspect_catalog",
unsupported_but_understood_family: "schema_surface"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("catalog_drilldown");
expect(result.proposed_primitives).toEqual(["inspect_1c_metadata"]);
expect(result.required_axes).toEqual(["metadata_scope"]);
expect(result.reason_codes).toContain("planner_selected_catalog_drilldown_from_confirmed_metadata_surface_ref");
expect(result.reason_codes).toContain("planner_selected_catalog_primitives_from_metadata_surface_search");
});
it("scores an explicit document data-need over an ambiguous metadata surface without carrying movement primitives", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: ["SVK"],
business_fact_family: "document_evidence",
action_family: "list_documents",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["fetch_scoped_documents", "fetch_scoped_movements", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built"]
},
metadataSurface: {
selected_entity_set: null,
selected_surface_objects: ["Документ.СчетФактураВыданный", "РегистрНакопления.ДвиженияДенежныхСредств"],
downstream_route_family: null,
route_family_selection_basis: null,
recommended_next_primitive: null,
ambiguity_detected: true,
ambiguity_entity_sets: ["Документ", "РегистрНакопления"]
},
turnMeaning: {
asked_domain_family: "documents",
asked_action_family: "list_documents",
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020",
unsupported_but_understood_family: "document_evidence"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.reason_codes).toContain("planner_consumed_metadata_surface_ref_v1");
expect(result.reason_codes).toContain("planner_filtered_catalog_primitives_by_explicit_data_need_lane");
expect(result.reason_codes).toContain("planner_metadata_surface_scored_with_explicit_lane_family");
expect(result.reason_codes).not.toContain("planner_filtered_catalog_primitives_by_confirmed_metadata_surface");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]);
expect(result.proposed_primitives).not.toContain("query_movements");
});
it("scores an explicit movement data-need over an ambiguous metadata surface without carrying document primitives", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: ["SVK"],
business_fact_family: "movement_evidence",
action_family: "list_movements",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["fetch_scoped_documents", "fetch_scoped_movements", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built"]
},
metadataSurface: {
selected_entity_set: null,
selected_surface_objects: ["Document.InvoiceIssued", "Register.BankOperations"],
downstream_route_family: null,
route_family_selection_basis: null,
recommended_next_primitive: null,
ambiguity_detected: true,
ambiguity_entity_sets: ["Document", "AccumulationRegister"]
},
turnMeaning: {
asked_domain_family: "movements",
asked_action_family: "list_movements",
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020",
unsupported_but_understood_family: "movement_evidence"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("movement_evidence");
expect(result.reason_codes).toContain("planner_filtered_catalog_primitives_by_explicit_data_need_lane");
expect(result.reason_codes).toContain("planner_metadata_surface_scored_with_explicit_lane_family");
expect(result.proposed_primitives).toEqual(["resolve_entity_reference", "query_movements", "probe_coverage"]);
expect(result.proposed_primitives).not.toContain("query_documents");
});
it("does not force a thin follow-up into a lane when the carried metadata surface is still ambiguous", () => {
const result = planAssistantMcpDiscovery({
metadataSurface: {
selected_entity_set: null,
selected_surface_objects: ["Document.InvoiceIssued", "Register.BankOperations"],
downstream_route_family: null,
route_family_selection_basis: null,
recommended_next_primitive: null,
ambiguity_detected: true,
ambiguity_entity_sets: ["Document", "AccumulationRegister"]
},
turnMeaning: {
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("entity_resolution");
expect(result.reason_codes).toContain("planner_selected_entity_resolution_recipe");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_entity_resolution");
expect(result.reason_codes).not.toContain("planner_selected_document_from_confirmed_metadata_surface_ref");
expect(result.reason_codes).not.toContain("planner_selected_movement_from_confirmed_metadata_surface_ref");
});
it("can select value-flow chain from data need graph even when turn meaning family is still under-specified", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: ["SVK"],
business_fact_family: "value_flow",
action_family: "net_value_flow",
aggregation_need: "by_month",
time_scope_need: "explicit_period",
comparison_need: "incoming_vs_outgoing",
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: [
"resolve_entity_reference",
"collect_incoming_movements",
"collect_outgoing_movements",
"aggregate_by_month",
"probe_coverage"
],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built"]
},
turnMeaning: {
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020",
asked_aggregation_axis: "month"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("value_flow");
expect(result.proposed_primitives).toEqual([
"resolve_entity_reference",
"query_movements",
"aggregate_by_axis",
"probe_coverage"
]);
expect(result.required_axes).toEqual([
"counterparty",
"period",
"aggregate_axis",
"amount",
"coverage_target",
"calendar_month"
]);
expect(result.reason_codes).toContain("planner_selected_monthly_value_flow_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_value_flow");
});
it("does not collapse a ranking-shaped value graph into entity-resolution just because no subject is preselected", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
business_fact_family: "value_flow",
action_family: "turnover",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: "top_desc",
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["collect_scoped_movements", "aggregate_ranked_axis_values", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built", "data_need_graph_ranking_top_desc"]
},
turnMeaning: {
asked_domain_family: "counterparty_value",
asked_action_family: "turnover",
explicit_date_scope: "2020"
}
});
expect(result.planner_status).toBe("needs_clarification");
expect(result.selected_chain_id).toBe("value_flow_ranking");
expect(result.proposed_primitives).toEqual(["query_movements", "aggregate_by_axis", "probe_coverage"]);
expect(result.required_axes).toEqual(["period", "aggregate_axis", "amount", "coverage_target"]);
expect(result.catalog_review.review_status).toBe("needs_more_axes");
expect(result.reason_codes).toContain("planner_selected_top_ranked_value_flow_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_value_flow_ranking");
expect(result.selected_chain_id).not.toBe("entity_resolution");
});
it("keeps ranked value-flow ready for execution once checked period and organization are known", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
business_fact_family: "value_flow",
action_family: "turnover",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: "top_desc",
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["collect_scoped_movements", "aggregate_ranked_axis_values", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built", "data_need_graph_ranking_top_desc"]
},
turnMeaning: {
asked_domain_family: "counterparty_value",
asked_action_family: "turnover",
explicit_date_scope: "2020",
explicit_organization_scope: "ООО Альтернатива Плюс"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("value_flow_ranking");
expect(result.proposed_primitives).toEqual(["query_movements", "aggregate_by_axis", "probe_coverage"]);
expect(result.required_axes).toEqual(["organization", "period", "aggregate_axis", "amount", "coverage_target"]);
expect(result.catalog_review.review_status).toBe("catalog_compatible");
expect(result.reason_codes).toContain("planner_selected_top_ranked_value_flow_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_value_flow_ranking");
});
it("does not collapse incoming-vs-outgoing comparison into entity-resolution when no counterparty is preselected", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
business_fact_family: "value_flow",
action_family: "net_value_flow",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: "incoming_vs_outgoing",
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["collect_incoming_movements", "collect_outgoing_movements", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built", "data_need_graph_comparison_incoming_vs_outgoing"]
},
turnMeaning: {
asked_domain_family: "counterparty_value",
asked_action_family: "net_value_flow",
explicit_date_scope: "2020"
}
});
expect(result.planner_status).toBe("needs_clarification");
expect(result.selected_chain_id).toBe("value_flow_comparison");
expect(result.proposed_primitives).toEqual(["query_movements", "probe_coverage"]);
expect(result.required_axes).toEqual(["period", "amount", "coverage_target"]);
expect(result.reason_codes).toContain("planner_selected_bidirectional_value_flow_comparison_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_value_flow_comparison");
expect(result.selected_chain_id).not.toBe("entity_resolution");
});
it("keeps bidirectional comparison ready for execution once checked period and organization are known", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
business_fact_family: "value_flow",
action_family: "net_value_flow",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: "incoming_vs_outgoing",
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["collect_incoming_movements", "collect_outgoing_movements", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built", "data_need_graph_comparison_incoming_vs_outgoing"]
},
turnMeaning: {
asked_domain_family: "counterparty_value",
asked_action_family: "net_value_flow",
explicit_date_scope: "2020",
explicit_organization_scope: "ООО Альтернатива Плюс"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("value_flow_comparison");
expect(result.proposed_primitives).toEqual(["query_movements", "probe_coverage"]);
expect(result.required_axes).toEqual(["organization", "period", "amount", "coverage_target"]);
expect(result.catalog_review.review_status).toBe("catalog_compatible");
expect(result.reason_codes).toContain("planner_selected_bidirectional_value_flow_comparison_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_value_flow_comparison");
});
it("builds an inference-safe lifecycle plan with evidence explanation", () => {
const result = planAssistantMcpDiscovery({
turnMeaning: {
asked_domain_family: "counterparty_lifecycle",
asked_action_family: "activity_duration",
explicit_entity_candidates: ["SVK"]
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.proposed_primitives).toEqual([
"resolve_entity_reference",
"query_documents",
"probe_coverage",
"explain_evidence_basis"
]);
expect(result.required_axes).toEqual([
"counterparty",
"document_date",
"coverage_target",
"evidence_basis",
"activity_window",
"legal_fact_boundary"
]);
expect(result.reason_codes).toContain("planner_lifecycle_bounded_activity_window_template");
expect(result.reason_codes).toContain("planner_lifecycle_legal_fact_boundary_required");
});
it("instantiates inventory stock snapshot from the catalog fabric", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
business_fact_family: "inventory_stock_snapshot",
action_family: "stock_snapshot",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: [
"fetch_scoped_movements",
"aggregate_checked_amounts",
"probe_coverage",
"explain_evidence_basis"
],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_stock_snapshot"],
reason_codes: ["data_need_graph_built", "data_need_graph_family_inventory_stock_snapshot"]
},
turnMeaning: {
asked_domain_family: "inventory_stock",
asked_action_family: "stock_snapshot",
explicit_organization_scope: "ООО Альтернатива Плюс",
explicit_date_scope: "2021-09-30"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("inventory_stock_snapshot");
expect(result.proposed_primitives).toEqual([
"query_movements",
"aggregate_by_axis",
"probe_coverage",
"explain_evidence_basis"
]);
expect(result.required_axes).toEqual([
"organization",
"period",
"as_of_date",
"warehouse",
"aggregate_axis",
"quantity",
"coverage_target",
"evidence_basis"
]);
expect(result.reason_codes).toContain("planner_selected_inventory_stock_snapshot_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_inventory_stock_snapshot");
});
it("instantiates inventory provenance and sale-trace chains from reviewed templates", () => {
const provenance = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: ["Столешница 600"],
business_fact_family: "inventory_purchase_provenance",
action_family: "purchase_provenance",
aggregation_need: null,
time_scope_need: null,
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: [
"resolve_entity_reference",
"fetch_scoped_documents",
"drilldown_related_objects",
"probe_coverage",
"explain_evidence_basis"
],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unproven_supplier_attribution"],
reason_codes: ["data_need_graph_built", "data_need_graph_family_inventory_purchase_provenance"]
},
turnMeaning: {
asked_domain_family: "inventory_stock",
asked_action_family: "purchase_provenance",
explicit_entity_candidates: ["Столешница 600"]
}
});
const saleTrace = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: ["Столешница 600"],
business_fact_family: "inventory_sale_trace",
action_family: "sale_trace",
aggregation_need: null,
time_scope_need: null,
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: [
"resolve_entity_reference",
"fetch_scoped_documents",
"drilldown_related_objects",
"probe_coverage",
"explain_evidence_basis"
],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unproven_buyer_or_sale_trace"],
reason_codes: ["data_need_graph_built", "data_need_graph_family_inventory_sale_trace"]
},
turnMeaning: {
asked_domain_family: "inventory_stock",
asked_action_family: "sale_trace",
explicit_entity_candidates: ["Столешница 600"]
}
});
expect(provenance.planner_status).toBe("ready_for_execution");
expect(provenance.selected_chain_id).toBe("inventory_purchase_provenance");
expect(provenance.proposed_primitives).toEqual([
"resolve_entity_reference",
"query_documents",
"drilldown_related_objects",
"probe_coverage",
"explain_evidence_basis"
]);
expect(provenance.reason_codes).toContain("planner_instantiated_catalog_chain_template_inventory_purchase_provenance");
expect(saleTrace.planner_status).toBe("ready_for_execution");
expect(saleTrace.selected_chain_id).toBe("inventory_sale_trace");
expect(saleTrace.proposed_primitives).toEqual([
"resolve_entity_reference",
"query_documents",
"drilldown_related_objects",
"probe_coverage",
"explain_evidence_basis"
]);
expect(saleTrace.reason_codes).toContain("planner_instantiated_catalog_chain_template_inventory_sale_trace");
});
it("uses metadata-only planning when the user asks about available schema surface", () => {
const result = planAssistantMcpDiscovery({
turnMeaning: {
asked_domain_family: "metadata",
asked_action_family: "inspect_catalog"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.proposed_primitives).toEqual(["inspect_1c_metadata"]);
expect(result.required_axes).toEqual(["metadata_scope"]);
expect(result.catalog_review.evidence_floors.inspect_1c_metadata).toBe("source_summary");
});
it("keeps broad metadata surface inspection on inspect_1c_metadata", () => {
const result = planAssistantMcpDiscovery({
turnMeaning: {
asked_domain_family: "metadata",
asked_action_family: "inspect_surface",
explicit_entity_candidates: ["НДС"]
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.semantic_data_need).toBe("1C metadata evidence");
expect(result.proposed_primitives).toEqual(["inspect_1c_metadata"]);
expect(result.proposed_primitives).not.toContain("query_documents");
expect(result.proposed_primitives).not.toContain("query_movements");
expect(result.reason_codes).toContain("planner_selected_metadata_recipe");
});
it("keeps metadata document inspection on inspect_1c_metadata instead of query_documents", () => {
const result = planAssistantMcpDiscovery({
turnMeaning: {
asked_domain_family: "metadata",
asked_action_family: "inspect_documents"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.proposed_primitives).toEqual(["inspect_1c_metadata"]);
expect(result.proposed_primitives).not.toContain("query_documents");
});
it("keeps metadata lane-choice clarification in needs_clarification without launching MCP primitives", () => {
const result = planAssistantMcpDiscovery({
turnMeaning: {
asked_domain_family: "metadata",
asked_action_family: "resolve_next_lane",
explicit_entity_candidates: ["SVK"],
explicit_date_scope: "2020",
unsupported_but_understood_family: "metadata_lane_choice_clarification"
}
});
expect(result.planner_status).toBe("needs_clarification");
expect(result.semantic_data_need).toBe("metadata lane clarification");
expect(result.selected_chain_id).toBe("metadata_lane_clarification");
expect(result.selected_chain_summary).toContain("choose the next data lane");
expect(result.proposed_primitives).toEqual([]);
expect(result.required_axes).toEqual(["counterparty", "period", "lane_family_choice"]);
expect(result.discovery_plan.plan_status).toBe("needs_clarification");
expect(result.reason_codes).toContain("planner_selected_metadata_lane_clarification_recipe");
expect(result.reason_codes).toContain("planner_needs_more_user_or_scope_context");
});
it("does not mark an unclassified turn as executable without turn meaning context", () => {
const result = planAssistantMcpDiscovery({});
expect(result.planner_status).toBe("needs_clarification");
expect(result.discovery_plan.plan_status).toBe("needs_clarification");
expect(result.reason_codes).toContain("planner_needs_more_user_or_scope_context");
});
it("exposes an explicit entity-resolution chain instead of silently collapsing into a lifecycle lane", () => {
const result = planAssistantMcpDiscovery({
turnMeaning: {
explicit_entity_candidates: ["SVK"]
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.semantic_data_need).toBe("entity discovery evidence");
expect(result.selected_chain_id).toBe("entity_resolution");
expect(result.selected_chain_summary).toContain("resolve the most relevant 1C reference");
expect(result.proposed_primitives).toEqual(["search_business_entity", "resolve_entity_reference", "probe_coverage"]);
});
it("keeps organization-scoped one-sided value-flow totals executable without forcing a counterparty", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
business_fact_family: "value_flow",
action_family: "turnover",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["collect_scoped_movements", "aggregate_checked_amounts", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built", "data_need_graph_open_scope_total_without_subject"]
},
turnMeaning: {
asked_domain_family: "counterparty_value",
asked_action_family: "turnover",
explicit_date_scope: "2020",
explicit_organization_scope: "ООО Альтернатива Плюс"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.semantic_data_need).toBe("organization-scoped value-flow evidence");
expect(result.selected_chain_id).toBe("value_flow");
expect(result.proposed_primitives).toEqual(["query_movements", "aggregate_by_axis", "probe_coverage"]);
expect(result.required_axes).toEqual(["organization", "period", "aggregate_axis", "amount", "coverage_target"]);
expect(result.catalog_review.review_status).toBe("catalog_compatible");
expect(result.reason_codes).toContain("planner_selected_open_scope_value_flow_total_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_value_flow");
});
it("keeps generic one-sided open totals in organization clarification instead of forcing entity resolution", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
business_fact_family: "value_flow",
action_family: "turnover",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: null,
proof_expectation: "clarification_required",
clarification_gaps: ["organization"],
decomposition_candidates: ["collect_scoped_movements", "aggregate_checked_amounts", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: [
"data_need_graph_built",
"data_need_graph_open_scope_total_without_subject",
"data_need_graph_open_scope_total_needs_organization"
]
},
turnMeaning: {
asked_domain_family: "counterparty_value",
asked_action_family: "turnover",
explicit_date_scope: "2020"
}
});
expect(result.planner_status).toBe("needs_clarification");
expect(result.selected_chain_id).toBe("value_flow");
expect(result.proposed_primitives).toEqual(["query_movements", "aggregate_by_axis", "probe_coverage"]);
expect(result.required_axes).toEqual(["period", "organization", "aggregate_axis", "amount", "coverage_target"]);
expect(result.catalog_review.review_status).toBe("needs_more_axes");
expect(result.catalog_review.missing_axes_by_primitive.query_movements).toContainEqual(["organization"]);
expect(result.reason_codes).toContain("planner_selected_open_scope_value_flow_total_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_value_flow");
expect(result.selected_chain_id).not.toBe("entity_resolution");
});
it("treats all-time organization-scoped open totals as execution-ready without reintroducing a fake period gap", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
business_fact_family: "value_flow",
action_family: "turnover",
aggregation_need: null,
time_scope_need: "all_time_scope",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["collect_scoped_movements", "aggregate_checked_amounts", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: [
"data_need_graph_built",
"data_need_graph_open_scope_total_without_subject",
"data_need_graph_all_time_scope_hint"
]
},
turnMeaning: {
asked_domain_family: "counterparty_value",
asked_action_family: "turnover",
explicit_organization_scope: "ООО Альтернатива Плюс"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.semantic_data_need).toBe("organization-scoped value-flow evidence");
expect(result.selected_chain_id).toBe("value_flow");
expect(result.proposed_primitives).toEqual(["query_movements", "aggregate_by_axis", "probe_coverage"]);
expect(result.required_axes).toEqual([
"organization",
"all_time_scope",
"aggregate_axis",
"amount",
"coverage_target"
]);
expect(result.catalog_review.review_status).toBe("catalog_compatible");
expect(result.reason_codes).toContain("planner_selected_open_scope_value_flow_total_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_value_flow");
});
it("keeps metadata-scoped movement evidence in clarification instead of forcing entity resolution", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
metadata_scope_hint: "НДС",
subject_resolution_optional: true,
business_fact_family: "movement_evidence",
action_family: "list_movements",
aggregation_need: null,
time_scope_need: "period_required",
comparison_need: null,
ranking_need: null,
proof_expectation: "clarification_required",
clarification_gaps: ["organization", "period"],
decomposition_candidates: ["fetch_scoped_movements", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: [
"data_need_graph_built",
"data_need_graph_metadata_scoped_open_lane_without_subject"
]
},
turnMeaning: {
asked_domain_family: "movements",
asked_action_family: "list_movements",
metadata_scope_hint: "НДС",
subject_resolution_optional: true,
unsupported_but_understood_family: "movement_evidence"
}
});
expect(result.planner_status).toBe("needs_clarification");
expect(result.selected_chain_id).toBe("movement_evidence");
expect(result.proposed_primitives).toEqual(["query_movements", "probe_coverage"]);
expect(result.required_axes).toEqual(["metadata_scope", "organization", "coverage_target"]);
expect(result.reason_codes).toContain("planner_selected_metadata_scoped_movement_from_data_need_graph");
expect(result.selected_chain_id).not.toBe("entity_resolution");
});
it("keeps metadata-scoped movement evidence execution-ready once organization and period are known", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
metadata_scope_hint: "НДС",
subject_resolution_optional: true,
business_fact_family: "movement_evidence",
action_family: "list_movements",
aggregation_need: null,
time_scope_need: "explicit_period",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["fetch_scoped_movements", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: [
"data_need_graph_built",
"data_need_graph_metadata_scoped_open_lane_without_subject"
]
},
turnMeaning: {
asked_domain_family: "movements",
asked_action_family: "list_movements",
metadata_scope_hint: "НДС",
subject_resolution_optional: true,
explicit_organization_scope: "ООО Альтернатива Плюс",
explicit_date_scope: "2020",
unsupported_but_understood_family: "movement_evidence"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("movement_evidence");
expect(result.proposed_primitives).toEqual(["query_movements", "probe_coverage"]);
expect(result.required_axes).toEqual(["organization", "period", "metadata_scope", "coverage_target"]);
expect(result.catalog_review.review_status).toBe("catalog_compatible");
expect(result.reason_codes).toContain("planner_selected_metadata_scoped_movement_from_data_need_graph");
});
it("keeps metadata-scoped document evidence execution-ready with all-time scope once organization is known", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
metadata_scope_hint: "НДС",
subject_resolution_optional: true,
business_fact_family: "document_evidence",
action_family: "list_documents",
aggregation_need: null,
time_scope_need: "all_time_scope",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["fetch_scoped_documents", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: [
"data_need_graph_built",
"data_need_graph_metadata_scoped_open_lane_without_subject",
"data_need_graph_all_time_scope_hint"
]
},
turnMeaning: {
asked_domain_family: "documents",
asked_action_family: "list_documents",
metadata_scope_hint: "НДС",
subject_resolution_optional: true,
explicit_organization_scope: "ООО Альтернатива Плюс",
unsupported_but_understood_family: "document_evidence"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("document_evidence");
expect(result.proposed_primitives).toEqual(["query_documents", "probe_coverage"]);
expect(result.required_axes).toEqual(["organization", "metadata_scope", "all_time_scope", "coverage_target"]);
expect(result.catalog_review.review_status).toBe("catalog_compatible");
expect(result.reason_codes).toContain("planner_selected_metadata_scoped_document_from_data_need_graph");
});
});