ARCH: добавить MCP catalog index для discovery
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { ASSISTANT_MCP_DISCOVERY_PRIMITIVES, buildAssistantMcpDiscoveryPlan } from "../src/services/assistantMcpDiscoveryPolicy";
|
||||
import {
|
||||
buildAssistantMcpCatalogIndex,
|
||||
getAssistantMcpCatalogPrimitive,
|
||||
reviewAssistantMcpDiscoveryPlanAgainstCatalog
|
||||
} 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(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.required_axes_any_of.length).toBeGreaterThan(0);
|
||||
expect(entry.output_fact_kinds.length).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
|
||||
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"]
|
||||
]);
|
||||
});
|
||||
|
||||
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");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user