diff --git a/docs/ARCH/11 - architecture_turnaround/11 - continuity_stabilization_plan_2026-04-17.md b/docs/ARCH/11 - architecture_turnaround/11 - continuity_stabilization_plan_2026-04-17.md index d34067e..14d04c7 100644 --- a/docs/ARCH/11 - architecture_turnaround/11 - continuity_stabilization_plan_2026-04-17.md +++ b/docs/ARCH/11 - architecture_turnaround/11 - continuity_stabilization_plan_2026-04-17.md @@ -486,6 +486,19 @@ Still open after the accepted phase12 replay: - this matters because `address vs deep` arbitration is one of the last heavy control-plane seams in the project: it decides whether the assistant stays in exact-data mode or escalates into deep-analysis mode, and leaving that logic as a long inline branch makes future domain expansion much more likely to reintroduce contradictory fallback rules; - the move does not change the route owner, but it makes the owner explicit and testable as one decision unit inside route policy rather than a fragile chain of local booleans; - targeted route/continuity/transition suites remain green after the move, and a fresh live rerun of `address_truth_harness_phase12_wider_saved_session_pool` on `2026-04-19` remains accepted `20/20`, which is the proof that the flagship mixed contour survives the extraction of the deep fallback arbitration seam. +- the next route-arbitration pass now extracts the protected exact-route contract from another dense inline branch: + - `assistantRoutePolicy` now owns `resolveAddressLaneProtectionArbitration(...)`, so the following coupled verdicts are produced by one explicit helper instead of a scattered cluster of route-local booleans: + - `supportedAddressIntentDetected` + - `supportedAddressRouteCandidateDetected` + - `semanticDeepInvestigationHintDetected` + - `semanticAggregateShapeDetected` + - `followupSemanticOverrideToDeepAllowed` + - `exactAddressIntentProtectedFromSemanticDeepHint` + - `protectAddressLaneFromFallback` + - this matters because the exact-route protection contract is what stops a valid address route from being pulled into deep-analysis mode just because semantic guards or hybrid prompts hint at deeper investigation; + - keeping that contract in one helper reduces another major chance that future domain expansion introduces contradictory exact-route vs deep-fallback precedence in nearby branches; + - targeted route/continuity/transition suites remain green after the move, including direct regression coverage that an exact VAT route must stay in the address lane even when only a semantic deep hint is present; + - a fresh live rerun of `address_truth_harness_phase12_wider_saved_session_pool` on `2026-04-19` remains accepted `20/20`, which is the proof that the flagship mixed contour still survives after extracting the route-protection seam. ## Next Execution Slice (2026-04-18) diff --git a/llm_normalizer/backend/dist/services/assistantRoutePolicy.js b/llm_normalizer/backend/dist/services/assistantRoutePolicy.js index 3629a3b..1ae3508 100644 --- a/llm_normalizer/backend/dist/services/assistantRoutePolicy.js +++ b/llm_normalizer/backend/dist/services/assistantRoutePolicy.js @@ -89,6 +89,59 @@ function resolveAddressFallbackToDeepArbitration(input) { deepSessionContinuationFallbackToDeep }; } +function resolveAddressLaneProtectionArbitration(input) { + const { resolvedIntent, llmContractIntent, llmContractMode, strictDeepInvestigationCueDetected, strictDeepInvestigationBypassAllowed, openContractsAddressSignal, keepAddressLaneByIntent, baseToolGateRunAddressLane, baseToolGateReason, semanticExtractionContract, followupContext, rootContextOnlyFollowup, semanticApplyCanonicalRecommended, deepAnalysisPreferenceDetected } = input; + const supportedAddressIntentDetected = (!strictDeepInvestigationCueDetected || strictDeepInvestigationBypassAllowed) && + Boolean((resolvedIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(resolvedIntent)) || + (llmContractIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent)) || + openContractsAddressSignal); + const supportedAddressRouteCandidateDetected = Boolean(supportedAddressIntentDetected || + keepAddressLaneByIntent || + (baseToolGateRunAddressLane && + llmContractMode !== "deep_analysis" && + !strictDeepInvestigationCueDetected && + ["address_intent_resolver_detected", "address_mode_classifier_detected", "address_signal_detected", "llm_canonical_data_signal_detected"].includes(String(baseToolGateReason ?? "")))); + const semanticGuardHints = semanticExtractionContract?.guard_hints && + typeof semanticExtractionContract.guard_hints === "object" + ? semanticExtractionContract.guard_hints + : null; + const semanticExtraction = semanticExtractionContract?.extraction && + typeof semanticExtractionContract.extraction === "object" + ? semanticExtractionContract.extraction + : null; + const semanticDeepInvestigationHintDetected = semanticGuardHints?.deep_investigation_signal_detected === true; + const semanticAggregateShapeDetected = semanticExtraction?.query_shape === "AGGREGATE_LOOKUP" || + semanticExtraction?.aggregation_profile === "management_profile"; + const followupSemanticOverrideToDeepAllowed = Boolean(followupContext && + !supportedAddressIntentDetected && + (rootContextOnlyFollowup || + llmContractMode === "unsupported" || + semanticAggregateShapeDetected || + semanticDeepInvestigationHintDetected || + !semanticApplyCanonicalRecommended)); + const exactAddressIntentProtectedFromSemanticDeepHint = Boolean(supportedAddressRouteCandidateDetected && + llmContractMode === "address_query" && + llmContractIntent && + ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent) && + semanticApplyCanonicalRecommended && + !deepAnalysisPreferenceDetected && + !strictDeepInvestigationCueDetected && + !semanticAggregateShapeDetected); + const protectAddressLaneFromFallback = Boolean(supportedAddressRouteCandidateDetected && + !deepAnalysisPreferenceDetected && + (exactAddressIntentProtectedFromSemanticDeepHint || + !semanticDeepInvestigationHintDetected || + strictDeepInvestigationBypassAllowed)); + return { + supportedAddressIntentDetected, + supportedAddressRouteCandidateDetected, + semanticDeepInvestigationHintDetected, + semanticAggregateShapeDetected, + followupSemanticOverrideToDeepAllowed, + exactAddressIntentProtectedFromSemanticDeepHint, + protectAddressLaneFromFallback + }; +} function createAssistantRoutePolicy(deps) { const { repairAddressMojibake, findLastGroundedAddressAnswerDebug, findLastOrganizationClarificationAddressDebug, mergeKnownOrganizations, normalizeOrganizationScopeValue, resolveOrganizationSelectionFromMessage, resolveMetaSignalSet, resolveHardMetaMode, isMetaFollowupOverGroundedAnswer, isAnswerInspectionFollowupOverGroundedAnswer, hasDataRetrievalRequestSignal, hasOrganizationFactLookupSignal, hasOrganizationFactFollowupSignal, hasAggregateBusinessAnalyticsSignal, hasStandaloneAddressTopicSignal, hasOpenContractsAddressSignal, detectAddressQuestionMode, resolveAddressIntent, toNonEmptyString, hasStrictDeepInvestigationCue, hasStrongDataIntentSignal, hasAccountingSignal, hasDangerOrCoercionSignal, hasAddressFollowupContextSignal, hasShortDebtMirrorFollowupSignal, isInventorySelectedObjectIntent, hasShortInventoryObjectFollowupSignal, isGroundedInventoryContextDebug, resolveRouteMemorySignals, findLastAddressAssistantItem, resolveAddressToolGateDecision: resolveAddressToolGateDecisionOverride, hasAddressLlmPreDecomposeCandidate, hasSameDateAccountFollowupSignalForPredecompose, hasLooseAllTimeAddressLookupSignal, hasDeepAnalysisPreferenceSignal, hasDirectDeepAnalysisSignal, compactWhitespace, hasDeepSessionContinuationSignal, resolveLivingAssistantModeDecision, resolveProviderExecutionState } = deps; function resolveBaseAddressToolGateDecision(addressInputMessage, followupContext, llmPreDecomposeMeta = null, rawUserMessage = null) { @@ -788,39 +841,6 @@ function createAssistantRoutePolicy(deps) { hasShortDebtMirrorFollowupSignal(repairedRawUserMessage) || hasShortDebtMirrorFollowupSignal(repairedEffectiveAddressUserMessage) || inventoryRootRestatementFollowupDetected); - const supportedAddressIntentDetected = (!strictDeepInvestigationCueDetected || strictDeepInvestigationBypassAllowed) && - Boolean((resolvedIntentResolution.intent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(resolvedIntentResolution.intent)) || - (llmContractIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent)) || - openContractsAddressSignal); - const supportedAddressRouteCandidateDetected = Boolean(supportedAddressIntentDetected || - keepAddressLaneByIntent || - (baseToolGate?.runAddressLane && - llmContractMode !== "deep_analysis" && - !strictDeepInvestigationCueDetected && - ["address_intent_resolver_detected", "address_mode_classifier_detected", "address_signal_detected", "llm_canonical_data_signal_detected"].includes(String(baseToolGate?.reason ?? "")))); - const semanticGuardHints = semanticExtractionContract?.guard_hints && - typeof semanticExtractionContract.guard_hints === "object" - ? semanticExtractionContract.guard_hints - : null; - const semanticExtraction = semanticExtractionContract?.extraction && - typeof semanticExtractionContract.extraction === "object" - ? semanticExtractionContract.extraction - : null; - const semanticDeepInvestigationHintDetected = semanticGuardHints?.deep_investigation_signal_detected === true; - const semanticAggregateShapeDetected = semanticExtraction?.query_shape === "AGGREGATE_LOOKUP" || - semanticExtraction?.aggregation_profile === "management_profile"; - const followupSemanticOverrideToDeepAllowed = Boolean(followupContext && - !supportedAddressIntentDetected && - (rootContextOnlyFollowup || - llmContractMode === "unsupported" || - semanticAggregateShapeDetected || - semanticDeepInvestigationHintDetected || - !semanticApplyCanonicalRecommended)); - const unsupportedIntentOrMode = (resolvedModeDetection.mode !== "address_query" && resolvedIntentResolution.intent === "unknown") || - llmContractMode === "unsupported" || - (rootContextOnlyFollowup && - resolvedIntentResolution.intent === "unknown" && - (!llmContractIntent || llmContractIntent === "unknown")); const deepAnalysisPreferenceDetected = Boolean(hasDeepAnalysisPreferenceSignal(rawUserMessage) || hasDeepAnalysisPreferenceSignal(repairedRawUserMessage) || hasDeepAnalysisPreferenceSignal(effectiveAddressUserMessage) || @@ -829,19 +849,34 @@ function createAssistantRoutePolicy(deps) { hasDirectDeepAnalysisSignal(repairedRawUserMessage) || hasDirectDeepAnalysisSignal(effectiveAddressUserMessage) || hasDirectDeepAnalysisSignal(repairedEffectiveAddressUserMessage)); - const exactAddressIntentProtectedFromSemanticDeepHint = Boolean(supportedAddressRouteCandidateDetected && - llmContractMode === "address_query" && - llmContractIntent && - ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent) && - semanticApplyCanonicalRecommended && - !deepAnalysisPreferenceDetected && - !strictDeepInvestigationCueDetected && - !semanticAggregateShapeDetected); - const protectAddressLaneFromFallback = Boolean(supportedAddressRouteCandidateDetected && - !deepAnalysisPreferenceDetected && - (exactAddressIntentProtectedFromSemanticDeepHint || - !semanticDeepInvestigationHintDetected || - strictDeepInvestigationBypassAllowed)); + const laneProtectionArbitration = resolveAddressLaneProtectionArbitration({ + resolvedIntent: resolvedIntentResolution.intent, + llmContractIntent, + llmContractMode, + strictDeepInvestigationCueDetected, + strictDeepInvestigationBypassAllowed, + openContractsAddressSignal, + keepAddressLaneByIntent, + baseToolGateRunAddressLane: Boolean(baseToolGate?.runAddressLane), + baseToolGateReason: baseToolGate?.reason, + semanticExtractionContract, + followupContext, + rootContextOnlyFollowup, + semanticApplyCanonicalRecommended, + deepAnalysisPreferenceDetected + }); + const supportedAddressIntentDetected = laneProtectionArbitration.supportedAddressIntentDetected; + const supportedAddressRouteCandidateDetected = laneProtectionArbitration.supportedAddressRouteCandidateDetected; + const semanticDeepInvestigationHintDetected = laneProtectionArbitration.semanticDeepInvestigationHintDetected; + const semanticAggregateShapeDetected = laneProtectionArbitration.semanticAggregateShapeDetected; + const followupSemanticOverrideToDeepAllowed = laneProtectionArbitration.followupSemanticOverrideToDeepAllowed; + const unsupportedIntentOrMode = (resolvedModeDetection.mode !== "address_query" && resolvedIntentResolution.intent === "unknown") || + llmContractMode === "unsupported" || + (rootContextOnlyFollowup && + resolvedIntentResolution.intent === "unknown" && + (!llmContractIntent || llmContractIntent === "unknown")); + const exactAddressIntentProtectedFromSemanticDeepHint = laneProtectionArbitration.exactAddressIntentProtectedFromSemanticDeepHint; + const protectAddressLaneFromFallback = laneProtectionArbitration.protectAddressLaneFromFallback; const vatExplainFollowupSignal = Boolean(followupContext && toNonEmptyString(followupContext.previous_intent) === "vat_payable_forecast" && /(?:\u043f\u043e\u0447\u0435\u043c\u0443|why).*(?:\u043f\u0440\u043e\u0433\u043d\u043e\u0437|forecast).*(?:\u0443\u043f\u043b\u0430\u0442|payable|\b0\b)/iu.test(compactWhitespace(`${repairedRawUserMessage} ${repairedEffectiveAddressUserMessage}`))); diff --git a/llm_normalizer/backend/src/services/assistantRoutePolicy.ts b/llm_normalizer/backend/src/services/assistantRoutePolicy.ts index 16b7f59..9fb75a6 100644 --- a/llm_normalizer/backend/src/services/assistantRoutePolicy.ts +++ b/llm_normalizer/backend/src/services/assistantRoutePolicy.ts @@ -112,6 +112,74 @@ function resolveAddressFallbackToDeepArbitration(input) { deepSessionContinuationFallbackToDeep }; } +function resolveAddressLaneProtectionArbitration(input) { + const { + resolvedIntent, + llmContractIntent, + llmContractMode, + strictDeepInvestigationCueDetected, + strictDeepInvestigationBypassAllowed, + openContractsAddressSignal, + keepAddressLaneByIntent, + baseToolGateRunAddressLane, + baseToolGateReason, + semanticExtractionContract, + followupContext, + rootContextOnlyFollowup, + semanticApplyCanonicalRecommended, + deepAnalysisPreferenceDetected + } = input; + const supportedAddressIntentDetected = (!strictDeepInvestigationCueDetected || strictDeepInvestigationBypassAllowed) && + Boolean((resolvedIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(resolvedIntent)) || + (llmContractIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent)) || + openContractsAddressSignal); + const supportedAddressRouteCandidateDetected = Boolean(supportedAddressIntentDetected || + keepAddressLaneByIntent || + (baseToolGateRunAddressLane && + llmContractMode !== "deep_analysis" && + !strictDeepInvestigationCueDetected && + ["address_intent_resolver_detected", "address_mode_classifier_detected", "address_signal_detected", "llm_canonical_data_signal_detected"].includes(String(baseToolGateReason ?? "")))); + const semanticGuardHints = semanticExtractionContract?.guard_hints && + typeof semanticExtractionContract.guard_hints === "object" + ? semanticExtractionContract.guard_hints + : null; + const semanticExtraction = semanticExtractionContract?.extraction && + typeof semanticExtractionContract.extraction === "object" + ? semanticExtractionContract.extraction + : null; + const semanticDeepInvestigationHintDetected = semanticGuardHints?.deep_investigation_signal_detected === true; + const semanticAggregateShapeDetected = semanticExtraction?.query_shape === "AGGREGATE_LOOKUP" || + semanticExtraction?.aggregation_profile === "management_profile"; + const followupSemanticOverrideToDeepAllowed = Boolean(followupContext && + !supportedAddressIntentDetected && + (rootContextOnlyFollowup || + llmContractMode === "unsupported" || + semanticAggregateShapeDetected || + semanticDeepInvestigationHintDetected || + !semanticApplyCanonicalRecommended)); + const exactAddressIntentProtectedFromSemanticDeepHint = Boolean(supportedAddressRouteCandidateDetected && + llmContractMode === "address_query" && + llmContractIntent && + ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent) && + semanticApplyCanonicalRecommended && + !deepAnalysisPreferenceDetected && + !strictDeepInvestigationCueDetected && + !semanticAggregateShapeDetected); + const protectAddressLaneFromFallback = Boolean(supportedAddressRouteCandidateDetected && + !deepAnalysisPreferenceDetected && + (exactAddressIntentProtectedFromSemanticDeepHint || + !semanticDeepInvestigationHintDetected || + strictDeepInvestigationBypassAllowed)); + return { + supportedAddressIntentDetected, + supportedAddressRouteCandidateDetected, + semanticDeepInvestigationHintDetected, + semanticAggregateShapeDetected, + followupSemanticOverrideToDeepAllowed, + exactAddressIntentProtectedFromSemanticDeepHint, + protectAddressLaneFromFallback + }; +} export function createAssistantRoutePolicy(deps) { const { repairAddressMojibake, @@ -852,39 +920,6 @@ export function createAssistantRoutePolicy(deps) { hasShortDebtMirrorFollowupSignal(repairedRawUserMessage) || hasShortDebtMirrorFollowupSignal(repairedEffectiveAddressUserMessage) || inventoryRootRestatementFollowupDetected); - const supportedAddressIntentDetected = (!strictDeepInvestigationCueDetected || strictDeepInvestigationBypassAllowed) && - Boolean((resolvedIntentResolution.intent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(resolvedIntentResolution.intent)) || - (llmContractIntent && ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent)) || - openContractsAddressSignal); - const supportedAddressRouteCandidateDetected = Boolean(supportedAddressIntentDetected || - keepAddressLaneByIntent || - (baseToolGate?.runAddressLane && - llmContractMode !== "deep_analysis" && - !strictDeepInvestigationCueDetected && - ["address_intent_resolver_detected", "address_mode_classifier_detected", "address_signal_detected", "llm_canonical_data_signal_detected"].includes(String(baseToolGate?.reason ?? "")))); - const semanticGuardHints = semanticExtractionContract?.guard_hints && - typeof semanticExtractionContract.guard_hints === "object" - ? semanticExtractionContract.guard_hints - : null; - const semanticExtraction = semanticExtractionContract?.extraction && - typeof semanticExtractionContract.extraction === "object" - ? semanticExtractionContract.extraction - : null; - const semanticDeepInvestigationHintDetected = semanticGuardHints?.deep_investigation_signal_detected === true; - const semanticAggregateShapeDetected = semanticExtraction?.query_shape === "AGGREGATE_LOOKUP" || - semanticExtraction?.aggregation_profile === "management_profile"; - const followupSemanticOverrideToDeepAllowed = Boolean(followupContext && - !supportedAddressIntentDetected && - (rootContextOnlyFollowup || - llmContractMode === "unsupported" || - semanticAggregateShapeDetected || - semanticDeepInvestigationHintDetected || - !semanticApplyCanonicalRecommended)); - const unsupportedIntentOrMode = (resolvedModeDetection.mode !== "address_query" && resolvedIntentResolution.intent === "unknown") || - llmContractMode === "unsupported" || - (rootContextOnlyFollowup && - resolvedIntentResolution.intent === "unknown" && - (!llmContractIntent || llmContractIntent === "unknown")); const deepAnalysisPreferenceDetected = Boolean(hasDeepAnalysisPreferenceSignal(rawUserMessage) || hasDeepAnalysisPreferenceSignal(repairedRawUserMessage) || hasDeepAnalysisPreferenceSignal(effectiveAddressUserMessage) || @@ -893,19 +928,34 @@ export function createAssistantRoutePolicy(deps) { hasDirectDeepAnalysisSignal(repairedRawUserMessage) || hasDirectDeepAnalysisSignal(effectiveAddressUserMessage) || hasDirectDeepAnalysisSignal(repairedEffectiveAddressUserMessage)); - const exactAddressIntentProtectedFromSemanticDeepHint = Boolean(supportedAddressRouteCandidateDetected && - llmContractMode === "address_query" && - llmContractIntent && - ADDRESS_INTENTS_KEEP_ADDRESS_LANE.has(llmContractIntent) && - semanticApplyCanonicalRecommended && - !deepAnalysisPreferenceDetected && - !strictDeepInvestigationCueDetected && - !semanticAggregateShapeDetected); - const protectAddressLaneFromFallback = Boolean(supportedAddressRouteCandidateDetected && - !deepAnalysisPreferenceDetected && - (exactAddressIntentProtectedFromSemanticDeepHint || - !semanticDeepInvestigationHintDetected || - strictDeepInvestigationBypassAllowed)); + const laneProtectionArbitration = resolveAddressLaneProtectionArbitration({ + resolvedIntent: resolvedIntentResolution.intent, + llmContractIntent, + llmContractMode, + strictDeepInvestigationCueDetected, + strictDeepInvestigationBypassAllowed, + openContractsAddressSignal, + keepAddressLaneByIntent, + baseToolGateRunAddressLane: Boolean(baseToolGate?.runAddressLane), + baseToolGateReason: baseToolGate?.reason, + semanticExtractionContract, + followupContext, + rootContextOnlyFollowup, + semanticApplyCanonicalRecommended, + deepAnalysisPreferenceDetected + }); + const supportedAddressIntentDetected = laneProtectionArbitration.supportedAddressIntentDetected; + const supportedAddressRouteCandidateDetected = laneProtectionArbitration.supportedAddressRouteCandidateDetected; + const semanticDeepInvestigationHintDetected = laneProtectionArbitration.semanticDeepInvestigationHintDetected; + const semanticAggregateShapeDetected = laneProtectionArbitration.semanticAggregateShapeDetected; + const followupSemanticOverrideToDeepAllowed = laneProtectionArbitration.followupSemanticOverrideToDeepAllowed; + const unsupportedIntentOrMode = (resolvedModeDetection.mode !== "address_query" && resolvedIntentResolution.intent === "unknown") || + llmContractMode === "unsupported" || + (rootContextOnlyFollowup && + resolvedIntentResolution.intent === "unknown" && + (!llmContractIntent || llmContractIntent === "unknown")); + const exactAddressIntentProtectedFromSemanticDeepHint = laneProtectionArbitration.exactAddressIntentProtectedFromSemanticDeepHint; + const protectAddressLaneFromFallback = laneProtectionArbitration.protectAddressLaneFromFallback; const vatExplainFollowupSignal = Boolean(followupContext && toNonEmptyString(followupContext.previous_intent) === "vat_payable_forecast" && /(?:\u043f\u043e\u0447\u0435\u043c\u0443|why).*(?:\u043f\u0440\u043e\u0433\u043d\u043e\u0437|forecast).*(?:\u0443\u043f\u043b\u0430\u0442|payable|\b0\b)/iu.test(compactWhitespace(`${repairedRawUserMessage} ${repairedEffectiveAddressUserMessage}`))); diff --git a/llm_normalizer/backend/tests/assistantRoutePolicy.test.ts b/llm_normalizer/backend/tests/assistantRoutePolicy.test.ts index 3e27739..43f7178 100644 --- a/llm_normalizer/backend/tests/assistantRoutePolicy.test.ts +++ b/llm_normalizer/backend/tests/assistantRoutePolicy.test.ts @@ -229,6 +229,51 @@ describe("assistantRoutePolicy", () => { 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: () => ({