NODEDC_1C/llm_normalizer/backend/tests/addressTruthGatePolicy.test.ts

76 lines
2.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { resolveAddressTruthGate } from "../src/services/addressTruthGatePolicy";
describe("address truth gate policy", () => {
it("treats factual exact no-match as confirmed negative with reusable root scope", () => {
const gate = resolveAddressTruthGate({
intent: "open_items_by_counterparty_or_contract",
filters: {
account: "60",
period_from: "2022-08-01",
period_to: "2022-08-31"
},
selectedRecipe: "open_items_by_counterparty_or_contract",
rowsMatched: 0,
limitedReasonCategory: "empty_match",
runtimeReadiness: "LIVE_QUERYABLE_WITH_LIMITS",
reasons: ["open_items_account_exact_negative_response"],
routeExpectationStatus: "matched",
replyType: "factual"
});
expect(gate.truth_gate_status).toBe("full_confirmed");
expect(gate.carryover_eligibility).toBe("root_only");
expect(gate.blocked_or_limited_explanation).toBeNull();
expect(gate.reason_codes).toContain("limited_category_empty_match");
});
it("keeps selected-item limited answers object-scoped", () => {
const gate = resolveAddressTruthGate({
intent: "inventory_sale_trace_for_item",
filters: {
item: "Рабочая станция"
},
semanticFrame: {
scope_kind: "selected_object_scope",
anchor_kind: "selected_object",
anchor_value: "Рабочая станция",
date_scope_kind: "explicit",
date_basis_hint: "explicit_as_of_date",
self_scope_detected: false,
selected_object_scope_detected: true
},
selectedRecipe: "inventory_sale_trace_for_item",
rowsMatched: 0,
limitedReasonCategory: "empty_match",
runtimeReadiness: "LIVE_QUERYABLE_WITH_LIMITS",
limitations: ["no_rows_after_recipe_and_scope_filter"],
routeExpectationStatus: "matched",
replyType: "partial_coverage"
});
expect(gate.truth_gate_status).toBe("partial_supported");
expect(gate.carryover_eligibility).toBe("object_only");
expect(gate.blocked_or_limited_explanation).toBe("evidence_or_coverage_is_partial");
});
it("blocks missing-anchor clarifications instead of pretending they are reusable evidence", () => {
const gate = resolveAddressTruthGate({
intent: "inventory_purchase_provenance_for_item",
selectedRecipe: "inventory_purchase_provenance_for_item",
rowsMatched: 0,
limitedReasonCategory: "missing_anchor",
runtimeReadiness: "LIVE_QUERYABLE_WITH_LIMITS",
missingRequiredFilters: ["item"],
limitations: ["missing_required_filters"],
routeExpectationStatus: "matched",
replyType: "partial_coverage"
});
expect(gate.truth_gate_status).toBe("blocked_missing_anchor");
expect(gate.carryover_eligibility).toBe("none");
expect(gate.blocked_or_limited_explanation).toBe("required_anchor_missing");
expect(gate.reason_codes).toContain("missing_filter_item");
});
});