Зафиксировать семантическую целостность VAT, debt mirror и trace-ответов

This commit is contained in:
2026-05-18 10:03:58 +03:00
parent a5fa940953
commit 9c86407937
16 changed files with 333 additions and 20 deletions
@@ -119,6 +119,51 @@ describe("address follow-up temporal regressions", () => {
expect(result?.filters.extracted_filters.counterparty).toBeUndefined();
});
it("suppresses stale counterparty filters from organization-scoped short debt mirror follow-up", () => {
const result = runAddressDecomposeStage("а нам?", {
previous_intent: "payables_confirmed_as_of_date",
target_intent: "receivables_confirmed_as_of_date",
previous_filters: {
as_of_date: "2026-05-17",
organization: "ООО Альтернатива Плюс",
counterparty: "нас самый доходный клиент"
},
previous_anchor_type: "organization",
previous_anchor_value: "ООО Альтернатива Плюс"
});
expect(result).not.toBeNull();
expect(result?.intent.intent).toBe("receivables_confirmed_as_of_date");
expect(result?.filters.extracted_filters.as_of_date).toBe("2026-05-17");
expect(result?.filters.extracted_filters.organization).toBe("ООО Альтернатива Плюс");
expect(result?.filters.extracted_filters.counterparty).toBeUndefined();
expect(result?.baseReasons).toContain("counterparty_carryover_suppressed_for_short_debt_mirror");
expect(result?.baseReasons).not.toContain("counterparty_from_followup_context");
});
it("keeps resolved counterparty focus for short debt mirror follow-up", () => {
const result = runAddressDecomposeStage("а нам?", {
previous_intent: "payables_confirmed_as_of_date",
target_intent: "receivables_confirmed_as_of_date",
previous_filters: {
as_of_date: "2026-05-17",
organization: "ООО Альтернатива Плюс",
counterparty: "Группа СВК"
},
previous_anchor_type: "counterparty",
previous_anchor_value: "Группа СВК",
resolved_counterparty_from_display: true
});
expect(result).not.toBeNull();
expect(result?.intent.intent).toBe("receivables_confirmed_as_of_date");
expect(result?.filters.extracted_filters.as_of_date).toBe("2026-05-17");
expect(result?.filters.extracted_filters.organization).toBe("ООО Альтернатива Плюс");
expect(result?.filters.extracted_filters.counterparty).toBe("Группа СВК");
expect(result?.baseReasons).toContain("counterparty_from_followup_context");
expect(result?.baseReasons).not.toContain("counterparty_carryover_suppressed_for_short_debt_mirror");
});
it("keeps same-date inventory pivot anchored to the previous VAT date", () => {
const result = runAddressDecomposeStage("какие остатки по складу на эту же дату", {
previous_intent: "vat_payable_confirmed_as_of_date",
@@ -703,6 +703,7 @@ describe("inventory selected-object follow-up", () => {
expect(result?.debug.extracted_filters?.as_of_date).toBe("2020-05-31");
expect(result?.debug.reasons).toContain("inventory_selected_object_sale_trace_signal_detected");
expect(String(result?.reply_text ?? "").split("\n")[0]).toContain("ООО \\Ромашка\\");
expect(String(result?.reply_text ?? "").split("\n")[0]).toContain("без партионного учета не доказывает");
expect(String(result?.reply_text ?? "")).toContain("Документы выбытия");
});
@@ -750,6 +751,8 @@ describe("inventory selected-object follow-up", () => {
expect(result?.debug.extracted_filters?.item).toBe("Кромка с клеем 33 альмандин 137 м");
expect(result?.debug.extracted_filters?.as_of_date).toBe("2020-03-31");
expect(String(result?.reply_text ?? "")).toContain("ООО \\Покупатель\\");
expect(String(result?.reply_text ?? "")).not.toContain("покупатель определен");
expect(String(result?.reply_text ?? "")).toContain("продажный след по номенклатуре");
});
it("detaches snapshot date from execution query during sale-trace history recovery", async () => {
@@ -479,6 +479,42 @@ describe("assistantContinuityPolicy organization authority", () => {
});
});
it("does not carry MCP discovery counterparty from a stale replay-forbidden turn", () => {
const filters = resolveAddressDebugCarryoverFilters({
detected_intent: "payables_confirmed_as_of_date",
extracted_filters: {
organization: "Org Alt",
as_of_date: "2026-05-17"
},
mcp_discovery_response_applied: true,
assistant_mcp_discovery_entry_point_v1: {
entry_status: "bridge_executed",
turn_input: {
turn_meaning_ref: {
explicit_entity_candidates: ["old ranking counterparty"],
metadata_scope_hint: "old ranking counterparty",
stale_replay_forbidden: true
}
},
bridge: {
bridge_status: "answer_draft_ready",
business_fact_answer_allowed: true,
answer_draft: {
answer_mode: "confirmed_with_bounded_inference"
},
pilot: {
pilot_scope: "counterparty_value_flow_query_movements_v1"
}
}
}
});
expect(filters).toEqual({
organization: "Org Alt",
as_of_date: "2026-05-17"
});
});
it("hydrates inventory root-frame state from navigation scope and preserves derived current frame kind", () => {
const state = hydrateInventoryRootFrameState(
{
@@ -445,9 +445,12 @@ describe("assistant MCP discovery response candidate", () => {
expect(candidate.reply_text).toContain("нельзя автоматически читать как обычного клиента или поставщика");
expect(candidate.reply_text).toContain("не полный бухгалтерский рейтинг доходности");
expect(candidate.reply_text).toContain("не как чистую бухгалтерскую прибыль");
expect(candidate.reply_text).toContain("Годовое операционное нетто в широком срезе не ранжирую");
expect(candidate.reply_text).toContain("проверка достигла лимита строк");
expect(candidate.reply_text).toContain("выбрать конкретный год или квартал для дозапроса");
expect(candidate.reply_text).toContain("без выдачи непроверенного итога");
expect(candidate.reply_text).not.toContain("По расчетному операционному нетто лучший год");
expect(candidate.reply_text).not.toContain("По годам:");
expect(candidate.reply_text).not.toContain("лимит выборки MCP");
expect(candidate.reply_text).not.toContain("MCP-срез");
expect(candidate.reply_text).not.toContain("Что подтверждено:");
@@ -657,8 +657,8 @@ describe("assistant MCP discovery runtime bridge", () => {
expect(overview?.accounting_financial_result?.net_margin_to_revenue_pct).toBe(-59.41);
expect(missingFamilies).not.toContain("accounting_profit_margin");
expect(userFacing).toContain("90/91/99");
expect(userFacing).toContain("90.01");
expect(userFacing).toContain("7 136 815,85");
expect(userFacing).not.toContain("90.01");
expect(userFacing).not.toContain("operating-flow/trading-margin proxy");
expect(result.reason_codes).toContain("pilot_derived_business_overview_accounting_financial_result_from_confirmed_rows");
expect(result.reason_codes).toContain("answer_contains_business_overview_accounting_financial_result");
@@ -850,7 +850,7 @@ describe("assistant MCP discovery runtime bridge", () => {
evidence_status: "financial_institution_leads_outgoing_cash"
});
expect(missingFamilies).not.toContain("vendor_risk_procurement_quality");
expect(userFacing).toContain("procurement-concentration route");
expect(userFacing).not.toContain("procurement-concentration route");
expect(userFacing).toContain("банк/финансовая организация");
expect(userFacing).toContain("Поставщик А");
expect(userFacing).toContain("Надежность поставщиков");
@@ -1861,6 +1861,62 @@ describe("assistantTransitionPolicy", () => {
period_to: "2017-05-31"
});
});
it("retargets same-period VAT payable follow-up away from current-date payable snapshots", () => {
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({
text: "Receivables as of 2017-05-31 were collected for May.",
debug: {
detected_intent: "receivables_confirmed_as_of_date",
extracted_filters: {
organization: 'ООО "Альтернатива Плюс"',
as_of_date: "2017-05-31",
period_from: "2017-05-01",
period_to: "2017-05-31"
},
anchor_type: "organization",
anchor_value_resolved: 'ООО "Альтернатива Плюс"'
}
}),
hasAddressFollowupContextSignal: () => true,
hasReferentialPointer: () => true,
resolveAddressIntent: () => ({ intent: "unknown" }),
resolveAddressIntentFamily: (intent: unknown) => {
if (String(intent ?? "").startsWith("receivables_")) return "receivables";
if (String(intent ?? "").startsWith("vat_")) return "vat";
return null;
},
resolveAssistantTurnMeaning: () => ({
schema_version: "assistant_turn_meaning_v1",
asked_domain_family: "vat",
asked_action_family: "confirmed_snapshot",
explicit_intent_candidate: "vat_payable_confirmed_as_of_date",
explicit_entity_candidates: [],
intent_override_strength: "explicit_current_turn_intent",
stale_replay_forbidden: false
})
});
const carryover = policy.resolveAddressFollowupCarryoverContext(
"а какой ндс мы должны примерно заплатить за этот период?",
[],
"Какой НДС мы должны заплатить за текущий период?",
{
predecomposeContract: {
intent: "vat_payable_confirmed_as_of_date"
}
},
null
);
expect(carryover?.followupContext?.previous_intent).toBe("receivables_confirmed_as_of_date");
expect(carryover?.followupContext?.target_intent).toBe("vat_liability_confirmed_for_tax_period");
expect(carryover?.followupContext?.previous_filters).toMatchObject({
organization: 'ООО "Альтернатива Плюс"',
period_from: "2017-05-01",
period_to: "2017-05-31"
});
});
it("carries metadata-scoped subjectless loop state through follow-up context", () => {
const policy = buildPolicy({
findLastAddressAssistantItem: () => ({