import { describe, expect, it } from "vitest"; import { createAssistantRoutePolicy } from "../src/services/assistantRoutePolicy"; function toNonEmptyString(value: unknown): string | null { if (value === null || value === undefined) { return null; } const text = String(value).trim(); return text.length > 0 ? text : null; } function normalizeOrganizationScopeValue(value: unknown): string | null { const text = toNonEmptyString(value); if (!text) { return null; } return text.replace(/^"+|"+$/g, "").replace(/^'+|'+$/g, ""); } function buildPolicy(overrides: Record = {}) { return createAssistantRoutePolicy({ repairAddressMojibake: (text: string) => text, findLastGroundedAddressAnswerDebug: () => null, findLastOrganizationClarificationAddressDebug: () => null, mergeKnownOrganizations: (values: unknown[]) => Array.from( new Set( (Array.isArray(values) ? values : []) .map((item) => normalizeOrganizationScopeValue(item)) .filter((item): item is string => Boolean(item)) ) ), normalizeOrganizationScopeValue, resolveOrganizationSelectionFromMessage: () => null, resolveMetaSignalSet: (input: { rawUserMessage?: string; repairedRawUserMessage?: string; effectiveAddressUserMessage?: string; repairedEffectiveAddressUserMessage?: string; }) => { const samples = [ input.rawUserMessage, input.repairedRawUserMessage, input.effectiveAddressUserMessage, input.repairedEffectiveAddressUserMessage ].join(" "); return { dataScopeMetaQuery: /РїРѕ какой компании|какая база|РїРѕ каким конторам/i.test(samples), capabilityMetaQuery: /что ты можешь|что ты умеешь/i.test(samples), metaAnswerFollowupSignal: /это РЅРѕСЂРј|что думаешь/i.test(samples), answerInspectionFollowupSignal: /это ошибка|у тебя написано кто контрагент/i.test(samples) }; }, resolveHardMetaMode: (input: { dataScopeMetaQuery?: boolean; capabilityMetaQuery?: boolean; dataRetrievalSignal?: boolean; }) => input.dataScopeMetaQuery ? "data_scope" : input.capabilityMetaQuery && !input.dataRetrievalSignal ? "capability" : null, isMetaFollowupOverGroundedAnswer: () => false, isAnswerInspectionFollowupOverGroundedAnswer: () => false, hasDataRetrievalRequestSignal: () => false, hasOrganizationFactLookupSignal: () => false, hasOrganizationFactFollowupSignal: () => false, hasAggregateBusinessAnalyticsSignal: () => false, hasStandaloneAddressTopicSignal: () => false, hasOpenContractsAddressSignal: () => false, detectAddressQuestionMode: () => ({ mode: "unsupported", confidence: "low" }), resolveAddressIntent: () => ({ intent: "unknown", confidence: "low" }), toNonEmptyString, hasStrictDeepInvestigationCue: () => false, hasStrongDataIntentSignal: () => false, hasAccountingSignal: () => false, hasDangerOrCoercionSignal: () => false, hasAddressFollowupContextSignal: () => false, hasShortDebtMirrorFollowupSignal: () => false, isInventorySelectedObjectIntent: (intent: unknown) => /inventory/i.test(String(intent ?? "")), hasShortInventoryObjectFollowupSignal: () => false, resolveRouteMemorySignals: () => ({ contextualHistoricalCapabilityFollowupDetected: false, contextualMemoryRecapFollowupDetected: false }), findLastAddressAssistantItem: () => null, hasAddressLlmPreDecomposeCandidate: () => false, resolveAddressToolGateDecision: () => ({ runAddressLane: false, decision: "skip_address_lane", reason: "no_address_signal_after_l0" }), hasSameDateAccountFollowupSignalForPredecompose: () => false, hasLooseAllTimeAddressLookupSignal: () => false, hasDeepAnalysisPreferenceSignal: () => false, hasDirectDeepAnalysisSignal: () => false, shouldEmitOrganizationSelectionReply: () => false, compactWhitespace: (text: string) => String(text ?? "").replace(/\s+/g, " ").trim(), hasDeepSessionContinuationSignal: () => false, resolveLivingAssistantModeDecision: (input: { addressLaneTriggered?: boolean }) => input.addressLaneTriggered ? { mode: "address_data", reason: "address_lane_triggered" } : { mode: "chat", reason: "living_chat_signal_detected" }, resolveProviderExecutionState: (input: { useMock?: unknown; llmPreDecomposeReason?: unknown }) => { const reason = String(input?.llmPreDecomposeReason ?? ""); return { provider_mode: Boolean(input?.useMock) ? "mock" : "unknown", normalized_provider: null, use_mock: Boolean(input?.useMock), llm_runtime_unavailable_detected: /missing api key|authentication|api key is missing/i.test(reason), living_mode_forced_deep: Boolean(input?.useMock), living_mode_forced_reason: Boolean(input?.useMock) ? "mock_mode_keeps_deep_pipeline" : null }; }, ...overrides }); } describe("assistantRoutePolicy", () => { it("routes data-scope meta question to chat contract", () => { const policy = buildPolicy(); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "РїРѕ какой компании РјС‹ можем работать?", effectiveAddressUserMessage: "РїРѕ какой компании РјС‹ можем работать?", followupContext: null, llmPreDecomposeMeta: null, useMock: false }); expect(decision.runAddressLane).toBe(false); expect(decision.toolGateReason).toBe("assistant_data_scope_query_detected"); expect(decision.livingMode).toBe("chat"); expect(decision.orchestrationContract?.hard_meta_mode).toBe("data_scope"); expect(decision.orchestrationContract?.provider_execution?.provider_mode).toBe("unknown"); }); it("keeps supported address intent in address lane", () => { const policy = buildPolicy({ detectAddressQuestionMode: () => ({ mode: "address_query", confidence: "high" }), resolveAddressIntent: () => ({ intent: "inventory_on_hand_as_of_date", confidence: "high" }), resolveAddressToolGateDecision: () => ({ runAddressLane: true, decision: "run_address_lane", reason: "address_mode_classifier_detected" }) }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "какие товары сейчас лежат РЅР° складе", effectiveAddressUserMessage: "какие товары сейчас лежат РЅР° складе", followupContext: null, llmPreDecomposeMeta: null, useMock: false }); expect(decision.runAddressLane).toBe(true); expect(decision.toolGateReason).toBe("address_mode_classifier_detected"); expect(decision.livingMode).toBe("address_data"); expect(decision.orchestrationContract?.semantic_route_arbitration?.supported_address_intent_detected).toBe(true); }); it("uses internal route-policy tool gate when no external override is provided", () => { const policy = buildPolicy({ resolveAddressToolGateDecision: undefined, detectAddressQuestionMode: () => ({ mode: "address_query", confidence: "high" }), resolveAddressIntent: () => ({ intent: "inventory_on_hand_as_of_date", confidence: "high" }), hasAddressLlmPreDecomposeCandidate: () => true }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "какие остатки на складе", effectiveAddressUserMessage: "какие остатки на складе", followupContext: null, llmPreDecomposeMeta: null, useMock: false }); expect(decision.runAddressLane).toBe(true); expect(decision.toolGateDecision).toBe("run_address_lane"); expect(decision.toolGateReason).toBe("address_mode_classifier_detected"); expect(decision.livingMode).toBe("address_data"); }); it("does not let deep session continuation override an exact VAT period route", () => { const policy = buildPolicy({ detectAddressQuestionMode: () => ({ mode: "address_query", confidence: "high" }), resolveAddressIntent: () => ({ intent: "vat_liability_confirmed_for_tax_period", confidence: "high" }), resolveAddressToolGateDecision: () => ({ runAddressLane: true, decision: "run_address_lane", reason: "address_mode_classifier_detected" }), hasDeepSessionContinuationSignal: () => true }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "Р° какой НДС РјС‹ должны сгрузить РЅР° март 2020?", effectiveAddressUserMessage: "Р° какой НДС РјС‹ должны сгрузить РЅР° март 2020?", followupContext: null, llmPreDecomposeMeta: { applied: true, llmCanonicalCandidateDetected: true, predecomposeContract: { mode: "address_query", mode_confidence: "high", intent: "vat_liability_confirmed_for_tax_period", intent_confidence: "high" }, semanticExtractionContract: { valid: true, apply_canonical_recommended: true, extraction: { query_shape: "UNKNOWN", aggregation_profile: "unknown" }, guard_hints: { deep_investigation_signal_detected: false } } } as any, useMock: false }); expect(decision.runAddressLane).toBe(true); expect(decision.toolGateDecision).toBe("run_address_lane"); expect(decision.toolGateReason).toBe("address_mode_classifier_detected"); expect(decision.livingMode).toBe("address_data"); expect(decision.orchestrationContract?.deep_session_continuation_fallback_to_deep).toBe(false); }); it("keeps an exact address route out of deep fallback when only semantic deep hint is present", () => { const policy = buildPolicy({ detectAddressQuestionMode: () => ({ mode: "address_query", confidence: "high" }), resolveAddressIntent: () => ({ intent: "vat_liability_confirmed_for_tax_period", confidence: "high" }), resolveAddressToolGateDecision: () => ({ runAddressLane: true, decision: "run_address_lane", reason: "address_mode_classifier_detected" }) }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "какой НДС мы должны заплатить на март 2020", effectiveAddressUserMessage: "какой НДС мы должны заплатить на март 2020", followupContext: null, llmPreDecomposeMeta: { applied: true, llmCanonicalCandidateDetected: true, predecomposeContract: { mode: "address_query", mode_confidence: "high", intent: "vat_liability_confirmed_for_tax_period", intent_confidence: "high" }, semanticExtractionContract: { valid: true, apply_canonical_recommended: true, extraction: { query_shape: "UNKNOWN", aggregation_profile: "unknown" }, guard_hints: { deep_investigation_signal_detected: true } } } as any, useMock: false }); expect(decision.runAddressLane).toBe(true); expect(decision.livingMode).toBe("address_data"); expect(decision.orchestrationContract?.semantic_route_arbitration?.supported_address_intent_detected).toBe(true); expect(decision.orchestrationContract?.deep_analysis_signal_fallback_to_deep).toBe(false); }); it("routes memory recap follow-up over grounded answer to chat", () => { const policy = buildPolicy({ resolveRouteMemorySignals: () => ({ contextualHistoricalCapabilityFollowupDetected: false, contextualMemoryRecapFollowupDetected: true }), findLastGroundedAddressAnswerDebug: () => ({ execution_lane: "address_query" }) }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "Р° ты помнишь что РјС‹ обсуждали?", effectiveAddressUserMessage: "Р° ты помнишь что РјС‹ обсуждали?", followupContext: null, llmPreDecomposeMeta: { applied: false, reason: "normalized_fragment_rejected_semantic_guard", predecomposeContract: { mode: "unsupported", mode_confidence: "low", intent: "unknown", intent_confidence: "low" } }, useMock: false }); expect(decision.runAddressLane).toBe(false); expect(decision.toolGateReason).toBe("memory_recap_followup_detected"); expect(decision.livingMode).toBe("chat"); expect(decision.livingReason).toBe("memory_recap_followup_detected"); }); it("routes answer inspection follow-up over grounded selected-object answer to chat", () => { const policy = buildPolicy({ findLastGroundedAddressAnswerDebug: () => ({ execution_lane: "address_query" }), resolveAddressToolGateDecision: () => ({ runAddressLane: true, decision: "run_address_lane", reason: "address_mode_classifier_detected" }), detectAddressQuestionMode: () => ({ mode: "address_query", confidence: "high" }), isAnswerInspectionFollowupOverGroundedAnswer: () => true }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "у тебя написано кто контрагент: рабочая станция - это ошибка?", effectiveAddressUserMessage: "у тебя написано кто контрагент: рабочая станция - это ошибка?", followupContext: { previous_intent: "inventory_sale_trace_for_item", previous_anchor_type: "item" }, llmPreDecomposeMeta: null, useMock: false }); expect(decision.runAddressLane).toBe(false); expect(decision.toolGateReason).toBe("answer_inspection_followup_over_grounded_answer"); expect(decision.livingMode).toBe("chat"); expect(decision.livingReason).toBe("answer_inspection_followup_detected"); }); it("routes organization fact lookup away from address lane even with follow-up context", () => { const policy = buildPolicy({ hasDataRetrievalRequestSignal: () => true, hasStrongDataIntentSignal: () => true, detectAddressQuestionMode: () => ({ mode: "address_query", confidence: "high" }), resolveAddressIntent: () => ({ intent: "inventory_on_hand_as_of_date", confidence: "low" }), hasOrganizationFactLookupSignal: (text: unknown) => /возраст.*альтернатива плюс/i.test(String(text ?? "")), resolveAddressToolGateDecision: () => ({ runAddressLane: true, decision: "run_address_lane", reason: "address_mode_classifier_detected" }) }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "а какой возраст у Альтернативы Плюс?", effectiveAddressUserMessage: "Какой возраст у контрагента Альтернатива Плюс?", followupContext: { previous_intent: "inventory_on_hand_as_of_date", previous_filters: { organization: "ООО \"Альтернатива Плюс\"", as_of_date: "2021-03-31" }, previous_anchor_type: "item", previous_anchor_value: "Модуль прямоугольный 1400*110*750" }, llmPreDecomposeMeta: null, useMock: false }); expect(decision.runAddressLane).toBe(false); expect(decision.toolGateReason).toBe("organization_fact_lookup_signal_detected"); expect(decision.livingMode).toBe("chat"); expect(decision.livingReason).toBe("organization_fact_lookup_signal_detected"); }); it("routes a late company switch to chat instead of reusing the old address contour", () => { const policy = buildPolicy({ detectAddressQuestionMode: () => ({ mode: "address_query", confidence: "high" }), resolveAddressIntent: () => ({ intent: "inventory_on_hand_as_of_date", confidence: "high" }), resolveAddressToolGateDecision: () => ({ runAddressLane: true, decision: "run_address_lane", reason: "address_mode_classifier_detected" }), resolveOrganizationSelectionFromMessage: () => "РАЙМ", shouldEmitOrganizationSelectionReply: () => true }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "теперь давай по РАЙМ", effectiveAddressUserMessage: "теперь давай по РАЙМ", followupContext: { previous_intent: "inventory_on_hand_as_of_date", previous_filters: { organization: "ООО Альтернатива Плюс", as_of_date: "2026-04-19" } }, sessionItems: [ { role: "assistant", debug: { execution_lane: "address_query", answer_grounding_check: { status: "grounded" }, extracted_filters: { organization: "ООО Альтернатива Плюс", as_of_date: "2026-04-19" } } } ], sessionOrganizationScope: { knownOrganizations: ["ООО Альтернатива Плюс", "РАЙМ"], selectedOrganization: null, activeOrganization: "ООО Альтернатива Плюс" }, llmPreDecomposeMeta: null, useMock: false }); expect(decision.runAddressLane).toBe(false); expect(decision.toolGateReason).toBe("organization_scope_switch_detected"); expect(decision.livingMode).toBe("chat"); expect(decision.livingReason).toBe("organization_scope_switch_detected"); expect(decision.orchestrationContract?.organization_scope_switch_detected).toBe(true); expect(decision.orchestrationContract?.organization_scope_selection).toBe("РАЙМ"); }); it("routes explicit recap wording with selected-object phrasing to chat even when address-like cues exist", () => { const policy = buildPolicy({ hasStrongDataIntentSignal: () => true, hasDataRetrievalRequestSignal: () => true, resolveRouteMemorySignals: () => ({ contextualHistoricalCapabilityFollowupDetected: false, contextualMemoryRecapFollowupDetected: true }), findLastGroundedAddressAnswerDebug: () => ({ execution_lane: "address_query", detected_intent: "inventory_purchase_provenance_for_item" }) }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "а ты помнишь, что мы по этой позиции уже выяснили?", effectiveAddressUserMessage: "а ты помнишь, что мы по этой позиции уже выяснили?", followupContext: null, llmPreDecomposeMeta: { applied: false, reason: "normalized_fragment_rejected_semantic_guard", predecomposeContract: { mode: "unsupported", mode_confidence: "low", intent: "unknown", intent_confidence: "low" } }, useMock: false }); expect(decision.runAddressLane).toBe(false); expect(decision.toolGateReason).toBe("memory_recap_followup_detected"); expect(decision.livingMode).toBe("chat"); expect(decision.livingReason).toBe("memory_recap_followup_detected"); }); it("does not force unsupported-intent fallback when predecompose runtime is unavailable", () => { const policy = buildPolicy({ hasStrongDataIntentSignal: () => true, hasDataRetrievalRequestSignal: () => true, resolveAddressToolGateDecision: () => ({ runAddressLane: true, decision: "run_address_lane", reason: "address_mode_classifier_detected" }) }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "покажи документы по сверке", effectiveAddressUserMessage: "покажи документы по сверке", followupContext: { root_context_only: true }, llmPreDecomposeMeta: { reason: "error:OpenAI API key is missing", predecomposeContract: { mode: "unsupported", mode_confidence: "low", intent: "unknown", intent_confidence: "low" } }, useMock: false }); expect(decision.toolGateReason).toBe("address_mode_classifier_detected"); expect(decision.orchestrationContract?.unsupported_address_intent_fallback_to_deep).toBe(false); expect(decision.orchestrationContract?.provider_execution?.llm_runtime_unavailable_detected).toBe(true); }); it("does not classify colloquial VAT root query as non-domain when L0 address gate is positive", () => { const policy = buildPolicy({ hasStrongDataIntentSignal: () => true, resolveAddressToolGateDecision: () => ({ runAddressLane: true, decision: "run_address_lane", reason: "address_signal_detected" }) }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "скок ндс надо заплатить в налоговую на февраль 2017", effectiveAddressUserMessage: "скок ндс надо заплатить в налоговую на февраль 2017", followupContext: null, llmPreDecomposeMeta: null, useMock: true }); expect(decision.runAddressLane).toBe(true); expect(decision.toolGateReason).toBe("address_signal_detected"); expect(decision.livingMode).toBe("address_data"); }); it("does not mark organization selection after grounded continuity as non-domain noise", () => { const policy = buildPolicy({ findLastGroundedAddressAnswerDebug: () => null, findLastOrganizationClarificationAddressDebug: () => ({ organization_candidates: ["Org A", "Org B"] }), resolveOrganizationSelectionFromMessage: (userMessage: unknown, knownOrganizations: unknown) => { const normalized = String(userMessage ?? "").trim().toLowerCase(); const candidates = Array.isArray(knownOrganizations) ? knownOrganizations.map((item) => String(item)) : []; return candidates.find((candidate) => candidate.toLowerCase() === normalized) ?? null; } }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "Org A", effectiveAddressUserMessage: "Org A", followupContext: null, llmPreDecomposeMeta: null, sessionItems: [ { role: "assistant", debug: { execution_lane: "address_query", answer_grounding_check: { status: "grounded" }, extracted_filters: { organization: "Org A", as_of_date: "2021-03-31" }, detected_intent: "receivables_confirmed_as_of_date" } } ], useMock: false }); expect(decision.runAddressLane).toBe(false); expect(decision.toolGateReason).toBe("no_address_signal_after_l0"); expect(decision.livingMode).toBe("chat"); expect(decision.orchestrationContract?.hard_meta_mode).toBeNull(); expect(decision.orchestrationContract?.followup_context_detected).toBe(false); }); it("does not turn short entity follow-up into organization switch just because scope already has an active company", () => { const policy = buildPolicy({ resolveAddressToolGateDecision: undefined, findLastOrganizationClarificationAddressDebug: () => ({ execution_lane: "address_query", limited_reason_category: "missing_anchor", organization_candidates: ["ООО Альтернатива Плюс", "ООО Лайсвуд", "РАЙМ"] }), shouldEmitOrganizationSelectionReply: () => true }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "а по свк", effectiveAddressUserMessage: "а по свк", followupContext: { previous_intent: "list_documents_by_counterparty", previous_filters: { counterparty: "Чепурнов П.Д." }, previous_anchor_type: "counterparty", previous_anchor_value: "Чепурнов П.Д." }, sessionItems: [ { role: "assistant", debug: { execution_lane: "address_query", answer_grounding_check: { status: "grounded" }, detected_intent: "list_documents_by_counterparty", extracted_filters: { counterparty: "Чепурнов П.Д.", organization: "ООО Альтернатива Плюс" } } } ], sessionOrganizationScope: { knownOrganizations: ["ООО Альтернатива Плюс", "ООО Лайсвуд", "РАЙМ"], selectedOrganization: "ООО Альтернатива Плюс", activeOrganization: "ООО Альтернатива Плюс" }, llmPreDecomposeMeta: null, useMock: false }); expect(decision.toolGateReason).not.toBe("organization_scope_switch_detected"); expect(decision.orchestrationContract?.organization_scope_switch_detected).not.toBe(true); }); it("keeps company activity assessment follow-up in address lane when lifecycle intent is resolved from grounded continuity", () => { const policy = buildPolicy({ resolveAddressIntent: () => ({ intent: "counterparty_activity_lifecycle", confidence: "high" }), findLastGroundedAddressAnswerDebug: () => ({ execution_lane: "address_query", answer_grounding_check: { status: "grounded" }, detected_intent: "counterparty_activity_lifecycle", extracted_filters: { organization: 'ООО "Альтернатива Плюс"', period_to: "2026-04-18" } }), resolveAddressToolGateDecision: () => ({ runAddressLane: false, decision: "skip_address_lane", reason: "no_address_signal_after_l0" }) }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "Как ты оценишь деятельность компании?", effectiveAddressUserMessage: "Как ты оценишь деятельность компании?", followupContext: null, llmPreDecomposeMeta: { applied: true, predecomposeContract: { mode: "unsupported", mode_confidence: "low", intent: "unknown", intent_confidence: "low" }, semanticExtractionContract: { valid: true, apply_canonical_recommended: true, extraction: { query_shape: "UNKNOWN", aggregation_profile: "unknown" }, guard_hints: { deep_investigation_signal_detected: false } } }, sessionItems: [ { role: "assistant", debug: { execution_lane: "address_query", answer_grounding_check: { status: "grounded" }, detected_intent: "counterparty_activity_lifecycle", extracted_filters: { organization: 'ООО "Альтернатива Плюс"', period_to: "2026-04-18" } } } ], useMock: false }); expect(decision.runAddressLane).toBe(true); expect(decision.toolGateDecision).toBe("run_address_lane"); expect(decision.livingMode).toBe("address_data"); }); it("recovers an address route from current-turn meaning when L0 resolver is noisy", () => { const policy = buildPolicy({ resolveAddressToolGateDecision: undefined, resolveAssistantTurnMeaning: () => ({ schema_version: "assistant_turn_meaning_v1", explicit_intent_candidate: "receivables_confirmed_as_of_date", meaning_confidence: "high", reason_codes: ["receivables_current_turn_meaning_signal"], stale_replay_forbidden: false }) }); const decision = policy.resolveAssistantOrchestrationDecision({ rawUserMessage: "\u043a\u0442\u043e \u043d\u0430\u043c\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u0434\u0435\u043d\u0435\u0433 \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f", effectiveAddressUserMessage: "\u043a\u0442\u043e \u043d\u0430\u043c\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u0434\u0435\u043d\u0435\u0433 \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f", followupContext: null, llmPreDecomposeMeta: null, useMock: false }); expect(decision.runAddressLane).toBe(true); expect(decision.livingMode).toBe("address_data"); expect(decision.orchestrationContract?.address_intent).toBe("receivables_confirmed_as_of_date"); expect(decision.orchestrationContract?.assistant_turn_meaning?.schema_version).toBe( "assistant_turn_meaning_v1" ); }); });