102 lines
4.0 KiB
TypeScript
102 lines
4.0 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 open-items movement fallback partial even when heuristic rows are found", () => {
|
||
const gate = resolveAddressTruthGate({
|
||
intent: "open_items_by_counterparty_or_contract",
|
||
filters: {
|
||
account: "60",
|
||
period_from: "2020-08-01",
|
||
period_to: "2020-08-31",
|
||
organization: "ООО Альтернатива Плюс"
|
||
},
|
||
selectedRecipe: "address_open_items_by_party_or_contract_v1",
|
||
rowsMatched: 8,
|
||
runtimeReadiness: "LIVE_QUERYABLE_WITH_LIMITS",
|
||
reasons: [
|
||
"confirmed_balance_unavailable_fallback_to_heuristic_candidates",
|
||
"open_items_account_query_override_to_movements"
|
||
],
|
||
routeExpectationStatus: "matched",
|
||
replyType: "factual"
|
||
});
|
||
|
||
expect(gate.truth_gate_status).toBe("partial_supported");
|
||
expect(gate.carryover_eligibility).toBe("root_only");
|
||
expect(gate.blocked_or_limited_explanation).toBe("evidence_or_coverage_is_partial");
|
||
expect(gate.reason_codes).toContain("confirmed_balance_unavailable_fallback_to_heuristic_candidates");
|
||
});
|
||
|
||
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");
|
||
});
|
||
});
|