АРЧ АП11 - Вынести coverage evidence contract для exact lane и завершить phase 4 агентным прогоном

This commit is contained in:
2026-04-17 11:14:10 +03:00
parent 1484c2375f
commit b3572d9d11
16 changed files with 1357 additions and 375 deletions
@@ -114,6 +114,8 @@ describe("counterparty shipment item flow and open-items routing", () => {
expect(result?.handled).toBe(true);
expect(result?.response_type).toBe("FACTUAL_LIST");
expect(result?.debug.detected_intent).toBe("list_documents_by_counterparty");
expect(result?.debug.address_coverage_evidence_v1?.coverage_status).toBe("full");
expect(result?.debug.address_coverage_evidence_v1?.evidence_basis).toBe("matched_rows");
expect(result?.debug.address_truth_gate_v1?.truth_gate_status).toBe("full_confirmed");
expect(String(result?.reply_text ?? "")).toContain("Контрагент: Чепурнов П.Д.");
expect(String(result?.reply_text ?? "")).toContain("Позиции:");
@@ -204,6 +206,8 @@ describe("counterparty shipment item flow and open-items routing", () => {
expect(String(result?.reply_text ?? "")).toContain("исходящих оплат поставщику");
expect(String(result?.reply_text ?? "")).toContain("возвратов от поставщика");
expect(String(result?.reply_text ?? "")).toContain("Договор:");
expect(result?.debug.address_coverage_evidence_v1?.coverage_status).toBe("blocked");
expect(result?.debug.address_coverage_evidence_v1?.evidence_basis).toBe("unknown");
expect(result?.debug.reasons).toContain("counterparty_item_flow_no_supply_but_bank_activity_explained");
expect(executeAddressMcpQueryMock.mock.calls.length).toBeGreaterThanOrEqual(2);
@@ -0,0 +1,90 @@
import { describe, expect, it } from "vitest";
import { resolveAddressCoverageEvidence } from "../src/services/addressCoverageEvidencePolicy";
describe("address coverage evidence policy", () => {
it("marks matched inventory balance replies as full confirmed-balance evidence", () => {
const contract = resolveAddressCoverageEvidence({
intent: "inventory_on_hand_as_of_date",
selectedRecipe: "address_inventory_on_hand_as_of_date_v1",
filters: {
as_of_date: "2021-03-31",
period_from: "2021-03-01",
period_to: "2021-03-31"
},
responseType: "FACTUAL_SUMMARY",
rowsMatched: 3
});
expect(contract.requested_result_mode).toBe("confirmed_balance");
expect(contract.result_mode).toBe("confirmed_balance");
expect(contract.coverage_status).toBe("full");
expect(contract.evidence_strength).toBe("strong");
expect(contract.balance_confirmed).toBe(true);
expect(contract.evidence_basis).toBe("matched_rows");
expect(contract.as_of_date_basis).toBe("explicit_as_of_date");
});
it("treats factual exact negatives as full confirmed-balance evidence instead of partial noise", () => {
const contract = resolveAddressCoverageEvidence({
intent: "payables_confirmed_as_of_date",
selectedRecipe: "address_payables_confirmed_as_of_date_v1",
filters: {
as_of_date: "2020-03-31",
period_from: "2020-03-01",
period_to: "2020-03-31"
},
responseType: "FACTUAL_SUMMARY",
rowsMatched: 0
});
expect(contract.result_mode).toBe("confirmed_balance");
expect(contract.coverage_status).toBe("full");
expect(contract.balance_confirmed).toBe(true);
expect(contract.evidence_basis).toBe("exact_negative");
expect(contract.reason_codes).toContain("evidence_basis_exact_negative");
});
it("keeps heuristic candidate answers partial even when rows exist", () => {
const contract = resolveAddressCoverageEvidence({
intent: "open_items_by_counterparty_or_contract",
selectedRecipe: "address_open_items_by_party_or_contract_v1",
filters: {
account: "60",
period_from: "2022-08-01",
period_to: "2022-08-31"
},
responseType: "FACTUAL_LIST",
rowsMatched: 4
});
expect(contract.requested_result_mode).toBe("confirmed_balance");
expect(contract.result_mode).toBe("confirmed_balance");
expect(contract.coverage_status).toBe("partial");
expect(contract.evidence_strength).toBe("medium");
expect(contract.balance_confirmed).toBe(false);
});
it("marks limited replies as blocked or partial according to the effective result mode", () => {
const confirmed = resolveAddressCoverageEvidence({
intent: "inventory_on_hand_as_of_date",
selectedRecipe: "address_inventory_on_hand_as_of_date_v1",
filters: {
as_of_date: "2021-03-31"
},
responseType: "LIMITED_WITH_REASON",
rowsMatched: 0
});
const heuristic = resolveAddressCoverageEvidence({
intent: "list_open_contracts",
selectedRecipe: "address_list_open_contracts_v1",
filters: {},
responseType: "LIMITED_WITH_REASON",
rowsMatched: 0
});
expect(confirmed.coverage_status).toBe("blocked");
expect(confirmed.evidence_basis).toBe("limited_response");
expect(heuristic.coverage_status).toBe("partial");
expect(heuristic.result_mode).toBe("heuristic_candidates");
});
});
@@ -107,6 +107,8 @@ describe("inventory selected-object follow-up", () => {
expect(result?.debug.capability_route_mode).toBe("exact");
expect(result?.debug.reasons).toContain("period_window_auto_broadened_to_available_data");
expect(result?.debug.limitations).toContain("period_window_auto_broadened_to_available_data");
expect(result?.debug.address_coverage_evidence_v1?.coverage_status).toBe("full");
expect(result?.debug.address_coverage_evidence_v1?.evidence_basis).toBe("matched_rows");
expect(result?.debug.address_truth_gate_v1?.truth_gate_status).toBe("limited_temporal_or_contextual");
expect(result?.debug.address_truth_gate_v1?.carryover_eligibility).toBe("object_only");
const replyLines = String(result?.reply_text ?? "").split("\n");
@@ -94,6 +94,18 @@ describe("assistant truth answer policy runtime adapter", () => {
addressDebug: {
capability_id: "inventory_counterparty_item_flow",
rows_matched: 0,
address_coverage_evidence_v1: {
schema_version: "address_coverage_evidence_v1",
policy_owner: "addressCoverageEvidencePolicy",
requested_result_mode: "confirmed_balance",
result_mode: "confirmed_balance",
evidence_strength: "medium",
balance_confirmed: true,
as_of_date_basis: "period_end",
coverage_status: "full",
evidence_basis: "exact_negative",
reason_codes: ["evidence_basis_exact_negative"]
},
address_truth_gate_v1: {
schema_version: "address_truth_gate_v1",
policy_owner: "addressTruthGatePolicy",
@@ -111,8 +123,10 @@ describe("assistant truth answer policy runtime adapter", () => {
expect(policy.truth_gate.coverage_status).toBe("full");
expect(policy.truth_gate.grounding_status).toBe("grounded");
expect(policy.truth_gate.truth_mode).toBe("confirmed");
expect(policy.truth_gate.evidence_grade).toBe("medium");
expect(policy.truth_gate.carryover_eligibility).toBe("root_only");
expect(policy.truth_gate.reason_codes).toContain("counterparty_item_flow_exact_negative_response");
expect(policy.truth_gate.reason_codes).toContain("evidence_basis_exact_negative");
expect(policy.answer_shape.answer_shape).toBe("confirmed_factual");
expect(policy.answer_shape.may_power_followup).toBe(true);
});