import { describe, expect, it } from "vitest"; import { ASSISTANT_MCP_DISCOVERY_PRIMITIVES, buildAssistantMcpDiscoveryPlan } from "../src/services/assistantMcpDiscoveryPolicy"; import { buildAssistantMcpCatalogIndex, getAssistantMcpCatalogChainTemplate, getAssistantMcpCatalogPrimitive, reviewAssistantMcpDiscoveryPlanAgainstCatalog, searchAssistantMcpCatalogPrimitivesByDecompositionCandidates, searchAssistantMcpCatalogPrimitivesByFactAxis, searchAssistantMcpCatalogPrimitivesByMetadataSurface } from "../src/services/assistantMcpCatalogIndex"; describe("assistant MCP catalog index", () => { it("declares a catalog contract for every reviewed discovery primitive", () => { const index = buildAssistantMcpCatalogIndex(); const primitiveIds = index.primitives.map((entry) => entry.primitive_id); expect(index.reason_codes).toContain("catalog_covers_all_discovery_primitives"); expect(index.reason_codes).toContain("catalog_chain_templates_reference_reviewed_primitives"); expect(primitiveIds).toEqual([...ASSISTANT_MCP_DISCOVERY_PRIMITIVES]); for (const entry of index.primitives) { expect(entry.safe_for_model_planning).toBe(true); expect(entry.runtime_must_execute).toBe(true); expect(entry.decomposition_hints.length).toBeGreaterThan(0); expect(Array.isArray(entry.supported_fact_families)).toBe(true); expect(Array.isArray(entry.supported_action_families)).toBe(true); expect(Array.isArray(entry.planning_tags)).toBe(true); expect(entry.required_axes_any_of.length).toBeGreaterThan(0); expect(entry.output_fact_kinds.length).toBeGreaterThan(0); } expect(index.chain_templates.map((entry) => entry.chain_id)).toEqual([ "metadata_inspection", "catalog_drilldown", "entity_resolution", "document_evidence", "movement_evidence", "value_flow", "value_flow_comparison", "value_flow_ranking", "lifecycle" ]); for (const template of index.chain_templates) { expect(template.safe_for_model_planning).toBe(true); expect(template.requires_evidence_gate).toBe(true); expect(template.semantic_data_need.length).toBeGreaterThan(0); expect(template.chain_summary.length).toBeGreaterThan(0); expect(template.fallback_primitives.length).toBeGreaterThan(0); for (const primitive of template.fallback_primitives) { expect(primitiveIds).toContain(primitive); } } }); it("exposes reusable chain templates for planner route-fabric selection", () => { const documentTemplate = getAssistantMcpCatalogChainTemplate("document_evidence"); const movementTemplate = getAssistantMcpCatalogChainTemplate("movement_evidence"); const valueFlowTemplate = getAssistantMcpCatalogChainTemplate("value_flow"); const valueFlowComparisonTemplate = getAssistantMcpCatalogChainTemplate("value_flow_comparison"); const valueFlowRankingTemplate = getAssistantMcpCatalogChainTemplate("value_flow_ranking"); expect(documentTemplate.fallback_primitives).toEqual([ "resolve_entity_reference", "query_documents", "probe_coverage" ]); expect(movementTemplate.fallback_primitives).toEqual([ "resolve_entity_reference", "query_movements", "probe_coverage" ]); expect(valueFlowTemplate.base_required_axes).toEqual(["aggregate_axis", "amount", "coverage_target"]); expect(valueFlowComparisonTemplate.fallback_primitives).toEqual(["query_movements", "probe_coverage"]); expect(valueFlowRankingTemplate.fallback_primitives).toEqual([ "query_movements", "aggregate_by_axis", "probe_coverage" ]); }); it("can search reviewed primitives from data-need decomposition candidates", () => { const primitives = searchAssistantMcpCatalogPrimitivesByDecompositionCandidates({ decomposition_candidates: [ "resolve_entity_reference", "collect_scoped_movements", "aggregate_checked_amounts", "probe_coverage" ] }); expect(primitives).toEqual([ "resolve_entity_reference", "query_movements", "aggregate_by_axis", "probe_coverage" ]); }); it("can suppress aggregate_by_axis for decomposition shapes that derive comparison without an aggregate primitive", () => { const primitives = searchAssistantMcpCatalogPrimitivesByDecompositionCandidates({ decomposition_candidates: [ "collect_incoming_movements", "collect_outgoing_movements", "aggregate_by_month", "probe_coverage" ], allow_aggregate_by_axis: false }); expect(primitives).toEqual(["query_movements", "probe_coverage"]); }); it("can search reviewed primitives directly from fact family and required axes", () => { const primitives = searchAssistantMcpCatalogPrimitivesByFactAxis({ business_fact_family: "document_evidence", action_family: "list_documents", has_subject_candidates: true, required_axes: ["counterparty", "period", "coverage_target"] }); expect(primitives).toEqual(["resolve_entity_reference", "query_documents", "probe_coverage"]); }); it("treats all-time organization-scoped value-flow as catalog-compatible without inventing a fake period axis", () => { const primitives = searchAssistantMcpCatalogPrimitivesByFactAxis({ business_fact_family: "value_flow", action_family: "turnover", has_subject_candidates: false, required_axes: ["organization", "all_time_scope", "aggregate_axis", "amount", "coverage_target"] }); expect(primitives).toEqual(["query_movements", "aggregate_by_axis", "probe_coverage"]); }); it("can search reviewed primitives directly from a confirmed document metadata surface", () => { const primitives = searchAssistantMcpCatalogPrimitivesByMetadataSurface({ downstream_route_family: "document_evidence", selected_entity_set: "Document", selected_surface_objects: ["Document.InvoiceIssued"], recommended_next_primitive: "query_documents", required_axes: ["counterparty", "period", "coverage_target"] }); expect(primitives).toEqual(["query_documents", "resolve_entity_reference", "probe_coverage"]); }); it("can search reviewed primitives directly from a confirmed movement metadata surface", () => { const primitives = searchAssistantMcpCatalogPrimitivesByMetadataSurface({ downstream_route_family: "movement_evidence", selected_entity_set: "AccumulationRegister", selected_surface_objects: ["Register.BankOperations"], recommended_next_primitive: "query_movements", required_axes: ["counterparty", "period", "coverage_target"] }); expect(primitives).toEqual(["query_movements", "resolve_entity_reference", "probe_coverage"]); }); it("can search reviewed primitives directly from a confirmed catalog metadata surface without inventing an unsupported drilldown primitive", () => { const primitives = searchAssistantMcpCatalogPrimitivesByMetadataSurface({ downstream_route_family: "catalog_drilldown", selected_entity_set: "Catalog", selected_surface_objects: ["Catalog.Counterparties"], recommended_next_primitive: "drilldown_related_objects", required_axes: ["metadata_scope"] }); expect(primitives).toEqual(["inspect_1c_metadata"]); }); it("marks a counterparty turnover discovery plan as catalog-compatible when required axes exist", () => { const plan = buildAssistantMcpDiscoveryPlan({ semanticDataNeed: "counterparty turnover evidence", turnMeaning: { asked_domain_family: "counterparty_value", asked_action_family: "turnover", explicit_entity_candidates: ["SVK"] }, proposedPrimitives: ["resolve_entity_reference", "query_movements", "aggregate_by_axis"], requiredAxes: ["counterparty", "period", "aggregate_axis", "amount"] }); const review = reviewAssistantMcpDiscoveryPlanAgainstCatalog(plan); expect(review.review_status).toBe("catalog_compatible"); expect(review.reason_codes).toContain("catalog_plan_compatible"); expect(review.missing_axes_by_primitive).toEqual({}); expect(review.evidence_floors.query_movements).toBe("rows_matched"); }); it("asks for more axes before document discovery can run safely", () => { const plan = buildAssistantMcpDiscoveryPlan({ semanticDataNeed: "document evidence", turnMeaning: { asked_domain_family: "counterparty_documents", asked_action_family: "list_documents" }, proposedPrimitives: ["query_documents"], requiredAxes: ["amount"] }); const review = reviewAssistantMcpDiscoveryPlanAgainstCatalog(plan); expect(review.review_status).toBe("needs_more_axes"); expect(review.reason_codes).toContain("catalog_required_axes_missing_for_primitive"); expect(review.missing_axes_by_primitive.query_documents).toEqual([ ["document"], ["counterparty"], ["contract"], ["period", "organization"], ["all_time_scope", "counterparty"], ["all_time_scope", "organization"] ]); }); it("marks an all-time organization-scoped value-flow plan as catalog-compatible without requiring an explicit period", () => { const plan = buildAssistantMcpDiscoveryPlan({ semanticDataNeed: "organization-scoped value-flow evidence", turnMeaning: { asked_domain_family: "counterparty_value", asked_action_family: "turnover", explicit_organization_scope: "ООО Альтернатива Плюс" }, proposedPrimitives: ["query_movements", "aggregate_by_axis", "probe_coverage"], requiredAxes: ["organization", "all_time_scope", "aggregate_axis", "amount", "coverage_target"] }); const review = reviewAssistantMcpDiscoveryPlanAgainstCatalog(plan); expect(review.review_status).toBe("catalog_compatible"); expect(review.reason_codes).toContain("catalog_plan_compatible"); expect(review.missing_axes_by_primitive).toEqual({}); }); it("marks an all-time organization-scoped document plan as catalog-compatible without requiring an explicit period", () => { const plan = buildAssistantMcpDiscoveryPlan({ semanticDataNeed: "document evidence", turnMeaning: { asked_domain_family: "documents", asked_action_family: "list_documents", explicit_organization_scope: "ООО Альтернатива Плюс", metadata_scope_hint: "НДС", subject_resolution_optional: true }, proposedPrimitives: ["query_documents", "probe_coverage"], requiredAxes: ["organization", "all_time_scope", "metadata_scope", "coverage_target"] }); const review = reviewAssistantMcpDiscoveryPlanAgainstCatalog(plan); expect(review.review_status).toBe("catalog_compatible"); expect(review.reason_codes).toContain("catalog_plan_compatible"); expect(review.missing_axes_by_primitive).toEqual({}); }); it("preserves source-summary evidence floors for metadata and coverage primitives", () => { expect(getAssistantMcpCatalogPrimitive("inspect_1c_metadata").evidence_floor).toBe("source_summary"); expect(getAssistantMcpCatalogPrimitive("probe_coverage").evidence_floor).toBe("source_summary"); expect(getAssistantMcpCatalogPrimitive("resolve_entity_reference").evidence_floor).toBe("rows_matched"); }); it("turns a non-allowed discovery plan into a catalog-level blocked review", () => { const plan = buildAssistantMcpDiscoveryPlan({ semanticDataNeed: "raw model sql", turnMeaning: { asked_domain_family: "counterparty_value", asked_action_family: "turnover", explicit_entity_candidates: ["SVK"] }, proposedPrimitives: ["raw_sql"], requiredAxes: ["counterparty"] }); const review = reviewAssistantMcpDiscoveryPlanAgainstCatalog(plan); expect(plan.plan_status).toBe("blocked"); expect(review.review_status).toBe("catalog_blocked"); expect(review.reason_codes).toContain("catalog_review_received_non_allowed_plan"); expect(review.reason_codes).toContain("catalog_plan_blocked"); }); });